at 23.05-pre 4.3 kB view raw
1# Test whether hibernation from partition works. 2 3{ system ? builtins.currentSystem 4, config ? {} 5, pkgs ? import ../.. { inherit system config; } 6, systemdStage1 ? false 7}: 8 9with import ../lib/testing-python.nix { inherit system pkgs; }; 10 11let 12 # System configuration of the installed system, which is used for the actual 13 # hibernate testing. 14 installedConfig = with pkgs.lib; { 15 imports = [ 16 ../modules/testing/test-instrumentation.nix 17 ../modules/profiles/qemu-guest.nix 18 ../modules/profiles/minimal.nix 19 ]; 20 21 hardware.enableAllFirmware = mkForce false; 22 documentation.nixos.enable = false; 23 boot.loader.grub.device = "/dev/vda"; 24 25 systemd.services.backdoor.conflicts = [ "sleep.target" ]; 26 27 powerManagement.resumeCommands = "systemctl --no-block restart backdoor.service"; 28 29 fileSystems."/" = { 30 device = "/dev/vda2"; 31 fsType = "ext3"; 32 }; 33 swapDevices = mkOverride 0 [ { device = "/dev/vda1"; } ]; 34 boot.resumeDevice = mkIf systemdStage1 "/dev/vda1"; 35 boot.initrd.systemd = mkIf systemdStage1 { 36 enable = true; 37 emergencyAccess = true; 38 }; 39 }; 40 installedSystem = (import ../lib/eval-config.nix { 41 inherit system; 42 modules = [ installedConfig ]; 43 }).config.system.build.toplevel; 44in makeTest { 45 name = "hibernate"; 46 47 nodes = { 48 # System configuration used for installing the installedConfig from above. 49 machine = { config, lib, pkgs, ... }: with lib; { 50 imports = [ 51 ../modules/profiles/installation-device.nix 52 ../modules/profiles/base.nix 53 ]; 54 55 nix.settings = { 56 substituters = mkForce []; 57 hashed-mirrors = null; 58 connect-timeout = 1; 59 }; 60 61 virtualisation.diskSize = 8 * 1024; 62 virtualisation.emptyDiskImages = [ 63 # Small root disk for installer 64 512 65 ]; 66 virtualisation.bootDevice = "/dev/vdb"; 67 }; 68 }; 69 70 # 9P doesn't support reconnection to virtio transport after a hibernation. 71 # Therefore, machine just hangs on any Nix store access. 72 # To avoid this, we install NixOS onto a temporary disk with everything we need 73 # included into the store. 74 75 testScript = 76 '' 77 def create_named_machine(name): 78 machine = create_machine( 79 { 80 "qemuFlags": "-cpu max ${ 81 if system == "x86_64-linux" then "-m 1024" 82 else "-m 768 -enable-kvm -machine virt,gic-version=host"}", 83 "hdaInterface": "virtio", 84 "hda": "vm-state-machine/machine.qcow2", 85 "name": name, 86 } 87 ) 88 driver.machines.append(machine) 89 return machine 90 91 92 # Install NixOS 93 machine.start() 94 machine.succeed( 95 # Partition /dev/vda 96 "flock /dev/vda parted --script /dev/vda -- mklabel msdos" 97 + " mkpart primary linux-swap 1M 1024M" 98 + " mkpart primary ext2 1024M -1s", 99 "udevadm settle", 100 "mkfs.ext3 -L nixos /dev/vda2", 101 "mount LABEL=nixos /mnt", 102 "mkswap /dev/vda1 -L swap", 103 # Install onto /mnt 104 "nix-store --load-db < ${pkgs.closureInfo {rootPaths = [installedSystem];}}/registration", 105 "nixos-install --root /mnt --system ${installedSystem} --no-root-passwd --no-channel-copy >&2", 106 ) 107 machine.shutdown() 108 109 # Start up 110 hibernate = create_named_machine("hibernate") 111 112 # Drop in file that checks if we un-hibernated properly (and not booted fresh) 113 hibernate.succeed( 114 "mkdir /run/test", 115 "mount -t ramfs -o size=1m ramfs /run/test", 116 "echo not persisted to disk > /run/test/suspended", 117 ) 118 119 # Hibernate machine 120 hibernate.execute("systemctl hibernate >&2 &", check_return=False) 121 hibernate.wait_for_shutdown() 122 123 # Restore machine from hibernation, validate our ramfs file is there. 124 resume = create_named_machine("resume") 125 resume.start() 126 resume.succeed("grep 'not persisted to disk' /run/test/suspended") 127 128 # Ensure we don't restore from hibernation when booting again 129 resume.crash() 130 resume.wait_for_unit("default.target") 131 resume.fail("grep 'not persisted to disk' /run/test/suspended") 132 ''; 133 134}