Sistema de arquivos aufs2 TUTORIAL Escrita invisível Obtenha capacidade de escrita em dispositivos somente leitura com o sistema de arquivos aufs. por Klaus Knopper O aufs [1] é um sistema de ar- quivos similar ao UnionFS [2]. Uma utilização comum do aufs é oferecer uma capacidade “de escrita temporária” a um sistema de arquivos residente em uma mídia somente de leitura. Uso o aufs no Knoppix para unir dados somente de leitura do arquivo compactado do Knoppix (localizado normalmente em um CD ou DVD) com um sistema de arquivos de leitura e escrita em um ramdisk ou um pendrive USB. Um sistema de arquivos em pilha cria uma pilha dos diretórios existentes que são “transparentes” ao usuário: cada acesso a um arquivo é 56 tentado em cada diretório da pilha até obter sucesso ou atingir o fim do montante. Mesmo que não esteja montando seu próprio sistema, ainda há uso prático para o aufs como um meio de adicionar acesso de leitura e escrita virtual a arquivos armazenados em um dispositivo de leitura. Neste artigo, descrevo como proporcionar capacidade de escrita a um dispositivo de leitura usando o aufs. Como obter o aufs2 O aufs2 vem em dois formatos: um kernel completamente baseado em Git com o aufs2 incluído e uma ver- são standalone que contém apenas as mudanças que precisam ser adicionadas ao código do kernel. Verificar completamente o kernel com a adição do aufs2 não é o cenário mais comum, e compilar a versão standalone não é um grande desafio, por isso, vou descrever o procedimento do uso da versão pronta em um código de kernel básico, que pode ser encontrada no Linux Kernel Archives [3]. Os exemplos a seguir baseiam-se na versão 2.6.29 do kernel, que reside em um subdiretório do diretório em funcionamento e chamado linux-2.6.29. http://www.linuxmagazine.com.br aufs2 | TUTORIAL Caso nunca tenha usado Git antes, ele pode não constar do seu sistema de desenvolvimento. Nos sistemas baseados em Debian, o comando para instalação é o seguinte: aptitude install git-core Para outros sistemas de gerenciamento de pacotes, consulte a documentação do fornecedor. O comando para verificar o patch standalone do kernel 2.6.29 é: git clone http://git.c3sl.ufpr.br /pub/scm/aufs/aufs2-standalone. git aufs2-standalone.git Após esse comando, aufs2-standalone.git será uma cópia local do repositório Git aufs2-standalone. O comando git checkout origin/ aufs2-29 verifica a versão aufs2 do kernel 2.6.29 (repare no 29 no final dos parâmetros de comando) e a define como versão corrente. É possível ver uma nota ou aviso do Git sobre o fato de origin/aufs2-29 não ser local, o que pode ser ignorado por enquanto. A listagem 1 mostra o diretório aufs2-standalone.git (ls -l) corrente. O diretório fs inclui o código do aufs2, e o diretório include contém os arquivos do kernel necessários ao aufs2. Ambos precisam ser copiados para o diretório do código do kernel. Adicionar arquivos de código aufs2 Se seu código do kernel estiver localizado um diretório acima de linux-2.6.29, digite: cd ../linux-2.6.29 cp -a ../aufs2-standalone.git/ {fs,include,Documentation} . cp ../aufs2-standalone.git/config. mk fs/aufs/ Linux Magazine #70 | Setembro de 2010 Complexidades O simples conceito de pilha de sistema de arquivos com permissão de escrita feita com um sistema de arquivos com permissão somente de leitura torna-se complicado quando se considera a necessidade de fazer mudanças dentro da pilha. Por exemplo, se um arquivo residente em um nó de diretório somente leitura for excluído, como fazer com que ele desapareça mesmo? No caso de exclusão de arquivos, um novo arquivo “oculto” (conhecido por “whiteout”) é criado no ramo com permissão de escrita, para informar o aufs que ele deve agir como se o arquivo original não existisse. Quando se escreve em um arquivo residente em um ramo sem permissão de escrita, uma cópia do arquivo alterado precisa ser criada no ramo que tenha essa permissão. Até mesmo casos mais complicados ocorrem com operações como acesso a arquivos concorrentes, diferenciação de permissões e métodos de acesso para divergir arquivos em diferentes ramos. Portanto, usar arquivos em um diretório em pilha não é tão fácil quanto parece e, de fato, o código-fonte do aufs tem o mesmo tamanho e complexidade que o de um sistema de arquivos normal do Linux O README do aufs2 descreve a instalação de modo diferente, mas acho que o método de copiar todos os arquivos de código do aufs2 diretamente para a árvore do código do kernel é uma maneira conveniente para montar pacotes de imagem do kernel do Linux contendo o aufs2, para o pronto uso no Debian, sem a necessidade de criar um subdiretório modules/aufs com uma infraestrutura externa de módulos correspondente. Correções no kernel No diretório aufs2-standalone.git (listagem 1), é possível notar um arquivo chamado aufs2-standalone. patch. Esse arquivo contém mudan- ças que precisam ser feitas em vários locais relacionados ao sistema de arquivos do código original do kernel. O Makefile do kernel e o sistema de configuração também exigem que algumas mudanças sejam feitas para que o aufs2 esteja visível como um novo sistema de arquivos em makemenuconfig. No diretório atual, linux-2.6.29, use patch da seguinte maneira: patch -p1 < ../aufs2-standalone. git/aufs2-standalone.patch o que irá produzir a saída mostrada na listagem 2. Um novo aufs Recentemente, o desenvolvimento da versão 1 do aufs foi interrompida em favor do aufs2, que é uma extensão do kernel para adicionar capacidades de pilhas de sistema de arquivos diretamente na árvore do kernel. Ao mesmo tempo, o autor do aufs, Junjiro Okajima, passou a usar o Git para gerenciar o código-fonte, que também é usado pelos mantenedores do kernel do Linux. De acordo com o desenvolvedor, a primeira meta da criação do aufs2 era oferecer revisões de códigos mais amplas e simples, além de simplificar e diminuir os arquivos do código. O aufs consistia de vários arquivos de correção altamente dependentes das versões e das opções de compilação do kernel, enquanto que o aufs2 apenas utiliza o próprio sistema de configuração do kernel e compila mais facilmente. 57 TUTORIAL | aufs2 Listagem 1: aufs2-standalone.git (ls -l ) 01 ‑rw‑r‑‑r‑‑ patch 02 ‑rw‑r‑‑r‑‑ 03 ‑rw‑r‑‑r‑‑ 04 ‑rw‑r‑‑r‑‑ 05 drwxr‑xr‑x 06 ‑rw‑r‑‑r‑‑ 07 drwxr‑xr‑x 08 drwxr‑xr‑x 09 ‑rw‑r‑‑r‑‑ 1 knopper users 9222 15. Apr 00:51 aufs2‑standalone. 1 1 1 4 1 3 3 1 knopper knopper knopper knopper knopper knopper knopper knopper users users users users users users users users 40296 15. Apr 00:51 ChangeLog 661 15. Apr 00:47 config.mk 17990 15. Apr 00:47 COPYING 104 15. Apr 00:51 Documentation 1481 15. Apr 00:51 ecryptfs.patch 72 15. Apr 00:51 fs 72 15. Apr 00:51 include 617 15. Apr 00:47 Makefile Se não houver nenhuma linha indicando algum erro de uma correção, então, tudo estará pronto para a compilação. Opções de configuração Ao executar o comando make menuconfig para configurar ou alterar as opções do kernel, você encontrará o aufs2 no grupo de opções File system, no submenu Miscellaneous filesistems (figura 1). Se o aufs não estiver lá e tudo tiver sido feito corretamente, verifique se o recurso do kernel experimental está habilitado na configuração. A linha Maximum number of branches mostrada na figura 1 de- fine quantos diretórios o aufs pode combinar em um único diretório virtual. A linha Use inotify... permite modificar um ramo (branch) diretamente, fazendo com que as mudanças apareçam de imediato no ponto de montagem (de outra maneira, geraria resultados inesperados, pois o aufs não monitora mudanças em arquivos até que estejam alterados no ponto de montagem). A linha NFSexportable habilita alguns recursos necessários para exportar diretórios através do sistema de arquivos de rede NFS, e a linha Ramfs as an aufs branch só é necessária se o ramdisk inicial permanecer como sistema de arquivos root após a inicialização e se for usado como um ramo de escrita do aufs. Listagem 2: Correção de Arquivos 01 02 03 04 05 06 07 08 09 10 11 12 13 58 patching patching patching patching patching patching patching patching patching patching patching patching patching file file file file file file file file file file file file file fs/Kconfig fs/Makefile fs/namei.c fs/namespace.c fs/open.c fs/splice.c fs/super.c include/linux/Kbuild include/linux/lockdep.h include/linux/namei.h include/linux/splice.h security/device_cgroup.c security/security.c A ajuda online no diretório Documentation fornece detalhes úteis sobre cada opção. Compilar o aufs Se o aufs tiver sido habilitado como um módulo (com a opção m), o aufs. ko será montado juntamente com todos os módulos do kernel a partir do comando: make modules Outra maneira seria montar apenas o módulo aufs, deixando os outros de lado: make ./fs/aufs/aufs.ko Algumas funções de sistema de arquivos exportados modificam-se com a correção do kernel, por isso, ainda pode ser preciso recompilar outros módulos, além do kernel estático; portanto, recompilar e instalar todo o kernel, com todos os módulos, é recomendável – tudo isso seguido de uma reinicialização. Depois, o módulo aufs pode ser carregado (caso ele não tenha sido compilado estaticamente) com: modprobe aufs União de partições Se uma partição de disco for montada apenas para leitura mount -r /dev/sdb1 /media/disk e um diretório para dados de escrita foi adicionado em algum lugar (/tmp seria suficiente) mkdir /tmp/cow é possível agora unir os dois diretórios como um só diretório virtual com acesso de escrita. Todos os arquivos virão primeiramente de / media/disk (área de leitura) e, por http://www.linuxmagazine.com.br aufs2 | TUTORIAL baixo dos panos, arquivos alterados ou recém-criados irão para /tmp/cow. mkdir /tmp/aufs mount -t "aufs" -o br:/tmp/ cow=rw:/media/disk=ro none /tmp/ aufs Repare que a lista de diretórios associados com um volume aufs não é dada como “arquivo de dispositivo” (device) como é o costume do comando mount mas, sim, dentro das opções do sistema de arquivos (-o) como br:directory1:directory2: …, onde todos os diretórios, com exceção do primeiro, terão um sufixo =ro para marcá-los com somente a leitura para o aufs. O primeiro diretório possui =rw indicando permissão de escrita. Além do mais, é possível unir virtualmente o conteúdo de múltiplos diretórios como um só – por exemplo, se for preciso, combinar uma coleção de vários arquivos de multimídia em um único diretório, quando todos eles estão espalhados em várias partes do disco. Para adicionar diretórios à pilha, use o comando: mount -o remount,append:new_ directory /tmp/aufs ou remova-os com a opção de mount del. O conjunto completo das opções do aufs, incluindo uma descrição de inserção, remoção ou modificação de ramos específicos de uma pilha de diretórios aufs, está em destaque em aufs.5, que é uma página de manual formatada como nroff. Para ler o aufs.5 sem instalação, use: nroff -man Documentation/ filesystems/aufs/aufs.5 | less Uma opção de montagem do aufs que pode ser bem útil em um sistema ativo é a noplink, que desabilita links não simbólicos (hard links) de Linux Magazine #70 | Setembro de 2010 Figura 1Habilitar a opção de kernel aufs. arquivos permanentes em diferentes ramos, economizando muito espaço valioso no ramo de escrita. Conclusão O aufs contorna problemas com facilidade para oferecer acesso de escrita à mídia ou arquivos somente de leitura, tais como o ISO9660 (que não suporta operações de escrita, mesmo que o dispositivo de bloco tenha esta permissão). Sem o aufs, os symlinks e bindmounts, a reestruturação de sistemas de arquivos seria necessária para suportar escrita em arquivos sem essa permissão. Configurar um ambiente chroot para gravar mudanças no sistema de arquivos é mais fácil com o aufs, pois ele inclui todos os arquivos alterados e um registro de modificações aos metadados no ramo de escrita. Com esse recurso, é possível criar instalações que podem ser incrementadas apenas com um histórico passo a passo do sistema de arquivos. Além disso, é possível utilizar pontos de montagem como alvos, para que os dados do antigo diretório sejam “escondidos” pelos dados modificados. Usuários do aufs2 há muito tempo o adicionam ao kernel principal. Por causa de tentativas de adicionar capacidades de overlay na camada genérica do sistema de arquivos virtual, em vez de em um sistema de arquivos separado, o aufs2 não chegará tão cedo ao kernel. n Mais informações [1]Aufs: http://aufs.sourceforge.net [2]UnionFS: http://www.filesystems.org/project-unionfs.html [3]Linux Kernel Archives: http://www.kernel.org [4]Wikipedia do aufs: http://en.wikipedia.org/wiki/AuFS Gostou do artigo? Queremos ouvir sua opinião. Fale conosco em [email protected] Este artigo no nosso site: http://lnm.com.br/article/3843 59