[pve-devel] r5170 - in qemu-server/pve2: . PVE PVE/API2/Qemu

svn-commits at proxmox.com svn-commits at proxmox.com
Fri Sep 17 12:31:42 CEST 2010


Author: dietmar
Date: 2010-09-17 10:31:42 +0000 (Fri, 17 Sep 2010)
New Revision: 5170

Modified:
   qemu-server/pve2/ChangeLog
   qemu-server/pve2/PVE/API2/Qemu/Config.pm
   qemu-server/pve2/PVE/QemuServer.pm
   qemu-server/pve2/qm
Log:
	* PVE/API2/Qemu/Config.pm: impl. unlink/delete for disks.

	* PVE/QemuServer.pm (change_config_nolock): remove 'unusedX'
	settings if we re-use a previously unused volume.
	(add_unused_volume): helper to add 'unusedX' settings. Used to
	store references to volume IDs previously used by this VM.



Modified: qemu-server/pve2/ChangeLog
===================================================================
--- qemu-server/pve2/ChangeLog	2010-09-17 09:10:02 UTC (rev 5169)
+++ qemu-server/pve2/ChangeLog	2010-09-17 10:31:42 UTC (rev 5170)
@@ -1,9 +1,18 @@
+2010-09-17  Proxmox Support Team  <support at proxmox.com>
+
+	* PVE/API2/Qemu/Config.pm: impl. unlink/delete for disks.
+
+	* PVE/QemuServer.pm (change_config_nolock): remove 'unusedX'
+	settings if we re-use a previously unused volume.
+	(add_unused_volume): helper to add 'unusedX' settings. Used to
+	store references to volume IDs previously used by this VM.
+
 2010-09-16  Proxmox Support Team  <support at proxmox.com>
 
 	* nqm: renamed to qm
-	
+
 	* qm: renamed to qm.old.
-	
+
 	* PVE/QemuServer.pm (disknames): removed - no longer needed
 	(parse_config): remove diskinfo
 	(config_to_command): also return volume ID list

Modified: qemu-server/pve2/PVE/API2/Qemu/Config.pm
===================================================================
--- qemu-server/pve2/PVE/API2/Qemu/Config.pm	2010-09-17 09:10:02 UTC (rev 5169)
+++ qemu-server/pve2/PVE/API2/Qemu/Config.pm	2010-09-17 10:31:42 UTC (rev 5170)
@@ -34,6 +34,8 @@
 
 use base qw(PVE::RESTHandler);
 
+my $opt_force_description = "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.";
+
 my $resolve_cdrom_alias = sub {
     my $param = shift;
 
@@ -206,6 +208,12 @@
 		    description => "A list of settings you want to delete.",
 		    optional => 1,
 		},
+		force => {
+		    type => 'boolean',
+		    description => $opt_force_description,
+		    optional => 1,
+		    requires => 'delete',
+		},
 	    }),
     },
     returns => { type => 'null'},
@@ -227,6 +235,7 @@
 	raise_param_exc({ skiplock => "Only root may use this option." }) if $user ne 'root';
 
 	my $delete = extract_param($param, 'delete');
+	my $force = extract_param($param, 'force');
 
 	die "no options specified\n" if !$delete && !scalar(keys %$param);
 
@@ -258,6 +267,8 @@
 
 	PVE::QemuServer::add_random_macs ($param);
 
+	my $vollist = [];
+
 	my $updatefn =  sub {
 
 	    my $conf = PVE::QemuServer::load_config ($vmid);
@@ -286,9 +297,24 @@
 		    if (PVE::QemuServer::drive_is_cdrom ($drive)) {
 			$cdchange->{$opt} = undef;
 		    } else {
-			PVE::QemuServer::unlink_image($storecfg, $vmid, $drive->{file});
+			my $volid = $drive->{file};
+
+			if ($volid !~  m|^/|) {
+			    my ($path, $owner);
+			    eval { ($path, $owner) = PVE::Storage::path ($storecfg, $volid); };
+			    if ($owner && ($owner == $vmid)) {
+				if ($force) {
+				    push @$vollist, $volid;
+				} else {
+				    PVE::QemuServer::add_unused_volume($conf, $param, $volid);
+				}
+			    }
+			}
 		    }
+		} elsif ($opt =~ m/^unused/) {
+		    push @$vollist, $conf->{$opt};
 		}
+
 		$unset->{$opt} = 1;
 	    }
 
@@ -308,6 +334,12 @@
 
 	PVE::QemuServer::lock_config ($vmid, $updatefn);
 
+	foreach my $volid (@$vollist) {
+	    eval { PVE::Storage::vdisk_free ($storecfg, $volid); };
+	    # fixme: log ?
+	    warn $@ if $@;
+	}
+
 	return undef;
     }});
 
@@ -366,4 +398,36 @@
 	return undef;
     }});
 
+__PACKAGE__->register_method ({
+    name => 'unlink', 
+    path => '{node}/{vmid}/{idlist}', 
+    method => 'DELETE',
+    description => "Unlink/delete disk images.",
+    parameters => {
+    	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	    vmid => get_standard_option('pve-vmid'),
+	    idlist => {
+		type => 'string', format => 'pve-configid-list',
+		description => "A list of disk IDs you want to delete.",
+	    },
+	    force => {
+		type => 'boolean',
+		description => $opt_force_description,
+		optional => 1,
+	    },
+	},
+    },
+    returns => { type => 'null'},
+    code => sub {
+	my ($param) = @_;
+
+	$param->{delete} = extract_param($param, 'idlist');
+
+	__PACKAGE__->update_vm($param);
+
+	return undef;
+    }});
+
 1;

Modified: qemu-server/pve2/PVE/QemuServer.pm
===================================================================
--- qemu-server/pve2/PVE/QemuServer.pm	2010-09-17 09:10:02 UTC (rev 5169)
+++ qemu-server/pve2/PVE/QemuServer.pm	2010-09-17 10:31:42 UTC (rev 5170)
@@ -399,6 +399,7 @@
 my $MAX_SCSI_DISKS = 16;
 my $MAX_VIRTIO_DISKS = 16;
 my $MAX_VLANS = 4095;
+my $MAX_UNUSED_DISKS = 8;
 
 my $nic_model_list = ['rtl8139', 'ne2k_pci', 'e1000',  'pcnet',  'virtio',
 		      'ne2k_isa', 'i82551', 'i82557b', 'i82559er'];
@@ -457,11 +458,22 @@
     $drivename_hash->{"scsi$i"} = 1;
     $confdesc->{"scsi$i"} = $scsidesc ;
 }
+
 for (my $i = 0; $i < $MAX_VIRTIO_DISKS; $i++)  {
     $drivename_hash->{"virtio$i"} = 1;
     $confdesc->{"virtio$i"} = $virtiodesc;
 }
 
+my $unuseddesc = {
+    optional => 1,
+    type => 'string', format => 'pve-volume-id',
+    description => "Reference to unused volumes.",
+};
+
+for (my $i = 0; $i < $MAX_UNUSED_DISKS; $i++)  {
+    $confdesc->{"unused$i"} = $unuseddesc;
+}
+
 PVE::JSONSchema::register_standard_option('pve-vncticket', { 
     description => "Secret VNC ticket.",
     type => 'string',
@@ -948,6 +960,24 @@
     }
 }
 
+sub add_unused_volume {
+    my ($config, $res, $volid) = @_;
+
+    my $key;
+    for (my $ind = $MAX_UNUSED_DISKS - 1; $ind >= 0; $ind--) {
+	my $test = "unused$ind";
+	if (my $vid = $config->{$test}) {
+	    return if $vid eq $volid; # do not add duplicates
+	} else {
+	    $key = $test;
+	} 
+    }
+
+    die "To many unused volume - please delete them first.\n" if !$key;
+
+    $res->{$key} = $volid;
+}
+
 # fixme: remove all thos $noerr parameters?
 
 PVE::JSONSchema::register_format('pve-qm-bootdisk', \&verify_bootdisk);
@@ -1375,18 +1405,21 @@
 	$unset->{smp} = 1;
     }
 
+    my $new_volids = {};
+
     foreach my $key (keys %$settings) {
 	my $value = $settings->{$key};
 	eval { $value = check_type($key, $value); };
-	if ($@) {
-	    die "unable to parse value of '$key' - $@";
+	die "unable to parse value of '$key' - $@" if $@;
+	if ($key eq 'cdrom') {
+	    $res->{ide2} = $value;
 	} else {
-	    if ($key eq 'cdrom') {
-		$res->{ide2} = $value;
-	    } else {
-		$res->{$key} = $value;
-	    }
+	    $res->{$key} = $value;
 	}
+	if (valid_drivename($key)) {
+	    my $drive = PVE::QemuServer::parse_drive($key, $value);
+	    $new_volids->{$drive->{file}} = 1 if $drive && $drive->{file};
+	}
     }
 
     my $filename = config_file ($vmid);
@@ -1414,10 +1447,14 @@
 		my $key = $1;
 		my $value = $2;
 
+		# remove 'unusedX' settings if we re-add a volume
+		next if $key =~ m/^unused/ && $new_volids->{$value};
+
 		# convert 'smp' to 'sockets'
 		$key = 'sockets' if $key eq 'smp';
 
 		next if $done->{$key};
+		$done->{$key} = 1;
 
 		if (defined ($res->{$key})) {
 		    $value = $res->{$key};
@@ -1426,7 +1463,7 @@
 		if (!defined ($unset->{$key})) {
 		    die $werror unless print $out "$key: $value\n";
 		} 
-		$done->{$key} = 1;
+
 		next;
 	    }
 

Modified: qemu-server/pve2/qm
===================================================================
--- qemu-server/pve2/qm	2010-09-17 09:10:02 UTC (rev 5169)
+++ qemu-server/pve2/qm	2010-09-17 10:31:42 UTC (rev 5170)
@@ -7,6 +7,7 @@
 use IO::Socket::UNIX;
 use IO::Select;
 
+use PVE::Tools qw(extract_param);
 use PVE::INotify qw(read_file);
 use PVE::RPCEnvironment;
 use PVE::QemuServer;
@@ -390,6 +391,8 @@
 
     set => [ "PVE::API2::Qemu::Config", 'update_vm', ['vmid'], { node => $hostname } ],
 
+    unlink => [ "PVE::API2::Qemu::Config", 'unlink', ['vmid', 'idlist'], { node => $hostname } ],
+
     config => [ "PVE::API2::Qemu::Config", 'vm_config', ['vmid'], 
 		{ node => $hostname }, sub {
 		    my $config = shift;



More information about the pve-devel mailing list