]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/API2/Qemu.pm
replace file_size_info by volume_size_info.
[qemu-server.git] / PVE / API2 / Qemu.pm
index 4978fb35c6a5983f21c77664c77b2556dae1421b..dccfbcc00ece08e77bc12bf5223af181d7f18a70 100644 (file)
@@ -53,8 +53,7 @@ my $check_storage_access = sub {
            die "no storage ID specified (and no default storage)\n" if !$storeid;
            $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
        } else {
-           my $path = $rpcenv->check_volume_access($authuser, $storecfg, $vmid, $volid);
-           die "image '$path' does not exists\n" if (!(-f $path || -b $path));
+           $rpcenv->check_volume_access($authuser, $storecfg, $vmid, $volid);
        }
     });
 };
@@ -87,7 +86,22 @@ my $create_disks = sub {
            $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
        } else {
            my $path = $rpcenv->check_volume_access($authuser, $storecfg, $vmid, $volid);
-           die "image '$path' does not exists\n" if (!(-f $path || -b $path));
+           PVE::Storage::activate_volumes($storecfg, [ $volid ])
+               if PVE::Storage::parse_volume_id ($volid, 1);
+
+           my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid);
+           my $dl = PVE::Storage::vdisk_list($storecfg, $storeid, undef);
+           my $foundvolid = undef;
+
+           PVE::Storage::foreach_volid($dl, sub {
+               my ($volumeid) = @_;
+               if($volumeid eq $volid) {
+                   $foundvolid = 1;
+                   return;
+               }
+           });
+       
+           die "image '$path' does not exists\n" if (!(-f $path || -b $path || $foundvolid));
            $res->{$ds} = $settings->{$ds};
        }
     });
@@ -268,7 +282,6 @@ __PACKAGE__->register_method({
 
        if (defined($pool)) {
            $rpcenv->check_pool_exist($pool);
-           $rpcenv->check_perm_modify($authuser, "/pool/$pool");
        } 
 
        $rpcenv->check($authuser, "/storage/$storage", ['Datastore.AllocateSpace'])
@@ -298,9 +311,13 @@ __PACKAGE__->register_method({
 
            if ($archive eq '-') {
                die "pipe requires cli environment\n"
-                   && $rpcenv->{type} ne 'cli';
+                   if $rpcenv->{type} ne 'cli';
            } else {
                my $path = $rpcenv->check_volume_access($authuser, $storecfg, $vmid, $archive);
+
+               PVE::Storage::activate_volumes($storecfg, [ $archive ])
+                   if PVE::Storage::parse_volume_id ($archive, 1);
+
                die "can't find archive file '$archive'\n" if !($path && -f $path);
                $archive = $path;
            }
@@ -594,7 +611,7 @@ my $delete_drive = sub {
        if (&$vm_is_volid_owner($storecfg, $vmid, $volid)) {
            if ($force || $key =~ m/^unused/) {
                eval { PVE::Storage::vdisk_free($storecfg, $volid); };
-               warn $@ if $@;
+               die $@ if $@;
            } else {
                PVE::QemuServer::add_unused_volume($conf, $volid, $vmid);
            }
@@ -657,6 +674,15 @@ my $vmconfig_update_disk = sub {
                &$vmconfig_delete_option($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force);
                $conf = PVE::QemuServer::load_config($vmid); # update/reload
            }
+
+            if($drive->{bps} != $old_drive->{bps} ||
+               $drive->{bps_rd} != $old_drive->{bps_rd} ||
+               $drive->{bps_wr} != $old_drive->{bps_wr} ||
+               $drive->{iops} != $old_drive->{iops} ||
+               $drive->{iops_rd} != $old_drive->{iops_rd} ||
+               $drive->{iops_wr} != $old_drive->{iops_wr} ) {
+               PVE::QemuServer::qemu_block_set_io_throttle($vmid,"drive-$opt",$drive->{bps}, $drive->{bps_rd}, $drive->{bps_wr}, $drive->{iops}, $drive->{iops_rd}, $drive->{iops_wr}) if !PVE::QemuServer::drive_is_cdrom($drive);
+            }
        }
     }
 
@@ -670,11 +696,11 @@ my $vmconfig_update_disk = sub {
 
        if (PVE::QemuServer::check_running($vmid)) {
            if ($drive->{file} eq 'none') {
-               PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0);
+               PVE::QemuServer::vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
            } else {
                my $path = PVE::QemuServer::get_iso_path($storecfg, $vmid, $drive->{file});
-               PVE::QemuServer::vm_monitor_command($vmid, "eject -f drive-$opt", 0); #force eject if locked
-               PVE::QemuServer::vm_monitor_command($vmid, "change drive-$opt \"$path\"", 0) if $path;
+               PVE::QemuServer::vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt"); #force eject if locked
+               PVE::QemuServer::vm_mon_cmd($vmid, "change",device => "drive-$opt",target => "$path") if $path;
            }
        }
 
@@ -902,11 +928,12 @@ __PACKAGE__->register_method({
 
        my $delVMfromPoolFn = sub {                    
            my $usercfg = cfs_read_file("user.cfg");
-           my $pool = $usercfg->{vms}->{$vmid};
-           if (my $data = $usercfg->{pools}->{$pool}) {
-               delete $data->{vms}->{$vmid};
-               delete $usercfg->{vms}->{$vmid};
-               cfs_write_file("user.cfg", $usercfg);
+           if (my $pool = $usercfg->{vms}->{$vmid}) {
+               if (my $data = $usercfg->{pools}->{$pool}) {
+                   delete $data->{vms}->{$vmid};
+                   delete $usercfg->{vms}->{$vmid};
+                   cfs_write_file("user.cfg", $usercfg);
+               }
            }
        };
 
@@ -1089,6 +1116,16 @@ __PACKAGE__->register_method({
        return $res;
     }});
 
+my $vm_is_ha_managed = sub {
+    my ($vmid) = @_;
+
+    my $cc = PVE::Cluster::cfs_read_file('cluster.conf');
+    if (PVE::Cluster::cluster_conf_lookup_pvevm($cc, 0, $vmid, 1)) {
+       return 1;
+    } 
+    return 0;
+};
+
 __PACKAGE__->register_method({
     name => 'vm_status',
     path => '{vmid}/status/current',
@@ -1113,15 +1150,10 @@ __PACKAGE__->register_method({
        # test if VM exists
        my $conf = PVE::QemuServer::load_config($param->{vmid});
 
-       my $vmstatus = PVE::QemuServer::vmstatus($param->{vmid});
+       my $vmstatus = PVE::QemuServer::vmstatus($param->{vmid}, 1);
        my $status = $vmstatus->{$param->{vmid}};
 
-       my $cc = PVE::Cluster::cfs_read_file('cluster.conf');
-       if (PVE::Cluster::cluster_conf_lookup_pvevm($cc, 0, $param->{vmid}, 1)) {
-           $status->{ha} = 1;
-       } else {
-           $status->{ha} = 0;
-       }
+       $status->{ha} = &$vm_is_ha_managed($param->{vmid});
 
        return $status;
     }});
@@ -1169,17 +1201,39 @@ __PACKAGE__->register_method({
 
        my $storecfg = PVE::Storage::config();
 
-       my $realcmd = sub {
-           my $upid = shift;
+       if (&$vm_is_ha_managed($vmid) && !$stateuri &&
+           $rpcenv->{type} ne 'ha') {
 
-           syslog('info', "start VM $vmid: $upid\n");
+           my $hacmd = sub {
+               my $upid = shift;
 
-           PVE::QemuServer::vm_start($storecfg, $vmid, $stateuri, $skiplock);
+               my $service = "pvevm:$vmid";
 
-           return;
-       };
+               my $cmd = ['clusvcadm', '-e', $service, '-m', $node];
 
-       return $rpcenv->fork_worker('qmstart', $vmid, $authuser, $realcmd);
+               print "Executing HA start for VM $vmid\n";
+
+               PVE::Tools::run_command($cmd);
+
+               return;
+           };
+
+           return $rpcenv->fork_worker('hastart', $vmid, $authuser, $hacmd);
+
+       } else {
+
+           my $realcmd = sub {
+               my $upid = shift;
+
+               syslog('info', "start VM $vmid: $upid\n");
+
+               PVE::QemuServer::vm_start($storecfg, $vmid, $stateuri, $skiplock);
+
+               return;
+           };
+
+           return $rpcenv->fork_worker('qmstart', $vmid, $authuser, $realcmd);
+       }
     }});
 
 __PACKAGE__->register_method({
@@ -1236,18 +1290,38 @@ __PACKAGE__->register_method({
 
        my $storecfg = PVE::Storage::config();
 
-       my $realcmd = sub {
-           my $upid = shift;
+       if (&$vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {
 
-           syslog('info', "stop VM $vmid: $upid\n");
+           my $hacmd = sub {
+               my $upid = shift;
 
-           PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0,
-                                    $param->{timeout}, 0, 1, $keepActive);
+               my $service = "pvevm:$vmid";
 
-           return;
-       };
+               my $cmd = ['clusvcadm', '-d', $service];
+
+               print "Executing HA stop for VM $vmid\n";
+
+               PVE::Tools::run_command($cmd);
+
+               return;
+           };
+
+           return $rpcenv->fork_worker('hastop', $vmid, $authuser, $hacmd);
+
+       } else {
+           my $realcmd = sub {
+               my $upid = shift;
 
-       return $rpcenv->fork_worker('qmstop', $vmid, $authuser, $realcmd);
+               syslog('info', "stop VM $vmid: $upid\n");
+
+               PVE::QemuServer::vm_stop($storecfg, $vmid, $skiplock, 0,
+                                        $param->{timeout}, 0, 1, $keepActive);
+
+               return;
+           };
+
+           return $rpcenv->fork_worker('qmstop', $vmid, $authuser, $realcmd);
+       }
     }});
 
 __PACKAGE__->register_method({
@@ -1585,15 +1659,38 @@ __PACKAGE__->register_method({
                if !$param->{online};
        }
 
-       my $realcmd = sub {
-           my $upid = shift;
+       my $storecfg = PVE::Storage::config();
+       PVE::QemuServer::check_storage_availability($storecfg, $conf, $target);
 
-           PVE::QemuMigrate->migrate($target, $targetip, $vmid, $param);
-       };
+       if (&$vm_is_ha_managed($vmid) && $rpcenv->{type} ne 'ha') {
+
+           my $hacmd = sub {
+               my $upid = shift;
+
+               my $service = "pvevm:$vmid";
+
+               my $cmd = ['clusvcadm', '-M', $service, '-m', $target];
+
+               print "Executing HA migrate for VM $vmid to node $target\n";
+
+               PVE::Tools::run_command($cmd);
+
+               return;
+           };
 
-       my $upid = $rpcenv->fork_worker('qmigrate', $vmid, $authuser, $realcmd);
+           return $rpcenv->fork_worker('hamigrate', $vmid, $authuser, $hacmd);
+
+       } else {
+
+           my $realcmd = sub {
+               my $upid = shift;
+
+               PVE::QemuMigrate->migrate($target, $targetip, $vmid, $param);
+           };
+
+           return $rpcenv->fork_worker('qmigrate', $vmid, $authuser, $realcmd);
+       }
 
-       return $upid;
     }});
 
 __PACKAGE__->register_method({
@@ -1627,7 +1724,7 @@ __PACKAGE__->register_method({
 
        my $res = '';
        eval {
-           $res = PVE::QemuServer::vm_monitor_command($vmid, $param->{command});
+           $res = PVE::QemuServer::vm_human_monitor_command($vmid, $param->{command});
        };
        $res = "ERROR: $@" if $@;