diff options
author | Niklas Hambüchen <mail@nh2.me> | 2017-12-11 04:05:15 +0100 |
---|---|---|
committer | Niklas Hambüchen <mail@nh2.me> | 2017-12-29 16:26:18 +0100 |
commit | 5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0 (patch) | |
tree | 99159701fb500a235b1682f184ff1b89a8fa11ca /pkgs/tools/virtualization | |
parent | 857a71cbc51017ad660316f860a6fccf1a700c67 (diff) | |
download | nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar.gz nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar.bz2 nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar.lz nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar.xz nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.tar.zst nixlib-5d83988c1e4a666086c0ba96cae7ab6cbb41c3b0.zip |
nixos-container: Fix `destroy` terminating before it's done. Fixes #32545.
This also fixes the race condition found in #32551. And it fixes nixops's repeated destroy/deploy being broken (https://github.com/NixOS/nixops/issues/809).
Diffstat (limited to 'pkgs/tools/virtualization')
-rwxr-xr-x | pkgs/tools/virtualization/nixos-container/nixos-container.pl | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/pkgs/tools/virtualization/nixos-container/nixos-container.pl b/pkgs/tools/virtualization/nixos-container/nixos-container.pl index fefdcd614a56..2cb723a7b71a 100755 --- a/pkgs/tools/virtualization/nixos-container/nixos-container.pl +++ b/pkgs/tools/virtualization/nixos-container/nixos-container.pl @@ -7,6 +7,7 @@ use File::Slurp; use Fcntl ':flock'; use Getopt::Long qw(:config gnu_getopt); use Cwd 'abs_path'; +use Time::HiRes; my $nsenter = "@utillinux@/bin/nsenter"; my $su = "@su@"; @@ -214,14 +215,31 @@ if (!-e $confFile) { die "$0: container ‘$containerName’ does not exist\n" ; } +# Return the PID of the init process of the container. +sub getLeader { + my $s = `machinectl show "$containerName" -p Leader`; + chomp $s; + $s =~ /^Leader=(\d+)$/ or die "unable to get container's main PID\n"; + return int($1); +} + sub isContainerRunning { my $status = `systemctl show 'container\@$containerName'`; return $status =~ /ActiveState=active/; } sub terminateContainer { + my $leader = getLeader; system("machinectl", "terminate", $containerName) == 0 or die "$0: failed to terminate container\n"; + # Wait for the leader process to exit + # TODO: As for any use of PIDs for process control where the process is + # not a direct child of ours, this can go wrong when the pid gets + # recycled after a PID overflow. + # Relying entirely on some form of UUID provided by machinectl + # instead of PIDs would remove this risk. + # See https://github.com/NixOS/nixpkgs/pull/32992#discussion_r158586048 + while ( kill 0, $leader ) { Time::HiRes::sleep(0.1) } } sub stopContainer { @@ -229,14 +247,6 @@ sub stopContainer { or die "$0: failed to stop container\n"; } -# Return the PID of the init process of the container. -sub getLeader { - my $s = `machinectl show "$containerName" -p Leader`; - chomp $s; - $s =~ /^Leader=(\d+)$/ or die "unable to get container's main PID\n"; - return int($1); -} - # Run a command in the container. sub runInContainer { my @args = @_; |