Portál AbcLinuxu, 31. července 2026 19:57

Jak zjistit, v čem se liší dva ramdisky

dnes 17:05 | Přečteno: 136× | Za vším hledej Linux | poslední úprava: dnes 17:07

Když "apt" aktualizuje systém, čas od času během instalace přegeneruje ramdisk, aby se do něj dostal aktuální firmware, nebo skript. Je to banální operace, která drtivé většině uživatelů nemusí vrtat hlavou. Ale u disklessové infrastruktury, kde se používá jeden a ten samý ramdisk pro desítky strojů, v nejrůznějších konstelacích, je důležité vědět co se změnilo.

Kupř. loni touhle dobou jsem dostal zadání: „Otestuj tenhle all-in-one, jestli na něm bude fungovat náš linux.”

Nevím, jak se takové zadání bude jednou řešit pomocí AI, ale bylo potřeba vybalit stroj z krabice, zapojit všechny kabely – včetně ethernetového co čumí do laboratorní sítě – a nabootovat přes PXE UEFI, které si stahuje soubor grubnetx64.efi.signed. Většinou s tím problém není, ale tentokrát obrazovka zčernala a zůstala černá.

Už jednou jsme na to narazili a to když jsme přecházeli z legacy PXE na UEFI PXE boot. Zavaděč už byl prostě moc starý. Ale řešení je prosté – stačí ten stahovaný soubor nahradit novější verzí, kterou si lze vylovit z debianího balíku grub-efi-amd64-signed a při opakovaném pokusu už se menu zavaděče objevilo.

Ale během zavádění obrazovka opět zčernala. Bylo jasné, že v ramdisku chybí ovladač pro grafiku. Jenže nebylo možné zjistit jaký modul se má do ramdisku přidat, protože systém zůstal viset v konzoli a síť byla nedostupná.

Nebylo tedy možné zjistit, jaký ovladač a firmware tomu chybí. Tak jsem nabootoval live Ubuntu, abych zjistil jaký ovladač se používá, doplnil vše požadované do disklessového ramdisku a pak už ten systém bez problému najel. Linux tedy fungoval a tak se ty all-in-one stroje nakoupily do počítačové učebny A 420.

Jenže ouha! Počátkem semestru se ukázal ještě jeden problém se kterým nikdo nepočítal, poněvadž v zadání nebyl požadavek, aby se otestoval také HDMI výstup. Ty stroje totiž mají pouze jeden HDMI port, který může fungovat buď jako vstup, nebo jako výstup. Přepíná se to tlačítkem, jenže se ukázalo, že se to přepínání neřeší na straně HW, ale OS. Ty stroje přišly s MS Windows 11, které šly obratem do háje ale jeden kus zůstal coby záložní a v něm to přepínání fungovalo.

Zjistil jsem že ovladač používá starší firmware, který to tlačítko obsluhovat neumí, což by vyřešila aktualizace jádra. Ale to by spustilo celý řetěz následných aktualizací, na které už nebyl čas. A také to nebyl jenom náš problém, protože linuxový systém katedry počítačů byl na tom úplně stejně. Takže se na učitelské místo strčil jiný stroj ke kterému se píchnul projektor a bylo minimálně na čtvrt roku po problému.

Porovnávání různých verzí ramdisků

Tím obšírným úvodem jsem chtěl ukázat, že se klíčové problémy disklessové infrastruktury obvykle řeší v prostředí ramdisku, do kterého musíte modifikované soubory a moduly dostat dřív, než v něm zůstaně nějaký stroj viset.

Náš diskless má tzv. dynamický ramdisk, který obsahuje pouze dva klíčové skripty, protože zbytek stahuje už na základě konfigurace. Jeden se stará o nahození wifi a druhý tu konfiguraci stahuje a zpracovává. V ní je uvedeno z čeho se má složit finální sendvič a jak ten systém bude vypadat.

Ty testovací verze se odlišují sufixem. Pokud jádro zpanikaří, pošlu system_reset přes monitorovací konzoli a najede ramdisk stávající, který funguje. Otestovaná verze ramdisku pak nahradí v konfiguraci tu původní.

Čas od času je ale potřeba porovnat změny, protože se ty úpravy dělají v overlayi, který se při restartu zahodí – zůstane jen nová verze ramdisku odeslaná do úložiště. A taky se může stát, že systém zůstane viset kvůli chybě v konfiguraci. Proto mám pomocné skripty s ukecanou nápovědou přes které spouštím i následující sekvence.

Nástroje, které obsahuje základní vrstva CLI

Na unixových systémech se mi líbí právě to, že se dá pomocí jednoduchých nástrojů relativně snadno a rychle vyřešit vše. A právě ty obsahuje sendvičová vrstva CLI která má momentálně cca 1,8G.

Je základní systém bez X serveru, jaký si nainstalujete pomocí debootstrapu, rozšířený o jádro a nejrůznější diagnostické nástroje, s nimiž lze pracovat přes SSH.

A ke zjišťování rozdílů lze použít tyto:

vbindiff

Lze použít k rychlému vizuálnímu binárnímu srovnání dvou souborů s různými jmény, ale stejným obsahem. Jenomže sestavený ramdisk není totéž co linuxové jádro. A v případě ramdisku mohou být dvě verze s různými jmény, i když obsahově identické, binárně zcela odlišné – bez ohledu na to, že byly obě sestaveny z identických souborů.

diff

Pokud tedy chceme zjistit v čem se liší, je nutné jejich obsah vybalit a teprve pak můžeme zjišťovat v čem se liší. Tím, v čem se ty ramdisky liší a jakým způsobem se dají balit a rozbalovat se teď nebudu zdržovat, protože je to na samostatný blogpost. A konec konců se na to můžete zeptat AI. Jenom bych si dejte pozor na to, abyste při extrakci souborů ze cpio archivů nezapomněli přidat parametr -m, který zajistí, že u nich bude zachován původní čas vytvoření.

Také se se vám může hodit sjednocení času vytvoření všech podadresářů, protože ty se zakládají těsně předtím než do nich cpio provede extrakci souboru. Použít můžete buď časové razítko (timestamp):

guest@lab-dc:~/ramdisk$ find . -type d  -exec touch -d @1758967685 {} +

Nebo některý z podadresářů vybaleného verze se kterou to hodláte porovnat.

guest@lab-dc:~/ramdisk$ find . -type d  -exec touch -d "$(date -R -r A/scripts )" {} +

Pak na ty adresáře můžete poštvat diff s parametrem -r a prožeňte to přes less:

guest@lab-dc:~/ramdisk$ diff -r A/ B/ | less

colordiff

Pokud terminál podporuje barvičky je lepší použít colordiff a za less přidat parametr aby zůstaly zachovány:

guest@lab-dc:~/ramdisk$ colordiff -r A/ B/ | less -R

wdiff

Použitelný je také wdiff.

Ten porovnává soubory, takže se mu místo adresářů předhodí výstupy z ls, zpracované pomocí awku tak, aby se před vypsané parametry souborů vložila i cesta adresáře ve kterém se nachází:

guest@lab-dc:~/ramdisk$ wdiff <(cd A/; ls -Ralr | awk '
   /:$/&&f{s=$0;f=0}
   /:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
   NF&&f{ print s"/"$0 }') <(cd B/; ls -Ralr | awk '
   /:$/&&f{s=$0;f=0}
   /:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
   NF&&f{ print s"/"$0 }')

Je výhodný pokud mne zajímají pouze změny na úrovni jednoho konkrétního adresáře, např. scripts. Pak není potřeba '''awk'''. Stačí použít:

guest@lab-dc:~/ramdisk$ wdiff <(cd A/scripts; ls -alrt) <(cd B/scripts; ls -alrt)

Výhodné je, že se dá výstup podle potřeby dál filtrovat přes grep

  1. .. | grep ^\\[ zobrazí co u ramdisku B chybí
  2. .. | grep ^\\{ vyfiltruje pro změnu to co přebývá
  3. A kolona .. | grep -v \\.$ | grep -v \/dr vykopne z výstupu všechny adresáře, včetně řádků co končí tečkou.

A pokud máme rádi barvičky, můžeme si nakonec přes colordiff ten výstup obarvit.

Testoval jsem i jiné alternativy

ccdiff funguje stejně jako klasický diff jehož výstup proženeme přes colordiff

dwdiff funguje stejně jako wdiff, jen s tím rozdílem, že k obarvení výstupu nepotřebuje colordiff, protože má implementovaný parametr -c, při jehož použití na výstupu vynechá syntaktické značky a použije pouze barvy.

diffoscope mne upřímně řečeno vyděsil svými závislostmi ještě než jsem ho nainstaloval, neboť zcela v duchu dnešní doby vyžaduje instalovanou kdejakou kravinu. A že jich už v té naší instalaci máme. Už se mi totiž fakt hodně dlouho nestalo, že by nějaká aplikace kvůli závislostem chtěla doinstalovat dalších 450MB zbytečného smetí. A jak se ukázalo, že také užvaněná a brutálně pomalá.

Ke srovnání jsem použil utilitu '''tardiff''', která umí porovnat obsah dvou tarovaných archívů:

guest@lab-dc:~/ramdisk$ ls -alh *tar
-rw-rw-r-- 1 guest guest 342M Jul 30 10:46 A.tar
-rw-rw-r-- 1 guest guest 342M Jul 30 11:31 B.tar
guest@lab-dc:~/ramdisk$ time tardiff A.tar B.tar 
- scripts/nfs

real    0m1.958s
user    0m0.453s
sys     0m1.330s
guest@lab-dc:~/ramdisk$ time tardiff -m A.tar B.tar 
- scripts/nfs
/ usr/lib/systemd/network/99-default.link

real    0m12.104s
user    0m9.539s
sys     0m2.428s

Pak jsem na to pustil diffoscope. Zpočátku se nic nedělo, pak to začalo něco dělat ale pak to vyjelo výpis, který bych musel prohnat přes less, abych zjistil kde jsou změny.

guest@lab-dc:~/ramdisk$ time diffoscope A.tar B.tar 
 |                           |    0%                             ETA:  --:--:-- 
..
│   --- A/conf/initramfs.conf
├── +++ B/conf/initramfs.conf
│┄ Files identical despite different names

real    1m44.701s
user    1m27.010s
sys     0m6.836s

Tak jsem jen tak pro zajímavost prohnal výpisy co vrací tar přes sed a porovnal je přes wdiff:

guest@lab-dc:~/ramdisk$ time wdiff <(tar -tvf A.tar | sed s_A/__) <(tar -tvf B.tar | sed s_B/__) | grep -v ^\[[:alnum:]]

[-scripts/nfs-]

real    0m0.165s
user    0m0.055s
sys     0m0.111s
guest@lab-dc:~/ramdisk$ time wdiff <(tar -tvf A.tar | sed s_A/__) <(tar -tvf B.tar | sed s_B/__) | colordiff
..
-rw-r--r-- guest/guest       16 2026-07-30 [-09:01-] {+09:02+} conf/arch.conf
lrwxrwxrwx guest/guest        0 2026-07-30 [-09:01-] {+09:02+} bin -> usr/bin

real    0m0.430s
user    0m0.148s
sys     0m0.331s

Ale vizualizaci rozdílů mezi dvěma adresáři dělá diffoscope pěknou:

guest@lab-dc:~/ramdisk$ time diffoscope A/ B/
..
│   --- A/var
├── +++ B/var
│ │   --- A/var/cache
│ ├── +++ B/var/cache
│ │ │   --- A/var/cache/fontconfig
│ │ ├── +++ B/var/cache/fontconfig
│ │ │ │   --- A/var/cache/fontconfig/0bd3dc0958fa2205aaaa8ebb13e2872b-le64.cache-9
│ │ │ ├── +++ B/var/cache/fontconfig/0bd3dc0958fa2205aaaa8ebb13e2872b-le64.cache-9
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 2712         Blocks: 8          IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000
│ │ │ │   --- A/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64.cache-9
│ │ │ ├── +++ B/var/cache/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64.cache-9
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 5768         Blocks: 16         IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000
│ │ │ │   --- A/var/cache/fontconfig/4c599c202bc5c08e2d34565a40eac3b2-le64.cache-9
│ │ │ ├── +++ B/var/cache/fontconfig/4c599c202bc5c08e2d34565a40eac3b2-le64.cache-9
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 104          Blocks: 8          IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000
│ │ │ │   --- A/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-le64.cache-9
│ │ │ ├── +++ B/var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-le64.cache-9
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 200          Blocks: 8          IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000
│ │ │ │   --- A/var/cache/fontconfig/CACHEDIR.TAG
│ │ │ ├── +++ B/var/cache/fontconfig/CACHEDIR.TAG
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 200          Blocks: 8          IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000
│ │ │ │   --- A/var/cache/fontconfig/d589a48862398ed80a3d6066f4f56f4c-le64.cache-9
│ │ │ ├── +++ B/var/cache/fontconfig/d589a48862398ed80a3d6066f4f56f4c-le64.cache-9
│ │ │ │ ├── stat {}
│ │ │ │ │ @@ -1,8 +1,8 @@
│ │ │ │ │  
│ │ │ │ │    Size: 3280         Blocks: 8          IO Block: 4096   regular file
│ │ │ │ │  Device: 0,30 Links: 1
│ │ │ │ │  Access: (0644/-rw-r--r--)  Uid: ( 1000/   guest)   Gid: ( 1000/   guest)
│ │ │ │ │  
│ │ │ │ │ +Modify: 2026-07-30 09:02:10.502477123 +0000
│ │ │ │ │ -Modify: 2026-07-29 14:12:00.000000000 +0000

real    3m56.302s
user    1m40.016s
sys     1m16.160s

Ovšem na můj vkus nekonečně dlouho, na to že jsou ty soubory v RAM. Ostatně, posuďte sami:

guest@lab-dc:~/ramdisk$ time wdiff <(cd A/; ls -Ralr | awk '
   /:$/&&f{s=$0;f=0}
   /:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
   NF&&f{ print s"/"$0 }') <(cd B/; ls -Ralr | awk '
   /:$/&&f{s=$0;f=0}
   /:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
   NF&&f{ print s"/"$0 }') | grep -v \\.$ | grep -v \/dr | colordiff
..
./conf/total 12
./conf/-rw-r--r-- 1 guest guest   19 Jul [-29 14:10-] {+30 09:02+} modules
./conf/-rw-r--r-- 1 guest guest 1583 [-Jun 10 13:58-] {+Jul 30 09:02+} initramfs.conf
./conf/drwxr-xr-x 2 guest guest   40 Jul 31 11:11 conf.d
./conf/-rw-r--r-- 1 guest guest   16 Jul [-29 14:10-] {+30 09:02+} arch.conf
./conf/conf.d/total 0

real    0m0.832s
user    0m0.170s
sys     0m0.330s
guest@lab-dc:~/ramdisk$ time colordiff -r A/ B/
..
Only in A/usr/lib/modules/6.12.95+deb13-amd64/kernel: net
Only in A/usr/lib/modules/6.12.95+deb13-amd64/kernel: virt

real    0m1.779s
user    0m0.432s
sys     0m1.252s
       

Hodnocení: -

zatím nehodnoceno
        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.