Noe om inode

Med jevne mellomrom, for å flytte til det sentrale distribusjonssenteret, intervjuer jeg ved forskjellige store selskaper, hovedsakelig i St. Petersburg og Moskva, for en DevOps-stilling. Jeg la merke til at mange selskaper (mange gode selskaper, for eksempel Yandex) stiller to lignende spørsmål:

  • hva er inode;
  • av hvilke grunner kan du få en diskskrivefeil (eller for eksempel: hvorfor du kan gå tom for diskplass, essensen er den samme).

Som ofte skjer, var jeg sikker på at jeg kjente dette emnet godt, men så snart jeg begynte å forklare, ble hull i kunnskap tydelige. For å systematisere kunnskapen min, fylle ut hullene og ikke lenger plage meg selv, skriver jeg denne artikkelen, kanskje den vil være nyttig for noen andre.

Jeg starter fra bunnen, dvs. fra en harddisk (vi forkaster flash-stasjoner, SSD-er og andre moderne ting; la oss for eksempel vurdere en hvilken som helst 20 eller 80 gig gammel stasjon, siden blokkstørrelsen der er 512 byte).

Harddisken vet ikke hvordan den skal adressere sin plass byte for byte; den er betinget delt inn i blokker. Blokknummerering starter fra 0. (Dette kalles LBA, detaljer her: ru.wikipedia.org/wiki/LBA)

Noe om inode

Som det fremgår av figuren, utpekte jeg LBA-blokker som HDD-nivået. Forresten, du kan se hvilken blokkstørrelse disken din har slik:

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

Nivået over er en partisjon, en for hele disken (igjen for enkelhets skyld). Oftest brukes to typer partisjonsmarkering: msdos og gpt. Følgelig er msdos et gammelt format som støtter disker på opptil 2Tb, gpt er et nytt format som kan adressere opptil 1 zettabyte med 512 byteblokker. I vårt tilfelle har vi en partisjon av typen msdos, som det fremgår av figuren begynner partisjonen med blokk nr. 1, mens null brukes for MBR.

I den første partisjonen jeg opprettet et ext2-filsystem, er standard blokkstørrelse 4096 byte, noe som også gjenspeiles i figuren. Du kan se filsystemets blokkstørrelse slik:

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

Parameteren vi trenger er "Blokkstørrelse".

Nå er den interessante delen hvordan du leser filen /home/serp/testfile? En fil består av en eller flere filsystemblokker der dens data er lagret. Å vite filnavnet, hvordan finner jeg det? Hvilke blokker bør jeg lese?

Det er her inoder kommer godt med. Ext2fs-filsystemet har en "tabell" som inneholder informasjon for alle inoder. Antall inoder i tilfelle av ext2fs angis når filsystemet opprettes. Vi ser på de nødvendige tallene i parameteren "Inode count" til tune2fs-utgangen, dvs. vi har 65536 stykker. Inoden inneholder informasjonen vi trenger: en liste over filsystemblokker for filen vi leter etter. Hvordan finne inodenummeret for en gitt fil?

Det tilsvarende navnet og inodenummeret finnes i katalogen, og en katalog i ext2fs er en spesiell filtype, dvs. har også sitt eget inodenummer. For å bryte denne onde sirkelen ble et "fast" inodenummer "2" tildelt rotkatalogen. La oss se på innholdet i inode nummer 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

Som du kan se, finnes katalogen vi trenger i blokknummer 579. I den finner vi nodenummeret for hjemmemappen, og så videre nedover i kjeden til vi i serp-katalogen ser nodenummeret for den forespurte filen. Hvis noen plutselig vil sjekke om nummeret stemmer og om nødvendig informasjon er der, er det ikke vanskelig. Vi gjør:

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 utgangen kan du lese navnene på filene i katalogen.

Så jeg kommer til hovedspørsmålet: "av hvilke grunner kan det oppstå en opptaksfeil?"

Naturligvis vil dette skje hvis det ikke er noen ledige blokker igjen i filsystemet. Hva kan gjøres i dette tilfellet? Foruten det åpenbare "slett alt som er unødvendig", bør du huske at i filsystemer ext2,3 og 4 er det noe slikt som "Reservert blokkantall". Hvis du ser på listen ovenfor, har vi "13094" slike blokker. Dette er blokker som kun kan skrives av root-brukeren. men hvis du trenger å løse problemet raskt, kan du som en midlertidig løsning gjøre dem tilgjengelige for alle, noe som resulterer i litt ledig plass:

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

De. som standard har du 5 % av diskplassen som ikke er tilgjengelig for skriving, og gitt volumet på moderne disker, kan dette være hundrevis av gigabyte.

Hva annet kan det være? Det er også mulig at det er ledige blokker, men det er ikke flere noder. Dette skjer vanligvis hvis du har en haug med filer på filsystemet som er mindre enn filsystemets blokkstørrelse. Med tanke på at 1 inode brukes på 1 fil eller katalog, og totalt har vi (for et gitt filsystem) 65536 - situasjonen er mer enn realistisk. Dette kan tydelig sees fra utgangen av df-kommandoen:

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

Som det er tydelig synlig på /var/www-partisjonen, varierer antall ledige blokker i filsystemet og antall ledige noder sterkt.

I tilfelle du går tom for inoder, vil jeg ikke fortelle deg noen staver, fordi... det er ingen (gi meg beskjed hvis jeg tar feil). Så for partisjoner der små filer multipliseres, bør du velge filsystemet med omhu. For eksempel kan btrfs-inoder ikke avsluttes, fordi Nye opprettes dynamisk om nødvendig.

Kilde: www.habr.com

Legg til en kommentar