Przejdź do treści
Lekcja 58 z 117

Kurs › Moduł 6 › Lekcja 58

Partycje

⏱ ok. 12 min czytania· moduł 6: Dyski i systemy plików

Po tej lekcji: kursant rozumie różnicę między MBR a GPT, dzieli dysk na partycje w fdisk, gdisk i parted, nadaje im właściwe typy i wie, co zrobić przez partprobe, kiedy jądro nie widzi nowej partycji.

Wstęp

lsblk na maszynie wirtualnej, dysk sda podzielony na sda1 1G /boot, sda2 reszta

Popatrz na dowolny serwer. Prawie nigdy nie zobaczysz systemu plików położonego bezpośrednio na całym dysku. Zawsze jest sda1, sda2, nvme0n1p1. Dysk najpierw jest dzielony na kawałki, a dopiero na kawałkach stoją regały.

Dlaczego? Bo jeden kawałek musi być dla programu rozruchowego, drugi dla systemu, trzeci może na dane, które przeżyją reinstalację. Jak mieszkanie: niby można mieć jedno wielkie pomieszczenie z wanną obok łóżka i kuchenką przy szafie, ale ktoś kiedyś wymyślił ściany i ludzkość na tym zyskała.

Dziś stawiamy ściany. Trzema narzędziami, bo na egzaminie i w pracy spotkasz wszystkie trzy.

Uwaga: zła partycja na złym dysku to najszybszy sposób, żeby skasować komuś cały serwer. Ćwicz na maszynie wirtualnej z dodatkowym, pustym dyskiem albo na pliku, tak jak ja. Przed każdym zapisem sprawdź lsblk, czy na pewno masz przed sobą właściwy dysk. Dwa razy.

Tablica partycji, czyli plan mieszkania na drzwiach

Na samym początku dysku leży mała tabliczka: plan mieszkania. Mówi, gdzie zaczyna się i kończy każdy pokój. To tablica partycji. Są dwa standardy takich tabliczek.

MBR, Master Boot Record. Stara tabliczka z czasów pierwszych pecetów, wyryta na jednym 512-bajtowym sektorze na samym początku dysku. Ma miejsce na cztery wpisy. Cztery pokoje i koniec. Chcesz więcej? Jeden z czterech pokoi zamieniasz na korytarz, czyli partycję rozszerzoną, a w korytarzu robisz kolejne pomieszczenia, czyli partycje logiczne. Działa, ale wygląda jak mieszkanie po trzech remontach różnych ekip. Do tego MBR liczy sektory na 32 bitach, więc przy zwykłych sektorach po 512 bajtów nie ogarnie więcej niż 2 TiB. Dysk 4 TB z MBR to mieszkanie, w którym połowy pokoi nie ma na planie.

GPT, GUID Partition Table. Nowoczesna tabliczka, część standardu UEFI. Domyślnie 128 wpisów, gigantyczne rozmiary, każda partycja ma własny unikalny identyfikator i nazwę. A co najważniejsze: kopię planu trzyma też na końcu dysku. Zniszczysz początek, plan przeżyje na zapleczu.

Wybór? Nowy dysk: GPT. MBR tylko wtedy, gdy musisz, na przykład stary sprzęt startujący w trybie BIOS albo mały pendrive dla starego telewizora.

Przygotowanie: dysk z pliku

Na maszynie wirtualnej po prostu dodajesz drugi dysk w ustawieniach VirtualBoxa czy virt-managera i pojawi się jako sdb albo vdb. Ja robię dysk z pliku i podpinam go jako urządzenie:

truncate -s 2G dysk.img
sudo losetup -fP --show dysk.img
/dev/loop8

losetup podpina plik jako urządzenie blokowe /dev/loop8. -f bierze pierwszy wolny numer, -P każe jądru szukać na nim partycji, --show wypisuje, co dostaliśmy. Od teraz /dev/loop8 udaje dysk tak dobrze, że fdisk nie zauważy różnicy. Ty w każdej komendzie zamiast /dev/loop8 wpisz swój dysk.

fdisk: klasyk z menu

fdisk to interaktywne menu sterowane literkami. Jak bankomat ze starego filmu: wciskasz literę, on o coś pyta.

sudo fdisk /dev/loop8

Wpisuję po kolei:

  • g, czyli nowa, pusta tablica GPT. Dla MBR byłoby o.
  • n, nowa partycja. Numer zostawiam domyślny Enterem, początek też Enterem, a na koniec wpisuję +500M, czyli pięćset megabajtów od początku.
  • n jeszcze raz, numer i początek Enterem, koniec +1G.
  • t, zmiana typu. Wybieram partycję 2 i wpisuję lvm.
  • p, pokaż, co mam.
Created a new GPT disklabel (GUID: 9980810F-58C1-40A2-9741-B1787FD88291).
Created a new partition 1 of type 'Linux filesystem' and of size 500 MiB.
Created a new partition 2 of type 'Linux filesystem' and of size 1 GiB.
Changed type of partition 'Linux filesystem' to 'Linux LVM'.

Disklabel type: gpt
Device         Start     End Sectors  Size Type
/dev/loop8p1    2048 1026047 1024000  500M Linux filesystem
/dev/loop8p2 1026048 3123199 2097152    1G Linux LVM

I teraz najważniejsze. Wszystko do tej pory było tylko na kartce. fdisk mówi to zresztą na powitanie: Changes will remain in memory only, until you decide to write them. Zmiany są w pamięci, dopóki nie wciśniesz w, czyli „write”, zapisz. q wychodzi bez zapisywania. To Twój hamulec bezpieczeństwa: pomyliłeś się, q, nic się nie stało.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Po co zmiana typu? Typ partycji to tabliczka na drzwiach pokoju: „kuchnia”, „łazienka”, „schowek”. Nic nie blokuje, ale narzędzia i ludzie się nią kierują. Najważniejsze dla admina: Linux filesystem na zwykłe dane, Linux LVM pod LVM, o którym za trzy lekcje, Linux swap pod pamięć wymiany, o której w lekcji sześćdziesiątym, i EFI System pod partycję rozruchową. W fdisk możesz wpisać skrót: lvm, swap, linux, zamiast szukać numeru na liście.

partprobe: kiedy jądro przespało zmianę

Sprawdzam, czy system widzi nowe partycje:

lsblk /dev/loop8
NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop8   7:8    0   2G  0 loop

Nic. Tablica jest zapisana na dysku, ale jądro dalej trzyma w pamięci stary plan. To się zdarza naprawdę, szczególnie gdy dysk jest w użyciu albo gdy ktoś zmieniał partycje innym narzędziem. Jak administracja budynku, która dostała nowy plan mieszkania, ale położyła go na stosie „do przeczytania w poniedziałek”.

partprobe każe jądru przeczytać plan od nowa:

sudo partprobe -s /dev/loop8
lsblk /dev/loop8
/dev/loop8: gpt partitions 1 2
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop8       7:8    0    2G  0 loop
|-loop8p1 259:2    0  500M  0 part
`-loop8p2 259:3    0    1G  0 part

Są. -s dopisuje krótkie podsumowanie. Na RHEL partprobe jest w pakiecie parted, na Ubuntu też, więc jeśli masz parted, masz i partprobe.

gdisk: fdisk w wersji GPT

gdisk wygląda prawie jak fdisk i powstał, kiedy fdisk jeszcze nie umiał GPT. Dziś fdisk umie, ale gdisk dalej jest w podręcznikach i na egzaminach. Jeśli go nie masz: sudo apt install gdisk [Ubuntu] albo sudo dnf install gdisk [RHEL].

Najpierw tylko podglądam:

sudo gdisk -l /dev/loop8
Partition table scan:
  MBR: protective
  GPT: present

Found valid GPT with protective MBR; using GPT.
Partition table holds up to 128 entries
Partitions will be aligned on 2048-sector boundaries

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1026047   500.0 MiB   8300
   2         1026048         3123199   1024.0 MiB  8E00

Typy w gdisk to czterocyfrowe kody: 8300 Linux filesystem, 8E00 LVM, 8200 swap, EF00 partycja EFI. Komendy w środku są podobne: o nowa tablica GPT, n nowa partycja, t typ, c nazwa partycji, p podgląd, w zapis, q wyjście bez zapisu. Przy zapisie gdisk pyta jeszcze raz i krzyczy wielkimi literami:

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to g.img.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)

Zobacz: sam gdisk podpowiada partprobe. Narzędzia też wiedzą, że jądro bywa śpiące.

parted: bez menu, za to od razu

parted działa inaczej niż dwaj poprzednicy. Można go używać jedną linijką, bez menu, co jest idealne do skryptów. I uwaga, ważna różnica: parted zapisuje zmiany od razu, bez żadnego w. Nie ma kartki w pamięci. Jest długopis po ścianie.

Podgląd z wolnym miejscem, w jednostkach MiB:

sudo parted /dev/loop8 unit MiB print free
Partition Table: gpt
Number  Start    End      Size     File system  Name  Flags
        0.02MiB  1.00MiB  0.98MiB  Free Space
 1      1.00MiB  501MiB   500MiB
 2      501MiB   1525MiB  1024MiB                     lvm
        1525MiB  2048MiB  523MiB   Free Space

Zostało 523 MiB wolnego od 1525 MiB do końca. Robię tam trzecią partycję o nazwie kopie:

sudo parted -s /dev/loop8 mkpart kopie ext4 1525MiB 100%
sudo parted /dev/loop8 print
Number  Start   End     Size    File system  Name   Flags
 1      1049kB  525MB   524MB
 2      525MB   1599MB  1074MB                      lvm
 3      1599MB  2146MB  547MB                kopie

-s to tryb „script”, czyli nie zadawaj pytań. mkpart przyjmuje nazwę, typ systemu plików, początek i koniec. 100% znaczy „do końca dysku”. Słowo ext4 w mkpart to tylko podpowiedź dla typu partycji. parted nie formatuje. Regały stawiasz dalej przez mkfs.

Pułapka z jednostkami: parted domyślnie pokazuje MB, czyli miliony bajtów, a fdisk MiB, czyli potęgi dwójki. 500 MiB to 524 MB. Ten sam pokój, dwie różne miarki. Dlatego przy tworzeniu zawsze pisz jednostkę wprost: MiB albo GiB.

Partycja jest, to stawiamy regały:

sudo partprobe /dev/loop8
sudo mkfs.ext4 -q -L KOPIE /dev/loop8p3
sudo blkid /dev/loop8p3
/dev/loop8p3: LABEL="KOPIE" UUID="a694c353-a877-4681-b13f-855c71e1f462" BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="kopie" PARTUUID="5cd92bfb-ac3a-473f-8efd-d5ace7246411"

Popatrz na końcówkę. Są dwa identyfikatory. UUID należy do systemu plików i zmieni się, gdy zrobisz mkfs od nowa. PARTUUID i PARTLABEL należą do partycji w tablicy GPT i przeżyją formatowanie. Jak numer mieszkania i nazwisko lokatora: lokator się wyprowadzi, numer zostaje.

Jak to działa pod spodem

Dysk to dla jądra długa taśma sektorów po 512 bajtów, czasem po 4096. Partycja to po prostu zapis „od sektora 2048 do sektora 1026047”. Nic więcej. Żadnych ścian w środku, tylko liczby na planie.

Dlaczego pierwsza partycja zaczyna się od sektora 2048, a nie od 34? 2048 sektorów po 512 bajtów to dokładnie 1 MiB. Wszystkie nowe narzędzia wyrównują partycje do pełnego mebibajta, bo dyski SSD i macierze pracują dużymi blokami. Partycja zaczynająca się w połowie bloku to jak meblościanka postawiona tak, że każda szafka zahacza o dwa panele podłogi: działa, ale wszystko robi się dwa razy.

GPT na dysku wygląda tak: sektor 0 to ochronny MBR, sektor 1 to nagłówek GPT, sektory od 2 do 33 to tablica 128 wpisów, a na samym końcu dysku leży kopia tablicy i kopia nagłówka. Dlatego fdisk pisze, że ostatni użyteczny sektor to 4194270, a nie 4194303: ostatnie 33 sektory są zajęte przez zapasowy plan.

Kiedy piszesz w, narzędzie zapisuje tablicę na dysk i prosi jądro przez wywołanie ioctl, żeby wczytało ją ponownie. Jądro tworzy wtedy urządzenia sdb1, sdb2 i ich odpowiedniki w /dev. Jeśli jądro odmówi albo przegapi prośbę, masz to, co widzieliśmy: tablica na dysku jest, urządzeń nie ma. Wtedy partprobe.

Ściąga flag

KomendaFlaga / klawiszCo robi
fdisk-lwypisuje tablice partycji
fdisk (menu)g / onowa tablica GPT / MBR
fdisk (menu)nnowa partycja
fdisk (menu)ttyp partycji (aliasy: linux, lvm, swap)
fdisk (menu)dusuwa partycję
fdisk (menu)ppokazuje plan
fdisk (menu)w / qzapisz i wyjdź / wyjdź bez zapisu
gdisk-lwypisuje tablicę GPT
gdisk (menu)o, n, t, c, p, w, qnowa tablica, partycja, typ, nazwa, podgląd, zapis, wyjście
parted-stryb skryptowy, bez pytań
partedmklabel gpt / msdosnowa tablica GPT / MBR
partedmkpart NAZWA TYP OD DOnowa partycja (zapis od razu)
partedunit MiB print freeplan w MiB z wolnym miejscem
partedrm Nusuwa partycję N
partprobe-sprzeładowuje tablicę w jądrze i pokazuje podsumowanie
losetup-fP --show PLIKpodpina plik jako dysk i szuka partycji
losetup-d URZĄDZENIEodpina dysk z pliku

⚠ Typowy błąd

Zrobiłeś partycję, od razu chcesz założyć system plików:

sudo mkfs.ext4 /dev/loop9p1
mke2fs 1.47.0 (5-Feb-2023)
The file /dev/loop9p1 does not exist and no size was specified.

Komunikat brzmi groźnie, ale znaczy tylko: „nie ma takiego urządzenia”. Partycja jest w tablicy, ale jądro jeszcze jej nie wystawiło. Zamiast od razu robić drugą partycję albo restartować, sprawdź:

lsblk /dev/loop9
sudo partprobe /dev/loop9
lsblk /dev/loop9
NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop9   7:9    0   1G  0 loop
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
loop9       7:9    0    1G  0 loop
`-loop9p1 259:1    0  300M  0 part

I dopiero teraz mkfs. Druga wersja tego błędu jest gorsza: wpisujesz mkfs.ext4 /dev/sda1 zamiast /dev/sdb1, bo palec się omsknął. Wtedy żadna komenda nie pomoże. Dlatego przed każdym mkfs i fdisk patrzysz w lsblk: rozmiar, czy coś jest zamontowane, czy na pewno nowy dysk.

✎ Zadanie

Na maszynie wirtualnej dodaj drugi dysk 2 GB albo zrób go z pliku przez truncate i losetup -fP --show. Potem:

  1. W fdisk załóż tablicę GPT, partycję 1 o rozmiarze 500 MiB typu Linux filesystem i partycję 2 o rozmiarze 1 GiB typu Linux LVM. Zapisz.
  2. Resztę dysku zajmij jedną linijką parted jako partycję o nazwie kopie.
  3. Sprawdź wynik w lsblk, gdisk -l i parted ... unit MiB print free. Jeśli lsblk nie widzi partycji, użyj partprobe.
  4. Załóż ext4 z etykietą DANE na partycji 1 i zapisz sobie jej UUID z blkid. Przyda się w następnej lekcji.
Pokaż rozwiązanie

Mój „drugi dysk” to znowu plik, podpięty jako /dev/loop1. Ty masz /dev/sdb albo /dev/vdb.

sudo fdisk /dev/loop1        # g, n (+500M), n (+1G), t 2 lvm, w
sudo parted -s /dev/loop1 mkpart kopie ext4 1525MiB 100%
sudo partprobe /dev/loop1
lsblk -o NAME,SIZE,TYPE /dev/loop1
sudo parted /dev/loop1 unit MiB print free
sudo mkfs.ext4 -q -L DANE /dev/loop1p1
sudo blkid /dev/loop1p1
NAME       SIZE TYPE
loop1        2G loop
|-loop1p1  500M part
|-loop1p2    1G part
`-loop1p3  522M part

 1      1.00MiB  501MiB   500MiB
 2      501MiB   1525MiB  1024MiB                      lvm
 3      1525MiB  2047MiB  522MiB                kopie
        2047MiB  2048MiB  0.98MiB  Free Space

/dev/loop1p1: LABEL="DANE" UUID="3d211a77-05fd-4f40-af9e-a59e28329d1f" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="bba0b016-23b8-477d-8674-90aebdd64b03"

Zwróć uwagę na ostatnią linijkę parted: „do końca dysku”, czyli 100%, zostawiło jeszcze prawie megabajt wolnego. To nie błąd. Na końcu dysku GPT trzyma zapasowy plan, a parted wyrównuje partycje do pełnych mebibajtów. Okruszek, który zostaje na talerzu z grzeczności.

UUID z ostatniej linijki zapisz. Za chwilę wpiszemy go do najważniejszego pliku tej lekcji.

Co dalej

Mamy partycję, mamy na niej system plików, mamy UUID. Brakuje jednego: drzwi z korytarza do tego pokoju. W następnej lekcji montowanie: mount, umount, „device is busy”, findmnt i plik /etc/fstab, w którym jedna literówka potrafi nie wpuścić serwera do własnego domu.