Elmord's Magic Valley

Software, lingüística e rock'n'roll. Às vezes em Português, sometimes in English.

Posts com a tag: mundane

15 graus a leste

2012-10-15 00:27 -0300. Tags: comp, unix, mundane, random, em-portugues

No próximo domingo, dia 21 de outubro de 2012, diversas cidades brasileiras sofrerão um deslocamento de 15 graus para leste, e por conseguinte estarão sob o fuso-horário -2. Habitantes dessas cidades deverão ajustar seus relógios de acordo. O fenômeno geológico ocorre todo ano por volta da terceira semana de outubro, e encerra-se por volta da terceira semana de fevereiro do ano seguinte, quando um deslocamento reverso restaura as posições originais das cidades.

Graças à regularidade do fenômeno, muitos sistemas operacionais já vêm preparados para realizar a mudança de fuso-horário automaticamente. A usuários que ajustam seus relógios manualmente, recomenda-se ajustar o fuso-horário do sistema (com um comando do tipo ln -sf /usr/share/zoneinfo/Etc/GMT+2 /etc/localtime em sistemas GNU/Linux), ao invés de adiantar o relógio em uma hora, já que o relógio do sistema é mantido em UTC, que não é afetado pelo deslocamento.

(Os nomes dos fusos-horários em /usr/share/zoneinfo/Etc possuem sinais contrários aos dos nomes convencionais dos fusos (i.e., o fuso-horário -2 corresponde ao arquivo GMT+2). A convenção de sinais anti-intuitivos vem de uma longa tradição na comunidade científica enraizada na nomenclatura das cargas elétricas.)

Recomenda-se fortemente manter-se sentado em uma cadeira firme durante o deslocamento, por razões de segurança.

1 comentário / comment

Laptop mode, ACPI, fsync, e a arte de interceptar syscalls

2012-09-27 13:46 -0300. Tags: comp, unix, mundane, prog, em-portugues

Recentemente eu comprei um Dell Inspiron Mini 10 usado. Essa máquina tem uma propriedade peculiar: ela não tem fan! O processador, um Intel Atom N270 1.6GHz, esquenta suficientemente pouco para que a máquina não precise de um. Conseqüentemente, a máquina é dead-silent – ou quase. Infelizmente esse modelo vem com um HD, ao invés de um SSD, e portanto a máquina faz algum barulho, ainda que isso só seja significativo em ambientes realmente silenciosos (e.g., à noite).

Felizmente, esse tal de Linux possui uma feature especial de primeira chamada laptop mode. Quando o laptop mode está ativo e ocorre uma leitura ou escrita física ao disco, o kernel aproveita para escrever em disco todos os blocos sujos (modificados) que estejam em buffers de memória. A idéia é que o disco fique desligado a maior parte do tempo, e nas poucas ocasiões em que ele é "acordado", realizam-se todas as operações de I/O pendentes, de modo que o disco não tenha que ser reativado tão cedo. Para que o laptop mode seja efetivo, é necessário ajustar o kernel para manter as coisas o maior tempo possível em buffers, através de certas configurações em /proc/sys/vm e outros locais. O laptop mode foi concebido para economizar bateria em laptops, mas também serve para deixá-lo mais silencioso.

Easy mode

A maneira mais fácil de usar o laptop mode é através das Laptop Mode Tools (pacote laptop-mode-tools no Debian e derivados), um conjunto de scripts que dão conta de ativar o laptop mode quando a máquina está fora da tomada, e desativá-lo quando a máquina é ligada na tomada e quando a bateria está fraca (evitando que se perca todas as mil coisas que estão em cache caso a bateria acabe). O laptop-mode-tools é um pacote bastante bloated completo, com mais de oito mil opções de configuração e módulos que controlam não somente o HD como diversas outras features de economia de energia, tais como brilho do display, redução da potência de certas placas wireless, USB auto-suspend, entre outras coisas. Basta um apt-get install laptop-mode-tools, e ser feliz para sempre.

Obviamente, tudo isso é insuportável.

True mode

Mais instrutivo é fazer o serviço na mão. O objetivo é ativar o disco apenas esporadicamente, tipicamente a cada 10 minutos. A idéia é que os buffers sejam gravados com uma freqüência suficiente para que não se perca muita coisa caso o sistema sofra uma queda (falta de energia ou whatever), mas se mantenha o disco desligado o maior tempo possível. São três os pontos que exigem configuração.

Arquivos em /proc/sys/vm

/proc/sys é uma interface para diversas variáveis que controlam o comportamento do kernel. /proc/sys/vm, em particular, contém as variáveis que controlam o gerenciamento de memória (Virtual Memory) do kernel. Essas variáveis podem ser manipuladas lendo e escrevendo nos arquivos, assim:

# cat /proc/sys/vm/laptop_mode 
0
# echo 2 >/proc/sys/vm/laptop_mode 
# cat /proc/sys/vm/laptop_mode 
2
As variáveis relevantes para o funcionamento do laptop mode são:
Arquivo Descrição Valor
padrão
Valor
laptop
laptop_mode Define quantos segundos o kernel espera quando ocorre um acesso ao disco para começar a despejar os buffers. 0 desativa o laptop mode. 0 2
dirty_writeback_centisecs Intervalo (em centésimos de segundo) entre ativações do daemon pdflush, que despeja os buffers sujos para o disco. 0 desativa o despejo periódico. 500 60000
dirty_expire_centisecs Tempo (em centésimos de segundo) depois do qual uma página suja é considerada velha o suficiente para ser elegível a ser despejada em disco na próxima ativação do pdflush. 3000 60000
dirty_ratio Percentual de páginas (da memória total) máximo que um processo pode sujar sem forçar um despejo em disco. 40 60
dirty_background_ratio Sem laptop mode: Percentual de páginas sujas (da memória total) que provoca a ativação do pdflush.

Com laptop mode: Percentual de páginas sujas máximo permitido depois de um despejo em disco causado por um processo que tenha excedido a dirty_ratio.

10 1

Os itens da coluna "Valor laptop" indicam valores típicos usados em laptop mode (roubados dos padrões do laptop-mode-tools e de alguma página que já não encontro mais).

Tempo de commit dos sistemas de arquivo

ext3 e outros sistemas de arquivo com journaling realizam um commit periódico (dos dados? dos metadados? do journal? de tudo? respostas são bem-vindas). No caso do ext3, o padrão é fazer um commit a cada 5 segundos. O intervalo de commit de um filesystem pode ser alterado com um comando do tipo:

mount filesystem -o remount,commit=600

onde filesystem pode ser um nome de dispositivo (e.g., /dev/sda1) ou um ponto de montagem (e.g., /).

Tempo de standby do disco e modo de economia de energia

Por fim, agora que evitamos que o disco seja acessado, podemos mandá-lo dormir quando não há acessos. Para isso, usamos o comando hdparm. O hdparm permite configurar dúzias de parâmetros do disco. Os que nos interessam no momento são as seguintes opções:

A sintaxe do hdparm é hdparm opções /dev/dispositivo.

Tudo de uma vez

Agora podemos fazer um pequeno script para ativar e desativar o laptop mode, no que diz respeito ao HD. Você pode colocar esse script em /usr/local/bin/set-laptop-mode, por exemplo. (O script segue a metodologia Facão-Driven Development™, e não se preocupa muito com flexibilidade de configuração. Afinal, basta alterar o fonte!)

#!/bin/bash

# Status atual do laptop mode. Evitaremos executar os comandos
# se o sistema já estiver no modo que queremos.
current_status="$(</proc/sys/vm/laptop_mode)"

# Mas se a primeira opção for -f, fazemos mesmo assim.
[[ $1 = -f ]] && { shift; current_status=-1; }

set_commit_time() {
    # set_commit_time DISK SECONDS
    # Ajusta o commit time de todos os filesystems do dispositivo DISK.
    for filesystem in $(mount | cut -d' ' | grep "^$DISK"); do
        mount "$filesystem" -o remount,commit="$SECONDS"
    done
}

case "$1" in
    on)
        [[ $current_status -gt 0 ]] && exit
        echo 60000 >/proc/sys/vm/dirty_expire_centisecs
        echo 60000 >/proc/sys/vm/dirty_writeback_centisecs
        echo 1 >/proc/sys/vm/dirty_background_ratio
        echo 60 >/proc/sys/vm/dirty_ratio
        echo 2 >/proc/sys/vm/laptop_mode
        set_commit_time sda 600
        hdparm -B 1 -S 4 /dev/sda
        ;;
    off)
        [[ $current_status -eq 0 ]] && exit
        echo 3000 >/proc/sys/vm/dirty_expire_centisecs
        echo 500 >/proc/sys/vm/dirty_writeback_centisecs
        echo 10 >/proc/sys/vm/dirty_background_ratio
        echo 40 >/proc/sys/vm/dirty_ratio
        echo 0 >/proc/sys/vm/laptop_mode
        set_commit_time sda 5
        hdparm -B 128 -S 0 /dev/sda
        ;;
    *)
        echo "Usage: ${0#*/} [-f] on|off" >&2
        exit 1
        ;;
esac

Agora basta dar permissão de executável para o camadada (chmod +x /usr/local/bin/set-laptop-mode), e ativar e desativar o laptop mode com os comandos set-laptop-mode on e set-laptop-mode off.

Mas eu quero automático

Bom, falta fazer o sistema chamar o script sozinho quando o laptop é ligado ou desligado da tomada. Para tal, podemos usar o acpid, um daemonzinho feliz que espera por eventos ACPI e executa comandos de acordo com os eventos que observa. ACPI trata-se do Advanced Configuration and Power Interface, um mecanismo para gerenciamento de energia e controle de certos dispositivos (notavelmente o botão Power da maior parte das máquinas e os botões multimídia de certos notebooks).

O acpid lê os arquivos de configuração contidos em /etc/acpi/events. Cada arquivo tem a forma:

event=regex
action=comando

O acpid identifica os eventos gerados pelo ACPI através de strings (tais como ac_adapter ACPI0003:00 00000080 00000000). Quando um evento é observado, o acpid procura por todos os arquivos cuja regex case com a string do evento, e executa os comandos associados. Na string do comando, o valor %e é substituído pela string do evento, e %% por um % literal. Como o comando é processado pelo shell, deve-se usar aspas em torno do %e caso não se queira que o shell splite a string de evento em palavras ou faça algum outro tipo de expansão.

Podemos então criar um arquivinho /etc/acpi/auto-laptop-mode:

event=ac_adapter.*
action=/usr/local/bin/auto-laptop-mode

Isso fará com que, toda vez que a máquina seja ligada ou desligada da tomada, o script /usr/local/bin/auto-laptop-mode seja chamado. Falta escrever o tal script. Ao invés de usarmos os números místicos da string de evento para determinar se a máquina foi ligada ou desligada, vamos ao invés disso usar o comando acpi para determinar o status da bateria (que é Discharging caso a máquina não esteja na tomada). Uma vantagem disso é que poderemos chamar o script por fora do ACPI (por exemplo, na inicialização da máquina, ou na cron).

O comando acpi imprime uma string do tipo:

Battery 0: Discharging, 97%, 01:56:46 remaining

Podemos extrair os dados que nos interessam com um sed:

# acpi | sed -r 's/^[^:]*: ([^,]*), ([0-9]+)%.*/\1 \2/'
Discharging 97

Nosso script ativará o laptop mode se a máquina não estiver na tomada e houver pelo menos 5% de carga, e o desativará caso contrário.

#!/bin/bash

# Coloca o status e o percentual de carga em $1 e $2.
set -- $(acpi | sed -r 's/^[^:]*: ([^,]*), ([0-9]+)%.*/\1 \2/')

if [[ $1 = Discharging && $2 -gt 5 ]]; then
    set-laptop-mode on
else
    set-laptop-mode off
fi

E está feito. Só temos um problema: quando a bateria ficar fraca, o evento ac_adapter não será gerado, e portanto o laptop mode não será desativado automaticamente. Há duas soluções para esse problema:

  1. Se a sua máquina gera eventos do tipo battery quando é (des)ligada na tomada e quando a bateria está fraca (o que não é o meu caso), você pode substituir a expressão regular do evento em /etc/acpi/events/auto-laptop-mode por battery.*.
  2. Se essa solução não lhe serve, você pode colocar uma tarefa na cron para executar o script uma vez por minuto. É por essa razão que o set-laptop-mode evita executar comandos caso seja executado múltiplas vezes: se colocado na cron, o script será chamado inúmeras vezes sem que tenha que fazer nada. Basta a seguinte linha no /etc/crontab:
    * * * * * root /usr/local/bin/auto-laptop-mode

    Você pode substituir o primeiro * por */5 para executar o script a cada 5 minutos, por exemplo.

Com isso, fizemos em cinqüenta linhas o que o laptop-mode-tools faz em umas mil, mais os módulos. Nada como o raciocínio categorial.

fsync

Tanto laptop-mode-tools quanto a nossa solução nos deixa um problema. Alguns programas fazem uso das chamadas de sistema fsync e fdatasync. Essas chamadas forçam o kernel a despejar os buffers de um arquivo para disco, e são usadas para garantir a consistência desses arquivos em caso de um crash do sistema. O kernel sempre obedece a essas chamadas, mesmo com o laptop mode ativo, fazendo com que o disco seja ativado. Se algum programa faz uso freqüente dessas chamadas, o laptop mode se torna inútil.

Três são os vilões mais comuns: o syslog, editores de texto como Vim e Emacs, e o Firefox.

O syslog pode ser configurado para não forçar o despejo dos logs adicionando-se um - antes dos nomes dos arquivos para os quais se deseja evitar o fsync nos arquivos de configuração (/etc/rsyslog.conf e /etc/rsyslog.d/*).

O Vim faz o fsync dos arquivos quando são salvos. Isso pode ser controlado pela opção fsync: :set fsync ativa o despejo automático (o padrão), e :set nofsync desativa. Além disso, o Vim faz o fsync dos swapfiles, arquivos temporários que são usados para recuperação de modificações caso haja um crash durante a edição antes de o arquivo ser salvo. Isso é controlado pela opção swapsync: se seu valor for fsync (o padrão), é usada a chamada a fsync na gravação do swapfile; se seu valor for sync, uma chamada a sync é feita; se for a string vazia, nada é feito.

Uma conseqüência de não fsyncar os arquivos é que se houver um crash seu trabalho pode ser perdido. Uma alternativa seria não sincronizar os arquivos quando salvos, mas sincronizar os arquivos de swap, e colocá-los em uma outra unidade (um pendrive ou um SD-card, por exemplo). Assim, se houver um crash os swapfiles são capazes de recuperar o arquivo, mas se evita escrever no HD. Note que normalmente, no momento em que o Vim salva um arquivo, ele considera que a informação atual do swapfile não é mais necessária, já que todas as modificações já foram para o disco, o que é falso caso desativemos o fsync. Para fazer com que o swapfile contenha toda a informação necessária para a recuperação do arquivo, pode-se usar o comando :preserve.

Uma pequena dose de Vimscript no ~/.vimrc dá conta de fazer tudo isso automaticamente:

function LaptopModeWrite()
    if readfile("/proc/sys/vm/laptop_mode")[0] == 0
        set fsync swapsync=fsync directory-=/media/seu-pendrive-ou-sdcard
    else
        set nofsync swapsync= directory^=/media/seu-pendrivre-ou-sdcard
        preserve
    fi
endfunction

call LaptopModeWrite()
autocmd BufWritePre * call LaptopModeWrite()

O caso do Firefox é mais complicado. O Firefox usa a biblioteca SQLite para guardar o histórico e favoritos, e a SQLite usa fsyncs para manter a consistência dos bancos de dados. Além disso, o Firefox fsynca um arquivinho chamado sessionrestore.js, que ele usa para recuperar as tabs abertas no caso de um crash do browser. Aparentemente não há uma opção para desativar o uso de fsync no Firefox. As únicas alternativas que nos restam são mover os arquivos em questão para outra unidade, ou alterar o fonte do Firefox e da SQLite para não chamar fsync.

Ou alterar a fsync para não fazer nada.

LD_PRELOAD

Que me conste, não há uma maneira "normal" de substituir uma syscall sem modificar o kernel. Entretanto, a maior parte dos programas não chama syscalls diretamente, mas sim por intermédio de funções da biblioteca padrão C (libc), que se encarregam de chamar as syscalls. Acontece que a libc, como a maior parte das bibliotecas, é uma biblioteca dinamicamente linkada. Isso significa que as chamadas para funções da biblioteca no programa não saltam para endereços fixos, mas sim para endereços contidos em uma tabela de indireção que é preenchida pelo linker quando o programa é iniciado. Isto é, o linker, quando carrega o programa, olha os nomes das funções que o programa procura na biblioteca, obtém seus endereços, e preenche a tabela, de modo que quando o programa chamar as funções, as chamadas apontarão para os lugares apropriados.

Acontece que o ld.so (o linker) permite sacanear esse processo. Se a variável de ambiente LD_PRELOAD existe, o linker a interpreta como uma lista (separada por espaços) de bibliotecas a serem carregadas antes de quaisquer outras. Se uma dessas bibliotecas redefinir um símbolo (por exemplo, a função fsync), a versão redefinida é a que vai parar na tabela de indireção do programa, e conseqüentemente chamadas à tal função caem na nossa função, e não na original. Isso quer dizer que podemos interceptar as chamadas a fsync e fdatasync que um programa qualquer faça, e repassá-las ou não para a fsync "legítima" segundo queiramos ou não.

A coisa mais simples que podemos fazer é simplesmente descartar todas as chamadas a fsync. Criemos um arquivo libnofsync.c:

#include <stdio.h>

int fsync(int fd) {
    fprintf(stderr, "Chamada a fsync interceptada.\n");
    return 0;
}

Agora compilemo-lo com gcc -Wall -shared -o libnofsync.so libnofsync.c. Está feito! Agora, se executarmos um export LD_PRELOAD=caminho-do-arquivo/libnofsync.so, todo programa que for executado a partir de agora nesse shell utilizará a fsync modificada. Experimente abrir o Firefox.

Podemos elaborar mais sobre o tema, entretanto. Idealmente, queremos interceptar fsyncs e fdatasyncs apenas quando o laptop mode estiver ativado, e apenas quando o arquivo a ser despejado se encontra no disco. Caso decidamos que o fsync é permitido, precisamos chamar a fsync legítima; para isso, utilizaremos a função dlsym, da biblioteca dl (dynamic linker), que permite procurar um símbolo por nome em uma biblioteca. Para mais detalhes, dê uma olhada na manpage da dlopen.

#include <stdio.h>
#include <dlfcn.h>  //define dlsym() e RTLD_NEXT

#include <sys/types.h>     // para uso da fstat()
#include <sys/stat.h>
#include <sys/unistd.h>

// Variáveis globais onde armazenaremos ponteiros para as versões legítimas
// das funções. 'static' faz com que as variáveis não sejam exportadas
// (visíveis a partir do programa ou de outras bibliotecas.)
static int (*sys_fsync)(int);
static int (*sys_fdatasync)(int);

// Função de inicialização da biblioteca. Qualquer função marcada por
// __attribute__((constructor)) é considerada pelo GCC/linker como uma função
// que deve ser chamada quando a biblioteca é carregada.

__attribute__((constructor)) void libnofsync_init() {
    // Procura por 'fsync' e 'fdatasync' nas bibliotecas que vêm depois da
    // atual na ordem de pesquisa de símbolos.
    sys_fsync = dlsym(RTLD_NEXT, "fsync");
    sys_fdatasync = dlsym(RTLD_NEXT, "fdatasync");
}

static int laptop_mode_enabled() {
    FILE *f = fopen("/proc/sys/vm/laptop_mode", "r");
    if (!f) return 1;
    int status = 0;
    fscanf(f, "%d", &status);
    fclose(f);
    return status;
}

static int fsync_allowed(int fd) {
    // Se não estamos em laptop mode, sempre permite.
    if (!laptop_mode_enabled())
        return 1;

    // Se o "major number" do dispositivo do arquivo for 0x08, trata-se do
    // dispositivo /dev/sda. Você pode descobrir o major number do seu disco
    // executando um 'stat -c %D /' e desprezando os dois últimos dígitos.
    struct stat info;
    if (fstat(fd, &info) < 0) return 1;
    if (major(info.st_dev) == 0x08) return 0;
    return 1;
}

static int handle_fsync(int fd, int (*sysfun)(int)) {
    if (fsync_allowed(fd))
        return sysfun(fd);
    else
        return 0;
}

int fsync(int fd) { return handle_fsync(fd, sys_fsync); }
int fdatasync(int fd) { return handle_fsync(fd, sys_fdatasync); }

E aí está. Para compilá-la, é necessário incluir a opção -ldl na linha de comando do GCC, para linkar a biblioteca com a biblioteca dl.

Caveat

Essa história de desligar e ligar o HD consome sua vida útil. Segundo alguém na Internet, HDs de laptops são feitos para durar cerca de 300 mil ciclos de liga-desliga. HDs de desktops duram ainda menos, por volta de 50 mil ciclos. Por isso, o ideal é evitar que o disco seja ligado e desligado com muita freqüência; por exemplo, enquanto se está em laptop mode, ficar lendo mil arquivos diferentes a intervalos espaçados (suficientes para que o HD tenha desligado) não é uma boa idéia, pois os arquivos não estarão em cache quando forem lidos. O laptop-mode-tools vem com uma ferramenta chamada lm-profiler, que é capaz de lhe dizer que programas estão produzindo acessos a disco. O que essa ferramenta faz é basicamente dar um echo 1 >/proc/sys/vm/block_dump, o que faz com que o kernel reporte todos os acessos a disco pelo log do kernel, acessível pelo comando dmesg, ou por cat /proc/kmsg, caso o daemon de logging não esteja ativo. (Aliás, é bom que ele não esteja, pois escrever nos logs pode gerar acessos extra ao disco.) Não tenho dados exatos de quanta bateria se economiza com o laptop mode, embora reze a lenda que é "bastante". Use com cautela.

1 comentário / comment

Shift-Up não funciona no Emacs

2012-08-21 04:50 -0300. Tags: comp, editor, mundane, em-portugues

Problema: em um terminal do tipo xterm-256color (variável de ambiente TERM), o Emacs interpreta Shift-Up como a misteriosa tecla <select>.

Solução: Recompilar a descrição de terminal do terminfo. Não, não tem que alterar nada, apenas regerar o arquivo. Go figure.

cp /lib/terminfo/x/xterm-256color{,~}
infocmp xterm-256color >xterm.tmp
tic -o/lib/terminfo xterm.tmp

Quem me contou foi esse cara.

Comentários / Comments

Diversão com keymaps no X

2012-08-20 04:35 -0300. Tags: comp, unix, mundane, kbd, em-portugues

Em que o poeta compartilha seus nem tão vastos conhecimentos sobre alteração de keymaps no X. Em um post futuro, pretendo falar sobre as modificações que fiz em meu keymap e que achei úteis.

Introdução ao caos

Keymaps no X funcionam da seguinte maneira: A cada tecla está associado um keycode, um número único para cada tecla. Ao pressionar (ou soltar) uma tecla, o X envia o keycode ao cliente que tem o foco do teclado. O cliente, então, pode fazer o que bem entender com esse keycode. Na maior parte dos casos, entretanto, o cliente utiliza-se da keymap table que o servidor X armazena para converter um keycode em um keysym, que dá o significado da tecla em questão. Por exemplo, ao pressionar a tecla Enter, o X repassa para o cliente o keycode 36 (em um teclado comum de PC), que normalmente está associado a um keysym Return na tabela de keymap. Você pode alterar a keymap table usando um programinha chamado xmodmap. Alternativamente, você pode usar alguma outra interface para realizar essa tarefa, como o programa gráfico XKeyCaps (que altera a keymap table em tempo real e gera um arquivo de configuração para o xmodmap).

A cada keycode está associado mais de um keysym; o keysym apropriado depende dos modificadores que estão ativos no momento em que a tecla é pressionada. Em geral, as teclas Shift e AltGr estão associadas a modificadores que influenciam na seleção do keysym (e.g., em um teclado ABNT2, o keycode 10 está associado aos keysyms 1, exclam (Shift+1) e onesuperior (AltGr+1)). [O Caps_Lock também controla um modificador, que não é o mesmo do Shift; mais informação adiante.]

Insatisfeitos com os poderes do xmodmap, o povo do X inventou o Xkb, um mecanismo mais flexível para a especificação de keymaps. Em tese, a criação do Xkb torna o xmodmap obsoleto, mas como disse um sábio:

In principle, Xkb is supposed to take over. In practice, there are only three people in the known universe who understand Xkb, and nobody is quite sure who they are.

O xmodmap, embora apresente o ocasional bug, é bem mais simples de usar do que o Xkb. (Os relatos de experiências com a migração do xmodmap para o Xkb que eu vejo por aí não são muito animadores.) Ainda não estudei o Xkb direito para poder dar instruções; talvez eu poste algo sobre ele no futuro. Para mais informações, vide links. Neste post, focarei no xmodmap.

Fundamentos de xmodmap

Usualmente, o xmodmap lê de um arquivo uma série de comandos, um por linha, que indicam as alterações que se deseja realizar no keymap. O tipo de comando mais simples é da forma:

keycode número = keysym1 keysym2 ...

Esse comando associa os keysyms ao keycode especificado. Até 8 keysyms podem ser especificados em um comando keycode. O primeiro keysym é usado quando a tecla é pressionada sozinha. O segundo é usado quando a tecla é pressionada enquanto o Shift está ativo. O terceiro é usado quando Mode_switch está ativo (já chegamos lá); o quarto com Mode_switch+Shift; o quinto com ISO_Level3_Shift; o sexto com ISO_Level3_Shift+Shift.

Agora, que diabos são Mode_switch e ISO_Level3_Shift?

No começo dos tempos, Mode_switch correspondia ao AltGr. Os quatro primeiros keysyms correspondiam à tecla pura, Shift, AltGr e AltGr+Shift. E o mundo era feliz.

Por algum diabo, em algum ponto da história o AltGr passou a ser mapeado como ISO_Level3_Shift na maior parte dos keymaps padrão do X. A conseqüência mais visível disso é que o terceiro e quarto keysym da tabela do xmodmap não fazem nada no keymap padrão. Conseqüentemente, se você pretende atribuir um keysym diferente para AltGr+alguma-coisa, você deve preencher as colunas 3 e 4 com algum valor tapa-buraco (e.g., NoSymbol, ou uma cópia das colunas 5 e 6, ou qualquer coisa).

Se o problema fosse só esse, seria apenas um pequeno inconveniente. O problema é que o tal ISO_Level3_Shift é uma invenção do Xkb que não interage muito bem com o xmodmap. Se uma tecla não possui um valor associado a ISO_Level3_Shift+tecla no keymap padrão, não é possível associar um valor a essa combinação via xmodmap; o X simplesmente ignorará o valor das colunas 5 e 6. Por exemplo, se você está usando um keymap us-intl (US Internacional) com AltGr mapeado para ISO_Level3_Shift, você conseguirá alterar o keysym da combinação AltGr+a, pois essa combinação existe no keymap original, mas você não conseguirá atribuir efetivamente um keysym a AltGr+j, pois essa combinação não possui mapeamento no us-intl. Da mesma forma, você não conseguirá mapear AltGr-↑.

A solução mais simples para esse problema é simplesmente remapear o AltGr para Mode_switch e ser feliz para sempre. O problema é que nesse caso você perde todos os mapeamentos com AltGr que possam existir originalmente no seu keymap padrão, pois eles estão associados ao ISO_Level3_Shift. Por exemplo, se você remapear o AltGr para Mode_switch em um layout ABNT2, você perderá o mapeamento padrão de AltGr+1 para ¹ e terá que remapeá-lo manualmente (ou com um script; vejamos mais adiante) se desejá-lo.

Evidentemente, isso só é um problema se você deseja usar o AltGr com alguma tecla não prevista no layout original.

A solução de remapear o AltGr não resolve o problema se você deseja ter tanto o Mode_switch quanto o ISO_Level3_Shift no mesmo teclado (permitindo associar seis keysyms por tecla). Nesse caso, você vai ter que arranjar um keymap do Xkb que mapeie todas as combinações desejadas com ISO_Level3_Shift. O keymap br(abnt2) parece servir bem para esse propósito. Em último caso, você pode experimentar alterar os arquivos /usr/share/X11/xkb/symbols/us e companhia e adicionar o que falta (mas nesse caso não teria mais por que usar o xmodmap, em tese (exceto pelo fato de que é mais prático alterar o teclado posteriormente via xmodmap do que alterando os arquivos de sistema)).

Quanto às colunas 7 e 8, elas aparentemente não servem para nada. Dizem as más línguas que elas deveriam conter o keysym associado à combinação Mode_switch+ISO_Level3_Shift+Shift+tecla, mas nunca consegui fazer funcionar. Tentar criar um modificador ISO_Level4_Shift ou ISO_Level5_Shift também não foi eficaz. (Por sinal, o keysym ISO_Level4_Shift não existe, mas ISO_Level5_Shift sim. Go figure.)

E como eu descubro os keycodes e keysyms?

O X vem com um programinha supimpa chamado xev. Esse programa cria uma janela e reporta pela stdout (o terminal por onde você abriu o xev) todos os eventos que essa janela recebe. Assim, ao pressionar uma tecla, o xev imprimirá algo do tipo:

KeyPress event, serial 33, synthetic NO, window 0x2200001,
root 0x69, subw 0x0, time 39264530, (38,371), root:(1137,799),
state 0x0, keycode 98 (keysym 0xff52, Up), same_screen YES,
XLookupString gives 0 bytes: 
XmbLookupString gives 0 bytes: 
XFilterEvent returns: False

Com isso, você consegue descobrir o keycode da tecla (para poder atribuir keysyms) e o keysym que ela gera atualmente (para poder atribuí-lo a outra tecla).

Se você deseja atribuir a uma tecla um keysym que ainda não existe no seu keymap e que você não sabe o nome (e.g., se você quiser atribuir o caractere ĉ à combinação Mode_switch+c), você pode:

  1. usar Uxxxx, onde xxxx é o código Unicode hexadecimal do caractere desejado (no caso de o símbolo desejado ser um caractere, e não um XF86AudioStop da vida); ou
  2. olhar uma tabela de keysyms, tal como a tabela incompleta em /usr/share/X11/XKeysymDB (que normalmente acompanha o X) ou a tabela completa em /usr/include/X11/keysymdef.h (descartando o prefixo XK_; esse arquivo vem no pacote x11proto-core-dev no Debian); ou
  3. adivinhar o nome do símbolo. Nomes típicos incluem:
    • dead_acute, dead_diaresis, dead_circumflex, dead_tilde, dead_macron, dead_breve, dead_abovedot, dead_cedilla, dead_caron, etc.: acentos e diacríticos de todos os sabores (uma deadkey é uma tecla que não faz nada até que seja digitado o caractere seguinte);
    • aacute, Aacute, ccedilla, Ccedilla, etc.: caracteres acentuados prontos;
    • XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume, XF86AudioPlay, XF86AudioStop, XF86AudioPrev, XF86AudioNext, XF86PowerOff, etc.: teclas "multimídia" e firulas relacionadas;

O comando keysym

Em alguns casos você não precisa saber o keycode de uma tecla para mapeá-la. O xmodmap reconhece o comando:

keysym keysym_velho = keysym1 keysym2 ...

Nesse caso, o xmodmap procura por todos keycodes que atualmente estão associados ao keysym_velho, e lhes atribui os valores novos. Isso é particularmente útil quando se deseja apenas associar valores novos às combinações com AltGr, sem alterar o valor puro da tecla:

! O primeiro par ccedilla/Ccedilla para o Mode_switch, o segundo para o ISO_Level3_Shift.
keysym c = c C ccedilla Ccedilla ccedilla Ccedilla

Para modificações que alteram o valor puro da tecla, entretanto, usar o comando keysym pode não ser uma boa idéia. Suponha que você deseja trocar os parênteses e os colchetes de lugar no teclado:

keysym 9 = 9 bracketleft
keysym 0 = 0 bracketright
keysym bracketleft = parenleft braceleft
keysym bracketright = parenright braceright

A aplicação dessas modificações no keymap original funciona (o xmodmap é esperto o suficiente para primeiro avaliar todos os lados esquerdos do =, e depois efetuar as mudanças, de modo que a alteração das duas primeiras linhas não interfere no funcionamento das duas últimas numa mesma execução). Porém, se esse arquivo de keymap for carregado uma segunda vez, catástrofes acontecem: as duas primeiras linhas fazem o que deveriam, mas as duas últimas associam parênteses a todas as teclas que atualmente estão mapeadas para colchetes, ou seja, as teclas 9 e 0! Como os comandos são avaliados na ordem, as duas últimas linhas sobrepõem o mapeamento de 9 e 0, de modo que tanto 9 e 0 quanto as teclas de colchetes agora contêm parênteses!

Evidentemente, o problema só surge se você carregar o arquivo duas vezes. Porém, enquanto você está experimentando com keymaps, você provavelmente vai querer fazer alterações e recarregar o arquivo de keymap diversas vezes sem ter que reiniciar o X. Em qualquer caso, parece melhor escrever um keymap que faz a coisa certa quando é carregado múltiplas vezes do que encontrar surpresas no futuro e levar mil instantes para entender o que está acontecendo.

Moral da história: só use o keysym para alterar valores secundários das teclas, e isso só se você tiver certeza de que keysym_velho só ocorre uma vez no keymap, ou que você queira realmente alterar todas as teclas associadas ao keysym_velho.

Modifiers

Remapear modificadores (Ctrl, Alt, Shift, Caps_Lock, JanelinhaFeliz, etc.) envolve alguns detalhes mais.

O X mantém uma tabela de modificadores; se você executar xmodmap sem parâmetros, ele imprimirá essa tabela. Essa tabela associa keycodes a modificadores. Os modificadores reconhecidos são control, shift (auto-explicativos), lock (correspondente ao Caps_Lock), e mod1 até mod5 (que não têm significado pré-definido). Sempre que você altera o mapeamento de uma tecla associada a modificadores, você deve lembrar de reajustar a tabela de modificadores também. Para controlar essa tabela, o xmodmap provê os comandos add, remove e clear.

add modifier_name = keysym ... adiciona as teclas associadas aos keysyms especificados à lista de teclas que ativam o modificador. Se você executar um comando do tipo add shift = a, o efeito será que a tecla A, além de funcionar como um A normal, também passará a funcionar como um Shift: se você segurar a tecla A enquanto digita outras teclas, o efeito será o mesmo de segurar Shift ao mesmo tempo que as outras teclas.

remove modifier_name = keysym ... desassocia todas as teclas associadas aos keysyms especificados do modificador em questão. clear modifier_name desassocia todas as teclas do modificador. O fato de que os comandos trabalham com keysyms mas a tabela trabalha com keycodes gera todo tipo de bizarrice na manipulação de keymaps. No geral, o mais simples, prático e indolor é, sempre que se remapeia teclas associadas a modificadores, limpar os modificadores em questão, fazer o remapeamento e adicionar as teclas novamente.

Exemplo: para inverter a posição usual do Ctrl da esquerda e do Caps_Lock:

clear lock
clear control
! Keycodes do Ctrl e Caps_Lock obtidos com o xev. Os valores podem ser diferentes no
! seu teclado / versão do X.
keycode 66 = Control_L
keycode 37 = Caps_Lock
add lock = Caps_Lock
! Não esqueça de readicionar o Ctrl da direita, que foi apagado no clear.
add control = Control_L Control_R

Opções de linha de comando do xmodmap

Além do xmodmap arquivo, para carregar um arquivo com comandos, o xmodmap suporta algumas outras opções. Em primeiro lugar, usando - como arquivo, o xmodmap lê da stdin. Isso é primariamente útil se por alguma razão você quiser gerar um keymap por script e alimentá-lo ao xmodmap. Além disso, o xmodmap suporta uma opção -e comando, que permite executar um comando de keymap diretamente a partir da linha de comando. Por exemplo:

xmodmap -e 'keysym a = a A ae AE'

Cada comando consiste de apenas um comando de keymap, mas a opção -e pode ser repetida.

Outro comando útil é xmodmap -pke, que imprime o keymap atual no formato que o xmodmap lê. Assim, você pode salvar o keymap atual com xmodmap -pke >.xmodmaprc e carregá-lo posteriormente (em outra sessão do X) com xmodmap .xmodmaprc. Isso é útil se você fez diversas modificações no layout pela linha de comando e deseja salvar o estado atual sem ter que encontrar todos os comandos dados e agrupá-los em um arquivo. (O xmodmap -pke não imprime linhas add, remove e clear, entretanto.) Isso também é útil para salvar o keymap atual antes de começar a bagunçá-lo, para poder retornar a um estado consistente sem ter que reiniciar o X. Para isso, é bom criar um meio de invocar o xmodmap seu-teclado-original sem ter que usar o teclado (e.g., com um atalho no seu ambiente gráfico favorito).

Carregando o keymap na inicialização

Todas as modificações feitas na keymap table duram apenas até o servidor X morrer; na próxima inicialização, a tabela volta a ser o que era. Para tornar as modificações permanentes, você precisa carregá-las toda vez que sua sessão X inicia. Para isso, você deverá colocar o comando xmodmap ~/seu-arquivo-com-comandos-de-keymap em algum lugar que seja executado pelo seu ambiente gráfico na inicialização. Se você usa o xinit para carregar a interface gráfica, o arquivo é o .xinitrc, no seu home. Alguns ambientes gráficos carregam o .xsessionrc. Alguns permitem que você adicione comandos para serem executados na inicialização em alguma configuração do ambiente. Finalmente, se não estou enganado, o GNOME detecta por conta arquivos de nome .xmodmaprc e assemelhados na inicialização e pergunta se você deseja carregá-los na inicialização da primeira vez que os encontra.

Notas soltas

Na transição do driver de teclado kbd para evdev (i.e., da época do Debian 4 para o Debian 5, embora ainda seja possível usar o driver kbd hoje em dia, desde que seja instalado o pacote xserver-xorg-input-kbd), algumas teclas mudaram de keycode. Em particular, o AltGr mudou de 113 para 108, e as setas e algumas outras teclas especiais também mudaram. Isso pode causar algum problema na hora de migrar de uma versão velha do X para uma mais recente.

Eu prometi links com informações sobre o Xkb. Eis o que eu encontrei (e ainda não li, mostly):

EOF.

3 comentários / comments

The woes of Firefox

2012-07-18 17:43 -0300. Tags: comp, web, mundane, em-portugues

Seguindo a aparente trend no mundo das interfaces gráficas para GNU/Linux, algumas das novas "features" do Firefox e seus addons só são configuráveis via propriedades no about:config. Eis uma relação das que me foram necessárias.

Itens úteis nessa vida de 3G:

Outros:

Provavelmente vou adicionar coisas a esse post no futuro.

5 comentários / comments

Rodando o VLC como root

2012-06-02 10:41 -0300. Tags: comp, unix, mundane, em-portugues

Por padrão, ao ser executado como root, o VLC prestativamente imprime a seguinte mensagem:

VLC is not supposed to be run as root. Sorry.
If you need to use real-time priorities and/or privileged TCP ports
you can use vlc-wrapper (make sure it is Set-UID root and
cannot be run by non-trusted users first).

"Sorry, Dave. I'm afraid you can't do that."

Há duas soluções para esse problema. A solução limpa é recompilar o VLC passando --enable-run-as-root para o ./configure. A solução suja é a sacada genial desse cara: substituir na mão a chamada de geteuid por getppid no binário do VLC. A idéia por trás disso é que os nomes geteuid e getppid têm o mesmo tamanho, e portanto é possível sobrescrever um com o outro no binário sem alterar as posições das coisas no resto do arquivo. geteuid retorna o UID efetivo do processo, que é 0 para o root. getppid retorna o PID do processo pai do processo atual, que nunca é zero, exceto para o /sbin/init [citation needed]. A treta é enganar o VLC fazendo-o pensar que o UID do processo atual é um número qualquer diferente de zero. O artigo original usa o Vim para isso, mas qualquer editor que não estrague binários serve – inclusive o sed sem locale Unicode:

# LC_ALL=C sed 's/geteuid/getppid/g' /usr/bin/vlc >/usr/bin/vlc-hacked
# chmod 755 /usr/bin/vlc-hacked

Pronto! Agora você tem um vlc-hacked, que aceita rodar como root. Você pode apagar/mover o vlc original e colocar o vlc-hacked no lugar, mas eu não recomendaria; melhor que para rodar o vlc como root você tenha que expressar explicitamente o desejo chamando o binário alternativo.

Caveat: Procurando por soluções para esse problema, encontrei um camarada dizendo que o VLC tem mil falhas de segurança, permitindo inclusive a execução de código arbitrário dependendo da fase da lua. (O que eu concluo dessa afirmação é que eu não deveria rodar o VLC at all, mas enfim.) Use por sua conta e risco.

Comentários / Comments

Menus ilegíveis no OpenOffice

2012-05-22 14:11 -0300. Tags: comp, mundane, em-portugues

Problema: menus e caixas de diálogo do OpenOffice/LibreOffice aparecem apenas com algumas linhazinhas onde deveria haver texto.

What happen? As linhazinhas são o texto, na fonte más pequeña del universo.

Solução: desabilitar o anti-aliasing. Não averigüei o suficiente para entender a moral do problema, e sinceramente não é a coisa que eu tenho mais vontade de fazer na vida. A parte divertida é fazer a configuração sem ver o texto dos menus:

  1. Escolha o menu "Tools" (sétimo menu da esquerda para a direita, terceiro da direita para a esquerda);
  2. Escolha a última opção ("Options");
  3. Escolha o quarto subitem do primeiro item da arvorezinha de opções ("View"; você pode conferir se escolheu o item certo verificando o título da janela);
  4. Desmarque a segunda checkbox da esquerda ("Screen font antialiasing");
  5. Clique em "OK" (o botão mais à esquerda).

Quem me contou foi esse cara.

Comentários / Comments

Mandando o processador/fan se acalmar

2012-05-12 01:03 -0300. Tags: comp, unix, mundane, em-portugues

Antes de destruir a máquina à minha frente e morrer de desgosto, compartilho com vocês o que eu descobri tentando fazer o cooler do PC parar de fazer barulho de espremedor de laranja.

Algumas máquinas permitem controlar a velocidade do fan, por meio dos arquivos pwm1 e pwm1_enable nos diretórios/sys/class/hwmon/hwmon*. echo 1 >pwm1_enable habilita o controle do fan por software (ao invés de deixar o firmware trabalhar sozinho), e echo N >pwm1, onde N costuma ser um valor entre 0 e 255, controla a velocidade do fan. No EeePC, a configuração funcionava temporariamente até o firmware resolver que era melhor que o OS e ligar o fan de novo; para desligar o fan, era necessário então setá-lo de novo para a velocidade máxima e de volta para zero (ou o valor que se quisesse; o EeePC só tinha o modo "ligado" e "desligado" por software, entretanto). Os arquivos se chamavam fan1 e fan1_enable no kernel 2.6.159265358979 e anteriores.

Outras máquinas não têm suporte ao PWM, mas possuem alguns controles interessantes nos diretórios /sys/class/thermal/cooling_device*. Cada um desses diretórios contém, entre outros, os arquivos: type, que diz o tipo do dispositivo em questão; cur_state, o estado atual do dispositivo; e max_state, o valor máximo que o estado pode assumir. Na máquina que estou usando agora (um Toshiba Satellite de uns cinco ou seis anos atrás), aparecem cinco dispositivos dos seguintes tipos:

# grep '' /sys/class/thermal/cooling_device*/type
/sys/class/thermal/cooling_device0/type:Processor
/sys/class/thermal/cooling_device1/type:Processor
/sys/class/thermal/cooling_device2/type:Fan
/sys/class/thermal/cooling_device3/type:LCD
/sys/class/thermal/cooling_device4/type:LCD

Você pode dar echo N >/sys/class/thermal/cooling_devicex/cur_state para alterar o estado do dispositivo.

Nesta máquina, o estado do fan fica sempre em 1 (ligado), e o valor não pode ser alterado. Os processadores/cores, porém, possuem um estado padrão 0 e um valor máximo 7; alterando esse valor, os processadores diminuem de velocidade, conseqüentemente aquecendo menos (e possivelmente gastando menos bateria, mas não cheguei a testar). Com um core desativado e o outro no estado máximo de economia, a máquina levou uns dez minutos para subir a temperatura (verificável em /sys/class/hwmon/hwmon*/temp*_input) de 50 a 80 graus (versus um minuto com dois cores no estado normal).

Outra regulagem de freqüência que pode ser feita independentemente é através do cpufreq. cpufreq-info mostra a freqüência atual e a "política de freqüência" em vigor. As configurações podem ser alteradas com cpufreq-set: cpufreq-set -c 0 -u 1G seta a velocidade máxima do core 0 para 1GHz, por exemplo. (Cada modelo de processador aceita apenas certos valores de freqüência; este aqui, por exemplo, aceita 1GHz, 1.33GHz e 1.66GHz. O cpufreq seleciona o valor mais próximo que satisfaz o limite de velocidade especificado, ou retorna um erro.)

Mais uma coisa: é possível desligar um core executando echo 0 >/sys/devices/system/cpu/cpuN/online (e reativá-lo trocando 0 por 1). Não testei o que acontece mandando desligar todos.

Se sua máquina é capaz de ligar e desligar o fan, o que você pode fazer é criar um script para ligar o fan sempre que a temperatura passar de um certo limite (e.g., 80 graus) e desligá-lo quando ela voltar a uma temperatura baixa (e.g., 50 graus). Assim, você só vai ter que ouvir o fan de vez em quando. Na verdade, aparentemente existe um pacote chamado fancontrol que faz basicamente isso. Aqui, entretanto, o fan tem vontade própria e escolhe a velocidade que quer; para pará-lo, tive que impedi-lo de girar. A máquina esquenta igual, apenas mais devagar, com as configurações alteradas, o que não me resolve nada. Obviously it is Allah's will that I throw the Unix box out the window. I submit to the will of Allah.

P.S.: Não, o Unix não tem nada que ver com o problema.

P.P.S.: Aparentemente leitores prospectivos do blog esperam alguma coisa mais interessante da tag mundane. Ela apenas marca os posts sobre "arrumar PC" (i.e., o que sua família pensa que você faz quando diz que estuda Ciência da Computação) e resolução de problemas de mortal (por oposição aos posts sobre programação, por exemplo). Além disso, há uma tag mundane e uma worldly, completamente não-relacionadas, embora as palavras sejam sinônimos. There are no rules anywhere. The Goddess Prevails.

Comentários / Comments

3G dos infernus

2012-04-19 22:08 -0300. Tags: about, comp, mundane, em-portugues

[Se você caiu aqui procurando por instruções de como configurar o modem ONDA MSA 190 no GNU/Linux, vá direto ao ponto.]

Parece que ficarei sem sinais de fumaça por tempo indeterminado...

Edit: It's back, às duas da madruga. 3G em Viamão é a maravilha das brilhantes maravilhas. Caso esteja pensando em adquirir um, eis o que posso lhe informar:

Atualmente estou usando um 3G da Tim. O preço provavelmente é o melhor que pode ser obtido: com o plano Infinity, se paga 50 centavos por dia (ou seja, 15 reais por mês, na média), e o plano é pré-pago. A banda mensal é ilimitada; supostamente, quando o tráfego mensal passa de 350MB, a velocidade é "reduzida" para 64kbps; na prática, a velocidade nunca passa de 6kB/s (= 48kbps) em qualquer período do mês. A latência normal (medida com ping) é por volta de 1 segundo (vs. os 50ms ou menos do ADSL), mas freqüentemente chega a 4 segundos ou mais. Costumava não cair, mas ultimamente tem caído (e por vezes ficado sem serviço por algumas horas) com uma freqüência menos que agradável.

Hoje, quando houve a queda de serviço, experimentei conectar usando a linha Oi do meu celular. Não tenho plano de dados nem nada que o valha nessa linha, portanto a conexão saiu por um real o minuto. Creio que não exista plano 3G pré-pago pela Oi, e não sei quais são os planos e preços atuais, mas quando procurei era mais do que 15 reais por mês. A velocidade da conexão é mais ou menos a mesma (6kB/s), mas a latência é menor (cerca de 300ms). Para acessar meu diretório home na Inf via sshfs, a latência menor fez uma diferença gritante. Porém, ter um contrato fixo e pagar mais só para ter uma latência menor não está valendo.

[UPDATE (04/10/2012): Existe 3G pré-pago da Oi. É mais barato (10 reais o pacote mensal) e infinitas vezes melhor do que o da Tim. A conexão raramente cai, praticamente nunca fica abaixo dos 50kbps (velocidade depois de consumida a franquia de 30MB), e ocasionalmente fica acima (1Mbps). Por outro lado, aparentemente todas as portas são bloqueadas para acesso remoto com a Oi, enquanto com a Tim a maior parte das portas ficava liberada.]

Não sei do sinal das outras operadoras; sei que são caras. A Vivo não quis me vender o serviço porque eu uso GNU/Linux. E isso que eu insisti (mas não muito; me tapei de desgosto em alguns instantes).

By the way, quando fui para Torres no começo do ano, o 3G da Tim foi simplesmente inutilizável. (Consegui acessar o webmail da Inf, depois de cerca de 15 minutos, setando o timeout do Firefox para 5 minutos (opções network.websocket.timeout.* no about:config).)

By the way[2], o modem que a Tim fornece (ONDA MSA 190) funciona no Linux, mas requer uma treta. Descobri como fazer num fórum do Viva o Linux, mas é mais fácil explicar do que encontrar a página em questão (que além do mais não era particularmente organizada). Assumo um sistema Debian ou derivado (leia-se Ubuntu):

  1. Vire root: sudo bash.
  2. apt-get install usb-modeswitch. Por padrão, o modem se apresenta ao sistema como se fosse um pendrive (com o instalador para Windows do driver do modem); o usb-modeswitch é um programinha que faz o modem alternar para o modo modem.
  3. Crie o arquivo /etc/udev/rules.d/77-mm-zte-port-types.rules, com o seguinte conteúdo:
    ACTION!="add|change", GOTO="mm_zte_port_types_end"
    SUBSYSTEM!="tty", GOTO="mm_zte_port_types_end"
    
    SUBSYSTEMS=="usb", ATTRS{idVendor}=="19d2", GOTO="mm_zte_port_types_vendorcheck"
    GOTO="mm_zte_port_types_end"
    
    LABEL="mm_zte_port_types_vendorcheck"
    SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="?*", ENV{.MM_USBIFNUM}="$attr{bInterfaceNumber}"
    
    ATTRS{idProduct}=="0091", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_ZTE_PORT_TYPE_MODEM}="1"
    ATTRS{idProduct}=="0091", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_ZTE_PORT_TYPE_AUX}="1"
    
    LABEL="mm_zte_port_types_end"
    
  4. Crie o arquivo /etc/usb_modeswitch.d/19d2:2000:uPr=ONDA_WCDMA_Technologies_MSM, com o seguinte conteúdo:
    ###################
    # ZTE devices
    # Onda MSA190UP
    
    DefaultVendor= 0x19d2
    DefaultProduct= 0x2000
    
    TargetVendor= 0x19d2
    TargetProductList="0001,0002,0015,0016,0017,0031,0037,0052,0055,0063,0064,0091,0108,0128"
    
    MessageContent="55534243123456782000000080000c85010101180101010101000000000000"
    
    NeedResponse=1
    CheckSuccess=20
    ###################
    
  5. Conecte o modem na máquina. (Se já estava conectado, o mais simples é desconectar e conectar de novo. Divirta-se fazendo o udev rodar sem desconectar o modem, se quiser.)
  6. Pronto! O modem aparecerá em alguns segundos como o dispositivo /dev/ttyUSB3. Você pode configurar a conexão usando o pppconfig (que fica no pacote pppconfig), ou usando as frescuras gráficas de seu ambiente desktop favorito. Se seu aplicativo de configuração pedir o número de discagem, utilize *99***1#, ou *99# (dependendo da operadora).

Hora de dormir, e esperar que o futuro seja melhor amanhã.

Comentários / Comments

Ubuntu vs. MTU

2012-03-17 13:35 -0300. Tags: comp, unix, mundane, em-portugues

Um camarada estava tendo problemas para acessar um certo livro de faces, entre outras páginas, no Ubuntu 10.10 e 11.04, tanto no Firefox quanto no Chromium. Solução? Diminuir o MTU da interface de rede em questão:

sudo ifconfig wlan0 mtu 1492

substituindo wlan0 pela interface usada para acessar a Internet. Se não funcionar, você pode experimentar valores menores para o MTU. Se alguém souber explicar por que alguns sites funcionam com o valor de MTU errado e outros não, tenha a bondade.

Quem me contou foi esse cara.

Comentários / Comments

Main menu

Posts recentes

Comentários recentes

Tags

em-portugues (213) comp (138) prog (68) in-english (51) life (47) unix (35) pldesign (35) lang (32) random (28) about (27) mind (25) lisp (23) mundane (22) fenius (20) web (18) ramble (17) img (13) rant (12) hel (12) privacy (10) scheme (10) freedom (8) bash (7) copyright (7) music (7) academia (7) lash (7) esperanto (7) home (6) mestrado (6) shell (6) conlang (5) emacs (5) misc (5) latex (4) editor (4) book (4) php (4) worldly (4) politics (4) android (4) etymology (4) wrong (3) security (3) tour-de-scheme (3) kbd (3) c (3) film (3) network (3) cook (2) poem (2) physics (2) wm (2) treta (2) philosophy (2) comic (2) lows (2) llvm (2) perl (1) en-esperanto (1) audio (1) german (1) kindle (1) old-chinese (1) pointless (1) translation (1)

Elsewhere

Quod vide


Copyright © 2010-2020 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.

Powered by Blognir.