Kažkas apie inodą

Periodiškai, norėdamas pereiti į Centrinį paskirstymo centrą, imu interviu įvairiose didelėse įmonėse, daugiausia Sankt Peterburge ir Maskvoje, siekdama DevOps pareigų. Pastebėjau, kad daugelis įmonių (daug gerų įmonių, pavyzdžiui, „Yandex“) užduoda du panašius klausimus:

  • kas yra inode;
  • dėl kokių priežasčių gali atsirasti disko rašymo klaida (arba pvz.: kodėl gali pritrūkti vietos diske, esmė ta pati).

Kaip dažnai nutinka, buvau tikra, kad šią temą išmanau gerai, bet vos pradėjus aiškintis, išryškėjo žinių spragos. Norėdamas susisteminti savo žinias, užpildyti spragas ir nebegėdinti savęs, rašau šį straipsnį, gal dar kam pravers.

Pradėsiu nuo apačios, t.y. iš kietojo disko (atmesime „flash drives“, SSD ir kitus šiuolaikinius dalykus; pavyzdžiui, panagrinėkime bet kurį 20 ar 80 GB seną diską, nes ten bloko dydis yra 512 baitų).

Kietasis diskas nežino, kaip adresuoti savo erdvę baitais po baito, jis sąlyginai suskirstytas į blokus. Blokų numeracija prasideda nuo 0. (Tai vadinama LBA, išsami informacija čia: ru.wikipedia.org/wiki/LBA)

Kažkas apie inodą

Kaip matyti iš paveikslo, LBA blokus paskyriau kaip HDD lygį. Beje, galite pamatyti, kokio dydžio blokas yra jūsų diske:

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

Aukščiau esantis lygis yra skaidinys, skirtas visam diskui (paprastumo dėlei). Dažniausiai naudojamas dviejų tipų skaidinio žymėjimas: msdos ir gpt. Atitinkamai, msdos yra senas formatas, palaikantis diskus iki 2Tb, o gpt yra naujas formatas, galintis adresuoti iki 1 zettabaito iš 512 baitų blokų. Mūsų atveju turime msdos tipo skaidinį, kaip matyti iš paveikslo, skaidinys prasideda bloku Nr. 1, o nulis naudojamas MBR.

Pirmajame skaidinyje sukūriau ext2 failų sistemą, jos numatytasis bloko dydis yra 4096 baitai, tai irgi atsispindi paveikslėlyje. Failų sistemos bloko dydį galite peržiūrėti taip:

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

Mums reikalingas parametras yra „Bloko dydis“.

Dabar įdomi dalis yra tai, kaip skaityti /home/serp/testfile failą? Failas susideda iš vieno ar daugiau failų sistemos blokų, kuriuose saugomi jo duomenys. Žinodami failo pavadinimą, kaip jį rasti? Kokius blokus turėčiau perskaityti?

Čia praverčia inodai. Ext2fs failų sistemoje yra "lentelė", kurioje yra informacija apie visus inodes. Inodų skaičius ext2fs atveju nustatomas kuriant failų sistemą. Tune2fs išvesties parametre “Inode count” žiūrime reikiamus skaičius, t.y. turime 65536 vnt. Inode yra mums reikalinga informacija: failų sistemos blokų sąrašas, skirtas mūsų ieškomam failui. Kaip rasti tam tikro failo inode numerį?

Atitinkamas pavadinimas ir inode numeris yra kataloge, o katalogas ext2fs yra specialus failo tipas, t.y. taip pat turi savo inodo numerį. Norėdami nutraukti šį užburtą ratą, šakniniam katalogui buvo priskirtas „fiksuotas“ indo numeris „2“. Pažvelkime į 2 inodo turinį:

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

Kaip matote, mums reikalingas katalogas yra bloke numeris 579. Jame rasime namų aplanko mazgo numerį ir taip toliau, kol serp kataloge pamatysime prašomo failo mazgo numerį. Jei staiga kas nors nori patikrinti, ar numeris teisingas ir ar yra reikiamos informacijos, tai nėra sunku. Mes darome:

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

Išvestyje galite perskaityti kataloge esančių failų pavadinimus.

Taigi prieinu prie pagrindinio klausimo: „dėl kokių priežasčių gali įvykti įrašymo klaida?

Natūralu, kad tai atsitiks, jei failų sistemoje neliks laisvų blokų. Ką galima padaryti šiuo atveju? Be akivaizdaus „ištrinkite viską, kas nereikalinga“, turėtumėte atsiminti, kad ext2,3, 4 ir 13094 failų sistemose yra toks dalykas kaip „Rezervuotų blokų skaičius“. Jei pažvelgsite į aukščiau esantį sąrašą, mes turime „XNUMX“ tokius blokus. Tai blokai, kuriuos gali įrašyti tik root naudotojas. bet jei jums reikia greitai išspręsti problemą, kaip laikiną sprendimą galite padaryti jas prieinamas visiems, todėl atsiras laisvos vietos:

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

Tie. pagal numatytuosius nustatymus turite 5% disko vietos, kuri nėra skirta rašymui, o atsižvelgiant į šiuolaikinių diskų tūrį, tai gali būti šimtai gigabaitų.

Kas dar galėtų būti? Taip pat gali būti, kad yra laisvų blokų, bet nebėra mazgų. Paprastai taip nutinka, jei failų sistemoje yra daug failų, kurie yra mažesni už failų sistemos bloko dydį. Atsižvelgiant į tai, kad 1 inode išleidžiama 1 failui ar katalogui, o iš viso turime (duotai failų sistemai) 65536 - situacija yra daugiau nei reali. Tai aiškiai matyti iš df komandos išvesties:

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

Kaip aiškiai matyti skaidinyje /var/www, laisvų blokų skaičius failų sistemoje ir laisvų mazgų skaičius labai skiriasi.

Jei pritrūks inodų, aš tau nesakysiu jokių burtų, nes... jų nėra (jei klystu, praneškite). Taigi skaidiniams, kuriuose dauginasi maži failai, rinkmenų sistemą reikėtų rinktis išmintingai. Pavyzdžiui, btrfs inodes negali baigtis, nes Jei reikia, dinamiškai kuriami nauji.

Šaltinis: www.habr.com

Добавить комментарий