[pve-devel] [PATCH 1/6] vm_deviceplug|unplug : implement pending change

Alexandre Derumier aderumier at odiso.com
Mon Nov 17 16:43:36 CET 2014


also cleanup intendation

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/QemuServer.pm |  127 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 86 insertions(+), 41 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index e43a228..141a21c 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -2994,63 +2994,81 @@ sub vm_devices_list {
 }
 
 sub vm_deviceplug {
-    my ($storecfg, $conf, $vmid, $deviceid, $device) = @_;
+    my ($storecfg, $conf, $vmid, $deviceid, $device, $optvalue) = @_;
 
-    return 1 if !check_running($vmid);
+    if (!check_running($vmid)){
+	if($conf->{pending}->{$deviceid}){
+	    $conf->{$deviceid} = $optvalue;
+	    delete $conf->{pending}->{$deviceid};
+	    PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+	}
+    }
 
     my $q35 = machine_type_is_q35($conf);
 
     if ($deviceid eq 'tablet') {
-	qemu_deviceadd($vmid, print_tabletdevice_full($conf));
+
+	eval { qemu_deviceadd($vmid, print_tabletdevice_full($conf->{pending}))};
+
+	if($conf->{pending}->{delete} =~ m/tablet/) {
+	    delete $conf->{$deviceid};
+	    vmconfig_undelete_pending_option($conf, $deviceid);
+	} else {
+	    $conf->{$deviceid} = $conf->{pending}->{$deviceid};
+	    delete $conf->{pending}->{$deviceid};
+	}
+
+	PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 	return 1;
     }
 
     return 1 if !$conf->{hotplug};
 
+    return 1 if ($deviceid =~ m/^(ide|sata)(\d+)$/);
+
     my $devices_list = vm_devices_list($vmid);
     return 1 if defined($devices_list->{$deviceid});
 
     qemu_bridgeadd($storecfg, $conf, $vmid, $deviceid); #add bridge if we need it for the device
 
     if ($deviceid =~ m/^(virtio)(\d+)$/) {
-        return undef if !qemu_driveadd($storecfg, $vmid, $device);
-        my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
-        qemu_deviceadd($vmid, $devicefull);
-        if(!qemu_deviceaddverify($vmid, $deviceid)) {
-           qemu_drivedel($vmid, $deviceid);
-           return undef;
-        }
+	return undef if !qemu_driveadd($storecfg, $vmid, $device);
+	my $devicefull = print_drivedevice_full($storecfg, $conf->{pending}, $vmid, $device);
+	qemu_deviceadd($vmid, $devicefull);
+	if(!qemu_deviceaddverify($vmid, $deviceid)) {
+	    qemu_drivedel($vmid, $deviceid);
+	    return undef;
+	}
     }
 
     if ($deviceid =~ m/^(scsihw)(\d+)$/) {
-        my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
-        my $pciaddr = print_pci_addr($deviceid);
-        my $devicefull = "$scsihw,id=$deviceid$pciaddr";
-        qemu_deviceadd($vmid, $devicefull);
-        return undef if(!qemu_deviceaddverify($vmid, $deviceid));
+	my $scsihw = defined($conf->{scsihw}) ? $conf->{scsihw} : "lsi";
+	my $pciaddr = print_pci_addr($deviceid);
+	my $devicefull = "$scsihw,id=$deviceid$pciaddr";
+	qemu_deviceadd($vmid, $devicefull);
+	return undef if(!qemu_deviceaddverify($vmid, $deviceid));
     }
 
     if ($deviceid =~ m/^(scsi)(\d+)$/) {
-        return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
-        return undef if !qemu_driveadd($storecfg, $vmid, $device);
-        my $devicefull = print_drivedevice_full($storecfg, $conf, $vmid, $device);
-        if(!qemu_deviceadd($vmid, $devicefull)) {
-           qemu_drivedel($vmid, $deviceid);
-           return undef;
-        }
+	return undef if !qemu_findorcreatescsihw($storecfg,$conf, $vmid, $device);
+	return undef if !qemu_driveadd($storecfg, $vmid, $device);
+	my $devicefull = print_drivedevice_full($storecfg, $conf->{pending}, $vmid, $device);
+	if(!qemu_deviceadd($vmid, $devicefull)) {
+	    qemu_drivedel($vmid, $deviceid);
+	    return undef;
+	}
     }
 
     if ($deviceid =~ m/^(net)(\d+)$/) {
-        return undef if !qemu_netdevadd($vmid, $conf, $device, $deviceid);
-        my $netdevicefull = print_netdevice_full($vmid, $conf, $device, $deviceid);
-        qemu_deviceadd($vmid, $netdevicefull);
-        if(!qemu_deviceaddverify($vmid, $deviceid)) {
-           qemu_netdevdel($vmid, $deviceid);
-           return undef;
-        }
+	return undef if !qemu_netdevadd($vmid, $conf->{pending}, $device, $deviceid);
+	my $netdevicefull = print_netdevice_full($vmid, $conf->{pending}, $device, $deviceid);
+	qemu_deviceadd($vmid, $netdevicefull);
+	if(!qemu_deviceaddverify($vmid, $deviceid)) {
+	    qemu_netdevdel($vmid, $deviceid);
+	    return undef;
+	}
     }
 
-
     if (!$q35 && $deviceid =~ m/^(pci\.)(\d+)$/) {
 	my $bridgeid = $2;
 	my $pciaddr = print_pci_addr($deviceid);
@@ -3059,30 +3077,46 @@ sub vm_deviceplug {
 	return undef if !qemu_deviceaddverify($vmid, $deviceid);
     }
 
+    #delete pending device after hotplug
+    if($conf->{pending}->{$deviceid}){
+	$conf->{$deviceid} = $optvalue;
+	delete $conf->{pending}->{$deviceid};
+	PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
+    }
+
     return 1;
 }
 
 sub vm_deviceunplug {
-    my ($vmid, $conf, $deviceid) = @_;
+    my ($vmid, $conf, $deviceid, $optvalue) = @_;
 
-    return 1 if !check_running ($vmid);
+    return 1 if !check_running($vmid);
 
     if ($deviceid eq 'tablet') {
-	qemu_devicedel($vmid, $deviceid);
+	eval { qemu_devicedel($vmid, $deviceid) };
+	$conf->{$deviceid} = $conf->{pending}->{$deviceid};
+	delete $conf->{pending}->{$deviceid};
+	PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
 	return 1;
     }
 
     return 1 if !$conf->{hotplug};
 
+    return 1 if ($deviceid =~ m/^(ide|sata)(\d+)$/);
+
     my $devices_list = vm_devices_list($vmid);
     return 1 if !defined($devices_list->{$deviceid});
 
     die "can't unplug bootdisk" if $conf->{bootdisk} && $conf->{bootdisk} eq $deviceid;
 
     if ($deviceid =~ m/^(virtio)(\d+)$/) {
-        qemu_devicedel($vmid, $deviceid);
-        return undef if !qemu_devicedelverify($vmid, $deviceid);
-        return undef if !qemu_drivedel($vmid, $deviceid);
+	qemu_devicedel($vmid, $deviceid);
+	return undef if !qemu_devicedelverify($vmid, $deviceid);
+	return undef if !qemu_drivedel($vmid, $deviceid);
+
+	my $drive = PVE::QemuServer::parse_drive($deviceid, $conf->{$deviceid});
+	PVE::QemuServer::add_unused_volume($conf, $drive->{file});
+
     }
 
     if ($deviceid =~ m/^(lsi)(\d+)$/) {
@@ -3090,14 +3124,25 @@ sub vm_deviceunplug {
     }
 
     if ($deviceid =~ m/^(scsi)(\d+)$/) {
-        return undef if !qemu_devicedel($vmid, $deviceid);
-        return undef if !qemu_drivedel($vmid, $deviceid);
+	return undef if !qemu_devicedel($vmid, $deviceid);
+	return undef if !qemu_drivedel($vmid, $deviceid);
+
+	my $drive = PVE::QemuServer::parse_drive($deviceid, $conf->{$deviceid});
+	PVE::QemuServer::add_unused_volume($conf, $drive->{file});
+
     }
 
     if ($deviceid =~ m/^(net)(\d+)$/) {
-        qemu_devicedel($vmid, $deviceid);
-        return undef if !qemu_devicedelverify($vmid, $deviceid);
-        return undef if !qemu_netdevdel($vmid, $deviceid);
+	qemu_devicedel($vmid, $deviceid);
+	return undef if !qemu_devicedelverify($vmid, $deviceid);
+	return undef if !qemu_netdevdel($vmid, $deviceid);
+    }
+
+    if($conf->{$deviceid}){
+
+	delete $conf->{$deviceid};
+	vmconfig_undelete_pending_option($conf, $deviceid);
+	PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
     }
 
     return 1;
-- 
1.7.10.4




More information about the pve-devel mailing list