[pve-devel] [RFC_V2 pve-storage 1/8] Include new storage function volume_send.
Wolfgang Link
w.link at proxmox.com
Wed Apr 19 11:52:02 CEST 2017
If the storage backend support import and export
we can send the contend to a remote host.
---
PVE/Storage.pm | 18 ++++++++++++++++
PVE/Storage/Plugin.pm | 8 ++++++++
PVE/Storage/ZFSPlugin.pm | 7 +++++++
PVE/Storage/ZFSPoolPlugin.pm | 49 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 82 insertions(+)
diff --git a/PVE/Storage.pm b/PVE/Storage.pm
index 50c2f3f..4794818 100755
--- a/PVE/Storage.pm
+++ b/PVE/Storage.pm
@@ -216,6 +216,24 @@ sub volume_snapshot {
}
}
+sub volume_send {
+ my ($cfg, $volid, $snap, $ip, $incremental_snap, $verbose, $limit,
+ $target_path) = @_;
+
+ my ($storeid, $volname) = parse_volume_id($volid, 1);
+ if ($storeid) {
+ my $scfg = storage_config($cfg, $storeid);
+ my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+ return $plugin->volume_send($scfg, $storeid, $volname, $ip, $snap,
+ $incremental_snap, $verbose, $limit, $target_path);
+
+ } elsif ($volid =~ m|^(/.+)$| && -e $volid) {
+ die "send file/device '$volid' is not possible\n";
+ } else {
+ die "unable to parse volume ID '$volid'\n";
+ }
+}
+
sub volume_snapshot_rollback {
my ($cfg, $volid, $snap) = @_;
diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm
index 31b8541..d0df1f9 100644
--- a/PVE/Storage/Plugin.pm
+++ b/PVE/Storage/Plugin.pm
@@ -697,6 +697,14 @@ sub volume_snapshot {
return undef;
}
+sub volume_send {
+ my ($class, $scfg, $storeid, $volname, $ip, $snap,
+ $incremental_snap, $verbose, $limit, $target_path) = @_;
+
+ # implement in subclass
+ die "Volume_send is not implemented for $class";
+}
+
sub volume_rollback_is_possible {
my ($class, $scfg, $storeid, $volname, $snap) = @_;
diff --git a/PVE/Storage/ZFSPlugin.pm b/PVE/Storage/ZFSPlugin.pm
index 9072205..9007193 100644
--- a/PVE/Storage/ZFSPlugin.pm
+++ b/PVE/Storage/ZFSPlugin.pm
@@ -336,6 +336,13 @@ sub volume_snapshot_rollback {
$class->zfs_add_lun_mapping_entry($scfg, $volname);
}
+sub volume_send {
+ my ($class, $scfg, $storeid, $volname, $ip, $snap,
+ $incremental_snap, $verbose, $limit, $target_path) = @_;
+
+ die "Volume_send is not implemented for ZFS over iSCSI.\n";
+}
+
sub volume_has_feature {
my ($class, $scfg, $feature, $storeid, $volname, $snapname, $running) = @_;
diff --git a/PVE/Storage/ZFSPoolPlugin.pm b/PVE/Storage/ZFSPoolPlugin.pm
index ca0a2cf..a7ba03b 100644
--- a/PVE/Storage/ZFSPoolPlugin.pm
+++ b/PVE/Storage/ZFSPoolPlugin.pm
@@ -465,6 +465,55 @@ sub volume_snapshot {
$class->zfs_request($scfg, undef, 'snapshot', "$scfg->{pool}/$vname\@$snap");
}
+sub volume_send {
+ my ($class, $scfg, $storeid, $volname, $ip, $snap,
+ $incremental_snap, $verbose, $limit, $target_path) = @_;
+
+ my ($vtype, $name, $vmid) = $class->parse_volname($volname);
+
+ my $zpath = "$scfg->{pool}/$name";
+
+ die "$vtype is not allowed in ZFSPool!" if ($vtype ne "images");
+
+ my $cmdsend = [];
+ my $cmdlimit = [];
+
+ push @$cmdsend, 'zfs', 'send', '-R';
+ push @$cmdsend, '-v' if defined($verbose);
+
+ #undefined or 0 no snapshot exists
+ if( defined($incremental_snap)) {
+ push @$cmdsend, '-I', "$zpath\@${incremental_snap}";
+ }
+
+ push @$cmdsend, '--', "$zpath\@${snap}";
+
+ # limit in kByte/s
+ if ($limit){
+ my $bwl = $limit * 1024;
+ push @$cmdlimit, 'cstream', '-t', $bwl;
+ }
+
+ my $cmdrecv = [];
+
+ push @$cmdrecv, 'ssh', '-o', 'BatchMode=yes', "root\@${ip}", '--' if $ip;
+ push @$cmdrecv, 'zfs', 'recv', '-F', '--';
+
+ $zpath = $target_path if defined($target_path);
+ push @$cmdrecv, $zpath;
+
+
+ if ($limit) {
+ eval { run_command([$cmdsend, $cmdlimit, $cmdrecv]) };
+ } else {
+ eval { run_command([$cmdsend, $cmdrecv]) };
+ }
+
+ if (my $err = $@) {
+ die $err;
+ }
+}
+
sub volume_snapshot_delete {
my ($class, $scfg, $storeid, $volname, $snap, $running) = @_;
--
2.1.4
More information about the pve-devel
mailing list