]> git.proxmox.com Git - pve-container.git/commitdiff
Improve feedback for startup
authorFabian Ebner <f.ebner@proxmox.com>
Tue, 8 Sep 2020 11:58:43 +0000 (13:58 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 9 Sep 2020 18:54:57 +0000 (20:54 +0200)
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@proxmox.com>
src/PVE/LXC.pm

index db5b8ca6ce82d9d40dbca1045b5afcb12da1a89e..370adda251a1322af2b64568be485966cc45d237 100644 (file)
@@ -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;