Quelque chose à propos de l'inode

Périodiquement, afin de passer au Central Distribution Center, j'interviewe dans diverses grandes entreprises, principalement à Saint-Pétersbourg et à Moscou, pour un poste DevOps. J'ai remarqué que de nombreuses entreprises (beaucoup de bonnes entreprises, par exemple Yandex) posent deux questions similaires :

  • qu'est-ce que l'inode ;
  • pour quelles raisons pouvez-vous obtenir une erreur d'écriture sur le disque (ou par exemple : pourquoi vous pourriez manquer d'espace disque, l'essence est la même).

Comme cela arrive souvent, j'étais sûr de bien connaître ce sujet, mais dès que j'ai commencé à l'expliquer, des lacunes dans mes connaissances sont devenues apparentes. Pour systématiser mes connaissances, combler les lacunes et ne plus m'embarrasser, j'écris cet article, il sera peut-être utile à quelqu'un d'autre.

Je vais commencer par le bas, c'est-à-dire à partir d'un disque dur (nous rejetterons les lecteurs flash, les SSD et autres objets modernes ; par exemple, considérons n'importe quel ancien disque de 20 ou 80 Go, puisque la taille du bloc est de 512 octets).

Le disque dur ne sait pas adresser son espace octet par octet, il est conditionnellement divisé en blocs. La numérotation des blocs commence à 0. (C'est ce qu'on appelle LBA, détails ici : ru.wikipedia.org/wiki/LBA)

Quelque chose à propos de l'inode

Comme le montre la figure, j'ai désigné les blocs LBA comme niveau de disque dur. À propos, vous pouvez voir la taille de bloc de votre disque comme ceci :

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

Le niveau supérieur est une partition, une pour l'ensemble du disque (encore une fois pour simplifier). Le plus souvent, deux types de balisage de partition sont utilisés : msdos et gpt. En conséquence, msdos est un ancien format qui prend en charge des disques jusqu'à 2 To, gpt est un nouveau format capable d'adresser jusqu'à 1 zettaoctet de blocs de 512 octets. Dans notre cas, nous avons une partition de type msdos, comme le montre la figure, la partition commence par le bloc n°1, tandis que zéro est utilisé pour le MBR.

Dans la première partition, j'ai créé un système de fichiers ext2, sa taille de bloc par défaut est de 4096 XNUMX octets, ce qui est également reflété dans la figure. Vous pouvez afficher la taille du bloc du système de fichiers comme ceci :

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

Le paramètre dont nous avons besoin est « Taille du bloc ».

Maintenant, la partie intéressante est de savoir comment lire le fichier /home/serp/testfile ? Un fichier se compose d'un ou plusieurs blocs du système de fichiers dans lesquels ses données sont stockées. Connaissant le nom du fichier, comment le trouver ? Quels blocs dois-je lire ?

C'est là que les inodes sont utiles. Le système de fichiers ext2fs possède une "table" qui contient des informations sur tous les inodes. Le nombre d'inodes dans le cas d'ext2fs est défini lors de la création du système de fichiers. Nous examinons les nombres requis dans le paramètre « Inode count » de la sortie tune2fs, c'est-à-dire nous avons 65536 pièces. L'inode contient les informations dont nous avons besoin : une liste de blocs du système de fichiers pour le fichier que nous recherchons. Comment trouver le numéro d’inode d’un fichier donné ?

Le nom et le numéro d'inode correspondants sont contenus dans le répertoire, et un répertoire dans ext2fs est un type spécial de fichier, c'est-à-dire possède également son propre numéro d'inode. Pour briser ce cercle vicieux, un numéro d'inode « fixe » « 2 » a été attribué au répertoire racine. Regardons le contenu de l'inode numéro 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

Comme vous pouvez le voir, le répertoire dont nous avons besoin est contenu dans le bloc numéro 579. Nous y trouverons le numéro de nœud du dossier de base, et ainsi de suite jusqu'à ce que dans le répertoire serp, nous voyions le numéro de nœud du fichier demandé. Si soudainement quelqu'un veut vérifier si le numéro est correct et si les informations nécessaires sont présentes, ce n'est pas difficile. Nous faisons:

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

Dans la sortie, vous pouvez lire les noms des fichiers du répertoire.

J’en viens donc à la question principale : « pour quelles raisons une erreur d’enregistrement peut-elle se produire ? »

Naturellement, cela se produira s'il n'y a plus de blocs libres dans le système de fichiers. Que peut-on faire dans ce cas ? Outre l'évidence « supprimez tout ce qui n'est pas nécessaire », vous devez vous rappeler que dans les systèmes de fichiers ext2,3, 4 et 13094, il existe une chose telle que « Nombre de blocs réservés ». Si vous regardez la liste ci-dessus, nous avons « XNUMX » de tels blocs. Ce sont des blocs accessibles en écriture uniquement par l'utilisateur root. mais si vous avez besoin de résoudre rapidement le problème, à titre de solution temporaire, vous pouvez les rendre accessibles à tous, ce qui libérera de l'espace :

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

Ceux. par défaut, vous disposez de 5 % de l'espace disque non disponible pour l'écriture, et compte tenu du volume des disques modernes, cela peut représenter des centaines de gigaoctets.

Quoi d'autre cela pourrait-il être? Il est également possible qu’il y ait des blocs libres, mais qu’il n’y ait plus de nœuds. Cela se produit généralement si vous avez sur votre système de fichiers un ensemble de fichiers plus petits que la taille de bloc du système de fichiers. Considérant qu'1 inode est dépensé pour 1 fichier ou répertoire, et au total nous en avons (pour un système de fichiers donné) 65536 - la situation est plus que réaliste. Cela peut être clairement vu dans le résultat de la commande 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

Comme cela est clairement visible sur la partition /var/www, le nombre de blocs libres dans le système de fichiers et le nombre de nœuds libres varient considérablement.

Au cas où vous manqueriez d'inodes, je ne vous dirai aucun sort, car... il n’y en a pas (si je me trompe, faites-le-moi savoir). Ainsi, pour les partitions dans lesquelles de petits fichiers se multiplient, vous devez choisir judicieusement le système de fichiers. Par exemple, les inodes btrfs ne peuvent pas se terminer, car De nouveaux sont créés dynamiquement si nécessaire.

Source: habr.com

Ajouter un commentaire