Ceva despre inode

Periodic, pentru a trece la Centrul Central de Distribuție, intervievez la diferite companii mari, în principal din Sankt Petersburg și Moscova, pentru un post DevOps. Am observat că multe companii (multe companii bune, de exemplu Yandex) pun două întrebări similare:

  • ce este inodul;
  • din ce motive puteți obține o eroare de scriere pe disc (sau de exemplu: de ce s-ar putea să rămâneți fără spațiu pe disc, esența este aceeași).

Așa cum se întâmplă adesea, eram sigur că cunoșteam bine acest subiect, dar de îndată ce am început să explic, lacunele în cunoștințe au devenit evidente. Ca să-mi sistematizez cunoștințele, să completez golurile și să nu mă mai stânjenesc, scriu acest articol, poate că va fi de folos altcuiva.

Voi începe de jos, adică. de pe un hard disk (vom arunca unități flash, SSD-uri și alte lucruri moderne; de ​​exemplu, să luăm în considerare orice unitate veche de 20 sau 80 de giga, deoarece dimensiunea blocului este de 512 octeți).

Hard disk-ul nu știe cum să-și adreseze spațiul octet cu octet; este împărțit condiționat în blocuri. Numerotarea blocurilor începe de la 0. (Acesta se numește LBA, detalii aici: ru.wikipedia.org/wiki/LBA)

Ceva despre inode

După cum se poate vedea din figură, am desemnat blocuri LBA ca nivel HDD. Apropo, puteți vedea ce dimensiune de bloc are discul dvs. astfel:

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

Nivelul de mai sus este o partiție, una pentru întregul disc (din nou pentru simplitate). Cel mai adesea, sunt utilizate două tipuri de marcare a partițiilor: msdos și gpt. În consecință, msdos este un format vechi care acceptă discuri de până la 2Tb, gpt este un format nou capabil să adreseze până la 1 zettabyte de blocuri de 512 octeți. În cazul nostru, avem o partiție de tip msdos, după cum se vede din figură, partiția începe cu blocul nr. 1, în timp ce zero este folosit pentru MBR.

În prima partiție am creat un sistem de fișiere ext2, dimensiunea implicită a blocului este de 4096 de octeți, ceea ce este reflectat și în figură. Puteți vizualiza dimensiunea blocului sistemului de fișiere astfel:

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

Parametrul de care avem nevoie este „Dimensiunea blocului”.

Acum, partea interesantă este cum să citești fișierul /home/serp/testfile? Un fișier este format din unul sau mai multe blocuri de sistem de fișiere în care sunt stocate datele sale. Cunoscând numele fișierului, cum să-l găsesc? Ce blocuri ar trebui să citesc?

Aici sunt utile inodele. Sistemul de fișiere ext2fs are un „tabel” care conține informații pentru toate inoduri. Numărul de inoduri în cazul ext2fs este setat la crearea sistemului de fișiere. Ne uităm la numerele necesare în parametrul „Număr de inode” al ieșirii tune2fs, adică. avem 65536 bucăți. Inodul conține informațiile de care avem nevoie: o listă de blocuri ale sistemului de fișiere pentru fișierul pe care îl căutăm. Cum să găsiți numărul de inod pentru un anumit fișier?

Numele și numărul inodul corespunzător sunt conținute în director, iar un director în ext2fs este un tip special de fișier, de exemplu. are, de asemenea, propriul număr de inod. Pentru a rupe acest cerc vicios, un număr de inod „fix” „2” a fost atribuit directorului rădăcină. Să ne uităm la conținutul inodei numărul 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

După cum puteți vedea, directorul de care avem nevoie este conținut în blocul numărul 579. În el vom găsi numărul nodului pentru folderul de acasă și așa mai departe în lanț până când în directorul serp vedem numărul nodului pentru fișierul solicitat. Dacă dintr-o dată cineva dorește să verifice dacă numărul este corect și dacă există informațiile necesare, nu este dificil. Noi facem:

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 puteți citi numele fișierelor din director.

Așa că ajung la întrebarea principală: „din ce motive poate apărea o eroare de înregistrare?”

Desigur, acest lucru se va întâmpla dacă nu mai există blocuri libere în sistemul de fișiere. Ce se poate face în acest caz? Pe lângă evidenta „Ștergeți orice nu este necesar”, ar trebui să vă amintiți că în sistemele de fișiere ext2,3 și 4 există și „Număr de blocuri rezervate”. Dacă te uiți la lista de mai sus, avem „13094” astfel de blocuri. Acestea sunt blocuri inscriptibile numai de utilizatorul root. dar dacă trebuie să rezolvați rapid problema, ca soluție temporară le puteți pune la dispoziție tuturor, rezultând un spațiu liber:

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

Acestea. în mod implicit, aveți 5% din spațiul pe disc care nu este disponibil pentru scriere și, având în vedere volumul discurilor moderne, acesta poate fi de sute de gigaocteți.

Ce altceva ar putea fi? De asemenea, este posibil să existe blocuri libere, dar nu mai există noduri. Acest lucru se întâmplă de obicei dacă aveți o grămadă de fișiere pe sistemul dvs. de fișiere care sunt mai mici decât dimensiunea blocului sistemului de fișiere. Având în vedere că 1 inod este cheltuit pe 1 fișier sau director, și în total avem (pentru un anumit sistem de fișiere) 65536 - situația este mai mult decât realistă. Acest lucru poate fi văzut clar din rezultatul 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

După cum este clar vizibil pe partiția /var/www, numărul de blocuri libere din sistemul de fișiere și numărul de noduri libere variază foarte mult.

În cazul în care rămâneți fără inode, nu vă voi spune nicio vrăji, pentru că... nu există (dacă greșesc, anunțați-mă). Deci, pentru partițiile în care fișierele mici se înmulțesc, ar trebui să alegeți cu înțelepciune sistemul de fișiere. De exemplu, inodul btrfs nu se poate termina, deoarece Altele noi sunt create dinamic dacă este necesar.

Sursa: www.habr.com

Adauga un comentariu