Portes ] [ Debian GNU/Hurd ] [ Novidades ] [ Configuração ] [ CDs do Hurd ] [ Documentação ] [ Desenvolvimento ] [ Contato ]

Debian GNU/Hurd

Tradutores

Conceito

Antes de examinarmos os tradutores, consideremos os sistemas de arquivos regulares. Um sistema de arquivo é um armazenamento para uma árvore hierárquica de diretórios e arquivos. Você acessa os diretórios e os arquivos através de uma string de caracteres especial, o caminho (path, em inglês). Além disso, existem links simbólicos para referenciar um arquivo em diversos lugares na árvore, existem hard links para dar diversos nomes a um mesmo e único arquivo. Existem também arquivos de dispositivo especiais para comunicação com os drivers de dispositivos de hardware do kernel, e existem pontos de montagem para incluir outros armazenamentos na árvore de diretórios. E existem objetos obscuros como os FIFOs.

Embora esses objetos sejam muito diferentes, eles compartilham de algumas propriedades comuns, por exemplo, todos eles têm um(a) proprietário(a) e um grupo associados, como também direitos de acesso (permissões). Esta informação fica escrita em inodes. Isto é, na verdade, uma convergência adicional: todo objeto tem exatamente um inode associado a ele (hard links são algo de especial já que eles compartilham um mesmo e único inode). Às vezes, o inode tem informações adicionais armazenadas nele. Por exemplo, o inode pode conter o alvo de um link simbólico.

Contudo, esses aspectos comuns geralmente não são aproveitados nas implementações, apesar da interface comum de programação entre eles. Todos os inodes podem ser acessados através de chamadas POSIX padrões, por exemplo, read() e write(). Ou para adicionar um novo tipo de objeto (por exemplo, um novo tipo de link) para um kernel unix comum e monolítico, você precisaria modificar o código para cada sistema de arquivos separadamente.

No Hurd, as coisas funcionam diferentemente. Embora no Hurd um servidor especial de sistema de arquivos possa explorar propriedades especiais de tipos de objeto padrões, como os links (no sistema de arquivo ext2 com links rápidos, por exemplo), ele tem uma interface genérica para adicionar tais funcionalidades sem modificar o código existente.

O truque está em permitir a um programa que se insira entre o atual conteúdo de um arquivo e o(a) usuário(a) que está acessando este arquivo. Tal programa é chamado de tradutor, porque ele é capaz de processar requisições de entrada por muitas e diferentes maneiras. Em outras palavras, um tradutor é um servidor Hurd que fornece uma interface básica de sistema de arquivos.

Os tradutores têm propriedades muito interessantes. Do ponto de vista do kernel, eles são apenas outro processo de usuário(a). Isto é, os tradutores podem ser executados por quaisquer usuários(as). Você não precisa de privilégios de root para instalar ou para modificar um tradutor, você somente precisa dos direitos de acesso para o inode subjacente ao tradutor ao qual está anexado. Muitos tradutores não requerem um arquivo real para operar, eles podem fornecer informações por seus próprios meios. Este é o motivo da informação sobre tradutores ficar armazenada no inode.

Os tradutores são responsáveis por servir todas as operações de sistema de arquivo que envolvem o inode no qual estão anexados. Porque não estão restritos aos usuais conjuntos de objetos (arquivo de dispositivo, link, etc.), eles estão livres para retornar qualquer coisa que faça sentido ao(à) programador(a). Pode-se imaginar um tradutor que se comporta como um diretório quando acessado por cd ou ls e, ao mesmo tempo, se comporta como um arquivo quando acessado por cat.

Exemplos

Pontos de montagem

Um ponto de montagem pode ser visto como um inode que tem um tradutor especial anexado a ele. Seu propósito seria traduzir as operações do sistema de arquivos no ponto de montagem em operações de sistema de arquivos em outro armazenamento, por exemplo, em uma outra partição.

De fato, é assim que os sistemas de arquivos são implementados sob o Hurd. Um sistema de arquivos é um tradutor. Este tradutor pega um armazenamento como seu argumento e é capaz de servir todas as operações de sistema de arquivos transparentemente.

Arquivos de dispositivo

Existem muitos e diferentes arquivos de dispositivos, e em sistemas de kernel monolítico, eles são todos fornecidos pelo kernel mesmo. No Hurd, todos os arquivos de dispositivo são fornecidos por tradutores. Um tradutor pode fornecer suporte para vários arquivos de dispositivo similares, por exemplo, todas as partições do disco rígido. Deste modo, o número de tradutores realmente existentes é muito pequeno. Contudo, note que para cada arquivo de dispositivo acessado, uma tarefa de tradutor separada é iniciada. Porque o Hurd é profundamente multithread, isso sai muito barato.

Quando hardware é envolvido, um tradutor geralmente começa a se comunicar com o kernel para obter os dados do hardware. Entretanto, se não é preciso acesso ao hardware, o kernel não precisa estar envolvido. Por exemplo, /dev/zero não requer acesso ao hardware e, portanto, pode ser implementado completamente no espaço de usuário(a).

Links simbólicos

Um link simbólico pode ser visto como um tradutor. Ao acessar o link simbólico, um tradutor seria iniciado, o qual encaminharia a requisição para o sistema de arquivos que contenha o arquivo para o qual o link aponta.

Contudo, para uma melhor performance, os sistemas de arquivos que possuem suporte nativo aos links simbólicos podem tirar vantagem desta funcionalidade e implementar links simbólicos de maneira diferente. Internamente, o acesso a um link simbólico não iniciaria um novo processo de tradutor. Porém, para o(a) usuário(a), ainda pareceria como se o tradutor passivo estivesse envolvido (veja abaixo uma explicação sobre o que é um tradutor passivo).

Devido ao Hurd vir com um tradutor de symlink, qualquer servidor de sistema de arquivos que fornece suporte para tradutores automaticamente tem suporte para symlinks (e firmlinks, e arquivos de dispositivos, etc.)! Ou seja, você pode conseguir um sistema de arquivos funcionando bem rápido e adicionar suporte nativo aos symlinks e a outras funcionalidades mais tarde.

Tradutores passivos, tradutores ativos

Existem dois tipos de tradutores, passivos e ativos. Eles realmente são coisas completamente diferentes, então não confunda; mas eles mantêm uma relação próxima.

Tradutores ativos

Um tradutor ativo é um processo de tradutor em execução, como visto acima. Você pode definir e remover tradutores ativos usando o comando settrans -a. A opção -a é necessária para dizer ao settrans que você quer modificar o tradutor ativo.

O comando settrans recebe três tipos de argumentos. Primeiro, você pode definir opções para o comando settrans mesmo, como -a para modificar o tradutor ativo. A seguir você define o inode que quer modificar. Lembre-se que um tradutor está sempre associado com um inode na hierarquia de diretórios. Você somente pode modificar um inode por vez. Se você não especificar mais nenhum argumento, settrans tentará remover um tradutor existente. O quanto ele vai tentar depende das opções de imposição que você especificar (se o tradutor está em uso por qualquer processo, você obterá uma mensagem de erro "device or resource busy" - dispositivo ou recurso ocupado - a menos que você force a remoção).

Mas se você especificar argumentos adicionais, eles serão interpretados como uma linha de comando para executar o tradutor. Isto é, o próximo argumento é o nome de arquivo do executável do tradutor. Argumentos adicionais são opções para o tradutor, e não para o comando settrans.

Por exemplo, para montar uma partição ext2fs, você pode executar settrans -a -c /mnt /hurd/ext2fs /dev/hd2s5. A opção -c criará um ponto de montagem se ele ainda não existir. Aliás, não precisa ser um diretório. Para desmontar, você tentaria settrans -a /mnt.

Tradutores passivos

Um tradutor passivo é definido e modificado pela mesma sintaxe dos tradutores ativos (somente ignore a opção -a), então tudo o que foi dito acima também é verdade para os tradutores passivos. Contudo, existe uma diferença: tradutores passivos ainda não foram iniciados.

Isto faz sentido porque isto é o que você geralmente quer. Você não quer a partição montada a menos que você realmente acesse os arquivos nesta partição. Você não quer ligar a rede a menos que exista algum tráfego, e assim por diante.

Ao contrário, a primeira vez que um tradutor passivo é acessado, ele é automaticamente lido do inode e um tradutor ativo é iniciado a partir dele usando a linha de comando que foi armazenada no inode. Isto é similar à funcionalidade de montagem automática do Linux. Contudo, ele não vem como um bônus que você tem que configurar manualmente, mas como uma parte integral do sistema. Assim, definir tradutores passivos posterga o início da tarefa de tradutor até que você realmente precise dela. A propósito, se o tradutor ativo morre por alguma razão, a próxima vez em que o inode for acessado, o tradutor é reiniciado.

Existe uma outra diferença: tradutores ativos podem morrer ou se perder. Logo após o término do processo do tradutor ativo (por exemplo, porque você reiniciou a máquina), ele estará perdido para sempre. Tradutores passivos não são transientes e ficam no inode durante a reinicialização até que você modifique-os com o programa settrans ou apague os inodes aos quais estão anexados. Isto significa que você não precisa manter um arquivo de configuração com seus pontos de montagem.

Um último ponto: mesmo se você definiu um tradutor passivo, você ainda pode definir um tradutor ativo diferente. Somente se o tradutor é automaticamente iniciado porque não existia tradutor ativo quando o inode foi acessado, assim o tradutor passivo é considerado.

Gerenciando tradutores

Como mencionado acima, você pode usar settrans para definir e alterar tradutores passivos e ativos. Existem muitas opções para alterar o comportamento do settrans no caso de algo dar errado e para condicionar suas ações. Aqui estão alguns usos comuns:

Você pode usar o comando showtrans para ver se um tradutor está anexado a um inode. Porém, isso só vai mostrar o tradutor passivo.

Você pode alterar as opções de um tradutor ativo (de sistema de arquivos) com fsysopts sem realmente reiniciá-lo. Isto é muito conveniente. Por exemplo, você pode fazer o chamado "remontando uma partição somente-leitura" sob o Linux executando simplesmente fsysopts /mntpoint --readonly. O tradutor ativo em execução mudará seu comportamento de acordo com sua requisição, se possível. O fsysopts /mntpoint sem nenhum parâmetro mostra as configurações atuais.

Exemplos

Eu recomendo que você inicie pela leitura do comando /bin/mount, é só um pequeno script. Devido à configuração de tradutores de sistemas de arquivos ser similar à montagem de partições, você facilmente pode captar o conceito desta maneira. Crie uma imagem de sistema de arquivo com dd if=/dev/zero of=dummy.fs bs=1024k count=8; mke2fs dummy.fs e "monte-a" com settrans -c dummy /hurd/ext2fs `pwd`/dummy.fs. Note que o tradutor ainda não iniciou, nenhum novo processo ext2fs está executando (verifique com ps Aux). Verifique se tudo está correto usando showtrans.

Agora digite ls dummy e você perceberá um curto atraso que acontece enquanto o tradutor é iniciado. Após isso, não haverá mais atrasos acessando o dummy. Sob o Linux, poderia se dizer que você montou automaticamente um sistema de arquivo em loop. Verifique com ps Aux que agora existe um processo ext2fs dummy ativo e executando. Agora coloque alguns arquivos no novo diretório. Tente fazer o sistema de arquivos ficar em somente-leitura com fsysopts. Note quão longe vão as falhas das tentativas de escrita. Tente matar o tradutor ativo com settrans -g.

Agora você deve ter alguma compreensão do que está acontecendo. Lembre-se de que foi somente um servidor especial, o servidor ext2fs do Hurd. Existem muitos mais servidores no diretório hurd. Alguns deles são para sistemas de arquivos. Alguns são necessários para funcionalidades de sistemas de arquivo, como os links. Alguns são necessários para arquivos de dispositivos. Alguns são úteis para redes. Imagine "montar" um servidor FTP com settrans e baixar arquivos simplesmente com o comando padrão cp. Ou editar seus sites web com emacs /ftp/homepage.my.server.org/index.html!