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.