System plików

System plików jest jednym z kluczowych elementów każdego systemu operacyjnego. Dostępnych systemów plików jest sporo, również na samego linuksa jest ich niemało. Na bardzo ogólnym poziomie możemy je podzielić na dwie grupy:

  • Tradycyjne systemy plików. Najczęściej spotykane to ext2, fat, minix.
  • Systemy plików z dziennikiem (journaling file systems). Te systemy plików zapisują zmiany do specjalnego dziennika, a dopiero potem nanoszę je we właściwe miejsce. W zależności od wybranego rodzaju jounalingu (określanego przy montowaniu), zapisywane (logowane) są same metadane albo również same dane. Najczęściej spotykane systemy plików tego typu to ext3, ReiserFS, XFS, NTFS

Aby zobaczyć systemy plików wspierane przez jądro systemu, należy wydać polecenie:

# cat /proc/filesystems

Virtual Filesystem Switch

VFS to warstwa abstrakcji pomiędzy programem, a konkretnym systemem plików, która zapewnia, że program operuje na plikach zawsze w taki sam sposób niezależnie na jakim systemem plików operuje. W szczególności dostęp do uprawnień zawsze jest taki sam, nawet na systemach plików, które ich nie oferują (np. FAT). Strukturę VFS można wyrazić następującym obrazkiem:

Virtual Filesystem Switch

Struktura ext2

Przestrzeń dyskowa systemu pliku jest podzielona na bloki, wszystkie tego samego rozmiaru, np. 1024B, 2048B lub 4096B (rozmiar bloku jest ustalany przy tworzeniu systemu plików i nie może być potem zmieniony). Systemy plików o klasycznym formacie, w tym i ext2, mają dane ułożone w listę bloków tego samego rozmiaru. Poprzedzona boot sectorem lista ta jest podzielona na grupy bloków (w grupie jest 32768 bloków), gdzie grupa bloków ma następujące składowe: superblock, group descriptor, block bitmap, i-node bitmap, i-node table, data blocks.

Strukturę systemu plików można przedstawić następująco:

Boot SectorBlock Group 1Block Group 2...Block Group N

a strukturę pojedynczej grupy bloków następująco:

SuperblockGroup DescriptorBlock BitmapInode BitmapInode TableData Blocks

Znaczenie poszczególnych składowych jest następujące:

  • Superblock. Odczytywany w momencie montowania systemu plików, zawiera następujące informacje:
    • liczba zajętych i wolnych bloków i i-node'ów (pojęcie i-node będzie opisane dalej)
    • liczba i-node na blok
    • informacje takie jak czas ostatniego montowania, ostatniego zapisu i liczbę montowań od ostatniego sprawdzania systemu plików
    • valid bit, który jest ustawiany na 0 przy montowaniu systemu plików i na 1 przy odmontowaniu. Przy starcie systemu bit jest sprawdzany i wartość 0 wyzwala automatyczne sprawdzenie systemu plików.
    W powyższej struktury grupy bloku widać, że superblock występuje w wielu kopiach – w razie uszkodzenia pierwszego superbloku, łatwo go odtworzyć z jednej z kopii.
  • Group Descriptor. Informacja o położeniu pozostałych składowych grupy bloków (np. block bitmap czy i-node table)
  • Block Bitmap. Określa, które bloki są zajęte, a które wolne.
  • Inode Bitmap. Określa, które i-node są zajęte, a które wolne.
  • Inode Table. Lista i-node'ów
  • Data Blocks. Dane i-node'ów.

Do tej pory wielokrotnie pojawiło się pojęcie i-node. Dalej omówimy zarówno to pojęcie jak i inne główne elementy wyższego poziomu:

  • i-node. Każdy plik lub katalog jest reprezentowany przez strukturę zwaną i-wezłęm (i-node). Inode zawiera informacje takie jak: typ pliku, prawa dostępu, właściciela, timestamps, rozmiar i wskaźniki do bloków danych. Tych wskaźników jest 15: 12 wskaźników bezpośrednich, 1 wskaźnik pośredni pierwszego poziomu, 1 wskaźnik pośredni drugiego poziomu i 1 wskaźnik pośredni trzeciego poziomu. Poniższy obrazek ilutruje strukturę pojedynczego i-node'a:

    i-node

  • Katalog. Każdy katalog może zawierać pliki i podkatalogi. Katalogi tworzą strukturę drzewiastą. Technicznie biorąc katalog to listę linkowana pozycji o zmiennej długości. Każda pozycja to nazwa pliku oraz skojarzony z nią i-node.

    i-node

    Dokładniej, struktura pojedynczego wpisu wygląda następująco:
    numer i-noderozmiar plikudługość nazwynazwa pliku
    Przykładowo:
    i11605file1
    i24014long_file_name
    i31202f2
  • Link twardy. Każdy i-node może mieć dowolną liczbę plików, które będą na niego wskazywać. i-node ma też dodatkowe pole zawierające liczbę takich odwołań (liczbę linków). Przy tworzeniu kolejnego linka, wartość pola zwiększana jest o 1, przy usuwaniu (np. poleceniem rm) – zmniejszana o 1. Kiedy wartość zejdzie do 0, i-node jest zwalniany, co oznacza usunięcie pliku. Linki tego typu mogą być tworzone tylko w obrębie jednego systemu plików, co więcej, mogą wskazywać tylko pliki.
  • Link symboliczny. Jest to drugi rodzaj linku, który nie wskazuje na i-node, a zawiera tylko nazwę (ścieżkę do) wskazywanego pliku. Może wskazywać na pliki innego systemu plików. Należy jednak pamiętać, że z linkiem jest skojarzony osobny i-node i bloki danych, przez co zajmuje miejsce na dysku jak każdy inny plik.
  • Pliki urządzeń. Ponieważ w Linuksie do wszystkich zasobów jest dostęp poprzez pliki, pliki urządzeń umożliwiają dostęp do urządzeń. Są to wirtualne pliki (nie zajmują miejsca na dysku), które wskazują tylko sterownik urządzenia. Mamy dwa rodzaje takich plików: znakowe i blokowe. Te pierwsze pozwalają na bezpośredni dostęp w trybie tekstowym (znaki są przekazywane bezpośrednio do sterownika), a te drugie przekazują dane przez bufor określonego rozmiaru.

ReiserFS

Ogólne założenia systemu ReiserFS są podobne do tych w ext2, jednak ReiserFS uchodzi za system lepszy dla małych plików, no i jest wyposażony w journaling. Gdzie tkwi przewaga tego systemu plików nad ext2?

W systemie plików ext2 o blokach rozmiaru 1024, plik o rozmiarze 8195 będzie zajmował 8 pełnych bloków i jeden blok z 3 bajtami. Niestety blok z trzema bajtami jest już zajęty i pozostałem 1021 bajty są zmarnowane. Ponieważ rzadko się zdarza, żeby rozmiary plików były wielokrotnościami, obliczono, że średnio strata wynosi 11%. W skrajnym wypadku może wynosić nawet ok. 50% (np. dla plików rozmiaru 1025). W ReiserFS w ramach bloku może być zapisanych więcej plików i stąd straty miejsca są istotnie mniejsze.

Drugą zaletą ReiserFS jest fakt, że bloki danych są pamiętane w zbalansowanym drzewie, przez co jest do nich szybszy dostęp. Niestety pojawia się koszt utrzymania drzewa zbalansowanego.

Obsługa systemu plików

Krótkie wprowadzenie do tego, jak obsługiwać systemy plików w linuksie. Najpierw nazewnictwo:
  • Dyski to hda, hdb, hdc, hdd (IDE), sda, sdb, sdc, sdd (SCSI, SATA)
  • Dla dysku sda kolejne partycje podstawowe to sda1-sda4, sda5- to dyski logiczne partycji rozszerzonej
  • Napędy to jedno z powyższych, ale zwykle instalator tworzy linki pt. cdrom, dvd, cdrecorder, itp.
  • Dyskietka to fd0
  • Dla wszystkieg powyżej są dostępne odpowiedni pliki w katalogu /dev, czyli np. /dev/sda1

Do zarządzania partycjami mamy programy YaST i fdisk. Oczywiście YaST jest ładny i kolorowy, a fdisk jest brzydki i czarnobiały. Niemniej jednak w jednym i drugim da się wykonać większość zadań, a w fdisku jeszcze więcej. Warto pamiętać, że jak już utworzymy nową tablicę partycji w fdisk, to żeby została ona załadowana prze jądro systemu bez konieczności restartu, wydajemy polecenie

# partprobe

Do tworzenia systemów plików możemy ponownie wykorzystać YaST, ale możemy też zrobić to z wiersza poleceń. Do tworzenia systemu plików z wiersza poleceń mamy ogólne poleceni mkfs, które po podaniu opcji -t określające typ tworzonego systemu plików, uruchamia jedno z docelowych poleceń mkfs.bfs, mkfs.ext2, mkfs.jfs, mkfs.msdos, mkfs.vfat, mkfs.cramfs, mkfs.ext3, mkfs.minix, mkfs.reiserfs, mkfs.xfs. Najczęście spotykane systemy plików to ext3 i reiserfs. Tworzymy je następująco:

# mkfs -t ext3 /dev/sda3
# mkfs -t reiserfs /dev/sda4

Przy tworzeniu ext3 możemy dodakowo podać opcje

  • -b blocksize – określa rozmiar bloku, dopuszczalne wartości to 1024, 2048, ..., 16384
  • -i bajty_na_inode – tak naprawdę opcja określa liczbę inodeów tworzonych na systemie plików

Jak już mamy utworzony system plików, możemy go podłączyć, czyli podmontować. Służy do tego polecenie mount, dualne, czyli od odmontowania to umount. Podstawowe składnie to:

mount [-t systemplikow] [-o opcje] urządzenie katalog
umount { urządzenie | katalog }

Jeśli chcemy zobaczyć aktulnie podmontowane systemy plików, wydajemy polecenie

# mount

Ewentualnie możemy też zajrzeć do plików /etc/mtab lub /proc/mounts (w przypadku konfliktu, ten drugi jest bardziej wiarygodny).

Konfiguracja montowania znajduje się w pliku /etc/fstab. Każdy wiersz określa konfigurację montowania jednego systemu plików i kolejne kolumny takiego wiersza mają następujące znaczenie:

  • urządzenie
  • ścieżka montowania (musi istnieć)
  • typ systemu plików
  • parametry montowania (oddzielone przecinkami)
  • określa, czy będzie robiona kopia zapasowa (0 - nie będzie, 1 - będzie)
  • określa kolejność, w której fsck będzie sprawdzało partycje:
    • 0: nie będzie sprawdzania
    • 1: główny katalog (będzie sprawdzany w pierwszej kolejności)
    • 2: pozostałe systemy plików (będą sprawdzane równolegle)

Przy podłączaniu systemu pliku można podać szereg opcji. Poniższe opcje można podawać zarówno w pliku /etc/fstab, jak i przy bezpośrednim wywoływaniu polecenia mount

  • remount. Powoduje ponowne podmontowanie już zamontowanego systemu plików. Przydatne, jeśli chcemy nanieść zmiany w pliku /etc/fstab, no i jedyny sposób, że zmienić opcje montowania dla głównego systemu plików.
  • rw, ro. Określają, czy system plików ma być w trybie tylko do odczytu, czy w trybie od odczytu i zapisu
  • sync, async. Określają, czy wymiana danych ma być synchroniczna, czy asynchroniczna.
  • atima, noatime. Określają, czy ma być aktualizowany czas dostępu do i-node'a (access time). Wyłaczenie tej opcji powinno zwiększyć nieco wydajność.
  • nodev, dev. Opcja nodev zapobiega traktowaniu plików urządzeń jako plików specjalnych.
  • noexec, exec. Użycie opcji noexec zapobiega wykonaniu programu z tak zamontowanej partycji.
  • nosuid, suid. Użycie nosuid sprawia, że bity suid i sgid będą ignorowane.
  • uid=user. Określa, kto będzie właścicielem plików podmontowanego systemu plików.
  • gid=group. Określa grupę plików podmontowanego systemu plików.
  • umask=perm. Określa uprawnienia podmontowanego systemu plików.

Niektóre opcje mają sens tylko w plku /etc/fstab

  • auto, noauto. Określa, czy montować system plików przy starcie systemu.
  • user,users,nouser. Określa, czy pozwolić konkretnemu/dowolnemu/żadnemu użytkownikowi na montownie/odmontowanie systemu plików.
  • defaults. Standardowy zestaw opcji: rw,suid,dev,exec,auto,nouser,async.

Dalej przedstawimy kilka użytecznych narzędzi w walce z systemami plików.

df

Wyświetla informacje o podmontowanych partycjach, rodzaju partycji, zużyciu miejsca, itp.

Podstawowa składnia:

df [opcje] [katalog|plik ...]

Wybrane opcje

  • -h – podawanie wielkość w "ludzkim" formacie, np. 4MB.
  • -T – dodatkowo pojawi informacja o typie systemu plików.

Przykładowe użycia

  • df -hT
    wyświetla podmontowane systemy plików wraz nagłówkiem i informacją o typie danego systemu
    plików
  • df / .
    wyświetla podstawowe informacje o partycjach głównej i w bieżącej ścieżce

du

Wyświetla informacje o zużyciu miejsca przez pliki i katalogi.

Podstawowa składnia

du [opcje] [katalog|plik ...]

Wybrane opcje

  • -c — wyświetla dla końcu wydruku sumę podanych rozmiarów
  • -h — rozmiary podaje w sposób czytelny dla człowieka, np. 4MB
  • -b — wartości podawane są w bajtach
  • -s — dla katalogu podaje sumę zawartości
  • --exclude='wzorzec' — rozmiar jest obliczany z pominięciem plików określonych przez wzorzec

Przykładowe użycia

  • du -hs
    podaje zajętość bieżącego katalogu
  • du -cbs /bin /home
    podaje dokładną zajętość katalogów /bin i /home oraz ile zajmują w sumie

lsof

Wyświetla listę otwartych plików wraz poleceniem, które używa danego pliku i innymi informacjami.

Podstawowa składnia:

lsof [opcje]

Wybrane opcje:

  • -c napis — na liście będą tylko pliki otwarte przez polecenia zaczynające się od "napis".
  • -u user1,user2,... — na liście będą tylko pliki otwarte przez użytkowników user1, user2, itd.

Przykładowe użycia:

  • lsof -u gucio,kulfon
    na liście będą pliki otwarte przez użytkowników gucio i kulfon
  • lsof -c b
    na liście będą pliki o nazwa na literę b

fuser

Wyświetla PID-y procesów używających danego pliku lub systemu plików, potrafi także zabijać znalezione procesu, lub ogólniej, wysyłać do nich sygnały. Drukując PID-y, dodatkowo obok każdego może się pojawić kombinacja liter. Ich znaczenie jest następujące:

  • c — bieżący katalog
  • e — proces aktualnie wykonywany
  • r — główny katalog
  • m — plik mapowania pamiędzi lub dzielona biblioteka
  • f, F — plik otwarty (lub otwarty do zapisu), przy standardowym formacie wydruku pomijane

Podstawowa składnia

fuser [opcje] plik_lub_katalog ...

Wybrane opcje:

  • -m katalog — podaje wszystkie procesy blokujące (używające) plików na partycji zawierającej wskazany katalog.
  • -u do każdego PID-a dopisywana jest także właściciel procesu,

Przykładowe użycia:

  • fuser -m /home
    lista procesów blokujących partycję /home. Przydatne, jeśli np. nie udaje nam się jej odmontować.

fsck

Jest to narzędzie do sprawdzania spójności systemu plików. Tak naprawdę fsck jest poleceniem pośrednim, które wywołuje docelowe polecenie sprawdzania już konkretnego systemu plików: fsck.ext2, fsck.jfs, fsck.msdos, fsck.vfat, fsck.cramfs, fsck.ext3, fsck.minix, fsck.reiserfs, fsck.xfs. Łatwo sprawdzić, że przypadku systemu plików ext2 i ext3 do sprawdzania mamy polecenia

/sbin/e2fsck
/sbin/fsck.ext2
/sbin/fsck.ext3
które są identyczne. Podobnie jest w przypadku systemu plików ReiserFS. Tutaj mamy 2 identyczne programy:
/sbin/fsck.reiserfs
/sbin/reiserfsck

Najprostsze użycie polecenia to np. po prostu

# fsck /dev/sda2

Program sam wywoła odpowiednie narzędzie docelowe. Wywołanie fsck.ext3 lub fsck.reiserfs może być istotne, jeśli chcemy przekazać opcje specyficzne dla konkretnego systemu plików (chociaż tak naprawdę przez fsck też to możemy zrobić).

dumpe2fs

Pokazuje zawartość superbloku oraz informacje o grupach bloków, w tym również o kopiach superbloków. W przypadku uszkodzenia pierwszego superbloku, można tym poleceniem odtworzyć superblok z jednej z kopii. Przykładowo:

e2fsck -f -b 32768 /dev/hda1

tune2fs, reiserfstune

Zmiana parametrów partycji ext2/3 i ReiserFS

resize2fs, resize_reiserfs

Zmiana rozmiaru partycji ext2/3 i ReiserFS. Ciekawe, że w przypadku partycji reiserfs, zmianę rozmiaru można wykonać online, tzn. na podmontowanej i działającej partycji.

Literatura