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:
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