Não Tem Mosquito

As aventuras de se desenvolver software no nosso Patropi.

Sexta-feira, Junho 16, 2006

Sexo Implícito

Recentemente eu me f... duas vezes por causa de programas que tentam ser espertos demais. A primeira foi um upgrade no sistema operacional. Esta mania nerd de se manter sempre atualizado as vezes é um tiro no pé. A dica estava lá no informativo do Gentoo. Devido a uma nova funcionalidade do kernel 2.6, chamada inotify, a troca do pacote fam pelo gamin deixaria o sistema muito mais eficiente.

Estes pacotes servem para monitorar a atualização de arquivos em um diretório. O fam é muito usado pelo KDE, ele permite, por exemplo, que se você estiver ripando um CD com uma aplicação, uma outra janela com o Konqueror seja automaticamente atualizada a medida que os arquivos vão sendo criados. O fam fica constantemente verificando se algo mudou no diretório. Uma ótima funcionalidade na interface com o usuário, mas este pooling constante toma bastantes recursos da máquina.

Pra resolver isto surgiu o tal inotify, que permite que o kernel avise a uma aplicação quando algo mudou em um diretório. O pooling se torna desnecessário e sua máquina mais eficiente. O gamin é uma grande idéia. Ele reimplementa a biblioteca do fam com exatamente a mesma interface, só que usa o inotify. Troque as bibliotecas em sua máquina e automaticamente todas as aplicações que usam o fam responderão muito mais rápido e sua máquina ficará mais eficiente. Fácil e de graça. Troquei logo os pacotes e tive uma surpresa: 100% de utilização de CPU. O tempo todo.

Isto mesmo. Nada conseguia fazer. Estava tudo lentíssimo. Meu computador começou a super-aquecer. Não sabia se chamava os bombeiros ou pegava um ovo para fritar sobre o placa mãe.

Analisando os processos rodando, tava lá um tal de gam_server consumindo tudo. Um excecutável instalado pelo gamin. Restarta. Mexe nas configurações. Reboota. Pesquisa nos fórums. Nada. Nada. Nada. Um ou outro com o problema , mas era um bug de uma versão antiga. Horas perdidas e já estava prestes a voltar à configuração antiga. Até que na documentação descubro que o gamin por padrão faz pooling nos diretórios /media/* e /mnt/*. A motivação é simples. Em algumas distribuições Linux, estes diretórios são utilizados para se montar automaticamente mídias como CD e drives USB. Se usar o inotify, o comando umount não funciona, impedindo-nos de tirar as mídias.

Só que esta auto-configuração é implícita no código. Não é apenas uma configuração default no arquivo de configuração do bicho, mas hardcoded. Por mais que eu procurasse nas configurações e nas mensagens de log, não teria como descobrir. E por infeliz coincidência, meu diretório /media é exatamente onde guardo todas minhas fotos e músicas. Dezenas de milhares de arquivos para o gam_server varrer sem parar:-(.

Minha segunda desventura foi com o Apache. Precisei configurá-lo para desenvolvimento, como um colega no trabalho já havia feito. Só que no meu CentOS 4 eu não conseguia permitir o acesso a uns simples diretórios. Mudava permissões e configurações e só dava a tal mensagem "Access Forbiden". O log do Apache não mostrava nada que desse uma dica do porquê. Os fóruns na Internet só davam as soluções feijão com arroz, coisas que tentei logo de cara. O pior é que no CentOS 3 do meu colega tudo estava lindo. Já estava desistindo, quando em um dos últimos posts de um fórum veio a dica: "veja se não é o SELinux".

Sobre este tal de Security Enhanced Linux eu só sabia que existia, que era uma iniciativa do governo americano e que tinha uns pacotes a respeito em minha máquina. Sabendo o que buscar, descobri rápido. O SELinux funciona por baixo do Apache, impedindo-o de acessar alguns diretórios, mesmo que isto contrarie a configuração do servidor web. As informações de seu funcionamento aparecem não nos logs do Apache, mas sim nas do sistema unix. Argh! Eu não sabia que tinha que olhar lá. Nunca precisei nas dezenas de vezes que o configurei. Novamente algo funcionando implicitamente me machucou. Lá se foi uma tarde de trabalho perdida com uma bobagem.

Que fique a lição quando eu estou do outro lado, desenvolvendo sistemas. Em matéria de programação, é sempre melhor ser explícito. É preciso dar um feedback claro do que se está fazendo e assumindo. Documente suas premissas. Use contratos nos métodos. Mostre ao usuário o que está acontecendo. Seja ele o usuário final, outro desenvolvedor que está chamando seu código, ou você mesmo daqui a alguns meses quando tiver esquecido o que fez.

Afinal de contas, se você descobrir tarde demais que em um sistema com o qual você está interagindo está rolando alguma sacanagem implícita, você acha que estará na posição ativa ou passiva?