[pve-devel] [PATCH v2 container 2/2] Improve feedback for startup

Fabian Ebner f.ebner at proxmox.com
Tue Sep 8 13:58:43 CEST 2020


Since it was necessary to switch to 'Type=Simple' in the systemd
service, see 545d6f0a13ac2bf3a8d3f224c19c0e0def12116d,
'systemctl start' would not wait for the 'lxc-start' command anymore.
Thus every container start was reported as a success and the 'post-start'
hook would trigger immediately after the 'systemctl start' command.

Use the monitor socket to get the necessary information and detect
startup failure, and only run the 'post-start' hookscript after
the container is effectively running. If something goes wrong
with the monitor socket, for example if lxc-monitord is not running,
fall back to the old behavior.

Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---

Changes from v1:
    * use monitor socket directly instead of forking off an lxc-monitor process
    * use run_with_timeout helper
    * warn instead of die on unexpected message

 src/PVE/LXC.pm | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index db5b8ca..370adda 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -32,6 +32,7 @@ use PVE::LXC::Config;
 use PVE::GuestHelpers qw(safe_string_ne safe_num_ne safe_boolean_ne);
 use PVE::LXC::Tools;
 use PVE::LXC::CGroup;
+use PVE::LXC::Monitor;
 
 use Time::HiRes qw (gettimeofday);
 my $have_sdn;
@@ -2191,10 +2192,47 @@ sub vm_start {
 
     PVE::Storage::activate_volumes($storage_cfg, $vollist);
 
+    my $monitor_socket = eval { PVE::LXC::Monitor::get_monitor_socket(); };
+    warn $@ if $@;
+
+    my $monitor_state_change = sub {
+	die "no monitor socket" if !defined($monitor_socket);
+
+	while (1) {
+	    my ($type, $name, $value) = PVE::LXC::Monitor::read_lxc_message($monitor_socket);
+
+	    die "monitor socket EOF" if !defined($type);
+
+	    next if $name ne "$vmid" || $type ne 'STATE';
+
+	    if ($value eq PVE::LXC::Monitor::STATE_STARTING) {
+		alarm(0); # don't timeout after seeing the starting state
+	    } elsif ($value eq PVE::LXC::Monitor::STATE_ABORTING ||
+		     $value eq PVE::LXC::Monitor::STATE_STOPPING ||
+		     $value eq PVE::LXC::Monitor::STATE_STOPPED) {
+		return 0;
+	    } elsif ($value eq PVE::LXC::Monitor::STATE_RUNNING) {
+		return 1;
+	    } else {
+		warn "unexpected message from monitor socket - " .
+		     "type: '$type' - value: '$value'\n";
+	    }
+	}
+    };
+
     my $cmd = ['systemctl', 'start', "pve-container\@$vmid"];
 
     PVE::GuestHelpers::exec_hookscript($conf, $vmid, 'pre-start', 1);
-    eval { PVE::Tools::run_command($cmd); };
+    eval {
+	PVE::Tools::run_command($cmd);
+
+	my $success = eval { PVE::Tools::run_with_timeout(10, $monitor_state_change); };
+	if (my $err = $@) {
+	    warn "problem with monitor socket: $err - continuing anyway\n";
+	} elsif (!$success) {
+	    die "startup for container '$vmid' failed\n";
+	}
+    };
     if (my $err = $@) {
 	unlink $skiplock_flag_fn;
 	die $err;
-- 
2.20.1






More information about the pve-devel mailing list