From de128feaccaf9751d7092d83f7dcc488f51a4dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Sun, 10 Oct 2021 17:58:06 +0200 Subject: [PATCH] nixos/switch-to-configuration: Ignore slice units --- .../activation/switch-to-configuration.pl | 4 +-- nixos/tests/switch-test.nix | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index 58453dddc602..d5b7f0c07300 100644 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -152,7 +152,7 @@ sub fingerprintUnit { sub handleModifiedUnit { my ($unit, $baseName, $newUnitFile, $activePrev, $unitsToStop, $unitsToStart, $unitsToReload, $unitsToRestart, $unitsToSkip) = @_; - if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target") { + if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target" || $unit =~ /\.slice$/) { # Do nothing. These cannot be restarted directly. # Slices and Paths don't have to be restarted since # properties (resource limits and inotify watches) @@ -161,7 +161,7 @@ sub handleModifiedUnit { # Reload the changed mount unit to force a remount. $unitsToReload->{$unit} = 1; recordUnit($reloadListFile, $unit); - } elsif ($unit =~ /\.slice$/ || $unit =~ /\.path$/) { + } elsif ($unit =~ /\.path$/) { # FIXME: do something? } else { my $unitInfo = parseUnit($newUnitFile); diff --git a/nixos/tests/switch-test.nix b/nixos/tests/switch-test.nix index 76a9ef6f624e..1acccbd17540 100644 --- a/nixos/tests/switch-test.nix +++ b/nixos/tests/switch-test.nix @@ -107,6 +107,8 @@ import ./make-test-python.nix ({ pkgs, ...} : { }; }; }; + + # The same system but with an activation script that restarts all services restart-and-reload-by-activation-script.configuration = { imports = [ config.specialisation.service-and-socket.configuration ]; system.activationScripts.restart-and-reload-test = { @@ -128,6 +130,25 @@ import ./make-test-python.nix ({ pkgs, ...} : { ''; }; }; + + # A system with a slice + with-slice.configuration = { + systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation + systemd.services.testservice = { + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.coreutils}/bin/true"; + Slice = "testslice.slice"; + }; + }; + }; + + # The same system but the slice allows to allocate memory + with-slice-non-crashing.configuration = { + imports = [ config.specialisation.with-slice.configuration ]; + systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null; + }; }; }; other = { ... }: { @@ -263,5 +284,18 @@ import ./make-test-python.nix ({ pkgs, ...} : { assert_contains(out, "would restart the following units: simple-restart-service.service\n") assert_contains(out, "\nwould start the following units: simple-service.service") + # This test ensures that changes to slice configuration get applied. + # We test this by having a slice that allows no memory allocation at + # all and starting a service within it. If the service crashes, the slice + # is applied and if we modify the slice to allow memory allocation, the + # service should successfully start. + with subtest("slices"): + machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing + out = switch_to_specialisation("with-slice") + machine.fail("systemctl start testservice.service") + out = switch_to_specialisation("with-slice-non-crashing") + machine.succeed("systemctl start testservice.service") + machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing + ''; })