Дещо про 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 XNUMX штук. В 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 іноді не можуть закінчитися, т.к. динамічно створюються нові за необхідності.

Джерело: habr.com

Додати коментар або відгук