Wie verwende ich kexec mit systemd unter CentOS 7 richtig?

13

Ich möchte Kexec verwenden, um den Neustart meines CentOS 7-Computers zu beschleunigen. Wie kann ich das auf eine Weise tun, die sich gut in vorhandene systemd-Ziele zum Herunterfahren / Neustarten integrieren lässt? Was ist der richtige (offizielle) Weg, um dies zu tun?

Matrix
quelle

Antworten:

11

Ich habe einen Weg gefunden, ein Kexec-Ladeskript zu erstellen, das gut funktioniert und den Standard-Kernel in Grub lädt. Das bedeutet, dass der neue Kernel nach einem Kernel-Update geladen werden sollte.

Datei: / usr / bin / kexec-load

#!/usr/bin/env bash

GRUBBY_FILE="/var/log/grubby"
TMP=$(mktemp)

#  Command "grubby --default-kernel" has a bug/feature that fsyncs
#  after writting each line to a debug log file, making it slow (several seconds).
#  Workaround is to write to /dev/null instead.
if [ -e $GRUBBY_FILE ]
        then rm -f $GRUBBY_FILE
fi
ln -s /dev/null $GRUBBY_FILE
KERNEL_IMG=$(grubby --default-kernel)
unlink $GRUBBY_FILE

#  Get the detailed information of the default kernel (as seen by grub)
#  This will create a temporary file in /tmp
grubby --info=$KERNEL_IMG | grep -v title > $TMP
source $TMP
rm $TMP

#  Simple log to see if this script gets executed
date --rfc-3339=seconds >> /var/log/kexec

#  Load (prepare) the kernel for execution
kexec -l $kernel --initrd=$initrd --command-line="root=$root $args"

Datei: /etc/systemd/system/kexec-load.service

[Unit]
Description=loads the kernel
Documentation=man:kexec(8)
DefaultDependencies=no
Before=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/usr/bin/kexec-load

[Install]
WantedBy=kexec.target 

$ chmod +x /usr/bin/kexec-load
$ systemctl enable kexec-load.service
$ systemctl kexec
Matrix
quelle
1
Wunderbar, ich verstehe nicht ganz, warum dies noch nicht 289 Upvotes hat ...
Kubanczyk
3
Um es einfach zu halten, werde ich die Skriptdatei los und benutze stattdessenExecStart=/bin/sh -c "kexec -l $$(grubby --default-kernel) --initrd=$$(grubby --default-kernel | sed 's!vmlinuz!initramfs!;s/$/.img/') --reuse-cmdline"
kubanczyk
7

Das ist ziemlich einfach.

Zuerst muss der Kernel gebootet werden:

kexec -l /boot/vmlinuz-3.10.0-123.6.3.el7.x86_64 \
--initrd=/boot/initramfs-3.10.0-123.6.3.el7.x86_64.img \
--command-line="root=/dev/mapper/centos-root ro rd.lvm.lv=centos/swap vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos/root crashkernel=auto  vconsole.keymap=us rhgb quiet LANG=en_US.UTF-8"

Diese Optionen wurden aus der generierten Grub-Konfiguration entfernt.

Sagen Sie nun systemd, es soll zaubern.

systemctl start kexec.target

Oder auf neueren Versionen von systemd:

systemctl kexec

Ein paar Sekunden später sind Sie in Ihrem neuen Kernel.


Ich habe kürzlich ein verteilungsunabhängiges Skript geschrieben , um dies zu automatisieren (Fehlerberichte erwünscht).

Michael Hampton
quelle
Würde nicht --command-line=$(cat /proc/cmdline)so gut funktionieren?
Dennis Kaarsemaker
1
@DennisKaarsemaker Ja, wahrscheinlich schon. Das Ändern der Befehlszeilenoptionen könnte jedoch eine der Aufgaben sein, die ich nicht unbedingt immer ausführen würde.
Michael Hampton
Danke für die Antwort. Gibt es eine Möglichkeit, die "Kexec-Vorbereitung" zu automatisieren? Kann systemd so konfiguriert werden, dass kexec automatisch vorbereitet wird, wenn "systemctl start kexec.target" ausgeführt wird?
Matrix
@ Matrix Gute Frage. Wenn es so etwas gibt, weiß ich es nicht. Über einen Neustart sollten Sie im Allgemeinen nachdenken.
Michael Hampton
Ich denke --reuse-cmdlineist kürzer und lesbarer. Weigert --reuseinitrdsich leider , ein aktuelles initramfs zu erkennen, daher muss ich es manuell angeben.
Kubanczyk