Algo sobre inode

Periodicamente, para mudar para o Centro de Distribuição Central, faço entrevistas em diversas grandes empresas, principalmente em São Petersburgo e Moscou, para uma posição de DevOps. Percebi que muitas empresas (muitas empresas boas, por exemplo Yandex) fazem duas perguntas semelhantes:

  • o que é inode;
  • por quais motivos você pode obter um erro de gravação no disco (ou por exemplo: por que você pode ficar sem espaço em disco, a essência é a mesma).

Como sempre acontece, eu tinha certeza de que conhecia bem o assunto, mas assim que comecei a explicar, surgiram lacunas de conhecimento. Para sistematizar meu conhecimento, preencher lacunas e não me envergonhar mais, estou escrevendo este artigo, talvez seja útil para outra pessoa.

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

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

Algo sobre inode

Como pode ser visto na figura, designei os blocos LBA como o nível do HDD. A propósito, você pode ver o tamanho do bloco do seu disco assim:

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

O nível acima é uma partição, uma para todo o disco (novamente para simplificar). Na maioria das vezes, dois tipos de marcação de partição são usados: msdos e gpt. Assim, msdos é um formato antigo que suporta discos de até 2 TB, gpt é um novo formato capaz de 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, a partição começa com o bloco nº 1, enquanto zero é usado para o MBR.

Na primeira partição que criei um sistema de arquivos ext2, seu tamanho de bloco padrão é 4096 bytes, o que também está refletido na figura. Você pode visualizar o tamanho do bloco do sistema de arquivos assim:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          a600bf40-f660-41f6-a3e6-96c303995479
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              261888
Reserved block count:     13094
Free blocks:              257445
Free inodes:              65525
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      63
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Fri Aug  2 15:02:13 2019
Last mount time:          n/a
Last write time:          Fri Aug  2 15:02:14 2019
Mount count:              0
Maximum mount count:      -1
Last checked:             Fri Aug  2 15:02:13 2019
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Default directory hash:   half_md4
Directory Hash Seed:      c0155456-ad7d-421f-afd1-c898746ccd76

O parâmetro que precisamos é “Tamanho do bloco”.

Agora a parte interessante é como ler o arquivo /home/serp/testfile? Um arquivo consiste em um ou mais blocos do sistema de arquivos nos quais seus dados são armazenados. Sabendo o nome do arquivo, como encontrá-lo? Quais blocos devo ler?

É aqui que os inodes são úteis. O sistema de arquivos ext2fs possui uma “tabela” que contém informações para todos os inodes. O número de inodes no caso de ext2fs é definido ao criar o sistema de arquivos. Observamos os números necessários no parâmetro “Inode count” da saída tune2fs, ou seja, temos 65536 peças. O inode contém as informações que precisamos: uma lista de blocos do sistema de arquivos para o arquivo que procuramos. Como encontrar o número do inode de um determinado arquivo?

O nome correspondente e o número do inode estão contidos no diretório, e um diretório em ext2fs é um tipo especial de arquivo, ou seja, também tem seu próprio número de inode. Para quebrar esse círculo vicioso, um número de inode “fixo” “2” foi atribuído ao diretório raiz. Vejamos o conteúdo do inode número 2:

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

Inode: 2   Type: directory    Mode:  0755   Flags: 0x0
Generation: 0    Version: 0x00000000:00000002
User:     0   Group:     0   Size: 4096
File ACL: 0    Directory ACL: 0
Links: 3   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Fri Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fri Aug  2 15:02:14 2019
Size of extra inode fields: 28
BLOCKS:
(0):579
TOTAL: 1

Como você pode ver, o diretório que precisamos está contido no bloco número 579. Nele encontraremos o número do nó da pasta inicial e assim por diante até que no diretório serp vejamos o número do nó do arquivo solicitado. Se de repente alguém quiser verificar se o número está correto e se as informações necessárias estão lá, não é difícil. Nós fazemos:

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

Na saída você pode ler os nomes dos arquivos no diretório.

Então chego à questão principal: “por que motivos pode ocorrer um erro de gravação?”

Naturalmente, isso acontecerá se não houver mais blocos livres no sistema de arquivos. O que pode ser feito neste caso? Além do óbvio “exclua tudo o que for desnecessário”, você deve lembrar que nos sistemas de arquivos ext2,3 e 4 existe algo como “Contagem de blocos reservados”. Se você olhar a listagem acima, temos “13094” desses blocos. Estes são blocos graváveis ​​apenas pelo usuário root. mas se precisar resolver o problema rapidamente, como solução temporária você pode disponibilizá-los para todos, resultando em algum espaço livre:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)

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

O que mais poderia ser? Também é possível que existam blocos livres, mas não existam mais nós. Isso geralmente acontece se você tiver vários arquivos em seu sistema de arquivos menores que o tamanho do bloco do sistema de arquivos. Considerando que 1 inode é gasto em 1 arquivo ou diretório, e no total temos (para um determinado sistema de arquivos) 65536 - a situação é mais do que realista. Isso pode ser visto 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 é claramente visível na partição /var/www, o número de blocos livres no sistema de arquivos e o número de nós livres variam bastante.

Caso você fique sem inodes, não vou te contar nenhum feitiço, porque... não há nenhum (se eu estiver errado, me avise). Portanto, para partições nas quais arquivos pequenos se multiplicam, você deve escolher o sistema de arquivos com sabedoria. Por exemplo, os inodes btrfs não podem terminar, porque Novos são criados dinamicamente, se necessário.

Fonte: habr.com

Adicionar um comentário