Sistemas de arquivos virtuais Linux: por que eles são necessários e como eles funcionam? Parte 2

Olá pessoal, estamos compartilhando com você a segunda parte da publicação “Sistemas de arquivos virtuais no Linux: por que eles são necessários e como funcionam?” A primeira parte pode ser lida aqui . Lembre-se de que esta série de publicações é dedicada ao lançamento de um novo thread no curso Linux Administrator , que começará muito em breve.

Como assistir ao VFS com ferramentas eBPF e cco

A maneira mais fácil de entender como o kernel opera nos arquivos sysfs é observá-lo na prática, e a maneira mais fácil de observar o ARM64 é usar o eBPF. O eBPF (abreviação de Berkeley Packet Filter) consiste em uma máquina virtual em execução no kernel que usuários privilegiados podem query na linha de comando. As fontes do kernel dizem ao leitor o que o kernel pode fazer; A execução de ferramentas eBPF em um sistema ocupado mostra o que o kernel realmente faz.



Felizmente, começar a usar o eBPF é bastante fácil com as ferramentas bcc , que estão disponíveis como pacotes na distribuição geral do Linux e são documentadas em detalhes por Bernard Gregg . bcc ferramentas bcc são scripts Python com pequenas inserções de código C, o que significa que qualquer pessoa familiarizada com os dois idiomas pode modificá-los facilmente. Existem 80 scripts Python em bcc/tools , o que significa que provavelmente o desenvolvedor ou administrador do sistema poderá escolher algo adequado para resolver o problema.

Para ter uma idéia superficial do que o VFS faz em um sistema em execução, tente vfscount ou vfsstat . Isso mostrará, por exemplo, que dezenas de chamadas para vfs_open() e "seus amigos" ocorrem literalmente a cada segundo.



vfsstat.py é um script Python com inserções de código C que simplesmente conta as chamadas de função do VFS.


Damos um exemplo mais trivial e vemos o que acontece quando inserimos uma unidade flash USB em um computador e o sistema a detecta.



Usando o eBPF, você pode ver o que acontece em /sys quando uma unidade flash USB é inserida. Um exemplo simples e complexo é mostrado aqui.


No exemplo acima, a ferramenta bcc trace.py exibe uma mensagem quando o comando sysfs_create_files() é sysfs_create_files() . Vimos que sysfs_create_files() foi iniciado usando o fluxo do kworker em resposta à unidade flash sendo inserida, mas qual arquivo foi criado? O segundo exemplo mostra todo o poder do eBPF. Aqui trace.py exibe o backtrace do kernel (opção -K) e o nome do arquivo criado por sysfs_create_files() . A inserção de instrução única é um código C que inclui uma sequência de formatos facilmente reconhecível fornecida por um script Python que executa o compilador just-in-time do LLVM. Ele compila e executa essa linha em uma máquina virtual dentro do kernel. A assinatura completa da função sysfs_create_files () deve ser reproduzida no segundo comando para que a cadeia de formato possa se referir a um dos parâmetros. Erros neste fragmento de código C resultam em erros reconhecíveis do compilador C. Por exemplo, se você omitir a opção -l, verá "Falha ao compilar o texto BPF". Os desenvolvedores familiarizados com C e Python acharão as ferramentas bcc fáceis de expandir e modificar.

Quando uma unidade USB é inserida, um kworker kernel mostrará que o PID 7711 é o fluxo do kworker que criou o arquivo «events» no sysfs . Assim, uma chamada com sysfs_remove_files() mostrará que a remoção da unidade excluiu o arquivo de events , o que está alinhado com o conceito geral de contagem de referência. Ao mesmo tempo, visualizar sysfs_create_link () com o eBPF ao inserir uma unidade USB mostrará que pelo menos 48 links simbólicos foram criados.

Então, qual é o significado do arquivo de eventos? O uso do cscope para procurar __device_add_disk () mostra que ele chama disk_add_events () , e "media_change" ou "eject_request" podem ser gravados no arquivo de evento. Aqui, a camada de bloco do kernel informa o espaço do usuário da aparência e extração do "disco". Observe o quão informativo esse método de pesquisa é pelo exemplo de inserção de uma unidade USB em comparação com a tentativa de descobrir como tudo funciona, exclusivamente a partir da fonte.

Os sistemas de arquivos raiz somente leitura permitem dispositivos incorporados

Obviamente, ninguém desliga o servidor ou o computador, puxando o plugue da tomada. Mas porque? E tudo porque os sistemas de arquivos montados em dispositivos de armazenamento físico podem ter registros pendentes e as estruturas de dados que registram seu estado podem não ser sincronizadas com os registros no armazenamento. Quando isso acontece, os proprietários do sistema precisam aguardar a próxima inicialização para executar o fsck filesystem-recovery e, na pior das hipóteses, perder dados.

No entanto, todos sabemos que muitos dispositivos de IoT, além de roteadores, termostatos e carros, agora estão executando o Linux. Muitos desses dispositivos praticamente não têm interface com o usuário e não há como desativá-los "de maneira limpa". Imagine iniciar um carro com uma bateria descarregada, quando a energia do dispositivo de controle no Linux constantemente sobe e desce. Como é que o sistema é inicializado sem um longo fsck quando o mecanismo finalmente começa a funcionar? E a resposta é simples. Os dispositivos incorporados contam com um sistema de arquivos raiz somente leitura (abreviado como ro-rootfs (sistema de arquivos raiz somente leitura)).

ro-rootfs oferece muitos benefícios menos óbvios do que genuínos. Uma vantagem é que o malware não pode gravar em /usr ou /lib se nenhum processo Linux puder escrever nele. Outra é que um sistema de arquivos amplamente imutável é essencial para o suporte de campo a dispositivos remotos, pois a equipe de suporte usa sistemas locais que são nominalmente idênticos aos sistemas locais. Talvez a vantagem mais importante (mas também a mais insidiosa) seja que o ro-rootfs força os desenvolvedores a decidir quais objetos do sistema serão alterados, mesmo no estágio de design do sistema. Trabalhar com ro-rootfs pode ser desconfortável e doloroso, como geralmente ocorre com variáveis ​​const em linguagens de programação, mas seus benefícios podem facilmente cobrir a sobrecarga extra.

Criar rootfs somente rootfs requer um esforço extra para desenvolvedores incorporados, e é aí que o VFS entra em cena. O Linux exige que os arquivos em /var sejam graváveis ​​e, além disso, muitos aplicativos populares que executam sistemas embarcados tentarão criar dot-files configuração em $HOME . Uma das soluções para arquivos de configuração no diretório inicial é geralmente a geração e montagem preliminares no rootfs . Para /var uma das abordagens possíveis é montá-lo em uma seção separada gravável, enquanto o / mount em si é somente leitura. Outra alternativa popular é usar montagens de ligação ou sobreposição.

Suportes vinculáveis ​​e sobrepostos, seu uso em contêineres

A execução do comando man mount é a melhor maneira de aprender sobre montagens mapeadas e sobrepostas que dão aos desenvolvedores e administradores de sistema a capacidade de criar um sistema de arquivos de uma maneira e depois fornecê-los para aplicativos de outra. Para sistemas embarcados, isso significa a capacidade de armazenar arquivos em /var em uma unidade flash somente leitura, mas a sobreposição ou vinculação do caminho de tmpfs para /var na inicialização permitirá que os aplicativos escrevam notas lá (rabisco). Na próxima vez que você ativá-lo, as alterações em /var serão perdidas. Uma montagem de sobreposição cria uma união entre tmpfs e o sistema de arquivos subjacente e permite que você supostamente faça alterações nos arquivos existentes no ro-tootf enquanto uma montagem vinculada pode tornar novas pastas vazias do tmpfs visíveis como graváveis ​​nos caminhos ro-rootfs . Enquanto overlayfs é o tipo proper de sistema de arquivos, montagens de ligação são implementadas no espaço para nome do VFS .

Com base na descrição de montagens sobrepostas e vinculadas, ninguém fica surpreso que os contêineres do Linux as usem ativamente. Vamos observar o que acontece quando usamos systemd-nspawn para iniciar o contêiner usando a ferramenta bcc mountsnoop .



Uma chamada para system-nspawn inicia o contêiner enquanto mountsnoop.py .

Vamos ver o que aconteceu:



A execução do mountsnoop durante a “inicialização” do contêiner indica que o tempo de execução do contêiner depende muito da montagem que está sendo conectada (apenas o início da saída longa é exibido).

Aqui, systemd-nspawn fornece os arquivos selecionados nos procfs e sysfs host para o contêiner como caminhos para seus rootfs . Além do sinalizador MS_BIND , que define a montagem de ligação, alguns outros sinalizadores no sistema montado determinam o relacionamento entre as alterações no espaço para nome do host e o contêiner. Por exemplo, uma montagem de ligação pode pular alterações em /proc e /sys para um contêiner ou ocultá-las, dependendo da chamada.

Conclusão

Compreender a estrutura interna do Linux pode parecer uma tarefa impossível, pois o próprio kernel contém uma enorme quantidade de código, deixando os aplicativos de espaço para usuário do Linux e as interfaces de chamada do sistema nas bibliotecas C, como a glibc . Uma maneira de progredir é ler o código-fonte de um subsistema do kernel, com ênfase na compreensão de chamadas e cabeçalhos do sistema voltados para o espaço do usuário, bem como as principais interfaces principais do kernel, por exemplo, a tabela file_operations . As operações de arquivo fornecem o princípio de "tudo é um arquivo", portanto, gerenciá-las é especialmente bom. Os arquivos do kernel de origem C no diretório de nível superior fs/ representam a implementação de sistemas de arquivos virtuais, que são uma camada de shell que fornece ampla e relativamente simples compatibilidade de sistemas de arquivos e dispositivos de armazenamento populares. Montar com ligação e sobreposição nos namespaces do Linux é uma mágica do VFS que possibilita a criação de contêineres somente leitura e sistemas de arquivos raiz. Combinado com o aprendizado do código fonte, a ferramenta principal do eBPF e sua interface cco
torne a pesquisa do kernel mais fácil do que nunca.

Amigos, escrever este artigo foi útil para você? Talvez você tenha algum comentário ou comentário? E aqueles que estão interessados ​​no curso Linux Administrator, nós convidamos você a abrir o dia da casa , que ocorrerá em 18 de abril.

A primeira parte

Source: https://habr.com/ru/post/pt447748/


All Articles