Add kexec support
You can now do a fast reboot (bypassing the BIOS, which may take several minutes on servers) by running ‘systemctl kexec’. Unfortunately the QEMU test for this is unreliable due to a QEMU bug (it randomly crashes with a message like ‘Guest moved used index from 8 to 0’), so it's commented out.
This commit is contained in:
parent
5332480454
commit
b825169404
|
@ -101,9 +101,25 @@ doing:
|
||||||
$ shutdown
|
$ shutdown
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
This is equivalent to running <command>systemctl poweroff</command>.
|
This is equivalent to running <command>systemctl
|
||||||
Likewise, <command>reboot</command> (a.k.a. <command>systemctl
|
poweroff</command>.</para>
|
||||||
reboot</command>) will reboot the system.</para>
|
|
||||||
|
<para>To reboot the system, run
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ reboot
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
which is equivalent to <command>systemctl reboot</command>.
|
||||||
|
Alternatively, you can quickly reboot the system using
|
||||||
|
<literal>kexec</literal>, which bypasses the BIOS by directly loading
|
||||||
|
the new kernel into memory:
|
||||||
|
|
||||||
|
<screen>
|
||||||
|
$ systemctl kexec
|
||||||
|
</screen>
|
||||||
|
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>The machine can be suspended to RAM (if supported) using
|
<para>The machine can be suspended to RAM (if supported) using
|
||||||
<command>systemctl suspend</command>, and suspended to disk using
|
<command>systemctl suspend</command>, and suspended to disk using
|
||||||
|
|
|
@ -232,9 +232,9 @@ sub connect {
|
||||||
|
|
||||||
$self->start;
|
$self->start;
|
||||||
|
|
||||||
local $SIG{ALRM} = sub { die "timed out waiting for the guest to connect\n"; };
|
local $SIG{ALRM} = sub { die "timed out waiting for the VM to connect\n"; };
|
||||||
alarm 300;
|
alarm 300;
|
||||||
readline $self->{socket} or die;
|
readline $self->{socket} or die "the VM quit before connecting\n";
|
||||||
alarm 0;
|
alarm 0;
|
||||||
|
|
||||||
$self->log("connected to guest root shell");
|
$self->log("connected to guest root shell");
|
||||||
|
|
|
@ -235,6 +235,7 @@
|
||||||
./system/activation/activation-script.nix
|
./system/activation/activation-script.nix
|
||||||
./system/activation/top-level.nix
|
./system/activation/top-level.nix
|
||||||
./system/boot/kernel.nix
|
./system/boot/kernel.nix
|
||||||
|
./system/boot/kexec.nix
|
||||||
./system/boot/loader/efi-boot-stub/efi-boot-stub.nix
|
./system/boot/loader/efi-boot-stub/efi-boot-stub.nix
|
||||||
./system/boot/loader/efi.nix
|
./system/boot/loader/efi.nix
|
||||||
./system/boot/loader/generations-dir/generations-dir.nix
|
./system/boot/loader/generations-dir/generations-dir.nix
|
||||||
|
|
21
modules/system/boot/kexec.nix
Normal file
21
modules/system/boot/kexec.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ pkgs.kexectools ];
|
||||||
|
|
||||||
|
systemd.services."prepare-kexec" =
|
||||||
|
{ description = "Preparation for kexec";
|
||||||
|
wantedBy = [ "kexec.target" ];
|
||||||
|
before = [ "systemd-kexec.service" ];
|
||||||
|
unitConfig.DefaultDependencies = false;
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
path = [ pkgs.kexectools ];
|
||||||
|
script =
|
||||||
|
''
|
||||||
|
p=$(readlink -f /nix/var/nix/profiles/system)
|
||||||
|
if ! [ -d $p ]; then exit 1; fi
|
||||||
|
exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -129,6 +129,7 @@ let
|
||||||
"umount.target"
|
"umount.target"
|
||||||
"final.target"
|
"final.target"
|
||||||
"kexec.target"
|
"kexec.target"
|
||||||
|
"systemd-kexec.service"
|
||||||
|
|
||||||
# Password entry.
|
# Password entry.
|
||||||
"systemd-ask-password-console.path"
|
"systemd-ask-password-console.path"
|
||||||
|
|
|
@ -10,6 +10,7 @@ with import ../lib/testing.nix { inherit system minimal; };
|
||||||
installer = makeTests (import ./installer.nix);
|
installer = makeTests (import ./installer.nix);
|
||||||
ipv6 = makeTest (import ./ipv6.nix);
|
ipv6 = makeTest (import ./ipv6.nix);
|
||||||
kde4 = makeTest (import ./kde4.nix);
|
kde4 = makeTest (import ./kde4.nix);
|
||||||
|
#kexec = makeTest (import ./kexec.nix);
|
||||||
login = makeTest (import ./login.nix {});
|
login = makeTest (import ./login.nix {});
|
||||||
latestKernel.login = makeTest (import ./login.nix ({ config, pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; }));
|
latestKernel.login = makeTest (import ./login.nix ({ config, pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; }));
|
||||||
misc = makeTest (import ./misc.nix);
|
misc = makeTest (import ./misc.nix);
|
||||||
|
|
18
tests/kexec.nix
Normal file
18
tests/kexec.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Test whether fast reboots via kexec work.
|
||||||
|
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
machine = { config, pkgs, ... }:
|
||||||
|
{ virtualisation.vlans = [ ]; };
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
''
|
||||||
|
$machine->waitForUnit("multi-user.target");
|
||||||
|
$machine->execute("systemctl kexec &");
|
||||||
|
$machine->{connected} = 0;
|
||||||
|
$machine->waitForUnit("multi-user.target");
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue