Perioodiliselt, eesmärgiga kolida andmekeskusesse, olen intervjueerimise protsessis erinevates suurtes ettevõtetes, peamiselt Peterburis ja Moskvas, DevOpsi ametikohale. Olen märganud, et paljudes ettevõtetes (paljudes heades ettevõtetes, näiteks Yandexis) küsitakse kahte sarnast küsimust:
- mis on inode;
- millised on põhjused, miks võib tekkida ketta kirjutamisviga (või näiteks: miks võib kettaruumi otsa saada, idee on sama).
Kuidas see sageli juhtub, olin kindel, et tunnen seda teemat hästi, kuid kui hakkasin selgitama, selgusid teadmiste lüngad. Oma teadmiste süsteemimiseks, aukude täitmiseks ja edaspidisest piinlikkusest hoidumiseks kirjutan seda artiklit, ehk on sellest kellelegi abi.
Alustan "allapoole", st kõvakettast (välistame mälupulgad, SSD-d ja muud kaasaegsed vidinad, vaatlen näitena mistahes 20 või 80 GB vana ketast, kuna seal on ploki suurus 512 baiti).
Kõvaketas ei suuda oma ruumi aadresseerida baitide kaupa, see on tinglikult jagatud plokkideks. Plokkide numbrimine algab nullist. (seda nimetatakse LBA-ks, üksikasjad siin: )

Nagu pildilt näha, olen LBA plokid tähistanud kui HDD taset. Üksikasju selle kohta, milline on teie ketta ploki suurus, saab vaadata järgmiselt:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512Üks tasand üles on jaotatud partitsioon, üks kogu ketta jaoks (taaskord lihtsuse huvides). Kõige sagedamini kasutatakse kahte tüüpi partitsioonide jaotust: msdos ja gpt. Vastavalt on msdos – vana formaat, mis toetab kettaid kuni 2Tb, gpt – uus formaat, mis suudab adresseerida kuni 1 zettabaidi 512 baitiste blokke. Meie juhul on partitsioon msdos tüüpi, nagu joonisest näha, partitsioon algab blokist nr 1, nullblokki kasutatakse MBR jaoks.
Esimeses partitsioonis lõin ext2 failisüsteemi, millel on vaikimisi 4096 baitine ploki suurus, mis on samuti joonisel kajastatud. Failisüsteemi ploki suurust saab vaadata järgmiselt:
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name:
Last mounted on:
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 ()
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-c898746ccd76Meile vajalik parameeter on "Block size."
Nüüd kõige huvitavam, kuidas lugeda faili /home/serp/testfile? Fail koosneb ühest või mitmest failisüsteemi blokist, kuhu on salvestatud tema andmed. Teades faili nime, kuidas seda leida? Milliseid blokeerida?
Siin tulebki appi inode. Failisüsteemis ext2fs on olemas "tabel", kus sisaldub informatsioon kõigi inode'ide kohta. inode'ide arv ext2fs puhul määratakse failisüsteemi loomisel. Vajalikud numbrid vaatame välja tune2fs väljundi parameetrist "Inode count", st meil on neid 65536. inode'ides on vajalik meile info: failisüsteemi plokkide loend otsitavale failile. Kuidas leida inode numbrit antud failile?
Failinime ja inode numbri vastavus on salvestatud kataloogis, ja kataloog ext2fs-is on erilise tüübiga fail, st sellel on samuti oma inode number. Selle nõiaringi katkemiseks on juurkataloogile määratud "fikseeritud" inode number "2". Vaatame inode sisu numbriga 2:
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs: stat
Inode: 2 Tüüp: kataloog Režiim: 0755 Lipud: 0x0
Generatsioon: 0 Versioon: 0x00000000:00000002
Kasutaja: 0 Grupp: 0 Suurus: 4096
File ACL: 0 Directory ACL: 0
Lingid: 3 Plokkide arv: 8
Fragment: Aadress: 0 Number: 0 Suurus: 0
ctime: 0x5d43cb51:16b61bcc -- Reede, 2. aug 2019 16:34:09
atime: 0x5d43c247:b704301c -- Reede, 2. aug 2019 15:55:35
mtime: 0x5d43cb51:16b61bcc -- Reede, 2. aug 2019 16:34:09
crtime: 0x5d43b5c6:00000000 -- Reede, 2. aug 2019 15:02:14
Lisa inode'i väljade suurus: 28
BLOCKID:
(0):579
KOKKU: 1Nagu näha, sisaldab vajalik kataloog plokki number 579. Sealt leiame sõlme numbri kausta home ja nii edasi, kuni kataloogis serp näeme soovi kohast faili sõlme numbrit. Kui keegi soovib kontrollida, kas number on õige ja seal on vajalik info, pole see keeruline. Teeme järgmist:
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_imageVäljundist saab lugeda kataloogis olevaid failide nimesid.
Nüüd olen jõudnud põhiküsimuse juurde: „miks võib tekkida kirjutusviga“?
Loomulikult juhtub see siis, kui failisüsteemis ei ole enam vabu blokke. Mida saaks selle olukorra jaoks teha? Lisaks ilmselgele „kustutada midagi mittevajalikku“, tuleks meeles pidada, et failisüsteemides ext2, 3 ja 4 on olemas selline asi nagu „Reserved block count“. Kui vaadata eeltoodud loetelus, siis on meil neid blokke „13094“. Need blokid on kirjutamiseks saadaval ainult kasutajale root. Kuid kui on vaja kiiresti olukord lahendada, saab ajutiselt teha need kõigile kättesaadavaks, mille tulemusena tekib veidi vaba ruumi:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Seadme reserveeritud plokkide protsent 0% (0 plokki)See tähendab, et vaikimisi pole teil kirjutamiseks kuni 5% kettaruumi, ning arvestades tänapäevaste kõvakettasuurusi, võib see olla sadu gigabaite.
Mis veel võib juhtuda? Võib juhtuda ka olukord, kus vabu blokke on, aga inode’id on otsas. See juhtub tavaliselt siis, kui teie failisüsteemis on palju faile, mille suurus on väiksem kui failisüsteemi bloki suurus. Arvestades, et iga faili või kausta jaoks kulub 1 inode ning meil on neid (antud failisüsteemi jaoks) kokku 65536 — olukord on rohkem kui reaalne. Seda on selgelt näha käskluse df väljundist:
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/wwwNagu hästi nähtav /var/www jagamisel, vaba failisüsteemi blokeeringute arv ja vabad noodid erinevad oluliselt.
Kuna inode'ide arv on lõppenud, ei saa ma soovitada nõusid, kuna neid pole (kui ma eksin, andke teada). Seega sellistele jaotistele, kus tekivad väikesed failid, tuleks õigesti valida failisüsteem. Näiteks btrfs-is ei saa inode'id otsa saada, kuna neid luuakse dünaamiliselt vajadusel.
Allikas: habr.com
