]> git.proxmox.com Git - pve-storage.git/commitdiff
Include new storage function volume_send.
authorWolfgang Link <w.link@proxmox.com>
Mon, 24 Apr 2017 15:15:26 +0000 (17:15 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 28 Apr 2017 08:05:27 +0000 (10:05 +0200)
If the storage backend support import and export
we can send the contend to a remote host.

PVE/Storage.pm
PVE/Storage/Plugin.pm
PVE/Storage/ZFSPlugin.pm
PVE/Storage/ZFSPoolPlugin.pm

index 50c2f3fbc447ba969676bda91dd989ba0deb78f8..47948188a623ac16e753391f7d05922027b8f3d9 100755 (executable)
@@ -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) = @_;
 
index 31b8541dc53134007c6bf0b2344b3f3dd4a2c427..d0df1f98b1d267a55012e668c2987d8c52464a29 100644 (file)
@@ -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) = @_; 
 
index 90722054309ef7b40d66a32eae0113f804a9ee28..900719303fbb7ca23cb1e187872e35ec3452f7ce 100644 (file)
@@ -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) = @_;
 
index ca0a2cf8c84d0e1f17e875ae1ad09941b67d2e7e..5b9837899350a6323802ad3e43eca0337adbd592 100644 (file)
@@ -465,6 +465,54 @@ 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);
+
+    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) = @_;