Något om inode

Med jämna mellanrum, för att flytta till Central Distribution Center, intervjuar jag på olika stora företag, främst i St. Petersburg och Moskva, för en DevOps-tjänst. Jag märkte att många företag (många bra företag, till exempel Yandex) ställer två liknande frågor:

  • vad är inode;
  • av vilka anledningar kan du få ett diskskrivfel (eller till exempel: varför du kan få slut på diskutrymme, kärnan är densamma).

Som ofta händer var jag säker på att jag kände till detta ämne väl, men så fort jag började förklara blev kunskapsluckor uppenbara. För att systematisera min kunskap, fylla i luckorna och inte längre skämma ut mig själv skriver jag den här artikeln, kanske kommer den att vara användbar för någon annan.

Jag börjar från botten, dvs. från en hårddisk (vi kasserar flashenheter, SSD:er och andra moderna saker; låt oss till exempel överväga vilken gammal enhet som helst på 20 eller 80 gig, eftersom blockstorleken där är 512 byte).

Hårddisken vet inte hur man adresserar sitt utrymme byte för byte, den är villkorligt uppdelad i block. Blocknumrering börjar från 0. (Detta kallas LBA, detaljer här: ru.wikipedia.org/wiki/LBA)

Något om inode

Som framgår av figuren angav jag LBA-block som HDD-nivån. Förresten, du kan se vilken blockstorlek din disk har så här:

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

Nivån ovan är en partition, en för hela disken (igen för enkelhetens skull). Oftast används två typer av partitionsuppmärkning: msdos och gpt. Följaktligen är msdos ett gammalt format som stöder diskar upp till 2Tb, gpt är ett nytt format som kan adressera upp till 1 zettabyte med 512 byteblock. I vårt fall har vi en partition av typen msdos, som framgår av figuren börjar partitionen med block nr 1, medan noll används för MBR.

I den första partitionen skapade jag ett ext2-filsystem, dess standardblockstorlek är 4096 byte, vilket också återspeglas i figuren. Du kan se filsystemets blockstorlek så här:

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

Parametern vi behöver är "Blockstorlek".

Nu är den intressanta delen hur man läser filen /home/serp/testfile? En fil består av ett eller flera filsystemblock där dess data lagras. Vet du filnamnet, hur hittar jag det? Vilka block ska jag läsa?

Det är här inoder kommer väl till pass. Filsystemet ext2fs har en "tabell" som innehåller information för alla inoder. Antalet inoder i fallet med ext2fs ställs in när filsystemet skapas. Vi tittar på de nödvändiga siffrorna i parametern "Inode count" för tune2fs-utgången, dvs. vi har 65536 stycken. Inoden innehåller den information vi behöver: en lista över filsystemblock för filen vi letar efter. Hur hittar man inodnumret för en given fil?

Motsvarande namn och inodnummer finns i katalogen, och en katalog i ext2fs är en speciell filtyp, dvs. har också ett eget inodnummer. För att bryta denna onda cirkel tilldelades ett "fast" inodnummer "2" till rotkatalogen. Låt oss titta på innehållet i inod 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 finns katalogen vi behöver i blocknummer 579. I den hittar vi nodnumret för hemmappen, och så vidare i kedjan tills vi ser nodnumret för den begärda filen i serp-katalogen. Om någon plötsligt vill kontrollera om numret stämmer och om nödvändig information finns är det inte svårt. Vi gö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 utgången kan du läsa namnen på filerna i katalogen.

Så jag kommer till huvudfrågan: "av vilka skäl kan ett inspelningsfel uppstå?"

Naturligtvis kommer detta att hända om det inte finns några lediga block kvar i filsystemet. Vad kan man göra i det här fallet? Förutom det uppenbara "ta bort allt som är onödigt", bör du komma ihåg att i filsystem ext2,3 och 4 finns det något som "Reserverat blockantal". Om du tittar på listan ovan har vi "13094" sådana block. Dessa är block som endast kan skrivas av root-användaren. men om du snabbt behöver lösa problemet kan du som en tillfällig lösning göra dem tillgängliga för alla, vilket resulterar i lite ledigt utrymme:

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

De där. som standard har du 5 % av diskutrymmet som inte är tillgängligt för skrivning, och med tanke på volymen på moderna diskar kan detta vara hundratals gigabyte.

Vad mer kan det vara? Det är också möjligt att det finns lediga block, men det finns inga fler noder. Detta händer vanligtvis om du har ett gäng filer på ditt filsystem som är mindre än filsystemets blockstorlek. Med tanke på att 1 inode spenderas på 1 fil eller katalog, och totalt har vi (för ett givet filsystem) 65536 - situationen är mer än realistisk. Detta kan tydligt ses från resultatet av kommandot 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

Som tydligt syns på /var/www-partitionen varierar antalet fria block i filsystemet och antalet fria noder kraftigt.

Om du får slut på inoder kommer jag inte att berätta några besvärjelser för dig, eftersom... det finns inga (låt mig veta om jag har fel). Så för partitioner där små filer multipliceras bör du välja filsystemet klokt. Till exempel kan btrfs-inoder inte sluta, eftersom Nya skapas dynamiskt vid behov.

Källa: will.com

Lägg en kommentar