Хабрахабр

[Из песочницы] Кое-что об inode

Периодически, с целью переезда в ЦРС собеседуюсь в разных крупных компаниях, в основном питера и москвы на должность DevOps. Обратил внимание, что во многих компаниях (во многих хороших компаниях, например в яндексе) задают два сходных вопроса:

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

Как часто бывает, я был уверен что эту тему знаю хорошо, но как только начал объяснять — обозначились провалы в знаниях. Что-бы систематизировать свои знания, заполнить пробелы и больше не позориться пишу эту статью, может еще кому пригодится.

с жесткого диска (флешки, SSD и прочие современные штуки отбросим, для примера рассмотрим любой 20 или 80 гиговый старый диск, т.к. Начну «снизу», т.е. там размер блока 512 байт).

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

К слову, посмотреть какой размер блока у вашего диска можно так:
Как видно из рисунка, блоки 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? Какие блоки читать? Зная имя файла, как его найти?

В файловой системе ext2fs есть «таблица», в которой содержится информация по всем inode. Вот тут нам и пригождаются inode. Нужные цифры смотрим в параметре «Inode count» вывода tune2fs, т.е. Количество inode, в случае с ext2fs задается при создании файловой системы. В inode содержится нужная нам информация: список блоков файловой системы для искомого файла. имеем 65536 штук. Как найти номер inode для указанного файла?

тоже имеет свой номер inode. Соответствие имени и номера inode, содержится в директории, а директория в ext2fs — это файл особого типа, т.е. Смотрим содежимое 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

В выводе можно прочитать имена файлов в директории.

Вот я и подошел к главному вопросу: «по каким причинам может возникнуть ошибка записи»?

Что можно в этом случае сделать? Естественно так случится, если не останется свободных блоков файловой системы. Если посмотреть в листинге выше, то у нас таких блоков «13094». Кроме очевидного «удалить что-нибудь не нужное», следует помнить, что в файловых системах ext2,3 и 4 есть такая штука, как «Reserved block count». но если нужно оперативно решить вопрос, как временное решение можно сделать их доступными для всех, в результате чего появится немного свободного места: Это блоки доступные для записи только пользователю root.

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

Т.е. по умолчанию, у вас не доступно для записи 10% дискового пространства, и учитывая объемы современных дисков, это могут быть сотни гигабайт.

Еще возможна ситуация, когда свободные блоки у есть, а ноды кончились. Что еще может быть? Учитывая, что на 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 не могут закончиться, т.к. Так что для разделов в которых плодятся мелкие файлы следует грамотно выбирать файловую систему. динамически создаются новые при необходимости.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть