Filosofický přesah dnešního zamyšlení se nad linuxovým stěhováním ten technický předčí hned v několika ohledech. Protože technicky vlastně není moc o čem vyprávět, všechno je už perfektně zdokumentované, ale zkrátka nezbývá než žasnout nad tím, že všechna trápení jsou vlastně jen v hlavě dosáhnout se dá čehokoliv, pokud je člověk nebo kocour dostatečně odvážný a není svým způsobem líný. A popravdě bych chtěl vidět naše anúbisy, jak by něco takového provedli s Windows, kdyby na to nedostali celý týden.
Provozovat si vlastní domácí server je jako starat se o Théseovu loď. Musí to běžet pořád, plout v moři proti pirátům a sem tam v přístavech nebo na ostrovech doplnit nějaký ten pamlsek na vylepšení a neustálý vývoj, aby bylo všechno hezky aktuální i po té hardwarové stránce. I přes některé objektivní potíže si – a hlavně díky zápisku – vzpomínám, jak probíhal přechod jednoho z prvních pokusů na konečně stabilní zázemí, kterak se v honbě za tichostí a energetickou nenáročností na zeleném koberci spolu s oranžovým emulgátorem skvěly malé, 2.5" notebookové disky, které byly po dlouhé éře IDE kabelů konečně připojeny elegantními SATA linkami na vlastní řadič, a to hezky v klícce pohlcující nadbytečné rázové vibrace. Už jen z toho možná vyplývá, že vlastně všechny technologické novinky jsou poplatné pouze své vlastní době a budou dříve nebo později stejně nakonec nahrazeny jiným (zejména myšlenkovým) principem.
Současná situace teď tak nějak dospěla do fáze, která si vyžádala kompletní přesun systémové instalace na jiný fyzický disk, než aby to dopadlo nějak špatně. Důvodem bude zřejmě souběh několika faktorů, přičemž se můžu vymlouvat, že zkrátka nemám čas pořádně provést diagnostiku. Jedním z nich bude zřejmě hardwarový problém v CPU cache, možná jen špatně nasazené či poškozené RAM, nebo je to taky tím, že se neustále někde vyhrožuje vyřazením JFS z jádra. Všechno začalo tím, že se nejdříve v logu suše objevilo ERROR: (device dm-2): txCommit [jfs]:
a nic víc, pak se z nějakého důvodu připojil datový svazek pouze ke čtení, nu a naposledy vše vyvrcholilo tím, že se systém prostě zahryzl bez jakéhokoliv hlášení, což by mohlo být tím, že totéž stalo s kořenem. Nevím nic, ale už je zatraceně nejvyšší čas na... novou instalaci? Nebo prostě nějaký nenáročný přesun, který by zohlednil celosystémové nasazení SSD s dynamickým swapováním a vůbec to hodil do něčeho, co je trendy v tomhle desetiletí. Což teď jsou souborové systémy kombinované přímo se správou svazků a kontrolním sčítáním a CoW a tak, jako jsou třeba APFS a Btrfs.
Předtím, tedy skoro před 15 lety, to bylo LVM. Někdy i v kombinaci s mdraid. To umožnilo velmi různé fyzické disky a jejich oddíly členit do ucelených logických svazků a teprve nad nimi tvořit souborové systémy. Bylo to legrační. Migrace systému na točivých discích se provedla klonováním, pak se upravila UUIDčka a pokud byl nový disk větší, na volném místě se vytvořily oddíly, které se prostě a jednoduše přidaly do již existujícího logického svazku. Žádná věda, jen ti bylo trochu krkolomné. Problematické na tom je ale to, že tyto logické svazky mají pevně danou velikost a nemohou se překrývat, pokud by to bylo zrovna nezbytně nutné. Naproti tomu ty moderní souborové systémy umí vytvářet vlastní podsvazky, které prostor s nadřazeným svazkem jednoduše sdílí – a když vezmeme v úvahu, že pro SSD není případná fragmentace vlastně žádný významný problém, je to jasná volba. Stávající systém byl sice taky na SSD, ale prostě se na něj jen migrovalo z malého točivého disku na větší točivý disk a z většího točivého disku na SSD – výsledkem byly tři logické oddíly, nad kterými byly definovány třetiny logických svazků pro LVM. Nic moc, už jen z hlediska opotřebení a možných skrytých chyb kdesi hluboko v historii.
Proces je víceméně přímočarý a nezabral víc jak půl hodiny se vším všudy. Náhradní disk stejné třídy přišel do USB3 rámečku a připojil se jako nové blokové zařízení k běžícímu systému. Toliko to dává smysl. Bylo nutné zvážit vlastně jedinou věc, a to jak to udělat se zaváděním systému. Ačkoliv se deska tváří, že umí UEFI, zůstalo vše u starého způsobu a disk dostal novou MBR tabulku se dvěma primárními oddíly, řekněmě sde1
pro /boot
a sde2
pro zbytek systému se vším všudy. Je to hlavně kvůli tomu, že se mi nepozdávalo mít příznak zavádění na celém disku.
Tak s oddílem pro /boot
je to pro začátek dost jednoduché, bude v klidu použít Ext4.
# mkfs.ext4 -L server-boot /dev/sde1
A nad celým druhým oddílem bude vytvořen hlavní svazek btrfs, ve kterém teprve vznikne všechno ostatní.
# mkfs.btrfs -L server-rootvol /dev/sde2
Tím proběhne vytvoření hlavního souborového systému, který bude použit pro podsvazky a víceméně nic jiného na něm nebude. Příkaz pro vytvoření pak především provede výpis s novým UUID tohoto hlavního svazku, které pak bude používáno pro mapování podsvazků. Aby se daly podsvazky vytvořit, ten hlavní je teď potřeba dočasně připojit – mkdir /tmp/disk-main
, # mount /dev/sde2 /tmp/disk-main
, cd /dev/disk-main
. Tam je zatím čisto, podsvazky se budou jevit jako adresáře, které je zvykem prefixovat zavináčkem. V závislosti na konkrétních potřebách je možné pak vyrobit vlastní strukturu, základem bude rozhodně kořen /
, pojmenovaný @rootfs
/tmp/disk-main# btrfs subvolume create @rootfs
a cokoliv dalšího obdobně, třeba pro /home
/tmp/disk-main# btrfs subvolume create @homes
a pak klidně i /var
a další; rozhodně zajímavé, ač to zní zatím nepravděpodobně, je vytvoření podsvazku pro swap
, který samozřejmě potřebuje mít vlastní formát a nemůže fyzicky být přímo na btrfs, ale jeho umístění v subsvazku umožní využít výhody rozprostření po SSD, prozatím jako
/tmp/disk-main# btrfs subvolume create @swap
Tím je všechno zhruba předpřipraveno a je možné začít postupně migrovat data. Tedy, nejprve se hlavní svazek odpojí – # umount /tmp/disk-main
– a vytvoří se taková ta základní kostra, aby bylo možné začít chrlit. Tak nejdřív kořen systému
# mkdir /tmp/disk && mount -o subvol=@rootfs /dev/sde2 /tmp/disk
a postupně do něj manuálně všechny externí záležitosti, o kterých tu byla řeč, takže postupně
# mkdir /tmp/disk/{boot,home,swap,var}
s následnými připojeními odpovídajících souborových systémů, tedy postupně
/tmp# mount /dev/sde1 disk/boot
/tmp# mount -o subvol=@homes /dev/sde2 disk/home
/tmp# mount -o subvol=@var /dev/sde2 disk/var
/tmp# mount -o subvol=@swap /dev/sde2 disk/swap
to by mělo správně projít a struktura se začne skvěle rýsovat.
/tmp/disk# ls -la
celkem 5
drwxr-xr-x 1 root root 30 2. úno 19.00 .
drwxrwxrwt 11 root root 1024 2. úno 18.55 ..
drwxr-xr-x 3 root root 4096 2. úno 18.53 boot
drwxr-xr-x 1 root root 0 2. úno 18.59 home
drwxr-xr-x 1 root root 16 2. úno 19.01 swap
drwxr-xr-x 1 root root 0 2. úno 18.59 var
Co tedy dále přesně s tím swapem? V první řadě je potřeba ho vyjmout z CoW mechanismu btrfs, to je možné nastavení atributu +C
, který ale funguje jen na soubory s nulovou délkou. Alternativně by se pak celý podsvazek, který stejně bude obsahovat pouze swapovací soubor, dal připojit s volbou nodatacow, fungovalo by to zhruba stejně. Jakmile bude soubor takto vytvořen, je možné ho inicializovat – naplnit doslova prázdnem o požadované délce, v tomto konkrétním případě na 16 GB. Velikost swapu je vždycky otázka, tak to tu bude pouze jako příklad.
/tmp# touch disk/swap/swapfile
/tmp# chattr +C disk/swap/swapfile
/tmp# dd if=/dev/zero of=disk/swap/swapfile bs=1M count=16384
Vytvoření potrvá (díky bs=1M) asi nějakou chvíli. Tento soubor musí mít odpovídající přístupová práva pro čtení a zápis pouze vlastníkem, jinak bude vytvoření swapu prskat. Samotné vytvoření se provede jako nad jakýmkoliv jiným zařízením pomocí mkswap, čímž bude zkrátka vytvořen swapovací systém v jednom souboru.
/tmp# chmod 0600 disk/swap/swapfile
/tmp# mkswap disk/swap/swapfile
Fungování se dá ověřit pomocí swapon /tmp/disk/swap/swapfile
, tím. by mělo swapovací místo odpovídajícím způsobem na stávajícím systému narůst, nicméně žádný praktický účel to nemá. A protože je už vše připraveno, je možné začít migrovat celý živý systém na nový disk. Nejlépe pomocí rsync s tím, že budou vyloučena speciální umístění a vřele ještě doporučuji flag velké -A
, který se soubory přenese i jejich ACL, což se ve výchozím stavu neděje. Pak je dále nutné vyloučená umístění vytvořit jako přípojné body pro nový systém, plus nastavit odpovídající oprávnění pro /tmp
.
/tmp/disk# rsync -aA / ./ --exclude dev --exclude proc --exclude sys --exclude run --exclude tmp
/tmp/disk# mkdir {dev,proc,sys,run,tmp}
/tmp/disk# chmod a+rwxt tmp
Samotné zkopírování systému ale samozřejmě nestačí, bude potřeba udělat ještě několik změn – především upravit nová umístění a pořádně přegenerovat novou konfiguraci a instalaci pro GRUB. Aby se to dalo poměrně snadno zařídit přes chrootnuté prostředí, musí z něj být nový disk dohledatelný, to znamená, že musí existovat připojené /dev
z existujícího systému, ale ne nutně z toho, co se právě zmigrovalo. K tomu se hodí bind mount, který prakticky nabídne alternativní pohled do připojeného stromu z jiného místa. V tomto případě se do vytvořené struktury promítne aktuální strom zařízení.
/tmp/disk# mount --bind /dev/ ./dev/
Pak už je to poměrně jednoduché. Po chrootnutí bude nutné přepsat /etc/fstab
na nové hodnoty (a ideálně podle UUID a ne podle názvu zařízení) a pak přeinstalovat ten divoký GRUB.
/tmp/disk# chroot .
Vytvořená UUID budou podle předchozího příkladu pouze dvě, dalo by se to zjednodušit výpisem pouze pro tento připojený disk.
/# blkid | grep sde
/dev/sde2: LABEL="server-rootvol" UUID="2e79fa7e-d377-42f5-9d5d-d6560cdd1620" UUID_SUB="59a00b42-4570-45da-a4f8-b7e8b02c569b" BLOCK_SIZE="4096" TYPE="btrfs" PARTUUID="277f206b-02"
/dev/sde1: LABEL="server-boot" UUID="3ed69fe6-3ceb-4011-b269-acadd4f8bb5e" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="277f206b-01"
Získané údaje přijdou v první řadě do /etc/fstab
tak, aby odpovídající pododdíly reflektovaly správná připojení. Daný swap si nejprve přimountuje svůj pododdíl a teprve pak se připojí jako soubor pro swapování. V tomto případě tady uvádím i poněkud nadbytečnou specifikaci nodatacow, ale alespoň to bude zajištěné.
# cat /etc/fstab
UUID=3ed69fe6-3ceb-4011-b269-acadd4f8bb5e /boot ext4 defaults 0 2
UUID=2e79fa7e-d377-42f5-9d5d-d6560cdd1620 / btrfs subvol=@rootfs,defaults,ssd_spread,discard=async 0 1
UUID=2e79fa7e-d377-42f5-9d5d-d6560cdd1620 /home btrfs subvol=@homes,defaults,ssd_spread,discard=async 0 2
UUID=2e79fa7e-d377-42f5-9d5d-d6560cdd1620 /var btrfs subvol=@var,defaults,ssd_spread,discard=async 0 2
UUID=2e79fa7e-d377-42f5-9d5d-d6560cdd1620 /swap btrfs subvol=@swap,nodatacow,ssd_spread,discard=async 0 0
/swap/swapfile none swap sw 0 0
Zapsáno, pohodka, teď ten ten systém. V první řadě initrd. Pokud se požívalo RESUME, bude potřeba novou cestu ke swapu zapsat i do /etc/initramfs-tools/conf.d/resume
, pak už by mělo stačit jen vygenerovat novou konfiguraci pro GRUB a samotný GRUB i nainstalovat.
/# grub-mkconfig -o boot/grub/grub.cfg
/# grub-install /dev/sde
Vše je hotovo, servis. Počítač se může s klidem vypnout, disk se přehodí namísto stávajícího, který bude pro případy nejvyšší potřeby ještě nějakou dobu uložen v pelíšku, a po začarování nového startu by měl naskočit z nového btrfs jako kamzíček a dělat zase radost. Opravdu bych chtěl vidět dělat někoho podobný proces na Windows, linuxová stěhování jsou proti tomu opravdu snadná a vyžadují jen patřičné mentální nastavení a ochotu. A tak to snad půjde dál, i kdyby budoucnost přinesla něco opravdu epického.