[pve-devel] Custom storage plugins API
Alexander Schmid
alex at modula-shop-systems.de
Fri Jan 13 10:55:58 CET 2017
Am 13.01.17 um 10:44 schrieb Dietmar Maurer:
>> I also extended ZFSPlugin to allow access to Snapshots (via zfs snapshot
>> + clone + iSCISI Target on the Clone) and cloning from Snapshots (via
>> send/rcv on a clone). Therefore i had some minor changes in
>> QemuServer.pm to allow this. Any chance these could be taken into one of
>> the next releases ?
> A first step would be to send the code to list (else nobody known what
> you really talk about).
>
Currently, i only changed qemu_img_convert to allow sort of delegation
to the storage-plugin. See comments.
This would let the storage-plugin jump-in, in my case zfs send/rcv is
used in favour of qemu-img convert as it's much faster.
Not sure about the call of deactivate_volume in the end and if it might
break other storage implementations.
I needed it to do some cleanup on the iscsi-targets that were temporary
created on the snap.
sub qemu_img_convert {
my ($src_volid, $dst_volid, $size, $snapname, $is_zero_initialized)
= @_;
my $storecfg = PVE::Storage::config();
my ($src_storeid, $src_volname) =
PVE::Storage::parse_volume_id($src_volid, 1);
my ($dst_storeid, $dst_volname) =
PVE::Storage::parse_volume_id($dst_volid, 1);
if ($src_storeid && $dst_storeid) {
PVE::Storage::activate_volumes($storecfg, [$src_volid], $snapname);
my $src_scfg = PVE::Storage::storage_config($storecfg, $src_storeid);
my $dst_scfg = PVE::Storage::storage_config($storecfg, $dst_storeid);
my $src_format = qemu_img_format($src_scfg, $src_volname);
my $dst_format = qemu_img_format($dst_scfg, $dst_volname);
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;
}
}
}
#END addition
my $cmd = [];
push @$cmd, '/usr/bin/qemu-img', 'convert', '-p', '-n';
push @$cmd, '-s', $snapname if($snapname && $src_format eq "qcow2");
push @$cmd, '-f', $src_format, '-O', $dst_format, $src_path;
if ($is_zero_initialized) {
push @$cmd, "zeroinit:$dst_path";
} else {
push @$cmd, $dst_path;
}
my $parser = sub {
my $line = shift;
if($line =~ m/\((\S+)\/100\%\)/){
my $percent = $1;
my $transferred = int($size * $percent / 100);
my $remaining = $size - $transferred;
print "transferred: $transferred bytes remaining: $remaining
bytes total: $size bytes progression: $percent %\n";
}
};
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;
}
}
More information about the pve-devel
mailing list