Câteva despre inode

Periodic, with the aim of relocating to a Data Center, I interview at various large companies, mainly in St. Petersburg and Moscow for the position of DevOps. I noticed that many companies (many good companies, for example in Yandex) ask two similar questions:

  • what is an inode;
  • what reasons can lead to a disk write error (or for example: why can disk space run out, the essence is the same).

As often happens, I was confident that I knew this topic well, but as soon as I started explaining, gaps in my knowledge became apparent. To systematize my knowledge, fill the gaps, and not embarrass myself anymore, I am writing this article; it may be useful to someone else as well.

I'll start 'from the bottom', i.e. from the hard drive (we'll set aside flash drives, SSDs, and other modern gadgets, for simplicity, let's consider any old 20 or 80 GB disk, as the block size is 512 bytes).

The hard drive cannot address its space byte by byte; conditionally, it is divided into blocks. The numbering of blocks starts at 0. (This is called LBA; details here: ro.wikipedia.org/wiki/LBA)

Câteva despre inode

As seen from the diagram, the LBA blocks are marked as the HDD level. By the way, you can check the block size of your disk like this:

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

One level up is the partition, one for the whole disk (again, for simplicity). The partitioning schemes most commonly used are of two types: msdos and gpt. Accordingly, msdos is an old format that supports disks up to 2TB, gpt is a new format capable of addressing up to 1 zettabyte of 512-byte blocks. In our case, we have an msdos-type partition, as seen from the diagram, the partition starts at block #1, while the zero block is used for the MBR.

In the first partition, I created an ext2 file system, the default block size is 4096 bytes, which is also reflected in the diagram. You can check the block size of the file system like this:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Numele volumului sistemului de fișiere:   
Ultima montare pe:          
UUID-ul sistemului de fișiere:          a600bf40-f660-41f6-a3e6-96c303995479
Numărul magic al sistemului de fișiere:  0xEF53
Revizia sistemului de fișiere #:    1 (dinamic)
Caracteristicile sistemului de fișiere:      ext_attr resize_inode dir_index filetype sparse_super large_file
Indicatorii sistemului de fișiere:         signed_directory_hash
Opțiunile de montare implicite:    user_xattr acl
Starea sistemului de fișiere:         curat
Comportamentul erorilor:          Continuare
Tipul sistemului de operare al sistemului de fișiere:       Linux
Numărul de inodes:              65536
Numărul de blocuri:              261888
Numărul de blocuri rezervate:     13094
Blocuri libere:              257445
Inodes libere:              65525
Primul bloc:              0
Dimensiunea blocului:               4096
Dimensiunea fragmentului:            4096
Blocuri rezervate GDT:      63
Blocuri pe grup:         32768
Fragmente pe grup:      32768
Inodes pe grup:         8192
Blocuri inode pe grup:   512
Sistemul de fișiere creat:       Vin  Aug  2 15:02:13 2019
Ultima montare:          n/a
Ultima scriere:          Vin  Aug  2 15:02:14 2019
Numărul de montări:              0
Numărul maxim de montări:      -1
Ultima verificare:             Vin  Aug  2 15:02:13 2019
Interval de verificare:           0 ()
UID pentru blocuri rezervate:      0 (user root)
GID pentru blocuri rezervate:      0 (group root)
Primul inode:              11
Dimensiunea inode-ului:               256
Dimensiunea suplimentară necesară:     28
Dimensiunea suplimentară dorită:      28
Hash-ul implicit al directorului:   half_md4
Semințele hash-ului directorului:      c0155456-ad7d-421f-afd1-c898746ccd76

Parametrul necesar este „Dimensiunea blocului”.

Acum devine interesant, cum citim fișierul /home/serp/testfile? Fișierul constă din unul sau mai multe blocuri de sistem de fișiere, în care sunt stocate datele sale. Având numele fișierului, cum îl găsim? Ce blocuri să citim?

Aici ne sunt de ajutor inode-urile. În sistemul de fișiere ext2fs există o „tabelă”, care conține informații cu privire la toate inode-urile. Numărul de inode-uri în cazul ext2fs este definit la crearea sistemului de fișiere. Cifrele necesare le vedem în parametrul „Numărul de inodes” din ieșirea tune2fs, adică avem 65536 de bucăți. În inode se regăsesc informațiile necesare: lista blocurilor de sistem de fișiere pentru fișierul căutat. Cum putem găsi numărul inode pentru fișierul specificat?

Asocierea numelui și a numărului inode este conținută în director, iar un director în ext2fs este un fișier de un tip special, adică are și el propriul număr inode. Pentru a rupe acest cerc vicios, directorului principal i-a fost atribuit un număr inode „fixat” de „2”. Să vedem conținutul inode-ului cu numărul 2:

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

Inode: 2   Tip: director    Mod:  0755   Indicatori: 0x0
Generație: 0    Versiune: 0x00000000:00000002
Utilizator:     0   Grup:     0   Dimensiune: 4096
File ACL: 0    Directory ACL: 0
Legături: 3   Număr blocuri: 8
Fragment:  Adresă: 0    Număr: 0    Dimensiune: 0
 ctime: 0x5d43cb51:16b61bcc -- Vin  Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Vin  Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Vin  Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Vin  Aug  2 15:02:14 2019
Dimensiunea câmpurilor inode suplimentare: 28
BLOCAJE:
(0):579
TOTAL: 1

După cum se poate observa, directorul necesar se află în blocul cu numărul 579. Aici vom găsi numărul nodului pentru folderul home, și așa mai departe, până când în directorul serp vom vedea numărul nodului pentru fișierul solicitat. Dacă cineva vrea să verifice dacă numărul este corect și dacă informația necesară se află acolo, este simplu de făcut. Procedăm astfel:

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

În ieșire se pot citi numele fișierelor din director.

Iată că am ajuns la întrebarea principală: „ce motive pot provoca o eroare de scriere”?

Desigur, acest lucru se va întâmpla dacă nu mai rămân blocuri libere în sistemul de fișiere. Ce se poate face în acest caz? Pe lângă evidentul „ștergeți ceva inutil”, trebuie să ne amintim că în sistemele de fișiere ext2,3 și 4 există un concept numit „Reserved block count”. Dacă ne uităm la listarea de mai sus, avem aceste blocuri „13094”. Acestea sunt blocuri disponibile pentru scriere doar utilizatorului root. Dar, dacă trebuie să rezolvăm problema rapid, ca soluție temporară, putem face aceste blocuri accesibile pentru toți, rezultând astfel o oarecare capacitate liberă:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setarea procentajului de blocuri rezervate la 0% (0 blocuri)

Adică, în mod implicit, nu aveți acces pentru a scrie 5% din spațiul pe disc, și având în vedere dimensiunile discurilor moderne, acestea pot fi sute de gigaocteți.

Ce altceva ar putea fi? O altă situație posibilă este când există blocuri libere, dar nodurile s-au terminat. Aceasta se întâmplă de obicei dacă în sistemul de fișiere aveți o mulțime de fișiere de dimensiuni mai mici decât dimensiunea blocului sistemului de fișiere. Având în vedere că pentru 1 fișier sau director se cheltuie 1 inode, iar total avem (pentru acest sistem de fișiere) 65536 — situația este mai mult decât reală. Acest lucru se poate observa clar din ieșirea comenzii 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

Așa cum se observă în secțiunea \/var\/www, numărul de blocuri libere al sistemului de fișiere și numărul de noduri libere diferă semnificativ.

În cazul în care s-au terminat inodele, nu am sugestii pentru probleme, deoarece nu există (dacă greșesc, vă rog să-mi spuneți). Așadar, pentru secțiunile în care se generează fișiere mici, este important să alegeți corect sistemul de fișiere. De exemplu, în btrfs, inodele nu se pot termina, deoarece se creează dinamic noi după nevoie.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster