14

I want to use kexec to speed up reboots of my CentOS 7 machine. How can I do that in a way that nicely integrates with existing shutdown/reboot systemd targets? What's the proper (official) way to do this?

Matrix
  • 363
  • 3
  • 10

2 Answers2

12

I figured out a way to make a kexec loading script that works well and will load the default kernel in grub, meaning it should load the new kernel after a kernel update.

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
u91317
  • 152
  • 1
  • 1
  • 7
Matrix
  • 363
  • 3
  • 10
  • 1
    Marvellous, I don't quite understand why this haven't got 289 upvotes yet... – kubanczyk Oct 28 '16 at 08:34
  • 3
    To keep it simple, I get rid of script file and I use instead `ExecStart=/bin/sh -c "kexec -l $$(grubby --default-kernel) --initrd=$$(grubby --default-kernel | sed 's!vmlinuz!initramfs!;s/$/.img/') --reuse-cmdline"` – kubanczyk Oct 28 '16 at 09:23
7

This is pretty straightforward.

First stage the kernel to be booted:

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"

These options having been swiped out of the generated grub configuration.

Now tell systemd to do its magic.

systemctl start kexec.target

Or on more recent versions of systemd:

systemctl kexec

A few seconds later, you will be up in your new kernel.


I've recently written a distribution-agnostic script to help automate this (bug reports welcome).

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • Wouldn't `--command-line=$(cat /proc/cmdline)` work as well? – Dennis Kaarsemaker Aug 13 '14 at 18:35
  • 1
    @DennisKaarsemaker Yeah, probably so. But changing the command line options might be one of the things being done, so I wouldn't necessarily _always_ do that. – Michael Hampton Aug 13 '14 at 18:37
  • Thank you for the answer. Is there a way to automate the "kexec preparation"? Can systemd be configured to automatically prepare kexec when I exectute "systemctl start kexec.target"? – Matrix Aug 13 '14 at 19:36
  • @Matrix Good question. If there is such a way, I'm not aware of it. And anyway, rebooting is something you generally want to think about. – Michael Hampton Aug 13 '14 at 19:39
  • I think `--reuse-cmdline` is shorter and more readable. Unfortunately `--reuseinitrd` refuses to recognize a current initramfs, so I need to specify it manually. – kubanczyk Oct 28 '16 at 08:30
  • @MichaelHampton how would I hook this up so that any reboot comand would be a kexec (before systemd, installing kexec-tools was enough for this, at least on Ubuntu) - especially issued from a GUI? – sup May 23 '18 at 14:20
  • @sup If you set up kexec, then any reboot will kexec, on a systemd system anyway. – Michael Hampton May 23 '18 at 14:43
  • Hm, and do you have any idea on how to set it up on Ubuntu? Because it does not behave that way. But I understand this question is about CentOS and Ubuntu might be buggy in this regard. – sup May 23 '18 at 17:27
  • @sup Ubuntu is a very strange system in a wide variety of ways. Most of this it inherits from Debian... I can take a look later and see if I can see what's wrong. – Michael Hampton May 23 '18 at 17:31
  • I am on 18.04. I tried fiddling with it for an hour but frankly I do not understand Systemd at all and I am a bit afraid of messing my system up. – sup May 23 '18 at 17:36