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.
wip/yesman
Eelco Dolstra 11 years ago
parent 5332480454
commit b825169404
  1. 22
      doc/manual/running.xml
  2. 4
      lib/test-driver/Machine.pm
  3. 1
      modules/module-list.nix
  4. 21
      modules/system/boot/kexec.nix
  5. 1
      modules/system/boot/systemd.nix
  6. 1
      tests/default.nix
  7. 18
      tests/kexec.nix

@ -101,9 +101,25 @@ doing:
$ shutdown
</screen>
This is equivalent to running <command>systemctl poweroff</command>.
Likewise, <command>reboot</command> (a.k.a. <command>systemctl
reboot</command>) will reboot the system.</para>
This is equivalent to running <command>systemctl
poweroff</command>.</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
<command>systemctl suspend</command>, and suspended to disk using

@ -232,9 +232,9 @@ sub connect {
$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;
readline $self->{socket} or die;
readline $self->{socket} or die "the VM quit before connecting\n";
alarm 0;
$self->log("connected to guest root shell");

@ -235,6 +235,7 @@
./system/activation/activation-script.nix
./system/activation/top-level.nix
./system/boot/kernel.nix
./system/boot/kexec.nix
./system/boot/loader/efi-boot-stub/efi-boot-stub.nix
./system/boot/loader/efi.nix
./system/boot/loader/generations-dir/generations-dir.nix

@ -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"
"final.target"
"kexec.target"
"systemd-kexec.service"
# Password entry.
"systemd-ask-password-console.path"

@ -10,6 +10,7 @@ with import ../lib/testing.nix { inherit system minimal; };
installer = makeTests (import ./installer.nix);
ipv6 = makeTest (import ./ipv6.nix);
kde4 = makeTest (import ./kde4.nix);
#kexec = makeTest (import ./kexec.nix);
login = makeTest (import ./login.nix {});
latestKernel.login = makeTest (import ./login.nix ({ config, pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; }));
misc = makeTest (import ./misc.nix);

@ -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…
Cancel
Save