Bagaimana cara menggunakan kexec dengan systemd di CentOS 7 dengan benar?

13

Saya ingin menggunakan kexec untuk mempercepat reboot mesin CentOS 7 saya. Bagaimana saya bisa melakukan itu dengan cara yang terintegrasi dengan baik dengan target shutdown / reboot systemd yang ada? Apa cara (resmi) yang tepat untuk melakukan ini?

Matriks
sumber

Jawaban:

11

Saya menemukan cara untuk membuat skrip pemuatan kexec yang berfungsi dengan baik dan akan memuat kernel default di grub, artinya harus memuat kernel baru setelah pembaruan kernel.

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

File: /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
Matriks
sumber
1
Luar biasa, saya tidak begitu mengerti mengapa ini belum mendapatkan 289 upvotes ...
kubanczyk
3
Untuk membuatnya tetap sederhana, saya menyingkirkan file skrip dan saya gunakan sebagai gantinyaExecStart=/bin/sh -c "kexec -l $$(grubby --default-kernel) --initrd=$$(grubby --default-kernel | sed 's!vmlinuz!initramfs!;s/$/.img/') --reuse-cmdline"
kubanczyk
7

Ini sangat mudah.

Tahap pertama kernel yang akan di-boot:

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"

Opsi-opsi ini telah dihapus dari konfigurasi grub yang dihasilkan.

Sekarang beritahu systemd untuk melakukan keajaibannya.

systemctl start kexec.target

Atau pada versi systemd yang lebih baru:

systemctl kexec

Beberapa detik kemudian, Anda akan berada di kernel baru.


Saya baru-baru ini menulis skrip distribusi-agnostik untuk membantu mengotomatiskan ini (laporan bug diterima).

Michael Hampton
sumber
Tidak akan --command-line=$(cat /proc/cmdline)bekerja juga?
Dennis Kaarsemaker
1
@ DennisKaarsemaker Ya, mungkin begitu. Tetapi mengubah opsi baris perintah mungkin merupakan salah satu hal yang dilakukan, jadi saya tidak akan selalu melakukan itu.
Michael Hampton
Terima kasih atas jawabannya. Apakah ada cara untuk mengotomatisasi "persiapan kexec"? Dapatkah systemd dikonfigurasi untuk secara otomatis menyiapkan kexec ketika saya mengecek "systemctl start kexec.target"?
Matriks
@ Matrix Pertanyaan yang bagus. Jika ada cara seperti itu, saya tidak menyadarinya. Lagi pula, me-reboot adalah sesuatu yang umumnya ingin Anda pikirkan.
Michael Hampton
Saya pikir --reuse-cmdlinelebih pendek dan lebih mudah dibaca. Sayangnya --reuseinitrdmenolak untuk mengenali initramf saat ini, jadi saya harus menentukannya secara manual.
kubanczyk