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?

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

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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.