[pve-devel] [PATCH container 1/2] Use lock_container when checking locks

Fabian Grünbichler f.gruenbichler at proxmox.com
Tue Jan 19 11:20:52 CET 2016


This should prevent race conditions by preventing config
file changes inbetween checking locks and actually doing
the start/stop/.. operation.

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 src/PVE/API2/LXC/Status.pm | 83 ++++++++++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/src/PVE/API2/LXC/Status.pm b/src/PVE/API2/LXC/Status.pm
index e119211..8d59436 100644
--- a/src/PVE/API2/LXC/Status.pm
+++ b/src/PVE/API2/LXC/Status.pm
@@ -156,20 +156,24 @@ __PACKAGE__->register_method({
 
 		syslog('info', "starting CT $vmid: $upid\n");
 
-		my $conf = PVE::LXC::load_config($vmid);
+		my $lockcmd = sub {
+		    my $conf = PVE::LXC::load_config($vmid);
 
-		die "you can't start a CT if it's a template\n"
-		    if PVE::LXC::is_template($conf);
+		    die "you can't start a CT if it's a template\n"
+			if PVE::LXC::is_template($conf);
 
-		PVE::LXC::check_lock($conf);
+		    PVE::LXC::check_lock($conf);
 
-		my $storage_cfg = cfs_read_file("storage.cfg");
+		    my $storage_cfg = cfs_read_file("storage.cfg");
 
-		PVE::LXC::update_lxc_config($storage_cfg, $vmid, $conf);
+		    PVE::LXC::update_lxc_config($storage_cfg, $vmid, $conf);
 
-		my $cmd = ['lxc-start', '-n', $vmid];
+		    my $cmd = ['lxc-start', '-n', $vmid];
 
-		run_command($cmd);
+		    run_command($cmd);
+		};
+
+		PVE::LXC::lock_container($vmid, 10, $lockcmd);
 
 		return;
 	    };
@@ -236,13 +240,17 @@ __PACKAGE__->register_method({
 
 		syslog('info', "stopping CT $vmid: $upid\n");
 
-		my $conf = PVE::LXC::load_config($vmid);
+		my $lockcmd = sub {
+		    my $conf = PVE::LXC::load_config($vmid);
 
-		PVE::LXC::check_lock($conf);
+		    PVE::LXC::check_lock($conf);
 
-		my $cmd = ['lxc-stop', '-n', $vmid, '--kill'];
+		    my $cmd = ['lxc-stop', '-n', $vmid, '--kill'];
 
-		run_command($cmd);
+		    run_command($cmd);
+		};
+
+		PVE::LXC::lock_container($vmid, 10, $lockcmd);
 
 		return;
 	    };
@@ -304,32 +312,37 @@ __PACKAGE__->register_method({
 
 	    syslog('info', "shutdown CT $vmid: $upid\n");
 
-	    my $cmd = ['lxc-stop', '-n', $vmid];
+	    my $lockcmd = sub {
+		my $cmd = ['lxc-stop', '-n', $vmid];
 
-	    $timeout = 60 if !defined($timeout);
+		$timeout = 60 if !defined($timeout);
 
-	    my $conf = PVE::LXC::load_config($vmid);
+		my $conf = PVE::LXC::load_config($vmid);
 
-	    PVE::LXC::check_lock($conf);
+		PVE::LXC::check_lock($conf);
 
-	    my $storage_cfg = PVE::Storage::config();
+		my $storage_cfg = PVE::Storage::config();
 
-	    push @$cmd, '--timeout', $timeout;
+		push @$cmd, '--timeout', $timeout;
 
-	    eval { run_command($cmd, timeout => $timeout+5); };
-	    my $err = $@;
-	    if ($err && $param->{forceStop}) {
-		$err = undef;
-		warn "shutdown failed - forcing stop now\n";
+		eval { run_command($cmd, timeout => $timeout+5); };
+		my $err = $@;
+		if ($err && $param->{forceStop}) {
+		    $err = undef;
+		    warn "shutdown failed - forcing stop now\n";
 
-		my $cmd = ['lxc-stop', '-n', $vmid, '--kill'];
-		run_command($cmd);
-	    }
+		    my $cmd = ['lxc-stop', '-n', $vmid, '--kill'];
+		    run_command($cmd);
+		}
+	    };
+
+	    PVE::LXC::lock_container($vmid, 10, $lockcmd);
 
 	    # make sure container is stopped
-	    $cmd = ['lxc-wait',  '-n', $vmid, '-t', 5, '-s', 'STOPPED'];
+	    my $cmd = ['lxc-wait',  '-n', $vmid, '-t', 5, '-s', 'STOPPED'];
 	    run_command($cmd);
-	    
+	    my $err = $@;
+
 	    die $err if $err;
 
 	    return;
@@ -378,15 +391,19 @@ __PACKAGE__->register_method({
 
             syslog('info', "suspend CT $vmid: $upid\n");
 
-	    my $conf = PVE::LXC::load_config($vmid);
+	    my $lockcmd = sub {
+		my $conf = PVE::LXC::load_config($vmid);
+
+		PVE::LXC::check_lock($conf);
 
-	    PVE::LXC::check_lock($conf);
+		my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/liv/vz/dump'];
 
-	    my $cmd = ['lxc-checkpoint', '-n', $vmid, '-s', '-D', '/var/liv/vz/dump'];
+		run_command($cmd);
+	    };
 
-	    run_command($cmd);
+	    PVE::LXC::lock_container($vmid, 10, $lockcmd);
 
-            return;
+	    return;
         };
 
         my $upid = $rpcenv->fork_worker('vzsuspend', $vmid, $authuser, $realcmd);
-- 
2.1.4





More information about the pve-devel mailing list