Como usar corretamente o kexec com systemd no CentOS 7?

13

Quero usar o kexec para acelerar as reinicializações da minha máquina CentOS 7. Como posso fazer isso de uma maneira que se integre perfeitamente aos destinos existentes de desligamento / reinicialização do sistema? Qual é a maneira (oficial) apropriada de fazer isso?

Matriz
fonte

Respostas:

11

Eu descobri uma maneira de criar um script de carregamento do kexec que funcione bem e carregará o kernel padrão no grub, o que significa que ele deve carregar o novo kernel após uma atualização do kernel.

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

Arquivo: /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
Matriz
fonte
1
Maravilhosa, eu não entendo muito bem por que isso não tem 289 upvotes ainda ...
kubanczyk
3
Para mantê-lo simples, para me livrar do arquivo de script e eu uso em vezExecStart=/bin/sh -c "kexec -l $$(grubby --default-kernel) --initrd=$$(grubby --default-kernel | sed 's!vmlinuz!initramfs!;s/$/.img/') --reuse-cmdline"
kubanczyk
7

Isso é bem direto.

Primeiro estágio do kernel a ser inicializado:

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"

Essas opções foram retiradas da configuração do grub gerada.

Agora diga ao systemd para fazer sua mágica.

systemctl start kexec.target

Ou nas versões mais recentes do systemd:

systemctl kexec

Alguns segundos depois, você estará no seu novo kernel.


Recentemente, escrevi um script independente de distribuição para ajudar a automatizar isso (relatórios de erros são bem-vindos).

Michael Hampton
fonte
Não --command-line=$(cat /proc/cmdline)funcionaria tão bem?
Dennis Kaarsemaker
1
@DennisKaarsemaker Sim, provavelmente sim. Mas alterar as opções da linha de comando pode ser uma das coisas que estão sendo feitas, então eu nem sempre faria isso.
Michael Hampton
Obrigado pela resposta. Existe uma maneira de automatizar a "preparação do kexec"? O systemd pode ser configurado para preparar automaticamente o kexec quando eu executar "systemctl start kexec.target"?
Matrix
@Matrix Boa pergunta. Se existe, não estou ciente disso. De qualquer forma, reiniciar é algo em que você geralmente deseja pensar.
Michael Hampton
Eu acho que --reuse-cmdlineé mais curto e mais legível. Infelizmente, --reuseinitrdrecuso-me a reconhecer um initramfs atual, então preciso especificá-lo manualmente.
Kubanczyk 28/10