Povremeno, kako bih prešao u Središnji distribucijski centar, obavljam razgovore u raznim velikim tvrtkama, uglavnom u St. Petersburgu i Moskvi, za DevOps poziciju. Primijetio sam da mnoge tvrtke (mnoge dobre tvrtke, na primjer Yandex) postavljaju dva slična pitanja:
- što je inode;
- iz kojih razloga se može pojaviti greška pri upisivanju na disk (ili na primjer: zašto bi vam moglo ponestati prostora na disku, bit je ista).
Kao što često biva, bio sam siguran da ovu temu dobro poznajem, ali čim sam počeo objašnjavati, pokazale su se rupe u znanju. Kako bih sistematizirao svoje znanje, popunio praznine i više se ne sramotio, pišem ovaj članak, možda će još nekome biti od koristi.
Krenut ću od dna, tj. s tvrdog diska (odbacit ćemo flash diskove, SSD-ove i druge moderne stvari; na primjer, uzmimo u obzir bilo koji stari disk od 20 ili 80 gigabajta, budući da je veličina bloka tamo 512 bajtova).
Tvrdi disk ne zna adresirati svoj prostor bajt po bajt, već je uvjetno podijeljen na blokove. Numeriranje blokova počinje od 0. (Ovo se zove LBA, detalji ovdje:
Kao što se može vidjeti na slici, odredio sam LBA blokove kao HDD razinu. Usput, ovako možete vidjeti koju veličinu bloka ima vaš disk:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512
Gornja razina je particija, jedna za cijeli disk (opet radi jednostavnosti). Najčešće se koriste dvije vrste označavanja particije: msdos i gpt. Sukladno tome, msdos je stari format koji podržava diskove do 2 Tb, gpt je novi format koji može adresirati do 1 zetabajta blokova od 512 bajta. U našem slučaju imamo particiju tipa msdos, kao što se vidi sa slike, particija počinje blokom br. 1, dok se za MBR koristi nula.
U prvoj particiji napravio sam ext2 datotečni sustav, njegova zadana veličina bloka je 4096 bajtova, što se također odražava na slici. Možete vidjeti veličinu bloka datotečnog sustava ovako:
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
Parametar koji nam treba je "Veličina bloka".
Sada je zanimljiv dio kako čitati datoteku /home/serp/testfile? Datoteka se sastoji od jednog ili više blokova datotečnog sustava u kojima su pohranjeni njezini podaci. Znajući naziv datoteke, kako je pronaći? Koje blokove trebam čitati?
Ovdje inode dobro dolaze. Datotečni sustav ext2fs ima "tablicu" koja sadrži informacije za sve inode. Broj inodesa u slučaju ext2fs postavlja se prilikom kreiranja datotečnog sustava. Gledamo potrebne brojeve u parametru "Inode count" izlaza tune2fs, tj. imamo 65536 komada. Inode sadrži informacije koje su nam potrebne: popis blokova datotečnog sustava za datoteku koju tražimo. Kako pronaći inode broj za određenu datoteku?
Odgovarajuće ime i inode broj sadržani su u direktoriju, a direktorij u ext2fs je posebna vrsta datoteke, tj. također ima svoj inode broj. Kako bi se razbio ovaj začarani krug, "fiksni" broj inode "2" dodijeljen je korijenskom direktoriju. Pogledajmo sadržaj inode broj 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
Kao što vidite, direktorij koji nam je potreban nalazi se u bloku broj 579. U njemu ćemo pronaći broj čvora za početnu mapu, i tako niz lanac sve dok u direktoriju serp ne vidimo broj čvora za traženu datoteku. Ako iznenada netko želi provjeriti je li broj točan i postoje li potrebne informacije, to nije teško. Radimo:
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
U izlazu možete pročitati nazive datoteka u direktoriju.
Tako dolazim do glavnog pitanja: "zbog kojih razloga može doći do greške u snimanju?"
Naravno, to će se dogoditi ako u sustavu datoteka nema slobodnih blokova. Što se može učiniti u ovom slučaju? Osim očitog "izbrišite sve nepotrebno", trebali biste zapamtiti da u ext2,3 i 4 datotečnim sustavima postoji takva stvar kao što je "Rezervirani broj blokova". Ako pogledate gornji popis, imamo "13094" takvih blokova. Ovo su blokovi u koje može pisati samo root korisnik. ali ako trebate brzo riješiti problem, kao privremeno rješenje možete ih učiniti dostupnima svima, što rezultira slobodnim prostorom:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)
Oni. prema zadanim postavkama imate 5% diskovnog prostora nedostupnog za pisanje, a s obzirom na volumen modernih diskova, to može iznositi stotine gigabajta.
Što bi drugo moglo biti? Također je moguće da postoje slobodni blokovi, ali nema više čvorova. To se obično događa ako na svom datotečnom sustavu imate hrpu datoteka koje su manje od veličine bloka datotečnog sustava. S obzirom da se 1 inode troši na 1 datoteku ili direktorij, a ukupno ih imamo (za određeni datotečni sustav) 65536 - situacija je više nego realna. To se jasno može vidjeti iz izlaza naredbe 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
Kao što je jasno vidljivo na /var/www particiji, broj slobodnih blokova u datotečnom sustavu i broj slobodnih čvorova jako varira.
U slučaju da vam ponestane inodea, neću vam govoriti nikakve čarolije, jer... nema ih (ako griješim, javite mi). Dakle, za particije u kojima se množe male datoteke, trebali biste mudro odabrati datotečni sustav. Na primjer, btrfs inodes ne može završiti, jer Novi se po potrebi dinamički stvaraju.
Izvor: www.habr.com