From ff867097e8a5ea1ab6ff1d5cbc381a4212c37254 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 9 Mar 2017 14:54:28 +0100 Subject: [PATCH] poststop: reboot: wait for lxc to exit before rebooting otherwise it'll leak cgroup directories... Note that we need to escape the lxc@.service context (by entering a new scope) as well as close our ties to the lxc monitor (the stdout pipe), otherwise this never finishes properly. --- src/lxc-pve-poststop-hook | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/lxc-pve-poststop-hook b/src/lxc-pve-poststop-hook index a4302d6..e3a8956 100755 --- a/src/lxc-pve-poststop-hook +++ b/src/lxc-pve-poststop-hook @@ -9,6 +9,7 @@ exit 0 if $ENV{LXC_NAME} && $ENV{LXC_NAME} !~ /^\d+$/; use POSIX; use File::Path; +use IO::Pipe; use PVE::SafeSyslog; use PVE::Tools; @@ -81,9 +82,39 @@ __PACKAGE__->register_method ({ # that we must not block because we're part of the service cgroup # systemd waits for to die before issuing the new lxc-start command. PVE::LXC::update_lxc_config($vmid, $conf); - PVE::Tools::run_command(['systemctl', '--no-block', 'restart', "lxc\@$vmid"]); + $SIG{HUP} = 'IGNORE'; + # Synchronization pipe + my $scope = IO::Pipe->new() or die "pipe failed: $!\n"; + my $pid = fork(); + die "fork failed: $!\n" if !defined($pid); + if (!$pid) { + $scope->writer(); + # We inherit a pipe from LXC, replace it with stderr otherwise + # lxc will keep waiting for us... + POSIX::dup2(2, 1); + POSIX::setsid(); + eval { + # Change scope otherwise we're part of lxc@.service and then + # if lxc finishes cleaning up before we restart it systemd + # might clean US up as well (read: kill us) => race + PVE::Tools::enter_systemd_scope("restart-$vmid", "Restarter for Proxmox VE CT $vmid", + Slice => 'lxc.slice', + KillMode => 'none'); + # Tell the main stop hook we're "in the clear": + close($scope); + # Wait for the container to clean up everything... + PVE::Tools::run_command(['lxc-wait', "--name=$vmid", '--state=STOPPED']); + # ... before finally triggering a restart: + PVE::Tools::run_command(['systemctl', 'restart', "lxc\@$vmid"]); + }; + warn "$@" if $@; + POSIX::_exit(0); + } + # Wait for the restarter scope to make sure systemd doesn't kill it before it started... + $scope->reader(); + <$scope>; # cause lxc to stop instead of rebooting - POSIX::_exit(1); + exit(1); } return undef; -- 2.39.2