]> git.proxmox.com Git - qemu-server.git/commitdiff
vmconfig_hotplug_pending : add update_disk
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 25 Nov 2014 10:37:37 +0000 (11:37 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 7 Jan 2015 05:44:30 +0000 (06:44 +0100)
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
PVE/API2/Qemu.pm
PVE/QemuServer.pm

index e400b6ece27ded7b3ad7821205383093284f362f..ceecc7b915f6d796efd5aa315fbdf7bdae85cbcc 100644 (file)
@@ -807,96 +807,6 @@ my $vmconfig_delete_option = sub {
     PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 };
 
-my $safe_num_ne = sub {
-    my ($a, $b) = @_;
-
-    return 0 if !defined($a) && !defined($b);
-    return 1 if !defined($a);
-    return 1 if !defined($b);
-
-    return $a != $b;
-};
-
-my $vmconfig_update_disk = sub {
-    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $value, $force) = @_;
-
-    my $drive = PVE::QemuServer::parse_drive($opt, $value);
-
-    if (PVE::QemuServer::drive_is_cdrom($drive)) { #cdrom
-       $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.CDROM']);
-    } else {
-       $rpcenv->check_vm_perm($authuser, $vmid, undef, ['VM.Config.Disk']);
-    }
-
-    if ($conf->{$opt}) {
-
-       if (my $old_drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt}))  {
-
-           my $media = $drive->{media} || 'disk';
-           my $oldmedia = $old_drive->{media} || 'disk';
-           die "unable to change media type\n" if $media ne $oldmedia;
-
-           if (!PVE::QemuServer::drive_is_cdrom($old_drive) &&
-               ($drive->{file} ne $old_drive->{file})) {  # delete old disks
-
-               &$vmconfig_delete_option($rpcenv, $authuser, $conf, $storecfg, $vmid, $opt, $force);
-               $conf = PVE::QemuServer::load_config($vmid); # update/reload
-           }
-
-            if(&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
-               &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
-               &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
-               &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
-               &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
-               &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
-               &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
-               &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
-               &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
-               &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
-               &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
-               &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
-               PVE::QemuServer::qemu_block_set_io_throttle($vmid,"drive-$opt",
-                                                          ($drive->{mbps} || 0)*1024*1024,
-                                                          ($drive->{mbps_rd} || 0)*1024*1024,
-                                                          ($drive->{mbps_wr} || 0)*1024*1024,
-                                                          $drive->{iops} || 0,
-                                                          $drive->{iops_rd} || 0,
-                                                          $drive->{iops_wr} || 0,
-                                                          ($drive->{mbps_max} || 0)*1024*1024,
-                                                          ($drive->{mbps_rd_max} || 0)*1024*1024,
-                                                          ($drive->{mbps_wr_max} || 0)*1024*1024,
-                                                          $drive->{iops_max} || 0,
-                                                          $drive->{iops_rd_max} || 0,
-                                                          $drive->{iops_wr_max} || 0)
-                  if !PVE::QemuServer::drive_is_cdrom($drive);
-            }
-       }
-    }
-
-    &$create_disks($rpcenv, $authuser, $conf, $storecfg, $vmid, undef, {$opt => $value});
-    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
-
-    $conf = PVE::QemuServer::load_config($vmid); # update/reload
-    $drive = PVE::QemuServer::parse_drive($opt, $conf->{$opt});
-
-    if (PVE::QemuServer::drive_is_cdrom($drive)) { # cdrom
-
-       if (PVE::QemuServer::check_running($vmid)) {
-           if ($drive->{file} eq 'none') {
-               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_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;
-           }
-       }
-
-    } else { # hotplug new disks
-
-       die "error hotplug $opt" if !PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
-    }
-};
-
 # POST/PUT {vmid}/config implementation
 #
 # The original API used PUT (idempotent) an we assumed that all operations
@@ -1083,8 +993,8 @@ my $update_vm_api  = sub {
 
                if (PVE::QemuServer::valid_drivename($opt)) {
 
-                   &$vmconfig_update_disk($rpcenv, $authuser, $conf, $storecfg, $vmid,
-                                          $opt, $param->{$opt}, $force);
+                   #&$vmconfig_update_disk($rpcenv, $authuser, $conf, $storecfg, $vmid,
+                   #                      $opt, $param->{$opt}, $force);
 
                } elsif ($opt =~ m/^net(\d+)$/) { #nics
 
index b86f5a7614d441f7d448d34ad7883daf3bfeeb44..7456158fda31c3b5e0991e3e55193bfb8ab27ac5 100644 (file)
@@ -3655,6 +3655,8 @@ sub vmconfig_hotplug_pending {
            } elsif ($opt =~ m/^net(\d+)$/) {
                die "skip\n" if !$hotplug;
                vm_deviceunplug($vmid, $conf, $opt);
+           } elsif (valid_drivename($opt)) {
+               die "skip\n"; # we do not allow to hot-remove disk?             
            } else {
                die "skip\n";
            }
@@ -3692,6 +3694,9 @@ sub vmconfig_hotplug_pending {
            } elsif ($opt =~ m/^net(\d+)$/) { 
                # some changes can be done without hotplug
                vmconfig_update_net($storecfg, $conf, $vmid, $opt, $value);
+           } elsif (valid_drivename($opt)) {
+               # some changes can be done without hotplug
+               vmconfig_update_disk($storecfg, $conf, $vmid, $opt, $value, 1);
            } else {
                die "skip\n";  # skip non-hot-pluggable options
            }
@@ -3809,6 +3814,93 @@ sub vmconfig_update_net {
     vm_deviceplug($storecfg, $conf, $vmid, $opt, $newnet);
 }
 
+sub vmconfig_update_disk {
+    my ($storecfg, $conf, $vmid, $opt, $value, $force) = @_;
+
+    # fixme: do we need force?
+
+    my $drive = parse_drive($opt, $value);
+
+    if ($conf->{$opt}) {
+
+       if (my $old_drive = parse_drive($opt, $conf->{$opt}))  {
+
+           my $media = $drive->{media} || 'disk';
+           my $oldmedia = $old_drive->{media} || 'disk';
+           die "unable to change media type\n" if $media ne $oldmedia;
+
+           if (!drive_is_cdrom($old_drive)) {
+
+               if ($drive->{file} ne $old_drive->{file}) {  
+
+                   die "skip\n" if !$conf->{hotplug};
+
+                   # unplug and register as unused
+                   vm_deviceunplug($vmid, $conf, $opt);
+                   vmconfig_register_unused_drive($storecfg, $vmid, $conf, $old_drive)
+       
+               } else {
+                   # update existing disk
+
+                   # skip non hotpluggable value
+                   if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) || 
+                       &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
+                       die "skip\n";
+                   }
+
+                   # apply throttle
+                   if (&$safe_num_ne($drive->{mbps}, $old_drive->{mbps}) ||
+                       &$safe_num_ne($drive->{mbps_rd}, $old_drive->{mbps_rd}) ||
+                       &$safe_num_ne($drive->{mbps_wr}, $old_drive->{mbps_wr}) ||
+                       &$safe_num_ne($drive->{iops}, $old_drive->{iops}) ||
+                       &$safe_num_ne($drive->{iops_rd}, $old_drive->{iops_rd}) ||
+                       &$safe_num_ne($drive->{iops_wr}, $old_drive->{iops_wr}) ||
+                       &$safe_num_ne($drive->{mbps_max}, $old_drive->{mbps_max}) ||
+                       &$safe_num_ne($drive->{mbps_rd_max}, $old_drive->{mbps_rd_max}) ||
+                       &$safe_num_ne($drive->{mbps_wr_max}, $old_drive->{mbps_wr_max}) ||
+                       &$safe_num_ne($drive->{iops_max}, $old_drive->{iops_max}) ||
+                       &$safe_num_ne($drive->{iops_rd_max}, $old_drive->{iops_rd_max}) ||
+                       &$safe_num_ne($drive->{iops_wr_max}, $old_drive->{iops_wr_max})) {
+                       
+                       qemu_block_set_io_throttle($vmid,"drive-$opt",
+                                                  ($drive->{mbps} || 0)*1024*1024,
+                                                  ($drive->{mbps_rd} || 0)*1024*1024,
+                                                  ($drive->{mbps_wr} || 0)*1024*1024,
+                                                  $drive->{iops} || 0,
+                                                  $drive->{iops_rd} || 0,
+                                                  $drive->{iops_wr} || 0,
+                                                  ($drive->{mbps_max} || 0)*1024*1024,
+                                                  ($drive->{mbps_rd_max} || 0)*1024*1024,
+                                                  ($drive->{mbps_wr_max} || 0)*1024*1024,
+                                                  $drive->{iops_max} || 0,
+                                                  $drive->{iops_rd_max} || 0,
+                                                  $drive->{iops_wr_max} || 0);
+
+                   }
+                   
+                   return 1;
+               }
+           }
+       }
+    }
+
+    if (drive_is_cdrom($drive)) { # cdrom
+
+       if ($drive->{file} eq 'none') {
+           vm_mon_cmd($vmid, "eject",force => JSON::true,device => "drive-$opt");
+       } else {
+           my $path = get_iso_path($storecfg, $vmid, $drive->{file});
+           vm_mon_cmd($vmid, "eject", force => JSON::true,device => "drive-$opt"); # force eject if locked
+           vm_mon_cmd($vmid, "change", device => "drive-$opt",target => "$path") if $path;
+       }
+
+    } else { 
+       die "skip\n" if !$conf->{hotplug};
+       # hotplug new disks
+       vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive);
+    }
+}
+
 sub vm_start {
     my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;