Periodično, z namenom selitve v CRS se sestajem z različnimi velikimi podjetji, predvsem v Sankt Peterburgu in Moskvi na položaju DevOps. Opazil sem, da v mnogih podjetjih (v številnih dobrih podjetjih, na primer v Yandexu) postavljajo dva podobna vprašanja:
- kaj je inode;
- iz katerih razlogov lahko pride do napake pri pisanju na disk (ali na primer: zakaj se lahko zmanjša prostor na disku, bistvo je isto).
Kot se pogosto zgodi, sem bil prepričan, da to temo dobro poznam, a takoj, ko sem začel razlagati — so se pokazale vrzeli v znanju. Da bi sistematiziral svoje znanje, zapolnil vrzeli in se več ne osmešil, pišem ta članek, morda bo še komu v pomoč.
Začel bom "spodaj", tj. z trdim diskom (USB ključki, SSD in druge moderne stvari bomo odložili, za primer pa bomo vzeli kateri koli star disk velikosti 20 ali 80 gigabajtov, ker je tam velikost bloka 512 bajtov).
Trdi disk ne zna naslavljati svojega prostora bajtno, pogojno je razdeljen na bloke. Numeracija blokov se začne z 0. (to se imenuje LBA, podrobnosti tukaj: )

Kot je razvidno s slike, sem bloke LBA označil kot raven HDD. Mimogrede, preveriti, kakšna je velikost bloka vašega diska, lahko tako:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512Nad nivojem so označeni particije, ena za celoten disk (spet za preprostost). Najpogosteje se uporabljajo dva tipa razdelitev: msdos in gpt. Ustrezno msdos — star format, ki podpira diske do 2Tb, gpt — nov format, ki lahko naslovi do 1 zettabajta 512 bajtnih blokov. V našem primeru imamo particijo tipa msdos, kot je razvidno s slike, particija pa se začne z blokom št. 1, ničelni pa se uporablja za MBR.
V prvi particiji sem ustvaril datotečni sistem ext2, privzeto je velikost bloka 4096 bajtov, kar je prav tako prikazano na sliki. Velikost bloka datotečnega sistema lahko preverite tako:
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-c898746ccd76Potrebni parameter je "Block size".
Zdaj se postavlja zanimivo vprašanje, kako prebrati datoteko /home/serp/testfile? Datoteka se sestavlja iz enega ali več blokov datotečnega sistema, v katerih so shranjeni njeni podatki. Kako najti blok, če poznamo ime datoteke? Kateri bloki naj se preberejo?
Tu nam priskočijo na pomoč inode. V datotečnem sistemu ext2fs obstaja "tabela", ki vsebuje informacije o vseh inode. Število inode je pri ext2fs določeno ob ustvarjanju datotečnega sistema. Potrebne številke lahko najdemo v parameterju "Inode count" iz izhoda tune2fs, torej imamo 65536 kosov. V inode so shranjene potrebne informacije: seznam blokov datotečnega sistema za iskano datoteko. Kako poiskati številko inode za določeno datoteko?
Ujemanje med imenom in številko inode je shranjeno v imeniku, imenik v ext2fs pa je poseben tip datoteke, torej ima tudi svojo številko inode. Da bi prekinili ta začarani krog, je bila za korenski imenik dodeljena "fiksna" številka inode "2". Oglejmo si vsebino inode s številko 2:
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs: stat
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: 1Kot se vidi, potrebna mapa se nahaja v bloku s številko 579. V njej bomo našli številko vozlišča za mapo home in tako naprej po verigi, dokler v mapi serp ne bomo videli številke vozlišča za zahtevano datoteko. Če bi kdo želel preveriti, ali je številka pravilna in ali so tam potrebne informacije, to ni težko. Naredimo:
root@ubuntu:~# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 recordov v
1+0 recordov ven
4096 bajtov (4,1 kB) kopirano, 0,000184088 s, 22,3 MB/s
root@ubuntu:~# hexdump -c /home/serp/dd_imageV izvodu lahko preberete imena datotek v mapi.
Tukaj pa sem prišel do glavnega vprašanja: «iz katerih razlogov lahko pride do napake pri zapisovanju»?
Seveda se to zgodi, če ne ostane prostih blokov v datotečnem sistemu. Kaj lahko v tem primeru storite? Poleg očitnega «izbriši kaj nepotrebnega», je treba vedeti, da v datotečnih sistemih ext2,3 in 4 obstaja nekaj, kar imenujemo «številka rezerviranih blokov». Če pogledate v seznam zgoraj, imamo takih blokov «13094». To so bloki, ki so na voljo za zapisovanje samo uporabniku root. Ampak če želite hitro rešiti težavo, lahko začasno omogočite dostop do njih za vse, kar bo povzročilo nekaj prostega prostora:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Nastavljanje odstotka rezerviranih blokov na 0% (0 blokov)Torej, privzeto za zapisovanje nimate dostopnih 5% prostora na disku in ob upoštevanju velikosti sodobnih diskov to lahko pomeni stotine gigabajtov.
Kaj še lahko pride v poštev? Možna je tudi situacija, ko imate proste bloke, a so vozlišča končana. To se običajno zgodi, če imate v datotečnem sistemu veliko datotek, ki so manjše od velikosti bloka datotečnega sistema. Glede na to, da se za 1 datoteko ali mapo porabi 1 inode, ki jih imamo skupaj (za ta datotečni sistem) 65536 — situacija je več kot realna. To je jasno vidno iz izhoda ukaza 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\/wwwKot vsem očitno na razdelku \/var\www, število prostih blokov datotečnega sistema in število prostih inode se močno razlikujeta.
V primeru, da so inodi pošli, čarobni recept ne poznam, ker ga ni (če se motim, mi sporočite). Tako, da za razdelke, kjer nastajajo majhne datoteke, velja pametno izbrati datotečni sistem. Na primer, v btrfs inodi ne morejo poiti, ker se dinamično ustvarjajo novi po potrebi.
Izvor: habr.com
