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: )

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
512Poziom 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-c898746ccd76Szukany 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: 1Jak 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_imageW 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/wwwJak 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
