Difference between revisions of "Kexec"

From ArchWiki
Jump to: navigation, search
(Installation: use new install wording)
 
(22 intermediate revisions by 15 users not shown)
Line 1: Line 1:
 
[[Category:Boot process]]
 
[[Category:Boot process]]
 
[[Category:Kernel]]
 
[[Category:Kernel]]
{{Article summary start}}
+
[[ja:Kexec]]
{{Article summary text|Covers how to install and configure kexec.}}
+
{{Related articles start}}
{{Article summary heading|Related}}
+
{{Related|Systemd}}
{{Article summary wiki|Systemd}}
+
{{Related articles end}}
{{Article summary end}}
+
'''Kexec''' is a system call that enables you to load and boot into another kernel from the currently running kernel. This is useful for kernel developers or other people who need to reboot very quickly without waiting for the whole BIOS boot process to finish. Note that kexec may not work correctly for you due to devices ''not'' fully re-initializing when using this method, however this is rarely the case.
  
'''Kexec''' is a system call that enables you to load and boot into another
+
== Installation ==
kernel from the currently running kernel. This is useful for kernel developers
+
or other people who need to reboot very quickly without waiting for the whole
+
BIOS boot process to finish. Note that there may appear some problems and kexec
+
may not work correctly for you because the devices ''won't'' fully reinitiate
+
when using this method.
+
  
==Installation==
+
[[Install]] the {{pkg|kexec-tools}} package.
  
To install kexec, [[pacman|install]] the {{pkg|kexec-tools}} package which is available in the [[Official Repositories|official repositories]].
+
== Rebooting using kexec ==
  
==Rebooting using kexec==
+
=== Systemd ===
  
===Systemd===
+
You will need to create a new unit file, {{ic|kexec-load@.service}}, that will load the specified kernel to be kexec'ed:
  
You will need to create a new unit file, {{ic|kexec-load.service}}, that will load the new kernel to be kexec'ed<sup>[[#Foot1|<nowiki>[1]</nowiki>]]</sup>.
+
{{hc|/etc/systemd/system/kexec-load@.service|2=
 
+
{{hc|# vim /etc/systemd/system/kexec-load.service|2=
+
 
[Unit]
 
[Unit]
 +
Description=load %i kernel into the current kernel
 +
Documentation=man:kexec(8)
 
DefaultDependencies=no
 
DefaultDependencies=no
 
Before=shutdown.target umount.target final.target
 
Before=shutdown.target umount.target final.target
Line 31: Line 26:
 
[Service]
 
[Service]
 
Type=oneshot
 
Type=oneshot
ExecStart=/sbin/kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
+
ExecStart=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline
  
 
[Install]
 
[Install]
 
WantedBy=kexec.target}}
 
WantedBy=kexec.target}}
  
Then enable the service file
+
Then enable the service file for the kernel you want to load, for example simply the default kernel {{ic|linux}}:
  
{{hc|# systemctl enable kexec-load|2=
+
{{hc|# systemctl enable kexec-load@linux|
ln -s '/etc/systemd/system/kexec-load.service' '/etc/systemd/system/kexec.target.wants/kexec-load.service'}}
+
ln -s '/etc/systemd/system/kexec-load@.service' '/etc/systemd/system/kexec.target.wants/kexec-load@linux.service'}}
  
 
Ensure that the shutdown hook is not part of your initramfs image by removing it from the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}. If it is, remove it and rebuild your initrd image with {{ic|mkinitcpio -p linux}}.
 
Ensure that the shutdown hook is not part of your initramfs image by removing it from the {{ic|HOOKS}} array in {{ic|/etc/mkinitcpio.conf}}. If it is, remove it and rebuild your initrd image with {{ic|mkinitcpio -p linux}}.
  
To kexec, simply
+
Then to kexec
 +
 
 +
# systemctl kexec
 +
 
 +
If you wish to load a different kernel for the next kexec, for example {{ic|linux-lts}}, disable the service for the current kernel and enable the one for the new kernel:
 +
 +
# systemctl disable kexec-load@linux
 +
# systemctl enable kexec-load@linux-lts
 +
 
 +
==== Separate /boot partition ====
 +
 
 +
The above systemd unit file will fail if /boot is not on the root file system, as systemd will likely unmount /boot before it runs the kexec-load unit file. An alternative approach is to load a "hook" unit file that does nothing on startup and invokes kexec upon termination. By making this unit file conflict with kexec.target and only kexec.target, you can ensure the new kernel gets loaded early enough and only after a "systemctl kexec" command. Here is an alternate {{ic|/etc/systemd/system/kexec-load@.service}} file that follows this strategy:
 +
 
 +
{{bc|1=
 +
[Unit]
 +
Description=hook to load vmlinuz-%i kernel upon kexec
 +
Documentation=man:kexec(8)
 +
DefaultDependencies=no
 +
RequiresMountsFor=/boot/vmlinuz-%i
 +
Conflicts=kexec.target
 +
 
 +
[Service]
 +
Type=oneshot
 +
ExecStart=-/usr/bin/true
 +
RemainAfterExit=yes
 +
ExecStop=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline
 +
 
 +
[Install]
 +
WantedBy=basic.target
 +
}}
 +
 
 +
Unfortunately, while the above file works reliably on some machines, the ExecStop command seems to fail to run on others.
 +
 
 +
Stronger alternative with sysinit based ordering (guaranteeing proper service shutdown before any unmount action could even take place) is:
 +
 
 +
{{bc|1=
 +
[Unit]
 +
Description=hook to load vmlinuz-%i kernel upon kexec
 +
Documentation=man:kexec(8)
 +
DefaultDependencies=no
 +
Requires=sysinit.target
 +
After=sysinit.target
 +
 
 +
[Service]
 +
Type=oneshot
 +
ExecStart=-/usr/bin/true
 +
RemainAfterExit=yes
 +
ExecStop=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline
 +
 
 +
[Install]
 +
WantedBy=basic.target
 +
}}
  
{{bc|1=# systemctl kexec}}
+
Note that Conflicts=shutdown.target is not really needed, as it's implicitly guaranteed by strict ordering on systinit.target which itself Conflicts= with shutdown.target.
  
===Manually===
+
=== Manually ===
  
 
It is also perfectly legal to invoke kexec manually:
 
It is also perfectly legal to invoke kexec manually:
  
{{bc|1=# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline}}
+
# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
 +
# kexec -e
  
==References==
+
{{Warning|Running {{ic|kexec -e}} directly will not unmount active filesystemd or terminate any running services gracefully.}}
  
<span id="Foot1">1. [http://lists.freedesktop.org/archives/systemd-devel/2012-March/004760.html <nowiki>[systemd-devel]</nowiki> Right way to do kexec]</span>
+
It is also possible to load kernel manually and then let systemd handle service shutdown and kexec for you:
  
==See also==
+
# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
 +
# systemctl kexec
  
*[http://lse.sourceforge.net/kdump/ kdump: a kexec based crash dumping mechansim for Linux]
+
== See also ==
*[http://www.ibm.com/developerworks/linux/library/l-kexec.html Reboot Linux faster using kexec]
+
* [http://lists.freedesktop.org/archives/systemd-devel/2012-March/004760.html <nowiki>[systemd-devel]</nowiki> Right way to do kexec]
 +
* [http://lse.sourceforge.net/kdump/ kdump: a kexec based crash dumping mechansim for Linux]
 +
* [https://web.archive.org/web/20090505132901/http://www.ibm.com/developerworks/linux/library/l-kexec.html Reboot Linux faster using kexec]

Latest revision as of 17:27, 22 August 2016

Related articles

Kexec is a system call that enables you to load and boot into another kernel from the currently running kernel. This is useful for kernel developers or other people who need to reboot very quickly without waiting for the whole BIOS boot process to finish. Note that kexec may not work correctly for you due to devices not fully re-initializing when using this method, however this is rarely the case.

Installation

Install the kexec-tools package.

Rebooting using kexec

Systemd

You will need to create a new unit file, kexec-load@.service, that will load the specified kernel to be kexec'ed:

/etc/systemd/system/kexec-load@.service
[Unit]
Description=load %i kernel into the current kernel
Documentation=man:kexec(8)
DefaultDependencies=no
Before=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline

[Install]
WantedBy=kexec.target

Then enable the service file for the kernel you want to load, for example simply the default kernel linux:

# systemctl enable kexec-load@linux
ln -s '/etc/systemd/system/kexec-load@.service' '/etc/systemd/system/kexec.target.wants/kexec-load@linux.service'

Ensure that the shutdown hook is not part of your initramfs image by removing it from the HOOKS array in /etc/mkinitcpio.conf. If it is, remove it and rebuild your initrd image with mkinitcpio -p linux.

Then to kexec

# systemctl kexec

If you wish to load a different kernel for the next kexec, for example linux-lts, disable the service for the current kernel and enable the one for the new kernel:

# systemctl disable kexec-load@linux
# systemctl enable kexec-load@linux-lts

Separate /boot partition

The above systemd unit file will fail if /boot is not on the root file system, as systemd will likely unmount /boot before it runs the kexec-load unit file. An alternative approach is to load a "hook" unit file that does nothing on startup and invokes kexec upon termination. By making this unit file conflict with kexec.target and only kexec.target, you can ensure the new kernel gets loaded early enough and only after a "systemctl kexec" command. Here is an alternate /etc/systemd/system/kexec-load@.service file that follows this strategy:

[Unit]
Description=hook to load vmlinuz-%i kernel upon kexec
Documentation=man:kexec(8)
DefaultDependencies=no
RequiresMountsFor=/boot/vmlinuz-%i
Conflicts=kexec.target

[Service]
Type=oneshot
ExecStart=-/usr/bin/true
RemainAfterExit=yes
ExecStop=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline

[Install]
WantedBy=basic.target

Unfortunately, while the above file works reliably on some machines, the ExecStop command seems to fail to run on others.

Stronger alternative with sysinit based ordering (guaranteeing proper service shutdown before any unmount action could even take place) is:

[Unit]
Description=hook to load vmlinuz-%i kernel upon kexec
Documentation=man:kexec(8)
DefaultDependencies=no
Requires=sysinit.target
After=sysinit.target

[Service]
Type=oneshot
ExecStart=-/usr/bin/true
RemainAfterExit=yes
ExecStop=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initramfs-%i.img --reuse-cmdline

[Install]
WantedBy=basic.target

Note that Conflicts=shutdown.target is not really needed, as it's implicitly guaranteed by strict ordering on systinit.target which itself Conflicts= with shutdown.target.

Manually

It is also perfectly legal to invoke kexec manually:

# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
# kexec -e
Warning: Running kexec -e directly will not unmount active filesystemd or terminate any running services gracefully.

It is also possible to load kernel manually and then let systemd handle service shutdown and kexec for you:

# kexec -l /boot/vmlinuz-linux --initrd=/boot/initramfs-linux.img --reuse-cmdline
# systemctl kexec

See also