Tento článek ukáže, jak zkrátit dobu bootu Fedory 17. Cílem je získat rychle bootující systém s běžícím NetworkManagerem a zobrazenou přihlašovací obrazovkou GDM.

Článek původně vydal Harald Hoyer na svém blogu jako Fedora 17 Boot Optimization (from 15 to 2.5 seconds).

Používal jsem počítač Lenovo T420s (2x2x Intel(R) Core(TM) i5-2540M CPU @ 2.60GHz) s pevným diskem INTEL SSDSA2BW160G3L.

Nejprve zvolíme ruční rozdělení disku, použijeme primární oddíly a naformátujeme je jako ext4. V mém případě vznikne:

sda1 ext4 /boot
sda2 swap
sda3 ext4 /

Po prvním bootu, nastavení uživatele atd. a 2 restartech (vždy restartujte dvakrát, než začnete měřit čas, protože se přednačítání [readahead] potřebuje přizpůsobit novému bootovacímu procesu) vše aktualizujeme, spustíme prelink a nainstalujeme systemd-analyze:

$ sudo yum update
$ sudo /etc/cron.daily/prelink
$ sudo yum install systemd-analyze

Po restartech dostanu:

# systemd-analyze
Startup finished in 1413ms (kernel) + 2911ms (initramfs) + 10593ms (userspace) = 14918ms

Dalším krokem je vypnout initramfs, protože jádro umí bootovat z ext4 oddílu i bez toho. Jelikož vím, jak případně obnovit svůj systém, mohu nastavit kořenové zařízení přímo sda3 a říct jádru, jaký souborový systém použít. Můj soubor /etc/grub2.cfg vypadá takto:

linux /vmlinuz-3.3.7-1.fc17.x86_64 root=/dev/sda3 rootfstype=ext4 quiet libahci.ignore_sss=1 raid=noautodetect
#       initrd /initramfs-3.3.7-1.fc17.x86_64.img

"raid=noautodetect" a "libahci.ignore_sss=1" ušetří trochu času při inicializaci jádra.

Startup finished in 1640ms (kernel) + 13043ms (userspace) = 14684ms

Protože nepoužívám žádné LVM, RAID nebo šifrované disky, můžu klidně vypnout skoro všechny služby fedora-*storage*. Kromě toho vypnu bootovací obrazovku plymouth, protože chci rychlost, ne omalovánky. K vypnutí těchto služeb použijeme příkaz "systemctl mask". Jako bonus tohoto mechanismu můžeme brát, že žádný rpm %post skript služby znovu automaticky nezapne.

$ cd /lib/systemd/system
$ for i in fedora*storage* plymouth-*.* lvm2-monitor.* mdmonitor*.*; do sudo systemctl mask $i;done

Vypadá to, že stále zbývají nějaké SysV initskripty, takže je vypneme:

$ for i in livesys livesys-late spice-vdagentd ; do sudo chkconfig $i off;done

Ušetřili jsme polovinu času v uživatelském prostoru:

Startup finished in 1640ms (kernel) + 6556ms (userspace) = 8197ms

Od této chvíle už je potřeba vědět, co děláte a jak to vrátit zpět. Abychom mohli Fedoru 17 srovnat např. s Ubuntu, vypnu teď všechny služby kromě NetworkManageru. Výsledkem bude linuxový systém bez pošty, firewallu, tisku, nástrojů abrt, avahi, některých přípojných bodů, rsyslog, irqbalance a SELinuxu.

$ cd /lib/systemd/system
$ for i in abrt*.service auditd.service avahi-daemon.* bluetooth.* dev-hugepages.mount dev-mqueue.mount \
      fedora-configure.service fedora-loadmodules.service fedora-readonly.service ip6tables.service \
      iptables.service irqbalance.service mcelog.service rsyslog.service sendmail.service sm-client.service \
      sys-kernel-config.mount sys-kernel-debug.mount; do \
    sudo systemctl mask $i; \
  done

SELinux vypneme editací souboru /etc/selinux/config a přidáním "selinux=0" do příkazové řádky jádra. Můj soubor /etc/grub2.cfg nyní vypadá takto:

linux /vmlinuz-3.3.7-1.fc17.x86_64 root=/dev/sda3 rootfstype=ext4 libahci.ignore_sss=1 raid=noautodetect selinux=0
#       initrd /initramfs-3.3.7-1.fc17.x86_64.img

Teď už jsme opravdu rychlí!

$ systemd-analyze
Startup finished in 1329ms (kernel) + 1596ms (userspace) = 2926ms

Mám rád automatické připojování zařízení [automount] (funkce automount v systemd byla můj nápad :-)), takže změním /boot na přípojný bod s připojením na vyžádání. Adresář /tmp nastavíme na tmpfs, což je jeden ze způsobů, jak omezit diskovou aktivitu (užitečné např. pro pomalý flashdisk). Výsledný soubor /etc/fstab vypadá takto:

/dev/sda3  /          ext4    defaults        1 1
/dev/sda1  /boot      ext4    noauto,comment=systemd.automount     1 2
/dev/sda2  swap       swap    defaults        0 0
tmpfs      /tmp       tmpfs   defaults        0 0

To ušetřilo jen trochu času, ale i tak:

$ systemd-analyze
Startup finished in 1342ms (kernel) + 1426ms (userspace) = 2769ms

Vzhledem k tomu, že je NetworkManager také spouštěn cílem „grafické přihlášení“, mohu ho odstranit z cíle „multi-user“ a spustí se souběžně s přihlašovací obrazovkou GDM.

$ sudo rm  /etc/systemd/system/multi-user.target.wants/NetworkManager.service

To ukrojí několik milisekund:

$ systemd-analyze
Startup finished in 1323ms (kernel) + 1279ms (userspace) = 2603ms

Aby bylo poznat, jak velký rozdíl způsobuje přednačítání, dočasně ho vypnu a restartuji:

$ cd /lib/systemd/system
$ for i in *readahead*; do sudo systemctl mask $i;done

Což nám dá:

$ systemd-analyze
Startup finished in 1336ms (kernel) + 1210ms (userspace) = 2547ms

Tento čas je trochu zavádějící. Ačkoliv se zdá rychlejší, skutečná doba před objevením přihlašovací obrazovky je delší. Takže k férovému srovnání bychom potřebovali stopky.

$ sudo dracut -f

A tady je doba se znovu zapnutým přednačítáním a initramfs (regenerované):

$ systemd-analyze
Startup finished in 803ms (kernel) + 2217ms (initramfs) + 1018ms (userspace) = 4039ms

I to lze samozřejmě optimalizovat – sestavením initramfs bez plymouth a v režimu host-only.

$ sudo dracut -f -H -o plymouth

Po restartu dostanu úžasný výsledek:

$ systemd-analyze
Startup finished in 612ms (kernel) + 499ms (initramfs) + 1330ms (userspace) = 2443ms

Na příkazu "systemctl mask" je pěkné, že jej můžete vždy vrátit pomocí "systemctl unmask" a povolit tak služby, které opravdu potřebujete.

Hodně zábavy a šťastné restarty!

A nezapomeňte restartovat dvakrát, aby začala působit optimalizace přednačítání!