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?

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

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


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.