Што-нішто пра inode

Перыядычна, з мэтай пераезду ў ЦРС гутару ў розных буйных кампаніях, у асноўным Піцера і Масквы на пасаду DevOps. Звярнуў увагу, што ў многіх кампаніях (у многіх добрых кампаніях, напрыклад у яндэксе) задаюць два падобныя пытанні:

  • што такое inode;
  • па якіх прычынах можна атрымаць памылку запісу на дыск (ці напрыклад: чаму можа скончыцца месца на дыску, сутнасць адна).

Як часта бывае, я быў упэўнены, што гэтую тэму ведаю добра, але як толькі пачаў тлумачыць - абазначыліся правалы ў ведах. Каб сістэматызаваць свае веды, запоўніць прабелы і больш не ганьбіцца, пішу гэты артыкул, можа яшчэ каму спатрэбіцца.

Пачну "знізу", г.зн. з цвёрдай кружэлкі (флэшкі, SSD і іншыя сучасныя штукі адкінем, для прыкладу разгледзім любую 20 ці 80 гігавая старая кружэлка, т.к. тамака памер блока 512 байт).

Жорсткая дыск не ўмее адрасаваць сваю прастору пабайтна, умоўна яна разбіта на блокі. Нумарацыя блокаў пачынаецца з 0. (завецца гэта LBA, падрабязнасці тут: ru.wikipedia.org/wiki/LBA)

Што-нішто пра inode

Як відаць з малюнка, блокі LBA я пазначыў як узровень HDD. Дарэчы, паглядзець, які памер блока ў вашага дыска можна так:

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

Узроўнем вышэй размечаны падзел, адзін на ўвесь дыск (ізноў жа для прастаты). Часцей за ўсё выкарыстоўваюць разметку раздзелаў двух тыпаў: msdos і gpt. Адпаведна msdos - стары фармат, які падтрымлівае дыскі да 2Tb, gpt - новы фармат, здольны адрасаваць да 1 зеттабайта 512 байтных блокаў. У нашым выпадку маем частку тыпу msdos, як відаць з малюнка, частка пры гэтым пачынаецца з блока №1, нулявы ж выкарыстоўваецца для MBR.

У першай частцы я стварыў файлавую сістэму ext2, па змаўчанні памер блока ў яе 4096 байт, што таксама адлюстравана на малюнку. Паглядзець памер блока файлавай сістэмы можна так:

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

Патрэбны нам параметр - "Block size".

Цяпер самае цікавае, як прачытаць файл /home/serp/testfile? Файл складаецца з аднаго ці некалькіх блокаў файлавай сістэмы, у якіх захоўваюцца ягоныя дадзеныя. Ведаючы імя файла, як яго знайсці? Якія блокі чытаць?

Вось тут нам і спатрэбяцца inode. У файлавай сістэме ext2fs ёсць "табліца", у якой утрымоўваецца інфармацыя па ўсіх inode. Колькасць inode у выпадку з ext2fs задаецца пры стварэнні файлавай сістэмы. Патрэбныя лічбы глядзім у параметры "Inode count" высновы tune2fs, г.зн. маем 65536 штук. У inode утрымоўваецца патрэбная нам інфармацыя: спіс блокаў файлавай сістэмы для шуканага файла. Як знайсці нумар inode для ўказанага файла?

Адпаведнасць імя і нумары inode утрымоўваецца ў дырэкторыі, а дырэкторыя ў ext2fs - гэта файл адмысловага тыпу, г.зн. таксама мае свой нумар inode. Каб разарваць гэты заганны круг, для каранёвай дырэкторыі прызначылі "фіксаваны" нумар inode "2". Глядзім змесціва inode за нумарам 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

Як відаць, патрэбная нам дырэкторыя ўтрымоўваецца ў блоку з нумарам 579. У ёй мы знойдзем нумар нода для тэчкі home, і гэтак далей па ланцужку, пакуль у дырэкторыі serp не ўбачым нумар нода для запытанага файла. Калі раптам камусьці захочацца праверыць, ці дакладны нумар, і ці ёсць там патрэбная інфа, гэта не складана. Які робіцца:

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

У выснове можна прачытаць імёны файлаў у дырэкторыі.

Вось я і падышоў да галоўнага пытання: "па якіх прычынах можа ўзнікнуць памылка запісу"?

Натуральна так здарыцца, калі не застанецца вольных блокаў файлавай сістэмы. Што можна зрабіць у гэтым выпадку? Акрамя відавочнага "выдаліць што-небудзь непатрэбнае", варта памятаць, што ў файлавых сістэмах ext2,3 і 4 ёсць такая штука, як "Reserved block count". Калі паглядзець у лістынгу вышэй, то ў нас такіх блокаў "13094". Гэта блокі даступныя для запісу толькі карыстачу root. але калі трэба аператыўна вырашыць пытанне, як часовае рашэнне можна зрабіць іх даступнымі для ўсіх, у выніку чаго з'явіцца крыху вольнага месца:

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

Г.зн. па змаўчанні, у вас не даступна для запісу 5% дыскавай прасторы, і улічваючы аб'ёмы сучасных дыскаў, гэта могуць быць сотні гігабайт.

Што яшчэ можа быць? Яшчэ магчымая сітуацыя, калі вольныя блокі ў ёсць, а ноды скончыліся. Такое звычайна здараецца, калі ў вас у файлавай сістэме куча файлаў памерам менш памеру блока файлавай сістэмы. Улічваючы, што на 1 файл або дырэкторыю марнуецца 1 inode, а ўсяго іх маем (для дадзенай файлавай сістэмы) 65536 – сітуацыя больш за рэальная. Наглядна гэта можна ўбачыць з вываду каманды 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

Як добра прыкметна на раздзеле /var/www, колькасць вольных блокаў файлавай сістэмы, і колькасць вольных нодаў моцна адрозніваецца.

На выпадак калі скончыліся inode, загавораў не падкажу, т.я. іх няма (калі не мае рацыю, дайце ведаць). Так што для частак у якіх размнажаюцца дробныя файлы варта пісьменна выбіраць файлавую сістэму. Так напрыклад у btrfs inode не могуць скончыцца, т.я. дынамічна ствараюцца новыя пры неабходнасці.

Крыніца: habr.com

Дадаць каментар