Initrd w Slackware

W Slackware jest tylko małe howto o initrd, trochę więcej jest w manualu, ale reszta jest już owiana tajemnicą 🙂

Przestawiłem się pełnego kernela (w zasadzie zawsze kompilowanego przeze mnie) na minimalne z initrd ładnych kilka lat temu. Od tego czasu wiele się nauczyłem o initrd, czasem w dosyć bolesny sposób 🙂

Dlatego tym razem opiszę swoją wersję radzenia sobie z initrd (trochę inną niż w manie i oficjalnym readme).

Instalacja

W czasie instalacji Slackware potrzebne są następujące pakiety:

  • kernel-generic (ale nie kernel-huge!)
  • kernel-modules
  • mkinitd

i oczywiście inne pakiety jakie lubi się mieć 🙂
Należy pamiętać, żeby NIE instalować pakietu kernel-huge.

Trzeba zainstalować wszystko jak zwykle, przejść przez ustawienia Lilo, stref czasowych itd. Na koniec NIE robimy reboota, bo to jeszcze nie koniec!

Teraz nadszedł czas na przygotowanie nowego initrd.

  1. Robimy chroot do /mnt (tam cały nowy system powinien być nadal zamontowany)
  2. Robimy kopię domyślnej konfiguracji mkinitrd: cp /etc/mkinitrd.conf.sample /etc/mkinitrd.conf
  3. Edytujemy /etc/mkinitrd.conf ulubionym edytorem i ustawiamy kilka zmiennych/opcji:
    • odkomentowujemy i ustawiamy MODULE_LIST i ROOTFS na typ filesystemu użytego jako nasz root, na przykład: ROOTFS="ext3"
      MODULE_LIST="ext3"
      Nie należy martwić się o moduły zależne, bo te zostaną dodane automatycznie.
    • jeżeli używamy softwarowego raida, to odkomentowujemy i ustawiamy RAID="1"
    • jeżeli używamy LVM-a lub szyfrowania, to trzeba odkomentować LVM="1"
    • zalecam również nadać dla SOURCE_TREE i OUTPUT_IMAGE jakieś unikalne nazwy, np. SOURCE_TREE="/boot/initrd-tree-3.10.12"
      OUTPUT_IMAGE="/boot/initrd-3.10.12.gz"
      Nie trzeba tego robić jeżeli nigdy nie będziesz się bawił z innymi kernelami niż ten z dystrybucji.
  4. Wygenerować nowe initrd przez: mkinitrd -F
  5. Dodać nowe initrd do lilo.conf tuż po linijce z nazwą kernela (zaczynającą się od image=), czyli żeby wyglądało to jakoś tak: image = /boot/vmlinuz-generic-3.10.12
    initrd = /boot/initrd-3.10.12.gz
  6. Wyjść z chroot-a i zainstalować jeszcze raz lilo z nowym konfigiem:mount --bind /dev /mnt/dev
    mount --bind /proc /mnt/proc
    lilo -r /mnt

Teraz już można przeładować system i cieszyć się ze Slackware z initrd:-)

Jaka jest zaleta tego sposobu w porównaniu do ręcznego odpalenia mkinitrd z mnóstwem dziwnych opcji? Myślę, że będzie to widać w dalszej części.

Utrzymanie systemu

Czasami przychodzi taki moment, gdy zmienimy kernel, coś uaktualnimy i trzeba w końcu przebudować initrd.

Są 2 podejścia do utrzymywania Slackware z initrd:

  1. Jedno initrd dla wszystkich kerneli
  2. Każdy kernel lub nawet pozycja w lilo ma swoje initrd

Jedno initrd dla wszystkich

Na początek należy się upewnić, że mamy zakomentowane CLEAR_TREE lub ustawione na 0 w mkinitrd.conf!

Po instalacji nowego kernela, ale działając jeszcze na starym, trzeba ustawić KERNEL_VERSION na wersje nowego kernela, np. KERNEL_VERSION="3.17.4"
Po tym wystarczy uruchomić mkinitrd -F
To wszystko, teraz initrd ma moduły tak dla starego kernela jak i dla nowego.
Oczywiście trzeba dodać nową pozycję w lilo.conf dla nowego kernela z dokładnie tą samą nazwą initrd jak dla starego.
Jeżeli robimy tylko upgrade kernela, to w takim wypadku nie trzeba nawet dotykać lilo.conf (tak długo jak linijka image= odwołuje się do linku vmlinuz wskazującego na aktualny kernel).
W obu przypadkach na końcu trzeba oczywiście uruchomić lilo.

Od czasu do czasu warto posprzątać stare i nieużywane moduły z initrd. Robi się to przez usunięcie jednego katalogu z /boot/initrd-tree/lib/modules/old-kernel-version i wygenerowanie nowego initrd jak zwykle przez mkinitrd -F. I uruchomienie lilo na koniec 🙂

Mam nadzieję, że teraz już widać przewagę użycia mkinitrd.conf zamiast pamiętania wszystkich dziwnych przełączników jakie ostatnio użyliśmy do wygenerowania poprzedniego initrd (czasem ładnych kilka miesięcy temu).

Osobne initrd dla każdego kernela

To podejście nie ma większego sensu jeżeli masz tylko jeden system i używasz tylko jednego dystrybucyjnego kernela, który czasem uaktualniasz.

Poza tym osobne initrd jest nawet łatwiejsze niż podejście ‚jedno dla wszystkich’.
Jedynym minusem jest to, że przełącznik -F do mkinitrd powoduje wczytanie zawsze tego samego konfiga (/etc/mkinitrd.conf) i nie ma innej opcji podania innego konfiga, więc za każdym razem trzeba sobie skopiować swój odpowiedni konfig w to miejsce.
Czyli dla pierwszego kernela powinniśmy ustawić sobie co najmniej unikalne SOURCE_TREE, OUTPUT_IMAGE i KERNEL_VERSION. Generujemy nowe initrd przez mkinitrd -F i robimy backup mkinitrd.conf do np. mkinitrd.conf.3.10.17.
Dla każdego następnego kernela zmieniamy sobie odpowiednie opcje w mkinitrd.conf, generujemy initrd, robimy backup i tak dalej.
Tym sposobem można mieć wiele różnych initrd i zapisanych konfigów do przebudowania każdego z nich. Jest to najbezpieczniejsza metoda przy zabawach z nowym kernelem czy opcjami initrd, bo zawsze mamy jeszcze starą i działającą wersję.

Osobiście używam podejścia mieszanego – dla każdej wersji systemu inne initrd (czyli Slackware 14.0 ma swoje, 14.1 ma inne). Kernele w obrębie jednej wersji zazwyczaj mam już ze wspólnym initrd. Eksperymenty też zazwyczaj mam już osobno.

To by było na tyle o tej prostszej części initrd 🙂
Następnym razem opiszę jak użyć initrd z zaszyfrowanym root-em lub nawet root-em na zaszyfrowanym lvm-ie 🙂

Uaktualnienie 2015.02.20

Znalazłem całkiem niezłą dokumentację w tym temacie na Slackware Documentation Project. Wygląda na to, że niezbyt dobrze sprawdziłem co jest już dostępne w tym temacie 🙂

This entry was posted in Linux and tagged , . Bookmark the permalink.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *