[pve-devel] [PATCH 16/16] Manage interrupt call when cloning disks
Alexandre Derumier
aderumier at odiso.com
Mon Jan 21 10:48:11 CET 2013
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/API2/Qemu.pm | 101 ++++++++++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 44 deletions(-)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index d186d97..0045b54 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -139,69 +139,82 @@ my $clone_disks = sub {
my $vollist = [];
my $voliddst = undef;
-
+ my $currentdrive = undef;
my $res = {};
- PVE::QemuServer::foreach_drive($conf, sub {
- my ($ds, $disk) = @_;
- return if ($onlysettings && !$settings->{$ds});
+ eval {
+ local $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = sub {die "interrupted by signal\n";};
- my $volid = $disk->{file};
- if (PVE::QemuServer::drive_is_cdrom($disk)) {
- $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
- } else{
+ PVE::QemuServer::foreach_drive($conf, sub {
+ my ($ds, $disk) = @_;
- if($mode eq 'clone'){
- $voliddst = PVE::Storage::volume_clone($storecfg, $volid, $snap, $vmid);
- push @$vollist, $voliddst;
+ $currentdrive = $ds;
- }elsif($mode eq 'copy'){
+ return if ($onlysettings && !$settings->{$ds});
- my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
- die "no storage ID specified (and no default storage)\n" if !$storeid;
+ my $volid = $disk->{file};
+ if (PVE::QemuServer::drive_is_cdrom($disk)) {
+ $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
+ } else{
- my $fmt = undef;
- if ($volname =~ m/\.(raw|qcow2|vmdk)$/){
- $fmt = $1;
- }
+ if($mode eq 'clone'){
+ print "clone volume $volid\n";
+ $voliddst = PVE::Storage::volume_clone($storecfg, $volid, $snap, $vmid);
+ push @$vollist, $voliddst;
- #target storage is different ? (ex: -virtio0:storeid:fmt)
- if($settings->{$ds} && $settings->{$ds} =~ m/^(\S+):(raw|qcow2|vmdk)?$/){
- ($storeid, $fmt) = ($1, $2);
- }
+ }elsif($mode eq 'copy'){
- $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
+ my ($storeid, $volname) = PVE::Storage::parse_volume_id($volid, 1);
+ die "no storage ID specified (and no default storage)\n" if !$storeid;
- PVE::Storage::activate_volumes($storecfg, [ $volid ]);
-
- my ($size) = PVE::Storage::volume_size_info($storecfg, $volid, 1);
+ my $fmt = undef;
+ if ($volname =~ m/\.(raw|qcow2|vmdk)$/){
+ $fmt = $1;
+ }
- $voliddst = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid,
- $fmt, undef, ($size/1024));
- push @$vollist, $voliddst;
+ #target storage is different ? (ex: -virtio0:storeid:fmt)
+ if($settings->{$ds} && $settings->{$ds} =~ m/^(\S+):(raw|qcow2|vmdk)?$/){
+ ($storeid, $fmt) = ($1, $2);
+ }
- PVE::Storage::activate_volumes($storecfg, [ $voliddst ]);
+ $rpcenv->check($authuser, "/storage/$storeid", ['Datastore.AllocateSpace']);
+ print "activate volume source $volid\n";
+ PVE::Storage::activate_volumes($storecfg, [ $volid ]);
- #copy from source
- if(!$running){
- PVE::QemuServer::qemu_img_convert($volid, $voliddst, $snap);
- }else{
- PVE::QemuServer::qemu_drive_mirror($clonefrom, $ds, $voliddst, $vmid);
- }
+ my ($size) = PVE::Storage::volume_size_info($storecfg, $volid, 1);
+ print "create target volume\n";
+ $voliddst = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, ($size/1024));
+
+ push @$vollist, $voliddst;
- }
+ print "activate volume $voliddst\n";
+ PVE::Storage::activate_volumes($storecfg, [ $voliddst ]);
- $disk->{file} = $voliddst;
- $disk->{size} = PVE::Storage::volume_size_info($storecfg, $voliddst, 1);
+ print "copy $volid to $voliddst\n";
+ if(!$running){
+ PVE::QemuServer::qemu_img_convert($volid, $voliddst, $snap);
+ }else{
+ PVE::QemuServer::qemu_drive_mirror($clonefrom, $ds, $voliddst, $vmid);
+ }
+ }
- delete $disk->{format}; # no longer needed
- $res->{$ds} = PVE::QemuServer::print_drive($vmid, $disk);
- }
- });
+ $disk->{file} = $voliddst;
+ $disk->{size} = PVE::Storage::volume_size_info($storecfg, $voliddst, 1);
+ 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");
+ syslog('err', "VM $vmid clone disks failed");
+
+ eval {
+ PVE::QemuServer::vm_mon_cmd($vmid, "block-job-cancel", device => "drive-$currentdrive") if ($mode eq 'copy' && $running);
+ };
+
+ sleep 1; #some storage like rbd need to wait before release volume
foreach my $volid (@$vollist) {
eval { PVE::Storage::vdisk_free($storecfg, $volid); };
warn $@ if $@;
--
1.7.10.4
More information about the pve-devel
mailing list