Périodiquement, dans le cadre de mon déménagement vers un Data Center, je passe des entretiens dans différentes grandes entreprises, principalement à Saint-Pétersbourg et à Moscou pour des postes de DevOps. J'ai remarqué que dans de nombreuses entreprises (dans de nombreuses bonnes entreprises, par exemple chez Yandex), on pose deux questions similaires :
- qu'est-ce qu'un inode ;
- pour quelles raisons peut-on obtenir une erreur d'écriture sur le disque (ou par exemple : pourquoi l'espace disque peut-il venir à manquer, la question est la même).
Comme c'est souvent le cas, je pensais que je connaissais bien ce sujet, mais dès que j'ai commencé à expliquer, des lacunes dans mes connaissances se sont manifestées. Pour systématiser mes connaissances, combler les lacunes et ne plus avoir honte, j'écris cet article, cela peut également être utile à d'autres.
Je vais commencer « par le bas », c'est-à-dire par le disque dur (les clés USB, SSD et autres dispositifs modernes seront mis de côté, prenons simplement un ancien disque de 20 ou 80 Go, car sa taille de bloc est de 512 octets).
Le disque dur ne peut pas adresser son espace octet par octet, il est schématiquement divisé en blocs. La numérotation des blocs commence à 0. (cette méthode est appelée LBA, plus de détails ici : )

Comme on peut le voir sur le schéma, j'ai désigné les blocs LBA comme le niveau HDD. À propos, on peut vérifier la taille du bloc de votre disque comme suit :
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512Au niveau supérieur, le partitionnement est indiqué, un pour tout le disque (encore une fois pour simplifier). On utilise le plus souvent deux types de partitionnement : msdos et gpt. Ainsi, msdos est un ancien format prenant en charge des disques jusqu'à 2 To, tandis que 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 le schéma, et cette partition commence au bloc n°1, le bloc zéro étant utilisé pour le MBR.
Dans la première partition, j'ai créé un système de fichiers ext2, par défaut, la taille de son bloc est de 4096 octets, ce qui est également reflété sur le schéma. On peut vérifier la taille du bloc du système de fichiers comme suit :
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-févr.-2014)
Nom du volume du système de fichiers :
Dernière monture :
UUID du système de fichiers : a600bf40-f660-41f6-a3e6-96c303995479
Numéro magique du système de fichiers : 0xEF53
Révision du système de fichiers : 1 (dynamique)
Fonctionnalités du système de fichiers : ext_attr resize_inode dir_index filetype sparse_super large_file
Drapeaux du système de fichiers : signed_directory_hash
Options de montage par défaut : user_xattr acl
État du système de fichiers : propre
Comportement en cas d'erreurs : Continuer
Type de système d'exploitation du système de fichiers : Linux
Nombre d'inodes : 65536
Nombre de blocs : 261888
Nombre de blocs réservés : 13094
Blocs libres : 257445
Inodes libres : 65525
Premier bloc : 0
Taille des blocs : 4096
Taille des fragments : 4096
Blocs GDT réservés : 63
Blocs par groupe : 32768
Fragments par groupe : 32768
Inodes par groupe : 8192
Blocs d'inodes par groupe : 512
Système de fichiers créé : Ven 2 Août 15:02:13 2019
Dernière heure de montage : n/a
Dernière heure d'écriture : Ven 2 Août 15:02:14 2019
Nombre de montages : 0
Nombre de montages maximum : -1
Dernière vérification : Ven 2 Août 15:02:13 2019
Intervalle de vérification : 0 ()
UID des blocs réservés : 0 (utilisateur root)
GID des blocs réservés : 0 (groupe root)
Premier inode : 11
Taille des inodes : 256
Taille d'extension supplémentaire requise : 28
Taille d'extension supplémentaire souhaitée : 28
Hachage de répertoire par défaut : half_md4
Graine de hachage de répertoire : c0155456-ad7d-421f-afd1-c898746ccd76Le paramètre dont nous avons besoin est « Taille de bloc ».
Maintenant, la partie intéressante : comment lire le fichier /home/serp/testfile ? Le fichier est constitué d'un ou plusieurs blocs du système de fichiers, dans lesquels sont stockées ses données. En connaissant le nom du fichier, comment le trouver ? Quels blocs lire ?
C'est là que les inodes entrent en jeu. Dans le système de fichiers ext2fs, il existe une « table » contenant 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. Les chiffres nécessaires se trouvent dans le paramètre « Nombre d'inodes » de la sortie de tune2fs, à savoir 65536. L'inode contient les informations nécessaires : la liste des blocs du système de fichiers pour le fichier recherché. Comment trouver le numéro inode pour le fichier spécifié ?
La correspondance entre le nom et le numéro inode se trouve dans le répertoire, et dans ext2fs, un répertoire est un fichier d'un type particulier, c'est-à-dire qu'il a aussi son propre numéro inode. Pour briser ce cercle vicieux, un numéro inode « fixe » a été affecté au répertoire racine : « 2 ». Regardons le contenu de l'inode numéro 2 :
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-févr.-2014)
debugfs: stat
Inode: 2 Type: répertoire Mode: 0755 Drapeaux: 0x0
Génération: 0 Version: 0x00000000:00000002
Utilisateur: 0 Groupe: 0 Taille: 4096
ACL de fichier: 0 ACL de répertoire: 0
Liens: 3 Nombre de blocs: 8
Fragment: Adresse: 0 Nombre: 0 Taille: 0
ctime: 0x5d43cb51:16b61bcc -- Ven 2 Août 16:34:09 2019
atime: 0x5d43c247:b704301c -- Ven 2 Août 15:55:35 2019
mtime: 0x5d43cb51:16b61bcc -- Ven 2 Août 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Ven 2 Août 15:02:14 2019
Taille des champs inode supplémentaires : 28
BLOCS :
(0):579
TOTAL : 1Comme on peut le voir, le répertoire dont nous avons besoin se trouve dans le bloc numéro 579. C'est là que nous trouverons le numéro de nœud pour le dossier home, et ainsi de suite, jusqu'à ce que nous voyions dans le répertoire serp le numéro de nœud pour le fichier demandé. Si quelqu'un souhaite vérifier si le numéro est correct et s'il y a les informations nécessaires, ce n'est pas compliqué. Faisons :
root@ubuntu:~/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 enregistrements dans
1+0 enregistrements sortants
4096 octets (4,1 kB) copiés, 0,000184088 s, 22,3 MB/s
root@ubuntu:~/# hexdump -c /home/serp/dd_imageDans la sortie, on peut lire les noms des fichiers dans le répertoire.
Voici donc ma question principale : « pour quelles raisons une erreur d'écriture peut-elle survenir » ?
Il est évident que 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 ? En plus de l'évident « supprimer quelque chose d'inutile », il convient de se rappeler que dans les systèmes de fichiers ext2, 3 et 4, il existe ce qu'on appelle le « Reserved block count ». Si on regarde dans le listing ci-dessus, nous avons ce nombre de blocs à « 13094 ». Ces blocs sont accessibles uniquement à l'utilisateur root. Mais si vous devez résoudre rapidement le problème, comme solution temporaire, vous pouvez les rendre accessibles à tous, ce qui créera un peu d'espace libre :
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Fév-2014)
Définition du pourcentage de blocs réservés à 0 % (0 blocs)C'est-à-dire que par défaut, 5 % de l'espace disque n'est pas accessible en écriture, et compte tenu des volumes des disques modernes, cela peut représenter des centaines de gigaoctets.
Que peut-il encore y avoir ? Une autre situation possible est que vous avez des blocs libres, mais les nœuds sont épuisés. Cela se produit généralement si vous avez dans votre système de fichiers beaucoup de fichiers de taille inférieure à la taille d'un bloc de système de fichiers. Étant donné qu'un inode est utilisé pour 1 fichier ou répertoire, et que nous en avons un total de 65536 (pour ce système de fichiers) — cette situation est plus que réaliste. Cela peut être clairement vu dans la sortie de la commande df :
serp@ubuntu:~$ df -hi
Système de fichiers Inodes IUsed IFree IUse% Monté sur
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
Système de fichiers Taille Utilisé Dispo Use% Monté sur
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/wwwComme on peut le voir dans la section /var/www, le nombre de blocs libres dans le système de fichiers et le nombre de nœuds disponibles diffèrent considérablement.
En cas d'épuisement des inodes, je ne peux pas vous donner d'astuces car il n'y en a pas (si je me trompe, faites-le moi savoir). Ainsi, pour les partitions où de nombreux petits fichiers sont créés, il convient de choisir judicieusement le système de fichiers. Par exemple, dans btrfs, les inodes ne peuvent pas être épuisés, car de nouveaux sont créés dynamiquement au besoin.
Source : habr.com
