Algumas informações sobre inode

Periodicamente, com o objetivo de me candidatar a vagas em centros de dados, faço entrevistas em diversas grandes empresas, principalmente em São Petersburgo e Moscovo, para cargos de DevOps. Notei que muitas empresas (em muitas boas empresas, como o Yandex) fazem duas perguntas semelhantes:

  • o que é inode;
  • quais são as razões para se obter um erro ao gravar no disco (ou, por exemplo: por que pode acabar o espaço no disco, a essência é a mesma).

Como costuma acontecer, eu estava convencido de que conhecia bem esse tema, mas assim que comecei a explicar — surgiram lacunas no meu conhecimento. Para sistematizar meus conhecimentos, preencher lacunas e não passar mais vergonha, escrevo este artigo, que pode ser útil para alguém mais.

Vou começar "de baixo", ou seja, pelo disco rígido (desconsiderando pen drives, SSDs e outras coisas modernas, vamos considerar qualquer disco antigo de 20 ou 80 GB, já que lá o tamanho do bloco é de 512 bytes).

O disco rígido não consegue endereçar seu espaço byte a byte; ele é, teoricamente, dividido em blocos. A numeração dos blocos começa a partir de 0. (isso é chamado de LBA, detalhes aqui: ru.wikipedia.org/wiki/LBA)

Algumas informações sobre inode

Como pode ser visto na figura, os blocos LBA estão marcados como nível HDD. A propósito, você pode verificar qual é o tamanho do bloco do seu disco da seguinte forma:

root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512

Um nível acima é a partição, uma para todo o disco (novamente para simplificação). Normalmente, utilizam-se dois tipos de formatação de partições: msdos e gpt. Assim, msdos é o formato antigo que suporta discos de até 2TB, enquanto gpt é o novo formato que pode endereçar até 1 zettabyte de blocos de 512 bytes. No nosso caso, temos uma partição do tipo msdos, como pode ser visto na figura, onde a partição começa no bloco nº 1, enquanto o zero é utilizado para o MBR.

Na primeira partição, criei um sistema de arquivos ext2, cujo tamanho de bloco padrão é de 4096 bytes, o que também é refletido na figura. Para verificar o tamanho do bloco do sistema de arquivos, você pode usar o seguinte comando:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Nome do volume do sistema de arquivos:   
Último montado em:          
UUID do sistema de arquivos:          a600bf40-f660-41f6-a3e6-96c303995479
Número mágico do sistema de arquivos:  0xEF53
Revisão do sistema de arquivos #:    1 (dinâmico)
Recursos do sistema de arquivos:      ext_attr resize_inode dir_index filetype sparse_super large_file
Flags do sistema de arquivos:         signed_directory_hash
Opções de montagem padrão:    user_xattr acl
Estado do sistema de arquivos:         limpo
Comportamento em caso de erros:          Continuar
Tipo de sistema operacional do sistema de arquivos:       Linux
Contagem de inodes:              65536
Contagem de blocos:              261888
Contagem de blocos reservados:     13094
Blocos livres:              257445
Inodes livres:              65525
Primeiro bloco:              0
Tamanho do bloco:               4096
Tamanho do fragmento:            4096
Blocos GDT reservados:      63
Blocos por grupo:         32768
Fragmentos por grupo:      32768
Inodes por grupo:         8192
Blocos de inodes por grupo:   512
Sistema de arquivos criado:       Sex Ago  2 15:02:13 2019
Último horário de montagem:          n/a
Último horário de gravação:          Sex Ago  2 15:02:14 2019
Contagem de montagens:              0
Contagem máxima de montagens:      -1
Última verificação:             Sex Ago  2 15:02:13 2019
Intervalo de verificação:           0 ()
UID de blocos reservados:      0 (usuário root)
GID de blocos reservados:      0 (grupo root)
Primeiro inode:              11
Tamanho do inode:               256
Tamanho extra requerido:     28
Tamanho extra desejado:      28
Hash de diretório padrão:   half_md4
Semente de Hash de Diretório:      c0155456-ad7d-421f-afd1-c898746ccd76

O parâmetro que precisamos é o "Tamanho do bloco".

Agora, a parte mais interessante: como ler o arquivo /home/serp/testfile? O arquivo consiste em um ou mais blocos do sistema de arquivos, onde estão armazenados seus dados. Sabendo o nome do arquivo, como encontrá-lo? Quais blocos ler?

Aqui os inodes entram em cena. No sistema de arquivos ext2fs, existe uma "tabela" que contém informações sobre todos os inodes. O número de inodes em um caso de ext2fs é definido durante a criação do sistema de arquivos. Os números necessários estão disponíveis no parâmetro "Contagem de inodes" da saída do tune2fs, ou seja, temos 65536 deles. O inode contém as informações que precisamos: a lista de blocos do sistema de arquivos para o arquivo desejado. Como encontrar o número do inode para o arquivo especificado?

A correspondência entre o nome e o número do inode está contida no diretório, e o diretório no ext2fs é um arquivo de tipo especial, ou seja, também tem seu próprio número de inode. Para quebrar esse ciclo vicioso, o número de inode "fixo" foi atribuído ao diretório raiz, que é "2". Vamos olhar o conteúdo do inode número 2:

root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs:  stat 

Inode: 2   Tipo: diretório    Modo:  0755   Flags: 0x0
Geração: 0    Versão: 0x00000000:00000002
Usuário:     0   Grupo:     0   Tamanho: 4096
ACL do arquivo: 0    ACL do diretório: 0
Links: 3   Contagem de blocos: 8
Fragmento:  Endereço: 0    Número: 0    Tamanho: 0
 ctime: 0x5d43cb51:16b61bcc -- Sex Ago  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Sex Ago  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Sex Ago  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Sex Ago  2 15:02:14 2019
Tamanho dos campos extras do inode: 28
BLOCOS:
(0):579
TOTAL: 1

Como pode ser visto, o diretório necessário está no bloco de número 579. Nele, encontramos o número do nó para a pasta home, e assim por diante na cadeia, até que no diretório serp vejamos o número do nó para o arquivo solicitado. Se alguém quiser verificar se o número está correto e se há informações relevantes, não é difícil. Faça:

root@ubuntu:~# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 registros lidos
1+0 registros escritos
4096 bytes (4,1 kB) copiados, 0,000184088 s, 22,3 MB/s
root@ubuntu:~# hexdump -c /home/serp/dd_image

Na saída, é possível ler os nomes dos arquivos no diretório.

Aqui estou eu, chegando à pergunta principal: "quais podem ser as razões para ocorrer um erro de gravação"?

Naturalmente, isso acontecerá se não houver blocos livres no sistema de arquivos. O que podemos fazer nesse caso? Além da óbvia opção de "deletar algo desnecessário", devemos lembrar que nos sistemas de arquivos ext2, 3 e 4 existe algo chamado "Reserved block count". Se olharmos para a listagem acima, temos "13094" desses blocos. Esses blocos estão disponíveis para gravação apenas para o usuário root. Mas se você precisar resolver a questão rapidamente, como solução temporária pode torná-los acessíveis a todos, resultando em um pouco de espaço livre:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Definindo a porcentagem de blocos reservados para 0% (0 blocos)

Ou seja, por padrão, você não tem 5% do espaço em disco disponível para gravação, e considerando os volumes dos discos modernos, isso pode ser centenas de gigabytes.

O que mais pode acontecer? Também é possível que haja blocos livres, mas os nós tenham acabado. Isso geralmente ocorre se você tiver muitos arquivos no sistema de arquivos com tamanho menor que o tamanho do bloco do sistema de arquivos. Considerando que para 1 arquivo ou diretório é gasto 1 inode, e temos um total de (para este sistema de arquivos) 65536 — essa situação é mais que real. Isso pode ser visualizado claramente na saída do comando df:

serp@ubuntu:~$ df -hi
Filesystem     Inodes IUsed IFree IUse% Mounted on
udev             493K   480  492K    1% \/dev
tmpfs            493K   425  493K    1% \/run
\/dev\/xvda1       512K  240K  273K   47% \/
none             493K     2  493K    1% \/sys\/fs\/cgroup
none             493K     2  493K    1% \/run\/lock
none             493K     1  493K    1% \/run\/shm
none             493K     2  493K    1% \/run\/user
\/dev\/xvdc1       320K  4,1K  316K    2% \/var
\/dev\/xvdb1        64K   195   64K    1% \/home
\/dev\/xvdh1       4,0M  3,1M  940K   78% \/var\/www
serp@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            2,0G  4,0K  2,0G   1% \/dev
tmpfs           395M  620K  394M   1% \/run
\/dev\/xvda1      7,8G  2,9G  4,6G  39% \/
none            4,0K     0  4,0K   0% \/sys\/fs\/cgroup
none            5,0M     0  5,0M   0% \/run\/lock
none            2,0G     0  2,0G   0% \/run\/shm
none            100M     0  100M   0% \/run\/user
\/dev\/xvdc1      4,8G  2,6G  2,0G  57% \/var
\/dev\/xvdb1      990M  4,0M  919M   1% \/home
\/dev\/xvdh1       63G   35G   25G  59% \/var\/www

Como é bem visível na seção \/var\/www, a quantidade de blocos livres do sistema de arquivos e a quantidade de inodes livres diferem bastante.

Caso os inodes acabem, não tenho dicas, pois não há (se estiver errado, me avise). Portanto, para partições onde pequenos arquivos se proliferam, é importante escolher corretamente o sistema de arquivos. Por exemplo, no btrfs, os inodes não podem acabar, pois novos são criados dinamicamente conforme a necessidade.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster