Kilka słów o inode

Cyklicznie, w celu przeprowadzki do CRU, rozmumiem się w różnych dużych firmach, głównie z Petersburga i Moskwy na stanowisko DevOps. Zauważyłem, że w wielu firmach (w wielu dobrych firmach, na przykład w Yandexie) zadają dwa podobne pytania:

  • co to jest inode;
  • z jakich powodów można otrzymać błąd zapisu na dysk (lub na przykład: dlaczego może zabraknąć miejsca na dysku, istota jest ta sama).

Jak to często bywa, byłem pewny, że dobrze znam ten temat, ale gdy tylko zacząłem wyjaśniać – pojawiły się luki w mojej wiedzy. Aby usystematyzować swoje wiadomości, wypełnić luki i więcej się nie zawstydzać, piszę ten artykuł, może jeszcze komuś się przyda.

Zacznę «od dołu», tzn. od twardego dysku (pendrive'ów, SSD i innych nowoczesnych rzeczy nie bierzemy pod uwagę, dla przykładu rozważamy każdy stary dysk 20 lub 80 gigowy, ponieważ tam rozmiar bloku wynosi 512 bajtów).

Twardy dysk nie potrafi adresować swojej przestrzeni bajt po bajcie, warunkowo jest ona podzielona na bloki. Numeracja bloków zaczyna się od 0. (nazywa się to LBA, szczegóły tutaj: ru.wikipedia.org/wiki/LBA)

Kilka słów o inode

Jak widać na rysunku, bloki LBA oznaczyłem jako poziom HDD. Nota bene, aby sprawdzić, jaki rozmiar bloku ma Twój dysk, możesz to zrobić w ten sposób:

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

Poziom wyżej jest partycja, jedna na cały dysk (znów dla prostoty). Najczęściej stosuje się dwa typy partycji: msdos i gpt. Odpowiednio msdos – stary format, obsługujący dyski do 2 TB, gpt – nowy format, zdolny adresować do 1 zettabajta 512-bajtowych bloków. W naszym przypadku mamy partycję typu msdos, jak widać na rysunku, partycja zaczyna się od bloku nr 1, zerowy zaś jest używany dla MBR.

W pierwszej partycji stworzyłem system plików ext2, domyślnie rozmiar bloku wynosi 4096 bajtów, co również zostało odzwierciedlone na rysunku. Rozmiar bloku systemu plików można sprawdzić w ten sposób:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Nazwa woluminu systemu plików:   
Ostatnio zamontowany na:          
UUID systemu plików:          a600bf40-f660-41f6-a3e6-96c303995479
Numer magiczny systemu plików:  0xEF53
Wersja systemu plików:    1 (dynamiczny)
Funkcje systemu plików:      ext_attr resize_inode dir_index filetype sparse_super large_file
Flagi systemu plików:         signed_directory_hash
Domyślne opcje montowania:    user_xattr acl
Stan systemu plików:         czysty
Zachowanie w przypadku błędów:          Kontynuuj
Typ OS systemu plików:       Linux
Liczba inode'ów:              65536
Liczba bloków:              261888
Zarezerwowana liczba bloków:     13094
Wolne bloki:              257445
Wolne inode'y:              65525
Pierwszy blok:              0
Rozmiar bloku:               4096
Rozmiar fragmentu:            4096
Zarezerwowane bloki GDT:      63
Bloków na grupę:         32768
Fragmentów na grupę:      32768
Inode'ów na grupę:         8192
Bloków inode na grupę:   512
System plików utworzony:       Piątek 2 sierpnia  15:02:13 2019
Ostatni czas montowania:          n/a
Ostatni czas zapisu:          Piątek 2 sierpnia  15:02:14 2019
Liczba montaży:              0
Maksymalna liczba montaży:      -1
Ostatnia kontrola:             Piątek 2 sierpnia  15:02:13 2019
Interwał kontroli:           0 ()
Zarezerwowane bloki uid:      0 (użytkownik root)
Zarezerwowane bloki gid:      0 (grupa root)
Pierwszy inode:              11
Rozmiar inode:               256
Wymagany dodatkowy rozmiar:     28
Pożądany dodatkowy rozmiar:      28
Domyślny hash katalogu:   half_md4
Ziarno hasha katalogu:      c0155456-ad7d-421f-afd1-c898746ccd76

Szukany przez nas parametr to „Rozmiar bloku”.

Teraz najciekawsze, jak odczytać plik /home/serp/testfile? Plik składa się z jednego lub kilku bloków systemu plików, w których przechowywane są jego dane. Jak znaleźć go, znając nazwę pliku? Które bloki odczytać?

Tutaj przydają się nam inode'y. W systemie plików ext2fs istnieje „tabela”, w której zawarte są informacje o wszystkich inode'ach. Liczba inode'ów w przypadku ext2fs jest ustalana w momencie tworzenia systemu plików. Potrzebne liczby sprawdzamy w parametrze „Liczba inode'ów” w wyjściu tune2fs, tzn. mamy ich 65536. W inode'ach przechowywane są nam potrzebne informacje: lista bloków systemu plików dla poszukiwanego pliku. Jak znaleźć numer inode dla wskazanego pliku?

Zgodność nazwy i numeru inode znajduje się w katalogu, a katalog w ext2fs to plik specjalnego rodzaju, tzn. również ma swój numer inode. Aby przełamać ten błędny krąg, dla katalogu głównego przypisano „stały” numer inode „2”. Zobaczmy zawartość inode o numerze 2:

root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs:  stat 

Inode: 2   Typ: katalog    Tryb:  0755   Flagi: 0x0
Generacja: 0    Wersja: 0x00000000:00000002
Użytkownik:     0   Grupa:     0   Rozmiar: 4096
ACL pliku: 0    ACL katalogu: 0
Linki: 3   Liczba bloków: 8
Fragment:  Adres: 0    Liczba: 0    Rozmiar: 0
 ctime: 0x5d43cb51:16b61bcc -- Piątek 2 sierpnia  16:34:09 2019
 atime: 0x5d43c247:b704301c -- Piątek 2 sierpnia  15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Piątek 2 sierpnia  16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Piątek 2 sierpnia  15:02:14 2019
Rozmiar dodatkowych pól inode: 28
BLOKI:
(0):579
ŁĄCZNIE: 1

Jak widać, potrzebny nam katalog znajduje się w bloku o numerze 579. W nim znajdziemy numer węzła dla katalogu home, i tak dalej w łańcuchu, aż w katalogu serp zobaczymy numer węzła dla żądanego pliku. Jeśli ktoś chciałby sprawdzić, czy numer jest poprawny i czy znajdują się tam potrzebne informacje, nie jest to trudne. Robimy to:

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

W wyjściu można odczytać nazwy plików w katalogu.

Oto dotarłem do głównego pytania: „jakie mogą być przyczyny błędu zapisu”?

Oczywiście tak się stanie, jeśli nie pozostanie wolnych bloków w systemie plików. Co można w tym przypadku zrobić? Oprócz oczywistego „usunąć coś niepotrzebnego”, należy pamiętać, że w systemach plików ext2, 3 i 4 istnieje taka rzecz, jak „Reserved block count”. Jeśli spojrzymy na wcześniejszą listę, mamy 13094 takich bloków. To są bloki dostępne do zapisu tylko dla użytkownika root. Ale jeśli trzeba szybko rozwiązać problem, jako rozwiązanie tymczasowe można uczynić je dostępnymi dla wszystkich, w wyniku czego pojawi się trochę wolnego miejsca:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Ustawienie procentu zarezerwowanych bloków na 0% (0 bloków)

To znaczy, domyślnie nie masz dostępu do zapisu 5% przestrzeni dyskowej, a biorąc pod uwagę rozmiary nowoczesnych dysków, może to być setki gigabajtów.

Co jeszcze może być? Może być także sytuacja, gdy masz wolne bloki, a węzły się skończyły. Taka sytuacja zazwyczaj występuje, jeśli w twoim systemie plików znajduje się wiele plików mniejszych niż rozmiar bloku systemu plików. Biorąc pod uwagę, że na jeden plik lub katalog przypada jeden inode, a mamy ich łącznie (dla tego systemu plików) 65536 — sytuacja jest więcej niż realna. Można to zobaczyć na przykładzie 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 widać na przykładzie /var/www, liczba dostępnych bloków systemu plików oraz liczba dostępnych i-node'ów znacznie się różnią.

Na wypadek, gdyby zabrakło inode'ów, trudno mi powiedzieć, co zrobić, bo po prostu ich nie ma (jeśli się mylę, proszę dać znać). Dlatego dla partycji, w których mnożą się małe pliki, należy mądrze wybierać system plików. Na przykład w btrfs inode'y nie mogą się skończyć, ponieważ nowe są dynamicznie tworzone w razie potrzeby.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster