Comment utiliser correctement kexec avec systemd sur CentOS 7?

13

Je veux utiliser kexec pour accélérer les redémarrages de ma machine CentOS 7. Comment puis-je faire cela d'une manière qui s'intègre parfaitement aux cibles systemd d'arrêt / de redémarrage existantes? Quelle est la bonne façon (officielle) de procéder?

Matrice
la source

Réponses:

11

J'ai trouvé un moyen de créer un script de chargement kexec qui fonctionne bien et chargera le noyau par défaut dans grub, ce qui signifie qu'il devrait charger le nouveau noyau après une mise à jour du noyau.

Fichier: / 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"

Fichier: /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
Matrice
la source
1
Merveilleux, je ne comprends pas très bien pourquoi cela n'a pas encore 289 votes positifs ...
kubanczyk
3
Pour rester simple, je me débarrasse du fichier de script et j'utilise à la placeExecStart=/bin/sh -c "kexec -l $$(grubby --default-kernel) --initrd=$$(grubby --default-kernel | sed 's!vmlinuz!initramfs!;s/$/.img/') --reuse-cmdline"
kubanczyk
7

C'est assez simple.

Première étape du noyau à démarrer:

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"

Ces options ont été glissées hors de la configuration grub générée.

Dites maintenant à systemd de faire sa magie.

systemctl start kexec.target

Ou sur des versions plus récentes de systemd:

systemctl kexec

Quelques secondes plus tard, vous serez dans votre nouveau noyau.


J'ai récemment écrit un script indépendant de la distribution pour aider à automatiser cela (les rapports de bugs sont les bienvenus).

Michael Hampton
la source
Ne --command-line=$(cat /proc/cmdline)fonctionnerait pas aussi bien?
Dennis Kaarsemaker
1
@DennisKaarsemaker Oui, probablement. Mais changer les options de ligne de commande pourrait être l'une des choses qui se font, donc je ne ferais pas nécessairement toujours cela.
Michael Hampton
Merci pour la réponse. Existe-t-il un moyen d'automatiser la "préparation kexec"? Systemd peut-il être configuré pour préparer automatiquement kexec lorsque j'exécute "systemctl start kexec.target"?
Matrix
@Matrix Bonne question. S'il existe un tel moyen, je n'en suis pas conscient. Et de toute façon, le redémarrage est quelque chose auquel vous voulez généralement penser.
Michael Hampton
Je pense que --reuse-cmdlinec'est plus court et plus lisible. Refuse malheureusement --reuseinitrdde reconnaître un initramfs actuel, donc je dois le spécifier manuellement.
kubanczyk du