]> git.proxmox.com Git - pve-container.git/commitdiff
api: status: move config locking from API handler into worker
authorFriedrich Weber <f.weber@proxmox.com>
Tue, 30 Jan 2024 17:10:53 +0000 (18:10 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 4 Apr 2024 15:21:05 +0000 (17:21 +0200)
Previously, container start/stop/shutdown/suspend would try to acquire
the config lock in the API handler prior to forking a worker. If the
lock was currently held elsewhere, this would block the API handler
and thus the pvedaemon worker thread until the 10s timeout expired (or
the lock could be acquired).

To avoid blocking the API handler, immediately fork off a worker
process and try to acquire the config lock in that worker.

Patch best viewed with `git show -w`.

Suggested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Friedrich Weber <f.weber@proxmox.com>
src/PVE/API2/LXC/Status.pm

index f7e31289d0995d6b2f69a4919df9d9bfc5f1e71e..77413748dc4e7f317f61ed52870350cefea2f709 100644 (file)
@@ -176,32 +176,31 @@ __PACKAGE__->register_method({
            my $realcmd = sub {
                my $upid = shift;
 
-               syslog('info', "starting CT $vmid: $upid\n");
+               PVE::LXC::Config->lock_config($vmid, sub {
+                   syslog('info', "starting CT $vmid: $upid\n");
 
-               my $conf = PVE::LXC::Config->load_config($vmid);
-
-               die "you can't start a CT if it's a template\n"
-                   if PVE::LXC::Config->is_template($conf);
+                   my $conf = PVE::LXC::Config->load_config($vmid);
 
-               if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
-                   PVE::LXC::Config->check_lock($conf);
-               }
+                   die "you can't start a CT if it's a template\n"
+                       if PVE::LXC::Config->is_template($conf);
 
-               if ($conf->{unprivileged}) {
-                   PVE::LXC::Config->foreach_volume($conf, sub {
-                       my ($ms, $mountpoint) = @_;
-                       die "Quotas are not supported by unprivileged containers.\n" if $mountpoint->{quota};
-                   });
-               }
+                   if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
+                       PVE::LXC::Config->check_lock($conf);
+                   }
 
-               PVE::LXC::vm_start($vmid, $conf, $skiplock, $param->{debug});
-           };
+                   if ($conf->{unprivileged}) {
+                       PVE::LXC::Config->foreach_volume($conf, sub {
+                           my ($ms, $mountpoint) = @_;
+                           die "Quotas are not supported by unprivileged containers.\n"
+                               if $mountpoint->{quota};
+                       });
+                   }
 
-           my $lockcmd = sub {
-               return $rpcenv->fork_worker('vzstart', $vmid, $authuser, $realcmd);
+                   PVE::LXC::vm_start($vmid, $conf, $skiplock, $param->{debug});
+               });
            };
 
-           return PVE::LXC::Config->lock_config($vmid, $lockcmd);
+           return $rpcenv->fork_worker('vzstart', $vmid, $authuser, $realcmd);
        }
     }});
 
@@ -258,21 +257,19 @@ __PACKAGE__->register_method({
            my $realcmd = sub {
                my $upid = shift;
 
-               syslog('info', "stopping CT $vmid: $upid\n");
+               PVE::LXC::Config->lock_config($vmid, sub {
+                   syslog('info', "stopping CT $vmid: $upid\n");
 
-               my $conf = PVE::LXC::Config->load_config($vmid);
-               if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
-                   PVE::LXC::Config->check_lock($conf);
-               }
+                   my $conf = PVE::LXC::Config->load_config($vmid);
+                   if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
+                       PVE::LXC::Config->check_lock($conf);
+                   }
 
-               PVE::LXC::vm_stop($vmid, 1);
+                   PVE::LXC::vm_stop($vmid, 1);
+               });
            };
 
-           my $lockcmd = sub {
-               return $rpcenv->fork_worker('vzstop', $vmid, $authuser, $realcmd);
-           };
-
-           return PVE::LXC::Config->lock_config($vmid, $lockcmd);
+           return $rpcenv->fork_worker('vzstop', $vmid, $authuser, $realcmd);
        }
     }});
 
@@ -339,19 +336,17 @@ __PACKAGE__->register_method({
        my $realcmd = sub {
            my $upid = shift;
 
-           syslog('info', "shutdown CT $vmid: $upid\n");
-
-           my $conf = PVE::LXC::Config->load_config($vmid);
-           PVE::LXC::Config->check_lock($conf);
+           PVE::LXC::Config->lock_config($vmid, sub {
+               syslog('info', "shutdown CT $vmid: $upid\n");
 
-           PVE::LXC::vm_stop($vmid, 0, $timeout, $param->{forceStop});
-       };
+               my $conf = PVE::LXC::Config->load_config($vmid);
+               PVE::LXC::Config->check_lock($conf);
 
-       my $lockcmd = sub {
-           return $rpcenv->fork_worker('vzshutdown', $vmid, $authuser, $realcmd);
+               PVE::LXC::vm_stop($vmid, 0, $timeout, $param->{forceStop});
+           });
        };
 
-       return PVE::LXC::Config->lock_config($vmid, $lockcmd);
+       return $rpcenv->fork_worker('vzshutdown', $vmid, $authuser, $realcmd);
     }});
 
 __PACKAGE__->register_method({
@@ -388,20 +383,18 @@ __PACKAGE__->register_method({
        my $realcmd = sub {
            my $upid = shift;
 
-           syslog('info', "suspend CT $vmid: $upid\n");
-
-           my $conf = PVE::LXC::Config->load_config($vmid);
-           PVE::LXC::Config->check_lock($conf);
+           PVE::LXC::Config->lock_config($vmid, sub {
+               syslog('info', "suspend CT $vmid: $upid\n");
 
-           my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/lib/vz/dump'];
-           run_command($cmd);
-       };
+               my $conf = PVE::LXC::Config->load_config($vmid);
+               PVE::LXC::Config->check_lock($conf);
 
-       my $lockcmd = sub {
-           return $rpcenv->fork_worker('vzsuspend', $vmid, $authuser, $realcmd);
+               my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/lib/vz/dump'];
+               run_command($cmd);
+           });
        };
 
-       return PVE::LXC::Config->lock_config($vmid, $lockcmd);
+       return $rpcenv->fork_worker('vzsuspend', $vmid, $authuser, $realcmd);
     }});
 
 __PACKAGE__->register_method({