Linux/Saját linux live CD készítése/ZFS root fájlrendszerű gép installálása
Ez a szócikk példa, hogyan használható a saját live CD. A ZFS root fájlrendszerű gép installálásán felül azt is ki akarjuk próbálni, hogyan alakítható át egy BIOS/mbr-ben partícionált gép UEFI/gpt-re. Nem célunk viszont belemélyedni a ZFS lehetőségeibe: nem készítünk RAID-et, dataset-eket is elsősorban a példa érdekében.
A gpt-re alakítás simán megy, kivéve azt az apróságot, hogy a gép bootolhatatlanná válik, újabb példával támasztva alá Murphy egyik számítástechnikai törvényét: igazán komoly kárt csak az admin tud tenni a saját gépében. Enyhítő körülmény, ha meg is tudja gyógyítani, amihez ZFS root fájlrendszerű gép esetén ZFS-t ismerő live/rescue CD kell.
Kiindulási helyzet
[szerkesztés]Üres (virtuális) gépen vagyunk, bebootoltunk a live CD-vel, bejelentkeztünk ssh-val. Van egy partícionálatlan üres diszkünk:
root@ZFS-live:~# cat /proc/partitions major minor #blocks name 11 0 518966 sr0 8 0 8388608 sda 7 0 490984 loop0
Partícionálás
[szerkesztés]Egy kissé zilált partíciós táblát készítünk a próba kedvéért:
Disk /dev/sda: 8 GiB, 8589934592 bytes, 16777216 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x146049cb Device Boot Start End Sectors Size Id Type /dev/sda1 2048 15362047 15360000 7.3G 83 Linux /dev/sda3 15362048 16777215 1415168 691M 5 Extended /dev/sda5 15364096 15978495 614400 300M 82 Linux swap / Solaris
A 2. partíció helyét szándékosan hagytuk ki. Az extended partíció minden maradék helyet elfoglal, de azon belül még lehetne partíciót létrehozni.
Meglennénk swap nélkül, amíg azt ZFS-ben létrehozzuk, de ha már van, használatba vesszük:
mkswap /dev/sda5
swapon /dev/sda5
free
total used free shared buff/cache available Mem: 1019716 32276 895288 1884 92152 869044 Swap: 307196 0 307196
Pool létrehozása
[szerkesztés]Először a poolt kell létrehozni: ez az a diszkterület, amivel a ZFS fájlrendszer gazdálkodik. Éles helyzetben RAID-es poolt hoznánk létre;[1] ettől itt az egyszerűség kedvéért eltekintünk.
modprobe zfs # a ZFS kernel-modulok nem toltodnek be automatikusan
zpool create -f -o ashift=12 \
-O atime=off -O canmount=off -O compression=lz4 -O normalization=formD \
-O devices=off -O mountpoint=/ -R /mnt \
helyi /dev/sda1
A pool neve helyi, a használt diszk a /dev/sda1. Az ashift=12
4096 (212) bájtos blokkméretet jelent. A -f
akkor is megcsinálja a poolt, ha egyébként csak figyelmeztetne valamilyen lehetséges hibára. A többi, -O
kapcsolóval megadott paraméter az automatikusan létrehozott dataset-re vonatkozik. (A dataset lényegében a fájlrendszer elnevezése a ZFS-terminológiában.) A létrejött datasetet nem fogjuk használni, de al-dataseteket hozunk majd létre benne, és azok – a root fájlrendszert is beleértve – örökölni fogják az itt beállított tulajdonságokat:
atime=off
: nem írja fel a fájlok utolsó hozzáférési dátumát. Ez jelentősen csökkenti a fájlrendszer írásterhelését, az elveszített információt pedig szinte sohasem használjuk.canmount=off
: a fájlrendszer nem mountolható. Csak arra használjuk, hogy al-fájlrendszereket hozzunk létre benne, melyekben ezt a paramétert majd módosítjuk.compression=lz4
: automatikus blokk-tömörítés lz4 algoritmussalnormalization=formD
: a fájlnevek UTF-8 kódolásúakdevices=off
: az eszközfájlok használata (olvasása) nem megengedett a fájlrendszerbenmountpoint=/
: a fájlrendszer csatolási pontja. A ZFS ezt nem a szokásos /etc/fstab-ban tartja, hanem magában a fájlrendszerben, mint annak egyik tulajdonságát. Ennek több következménye van:- a csatolási pontok ütközésének elkerülésére a ZFS csak üres könyvtárba tud fájlrendszert csatolni (ha a könyvtár nem létezik, létrehozza)
- két pool csatolási pontjainak ütközése a -R kapcsolóval kerülhető el: a pool valamennyi csatolási pontja ehhez a könyvtárhoz képest értendő. Ez esetben azért kell, mert a root fájlrendszer már foglalt – mint mindig, ha új root fájlrendszert hozunk létre.
Az eredmény ellenőrzése: zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT helyi 7.31G 324K 7.31G - 0% 0% 1.00x ONLINE /mnt
Datasetek létrehozása
[szerkesztés]A leendő tényleges root fájlrendszer:
zfs create -o canmount=on -o mountpoint=/ -o devices=on helyi/ROOT
A gyökér fájlrendszert nem a ROOT-ban, hanem az alatta levő datasetben szokás létrehozni. Ennek egyelőre linuxban nincs jelentősége.
A zfs -o
kapcsolója ugyanazokat a tulajdonságokat adja meg, mint a zpool -O
kapcsolója (a zpool -o
-ja a pool tulajdonsága, nem a dataseté).
Példaként három datasetet (al-fájlrendszert) hozunk létre. Éles rendszerben jobban szeparálnánk, annál is inkább, mert a ZFS-ben nemcsak a fájlrendszer jogosultságait, hanem a területének a méretét is ennek alapján lehet szabályozni. Külön dataset lehet pl.: /home, /var/log, /var/mail, /opt, stb. A /usr külön datasetbe tétele vitatható; e vitát itt most eldönti az a debian stretch bug, ami miatt a /usr/lib a gyökér fájlrendszerben kell legyen, egyébként a gép nem tud bootolni.
zfs create -o canmount=on -o setuid=off -o exec=off helyi/var
zfs create -o exec=on helyi/var/lib
zfs create -o canmount=on helyi/tmp
chmod 1777 /mnt/tmp
A /var fájlrendszerben nem megengedett a programvégrehajtás. A /var/lib visszakapja ezt a jogot, felülírva az öröklődést. A /var a tulajdonságait nem a ROOT, hanem a pool legfelső, névtelen datasetjétől örökli, vagyis eszközfájl nem használható /var-ban:
zfs get devices helyi/var
helyi/var devices off inherited from helyi
Ellenőrzés: zfs list
NAME USED AVAIL REFER MOUNTPOINT helyi 756K 7.08G 96K /mnt helyi/ROOT 96K 7.08G 96K /mnt helyi/tmp 96K 7.08G 96K /mnt/tmp helyi/var 192K 7.08G 96K /mnt/var helyi/var/lib 96K 7.08G 96K /mnt/var/lib
Debian installálás
[szerkesztés]Ezt már ismerjük a live CD előállításából. Gyorsabb, ha a live CD tartalmát másoljuk a leendő diszk fájlrendszerébe, mert abban van már ZFS és néhány más csomag és beállítás.
cd /media
mkdir p{1,2}
mount /dev/sr0 p1 -o ro
mount p1/live/filesystem.squashfs p2 -o ro # felcsatoltuk a live CD tartalmat /media/p2-re
rsync -a p2/* /mnt/ # atmasoljuk. Ellenoriztuk, nincs-e rejtett fajl p2-ben
mkdir /mnt/boot # a /boot mashol van a CD-n
cp -p p1/vmlinuz /mnt/`readlink /mnt/vmlinuz` # kernel masolas. initrd-t nem kell, mert ujra letrehozzuk
umount p2
umount p1 # lecsatoltuk a CD-tartalmat
rmdir p1 p2 # rendet teszunk magunk utan
# chroot elokeszites
mount /dev /mnt/dev --bind
mount /proc /mnt/proc --bind
mount /sys /mnt/sys --bind
chroot /mnt # beleptunk chroot-ba
export LC_ALL=C # ne nyafogjon az apt a magyar locale miatt
apt-get purge live-boot-initramfs-tools # a diszken nem kell live
apt-get autoremove # a live-hez tartozo, feleslegesse valt csomagok torlese
/etc/default/zfs-ben a kommentben levő ZFS_INITRD_ADDITIONAL_DATASETS paramétert erre állítsuk:
ZFS_INITRD_ADDITIONAL_DATASETS="helyi/var helyi/var/lib"
Erre azért van szükség, hogy a felsorolt két dataset a ROOT-tal együtt csatolódjék, még mielőtt a journald elkezdené írni a könyvtárakat. Ez esetben ui. már nem lennének üresek, és nem lehetne csatolni őket. A beállítást el kell magyarázni a grub-nak, és initrd-t generálni:
apt-get install zfs-initramfs # ZFS root-hoz kell
update-initramfs -u -t -k all # generaljuk initrd-t
apt-get install grub-pc # boot loader install BIOS módban. A grub-ot /dev/sda-ba rakatjuk, amikor megkerdezi.
apt-get clean
umount /proc /sys /dev
exit # kileptunk chroot-bol
zpool export helyi # lecsatoljuk ZFS-t
Bootolás, ellenőrzés
[szerkesztés]Leállítás, a live CD eltávolítása, bekapcsolás. A gépnek be kell bootolnia.
Ellenőrzések:
grub-probe / # a root fájlrendszer zfs
free # nincs swap
zfs list # a datasetek listája a helyfoglalással
zfs mount # a felcsatolt datasetek
zfs get compressratio -r helyi # a ZFS átlagos tömörítési aránya 1.8
systemctl list-unit-files --state enabled # a bootkor elinduló szolgáltatások listája
ip addr list # a hálókártyák és IP-címeik listája
Most kezdődik a konfigurálás és a szolgáltatások telepítése, de ez már túlnyúlik a szócikk keretein; egyedül a swap létrehozásával foglalkozunk.
A swap fájlrendszer nélküli diszkterület (raw disk), és ezt a ZFS-nek meg kell magyarázni. Ezeknek a területeknek – a ZFS fájlrendszerűekkel ellentétben – eszközfájljuk keletkezik /dev/zvol/poolnév/dataset néven, és a hagyományos módon, /etc/fstab-ban lehet őket kezelni. (Az így létrehozott területre nemcsak swap-ot, hanem akár a ZFS-től különböző fájlrendszert is lehet tenni. Ezt is tömöríti a ZFS, ha kérjük.)
A swapterület létrehozása:
zfs create -V 1G -b $(getconf PAGESIZE) -o compression=zle -o logbias=throughput \
-o sync=always -o primarycache=metadata -o secondarycache=none \
-o com.sun:auto-snapshot=false -o refreservation=200m helyi/swap
mkswap /dev/zvol/helyi/swap
swapon /dev/zvol/helyi/swap
free
A -V
jelzi, hogy raw diszket kell létrehozni, egyúttal a méretet is, mely a terület egyik tulajdonsága. Ez azt is jelenti, hogy a tulajdonság módosításával a swap mérete is változtatható (természetesen előbb a swap-ot le kell állítani, a méretváltoztatás után újra ki kell adni az mkswap
utasítást). A méret változtatása:
zfs set volsize=2500m
(A volsize
nem szerepelhet a -V
-vel együtt, mert ilyenkor az eredmény – nyilván a raw diszk mérete – kiszámíthatatlan.)
A refreservation=200m
200m helyet fenntart a swap számára a közös területből, és ha onnan elfogyott a hely, a swap számára még mindig van 200m. (Ez ZFS fájlrendszerek esetén is megtehető: így lehet a dataset minimális méretét szabályozni.)
Hogy a következő bootolás után automatikusan legyen swap, /etc/fstab-ba:
/dev/zvol/helyi/swap none swap sw 0 0 /dev/sda5 none swap sw 0 0
Konvertálás GPT-re
[szerkesztés]A dolog nagyon egyszerű. A gdisk automatikusan konvertálja a memóriában a beolvasott partíciós táblát, és w
-re diszkre írja.
A gdisk-et először fel kell installálni, célszerűen a parted-del együtt:
apt-get install gdisk parted
Ezt kaptuk a partíció gdisk-es módosítása után fdisk -l /dev/sda
-ra:
Disk /dev/sda: 8 GiB, 8589934592 bytes, 16777216 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: 504D36E2-3CE0-4A4B-B510-3F70F5B11F8A Device Start End Sectors Size Type /dev/sda1 2048 15362047 15360000 7.3G Linux filesystem /dev/sda5 15364096 15978495 614400 300M Linux swap
Az extended partíció eltűnt (ilyen nincs gpt-ben, hiszen felesleges). A rendszer működik partprobe /dev/sda
(a partíciós tábla kernelbe olvasása) után is, de nem bootol. Nem csoda: megszűnt az mbr, ahol a grub első fázisa volt, és eltűnt a partíciók közötti hely, ahol a grub második fázisa eddig hajléktalan módjára meghúzta magát.
A bootolhatatlan gép helyreállításának első lépése, hogy megpróbáljuk kézzel, grub-utasításokkal bootolni. Itt most ez szóba sem jön: a grub el sem indult.[2]
Bootolhatatlan gép javítása live CD-vel
[szerkesztés]Bebootoljuk a gépet a ZFS-tudó live CD-vel, és létrehozunk egy 10M méretű, 4-es típusú gpt-partíciót 2. partícióként a grub számára /dev/sda-n. Nem kell rá fájlrendszer. Most ilyen a partíciós tábla:
Device Start End Sectors Size Type /dev/sda1 2048 15362047 15360000 7.3G Linux filesystem /dev/sda2 15978496 15998975 20480 10M BIOS boot /dev/sda5 15364096 15978495 614400 300M Linux swap
Beimportáljuk a ZFS poolt, ezzel felmountoljuk a diszket /mnt-re:
zpool import -R /mnt helyi
A szokásos módon bemegyünk chroot-ba, és installáljuk a grub-ot:
grub-install /dev/sda
Ugyancsak a szokásos módon kilépünk chroot-ból, és exportáljuk a poolt:
zpool export helyi
A gép most már diszkről is bootol: a live CD-vel megjavítottunk egy bootolhatatlan gépet.
Még egy próba
[szerkesztés]Ha megér még egy próbát, nullázzuk ki a 2-es partíció elejét:
dd if=/dev/zero of=/dev/sda2 bs=1024 count=1024
Próbáljunk bootolni: nem sikerül. Tényleg ide került a grub.
Bootoljunk live CD-vel, hozzunk létre egy 6. partíciót 4-es típussal, a kinullázott 2. partíció típusát változtassuk meg, pl. 1-re (EFI System[3]):
Device Start End Sectors Size Type /dev/sda1 2048 15362047 15360000 7.3G Linux filesystem /dev/sda2 15978496 15998975 20480 10M EFI System /dev/sda5 15364096 15978495 614400 300M Linux swap /dev/sda6 15998976 16019455 20480 10M BIOS boot
Installáljuk a grubot a fenti módon: a gép bootolni fog, miközben a 2. partícióban továbbra is 0-k vannak:
hexdump -C /dev/sda2
Most már talán elhihetjük, hogy akárhol hozzuk is létre a BIOS boot partíciót, a grub bele tud települni, és bootolható lesz a gépünk. Ez fontos, ha éles gépen tervezzük a fenti akciót. (Azért mindenképpen mentsünk előtte, mert a gpt→mbr irány jóval macerásabb.)
Jegyzetek
[szerkesztés]- ↑ Hacsak a diszk maga már nem hardver RAID, pl. SAN-terület.
- ↑ A második lépés a live/rescue CD, a harmadik a visszatöltés mentésből. Ez utóbbit kerüljük, hiszen az utolsó mentéstől a visszatöltésig keletkezett/módosult adatok elvesznek.
- ↑ Önmagában ez még nem teszi UEFI-módban bootolhatóvá a gépet.