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 ccoA 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 incorporadosObviamente, 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êineresA 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ãoCompreender 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