|
@@ -1,48 +1,61 @@
|
|
|
-6147a6148,6188
|
|
|
|
|
-> #BEGIN addition
|
|
|
|
|
-> my $src_storage_plugin = PVE::Storage::Plugin->lookup($src_scfg->{type});
|
|
|
|
|
-> my $dst_storage_plugin = PVE::Storage::Plugin->lookup($dst_scfg->{type});
|
|
|
|
|
->
|
|
|
|
|
-> # in many cases the storage may have a better idea how to convert:
|
|
|
|
|
-> # if src and dst format is the same
|
|
|
|
|
-> # and src_storeid is dst_storeid
|
|
|
|
|
-> # and the storage has the feature
|
|
|
|
|
-> # and the feature is implemented as volume_copy / volume_snapshot_copy
|
|
|
|
|
-> # let the storage do the work as it quite sure is faster
|
|
|
|
|
-> if ( $src_format eq $dst_format ) {
|
|
|
|
|
-> if( $src_storeid eq $dst_storeid ) {
|
|
|
|
|
-> # this is the same storage
|
|
|
|
|
-> # and storage is capable of materializing snaps
|
|
|
|
|
-> if( $snapname ) {
|
|
|
|
|
-> my $canCopySnap = PVE::Storage::volume_has_feature($storecfg, 'copy', $src_volid, $snapname, undef) && $src_storage_plugin->can('volume_snapshot_copy');
|
|
|
|
|
-> if( $canCopySnap ) {
|
|
|
|
|
-> print "delegate to storage plugin volume_snapshot_copy (snap $snapname)\n";
|
|
|
|
|
-> $src_storage_plugin->volume_snapshot_copy($src_scfg, $src_volname, $snapname, $dst_volname);
|
|
|
|
|
->
|
|
|
|
|
-> $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
->
|
|
|
|
|
-> return 1;
|
|
|
|
|
-> }
|
|
|
|
|
-> }
|
|
|
|
|
->
|
|
|
|
|
-> my $canCopyVolume = PVE::Storage::volume_has_feature($storecfg, 'copy', $src_volid, undef, undef) && $src_storage_plugin->can('volume_copy');
|
|
|
|
|
-> if ( $canCopyVolume ) {
|
|
|
|
|
-> print "delegate to storage plugin: volume_copy (base)\n";
|
|
|
|
|
-> $src_storage_plugin->volume_copy($src_scfg, $src_volname, $dst_volname);
|
|
|
|
|
->
|
|
|
|
|
-> $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
->
|
|
|
|
|
-> return 1;
|
|
|
|
|
-> }
|
|
|
|
|
-> }
|
|
|
|
|
-> # @todo: two zfs-storages might be able to receive stream from each other
|
|
|
|
|
-> }
|
|
|
|
|
-> #END addition
|
|
|
|
|
->
|
|
|
|
|
->
|
|
|
|
|
-6173a6215,6219
|
|
|
|
|
->
|
|
|
|
|
-> # added: deactivate the src-volume, even on failure
|
|
|
|
|
-> # this can be safely called as qemu_img_convert is never called on a running volume (that is not a snap)
|
|
|
|
|
-> $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
->
|
|
|
|
|
|
|
+--- QemuServer.orig.pm 2019-02-01 13:04:19.000000000 +0100
|
|
|
|
|
++++ QemuServer.patched.pm 2019-02-12 16:47:56.000000000 +0100
|
|
|
|
|
+@@ -6461,6 +6461,46 @@
|
|
|
|
|
+ my $src_path = PVE::Storage::path($storecfg, $src_volid, $snapname);
|
|
|
|
|
+ my $dst_path = PVE::Storage::path($storecfg, $dst_volid);
|
|
|
|
|
+
|
|
|
|
|
++ #BEGIN addition
|
|
|
|
|
++ my $src_storage_plugin = PVE::Storage::Plugin->lookup($src_scfg->{type});
|
|
|
|
|
++ my $dst_storage_plugin = PVE::Storage::Plugin->lookup($dst_scfg->{type});
|
|
|
|
|
++
|
|
|
|
|
++ # in many cases the storage may have a better idea how to convert:
|
|
|
|
|
++ # if src and dst format is the same
|
|
|
|
|
++ # and src_storeid is dst_storeid
|
|
|
|
|
++ # and the storage has the feature
|
|
|
|
|
++ # and the feature is implemented as volume_copy / volume_snapshot_copy
|
|
|
|
|
++ # let the storage do the work as it quite sure is faster
|
|
|
|
|
++ if ( $src_format eq $dst_format ) {
|
|
|
|
|
++ if( $src_storeid eq $dst_storeid ) {
|
|
|
|
|
++ # this is the same storage
|
|
|
|
|
++ # and storage is capable of materializing snaps
|
|
|
|
|
++ if( $snapname ) {
|
|
|
|
|
++ my $canCopySnap = PVE::Storage::volume_has_feature($storecfg, 'copy', $src_volid, $snapname, undef) && $src_storage_plugin->can('volume_snapshot_copy');
|
|
|
|
|
++ if( $canCopySnap ) {
|
|
|
|
|
++ print "delegate to storage plugin volume_snapshot_copy (snap $snapname)\n";
|
|
|
|
|
++ $src_storage_plugin->volume_snapshot_copy($src_scfg, $src_volname, $snapname, $dst_volname);
|
|
|
|
|
++
|
|
|
|
|
++ $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
++
|
|
|
|
|
++ return 1;
|
|
|
|
|
++ }
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++ my $canCopyVolume = PVE::Storage::volume_has_feature($storecfg, 'copy', $src_volid, undef, undef) && $src_storage_plugin->can('volume_copy');
|
|
|
|
|
++ if ( $canCopyVolume ) {
|
|
|
|
|
++ print "delegate to storage plugin: volume_copy (base)\n";
|
|
|
|
|
++ $src_storage_plugin->volume_copy($src_scfg, $src_volname, $dst_volname);
|
|
|
|
|
++
|
|
|
|
|
++ $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
++
|
|
|
|
|
++ return 1;
|
|
|
|
|
++ }
|
|
|
|
|
++ }
|
|
|
|
|
++ # @todo: two zfs-storages might be able to receive stream from each other
|
|
|
|
|
++ }
|
|
|
|
|
++ #END addition
|
|
|
|
|
++
|
|
|
|
|
+ my $cmd = [];
|
|
|
|
|
+ push @$cmd, '/usr/bin/qemu-img', 'convert', '-p', '-n';
|
|
|
|
|
+ push @$cmd, '-l', "snapshot.name=$snapname" if($snapname && $src_format eq "qcow2");
|
|
|
|
|
+@@ -6487,6 +6527,11 @@
|
|
|
|
|
+
|
|
|
|
|
+ eval { run_command($cmd, timeout => undef, outfunc => $parser); };
|
|
|
|
|
+ my $err = $@;
|
|
|
|
|
++
|
|
|
|
|
++ # added: deactivate the src-volume, even on failure
|
|
|
|
|
++ # this can be safely called as qemu_img_convert is never called on a running volume (that is not a snap)
|
|
|
|
|
++ $src_storage_plugin->deactivate_volume($src_storeid, $src_scfg, $src_volname, $snapname);
|
|
|
|
|
++
|
|
|
|
|
+ die "copy failed: $err" if $err;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|