]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
clone: use new config_lock_shared
[qemu-server.git] / PVE / API2 / Qemu.pm
index 87fbd72aaff7789d7da5f4b7569eceb9aa454078..9fb886b4600eb367d49bee5a86c804476122d392 100644 (file)
@@ -1468,32 +1468,38 @@ __PACKAGE__->register_method({
        raise_param_exc({ skiplock => "Only root may use this option." })
            if $skiplock && $authuser ne 'root@pam';
 
-       # test if VM exists
-       my $conf = PVE::QemuConfig->load_config($vmid);
-       my $storecfg = PVE::Storage::config();
-       PVE::QemuConfig->check_protection($conf, "can't remove VM $vmid");
+       my $early_checks = sub {
+           # test if VM exists
+           my $conf = PVE::QemuConfig->load_config($vmid);
+           PVE::QemuConfig->check_protection($conf, "can't remove VM $vmid");
 
-       my $ha_managed = PVE::HA::Config::service_is_configured("vm:$vmid");
+           my $ha_managed = PVE::HA::Config::service_is_configured("vm:$vmid");
 
-       if (!$param->{purge}) {
-           die "unable to remove VM $vmid - used in HA resources and purge parameter not set.\n"
-               if $ha_managed;
-           # don't allow destroy if with replication jobs but no purge param
-           my $repl_conf = PVE::ReplicationConfig->new();
-           $repl_conf->check_for_existing_jobs($vmid);
-       }
+           if (!$param->{purge}) {
+               die "unable to remove VM $vmid - used in HA resources and purge parameter not set.\n"
+                   if $ha_managed;
+               # don't allow destroy if with replication jobs but no purge param
+               my $repl_conf = PVE::ReplicationConfig->new();
+               $repl_conf->check_for_existing_jobs($vmid);
+           }
+
+           die "VM $vmid is running - destroy failed\n"
+               if PVE::QemuServer::check_running($vmid);
+
+           return $ha_managed;
+       };
 
-       # early tests (repeat after locking)
-       die "VM $vmid is running - destroy failed\n"
-           if PVE::QemuServer::check_running($vmid);
+       $early_checks->();
 
        my $realcmd = sub {
            my $upid = shift;
 
+           my $storecfg = PVE::Storage::config();
+
            syslog('info', "destroy VM $vmid: $upid\n");
            PVE::QemuConfig->lock_config($vmid, sub {
-               die "VM $vmid is running - destroy failed\n"
-                   if (PVE::QemuServer::check_running($vmid));
+               # repeat, config might have changed
+               my $ha_managed = $early_checks->();
 
                PVE::QemuServer::destroy_vm($storecfg, $vmid, $skiplock, { lock => 'destroyed' });
 
@@ -2589,6 +2595,8 @@ __PACKAGE__->register_method({
            if $skiplock && $authuser ne 'root@pam';
 
        my $nocheck = extract_param($param, 'nocheck');
+       raise_param_exc({ nocheck => "Only root may use this option." })
+           if $nocheck && $authuser ne 'root@pam';
 
        my $to_disk_suspended;
        eval {
@@ -2850,9 +2858,6 @@ __PACKAGE__->register_method({
 
        my $running = PVE::QemuServer::check_running($vmid) || 0;
 
-       # exclusive lock if VM is running - else shared lock is enough;
-       my $shared_lock = $running ? 0 : 1;
-
        my $clonefn = sub {
            # do all tests after lock but before forking worker - if possible
 
@@ -3040,11 +3045,17 @@ __PACKAGE__->register_method({
            return $rpcenv->fork_worker('qmclone', $vmid, $authuser, $realcmd);
        };
 
-       return PVE::QemuConfig->lock_config_mode($vmid, 1, $shared_lock, sub {
-           # Aquire exclusive lock lock for $newid
+       # Aquire exclusive lock lock for $newid
+       my $lock_target_vm = sub {
            return PVE::QemuConfig->lock_config_full($newid, 1, $clonefn);
-       });
+       };
 
+       # exclusive lock if VM is running - else shared lock is enough;
+       if ($running) {
+           return PVE::QemuConfig->lock_config_full($vmid, 1, $lock_target_vm);
+       } else {
+           return PVE::QemuConfig->lock_config_shared($vmid, 1, $lock_target_vm);
+       }
     }});
 
 __PACKAGE__->register_method({
@@ -3455,9 +3466,6 @@ __PACKAGE__->register_method({
            $param->{online} = 0;
        }
 
-       raise_param_exc({ targetstorage => "Live storage migration can only be done online." })
-           if !$param->{online} && $param->{targetstorage};
-
        my $storecfg = PVE::Storage::config();
 
        if (my $targetstorage = $param->{targetstorage}) {
@@ -3687,8 +3695,7 @@ __PACKAGE__->register_method({
 
            PVE::QemuServer::qemu_block_resize($vmid, "drive-$disk", $storecfg, $volid, $newsize);
 
-           my $effective_size = eval { PVE::Storage::volume_size_info($storecfg, $volid, 3); };
-           $drive->{size} = $effective_size // $newsize;
+           $drive->{size} = $newsize;
            $conf->{$disk} = PVE::QemuServer::print_drive($drive);
 
            PVE::QemuConfig->write_config($vmid, $conf);