[pve-devel] [PATCH container] poststop: reboot: wait for lxc to exit before rebooting

Wolfgang Bumiller w.bumiller at proxmox.com
Thu Mar 9 14:54:28 CET 2017


otherwise it'll leak cgroup directories...

Note that we need to escape the lxc at .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 at .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.1.4





More information about the pve-devel mailing list