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?

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

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).


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.