[pve-devel] [PATCH 6/6] vmconfig_hotplug_pending : add update_disk
Alexandre Derumier
aderumier at odiso.com
Mon Nov 17 16:43:41 CET 2014
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/API2/Qemu.pm | 83 ++------------------------------------------
PVE/QemuServer.pm | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 99 insertions(+), 83 deletions(-)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index b87389f..9107543 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -733,85 +733,6 @@ my $safe_num_ne = sub {
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
#
@@ -995,8 +916,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
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 067bc1c..6614779 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -3540,10 +3540,14 @@ sub vmconfig_hotplug_pending {
}
}
+ update_config_nolock($vmid, $conf, 1);
+ $conf = load_config($vmid); # update/reload
+
#hotplug
foreach my $opt (keys %{$conf->{pending}}) {
-
- if ($opt =~ m/^net(\d+)$/) {
+ if (PVE::QemuServer::valid_drivename($opt)) {
+ vmconfig_update_disk($conf, $storecfg, $vmid, $opt, 1);
+ }elsif ($opt =~ m/^net(\d+)$/) {
vmconfig_update_net($storecfg, $conf, $vmid, $opt);
}elsif ($opt eq 'tablet'){
@@ -3558,6 +3562,9 @@ sub vmconfig_hotplug_pending {
}
+ update_config_nolock($vmid, $conf, 1);
+ $conf = load_config($vmid); # update/reload
+
}
@@ -3685,6 +3692,94 @@ sub vmconfig_update_net {
};
+sub vmconfig_update_disk {
+ my ($conf, $storecfg, $vmid, $opt, $force) = @_;
+
+ my $running = PVE::QemuServer::check_running($vmid);
+ my $pendingvalue = $conf->{pending}->{$opt};
+ my $drive = PVE::QemuServer::parse_drive($opt, $pendingvalue);
+
+ 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)){
+ #swap : unplug and put it in pending unusused
+ if ($drive->{file} ne $old_drive->{file}) { # unplug old disk
+ if(!PVE::QemuServer::vm_deviceunplug($vmid, $conf, $opt)){
+ warn "error hot-unplug $opt for update";
+ return;
+ }
+ } else { #update existing disk
+
+ #non hotpluggable value
+ if (&$safe_num_ne($drive->{discard}, $old_drive->{discard}) || &$safe_string_ne($drive->{cache}, $old_drive->{cache})) {
+ return if $running;
+ }
+
+ #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})) {
+
+ 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);
+
+ }
+ $conf->{$opt} = $conf->{pending}->{$opt};
+ delete $conf->{pending}->{$opt};
+ return;
+ }
+ }
+
+ }
+ }
+
+ PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+
+ if (PVE::QemuServer::drive_is_cdrom($drive)) { # cdrom
+
+ if ($running) {
+ 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;
+ }
+ }
+ $conf->{$opt} = $conf->{pending}->{$opt};
+ delete $conf->{pending}->{$opt};
+
+ } elsif (!PVE::QemuServer::vm_deviceplug($storecfg, $conf, $vmid, $opt, $drive, $pendingvalue)){
+ warn "error hotplug $opt";
+ }
+
+};
+
sub vm_start {
my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused, $forcemachine, $spice_ticket) = @_;
--
1.7.10.4
More information about the pve-devel
mailing list