[pve-devel] [PATCH 2/4] add copy_disks sub

Alexandre Derumier aderumier at odiso.com
Mon Oct 29 17:23:46 CET 2012


Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/API2/Qemu.pm |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 246a476..7a6337d 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -58,6 +58,81 @@ my $check_storage_access = sub {
     });
 };
 
+my $copy_disks = sub {
+    my ($rpcenv, $authuser, $conf, $storecfg, $vmid, $pool, $settings, $snapname) = @_;
+
+    my $vollist = [];
+
+    my $res = {};
+    PVE::QemuServer::foreach_drive($conf, sub {
+	my ($ds, $disk) = @_;
+	my $volid = $disk->{file};
+
+	if (PVE::QemuServer::drive_is_cdrom($disk)) {
+	    $disk->{file} = "none";
+	    delete $disk->{size};
+	    $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
+	    return $res->{$ds};
+	}
+
+	my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
+	die "no storage ID specified (and no default storage)\n" if !$storeid;
+
+	my $fmt = undef;
+	if ($volname =~ m/\.(raw|qcow2|qed|vmdk)$/){
+            $fmt = $1;
+	}
+	if($settings->{$ds} && $settings->{$ds} =~ m/^(\S+):(raw|qcow2|qed|vmdk)?$/){
+	    ($storeid, $fmt) = ($1, $2);
+	}
+
+	$rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
+
+	PVE::Storage::activate_volumes($storecfg, [ $volid ]);
+
+	my ($size) = PVE::Storage::volume_size_info($storecfg, $volid, 1);
+
+	my $dstvolid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
+                                                  $fmt, undef, ($size/1024));
+	push @$vollist, $dstvolid;
+
+	PVE::Storage::activate_volumes($storecfg, [ $dstvolid ]);
+
+	#copy from source
+	if(!$snapname || $snapname && $fmt && $fmt eq 'qcow2'){
+	    PVE::QemuServer::qemu_img_convert($volid, $dstvolid, $snapname);
+	}else{
+	    die"qemu img convert snapshot works only for qcow2";
+	    #fixme, need to implement import/export for storage plugin (reuse coming backup framework)
+	}
+	#verify size
+	my ($dstsize) = PVE::Storage::volume_size_info($storecfg, $dstvolid, 1);
+
+	$disk->{file} = $dstvolid;
+	$disk->{size} = $dstsize;
+	delete $disk->{format}; # no longer needed
+	$res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
+    });
+
+    # free allocated images on error
+    if (my $err = $@) {
+	syslog('err', "VM $vmid creating disks failed");
+	foreach my $volid (@$vollist) {
+	    eval { PVE::Storage::vdisk_free($storecfg, $volid); };
+	    warn $@ if $@;
+	}
+	die $err;
+    }
+
+    # modify vm config if everything went well
+    foreach my $ds (keys %$res) {
+	$conf->{$ds} = $res->{$ds};
+    }
+
+    return $vollist;
+
+};
+
 # Note: $pool is only needed when creating a VM, because pool permissions
 # are automatically inherited if VM already exists inside a pool.
 my $create_disks = sub {
-- 
1.7.10.4




More information about the pve-devel mailing list