Coś o i-węźle

Okresowo, aby przenieść się do Centralnego Centrum Dystrybucji, prowadzę rozmowy kwalifikacyjne w różnych dużych firmach, głównie w Petersburgu i Moskwie, na stanowisko DevOps. Zauważyłem, że wiele firm (wiele dobrych firm, na przykład Yandex) zadaje dwa podobne pytania:

  • co to jest i-węzeł;
  • z jakiego powodu może wystąpić błąd zapisu na dysku (lub na przykład: dlaczego może zabraknąć miejsca na dysku, istota jest taka sama).

Jak to często bywa, byłem pewien, że znam ten temat dobrze, jednak gdy tylko zacząłem się tłumaczyć, uwidoczniły się luki w wiedzy. Aby usystematyzować swoją wiedzę, uzupełnić luki i nie narażać się już na wstyd, piszę ten artykuł, może komuś się przyda.

Zacznę od dołu, tj. z dysku twardego (odrzucimy dyski flash, dyski SSD i inne nowoczesne rzeczy; na przykład rozważmy dowolny stary dysk o pojemności 20 lub 80 gigabajtów, ponieważ rozmiar bloku wynosi 512 bajtów).

Dysk twardy nie wie, jak adresować swoją przestrzeń bajt po bajcie, jest warunkowo podzielony na bloki. Numeracja bloków rozpoczyna się od 0. (Nazywa się to LBA, szczegóły tutaj: ru.wikipedia.org/wiki/LBA)

Coś o i-węźle

Jak widać na rysunku, jako poziom dysku twardego wyznaczyłem bloki LBA. Przy okazji, możesz zobaczyć, jaki rozmiar bloku ma twój dysk:

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

Poziom powyżej to partycja, jedna dla całego dysku (ponownie dla uproszczenia). Najczęściej używane są dwa typy znaczników partycji: msdos i gpt. W związku z tym msdos to stary format, który obsługuje dyski do 2 TB, gpt to nowy format, który może adresować do 1 zettabajta bloków o długości 512 bajtów. W naszym przypadku mamy partycję typu msdos, jak widać na rysunku, partycja zaczyna się od bloku nr 1, natomiast dla MBR używane jest zero.

Na pierwszej partycji utworzyłem system plików ext2, jego domyślny rozmiar bloku to 4096 bajtów, co również widać na rysunku. Rozmiar bloku systemu plików można wyświetlić w następujący sposób:

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

Parametr, którego potrzebujemy, to „Rozmiar bloku”.

Teraz interesującą częścią jest to, jak odczytać plik /home/serp/testfile? Plik składa się z jednego lub większej liczby bloków systemu plików, w których przechowywane są jego dane. Znając nazwę pliku, jak go znaleźć? Które bloki powinienem przeczytać?

Tutaj z pomocą przychodzą i-węzły. System plików ext2fs posiada „tabelę” zawierającą informacje o wszystkich i-węzłach. Liczbę i-węzłów w przypadku ext2fs ustala się podczas tworzenia systemu plików. Sprawdzamy wymagane liczby w parametrze „Inode count” wyjścia tune2fs, tj. mamy 65536 sztuk. I-węzeł zawiera potrzebne nam informacje: listę bloków systemu plików dla szukanego pliku. Jak znaleźć numer i-węzła dla danego pliku?

Odpowiednia nazwa i numer i-węzła zawarte są w katalogu, a katalog w ext2fs jest plikiem specjalnego typu, tj. ma również swój własny numer i-węzła. Aby przerwać to błędne koło, do katalogu głównego przypisano „stały” numer i-węzła „2”. Przyjrzyjmy się zawartości i-węzła numer 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

Jak widać potrzebny nam katalog znajduje się w bloku numer 579. Znajdziemy w nim numer węzła dla folderu domowego i tak dalej w dół łańcucha, aż w katalogu serp zobaczymy numer węzła dla żądanego pliku. Jeśli nagle ktoś będzie chciał sprawdzić, czy numer się zgadza i czy znajdują się w nim potrzebne informacje, nie jest to trudne. My robimy:

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

Na wyjściu możesz odczytać nazwy plików w katalogu.

Dochodzę zatem do zasadniczego pytania: „z jakich powodów może wystąpić błąd zapisu?”

Oczywiście stanie się tak, jeśli w systemie plików nie będzie już wolnych bloków. Co można zrobić w tym przypadku? Oprócz oczywistego „usuń wszystko, co niepotrzebne”, powinieneś pamiętać, że w systemach plików ext2,3 i 4 istnieje coś takiego jak „Zarezerwowana liczba bloków”. Jeśli spojrzysz na powyższą listę, mamy „13094” takich bloków. Są to bloki, które może zapisywać wyłącznie użytkownik root. ale jeśli chcesz szybko rozwiązać problem, jako rozwiązanie tymczasowe możesz udostępnić je wszystkim, co spowoduje trochę wolnego miejsca:

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

Te. domyślnie masz 5% miejsca na dysku niedostępnego do zapisu, a biorąc pod uwagę objętość nowoczesnych dysków, może to być setki gigabajtów.

Co jeszcze mogłoby to być? Możliwe jest również, że są wolne bloki, ale nie ma już węzłów. Zwykle dzieje się tak, jeśli w systemie plików masz kilka plików mniejszych niż rozmiar bloku systemu plików. Biorąc pod uwagę, że 1 i-węzeł zajmuje 1 plik lub katalog, to w sumie mamy (dla danego systemu plików) 65536 - sytuacja jest więcej niż realna. Można to wyraźnie zobaczyć na podstawie wyniku polecenia 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

Jak wyraźnie widać na partycji /var/www, liczba wolnych bloków w systemie plików i liczba wolnych węzłów znacznie się różnią.

Gdyby zabrakło Ci i-węzłów, nie będę Ci zdradzał żadnych zaklęć, bo... nie ma (jeśli się mylę, daj mi znać). Dlatego w przypadku partycji, w których mnożą się małe pliki, należy mądrze wybrać system plików. Na przykład i-węzły btrfs nie mogą się kończyć, ponieważ W razie potrzeby nowe są tworzone dynamicznie.

Źródło: www.habr.com

Dodaj komentarz