[pve-devel] [PATCH v7 pve-storage 08/10] Implement support for snapshots

mir at datanom.net mir at datanom.net
Tue Jun 20 22:40:00 CEST 2017


From: Michael Rasmussen <mir at datanom.net>

Signed-off-by: Michael Rasmussen <mir at datanom.net>
---
 PVE/Storage/FreeNASPlugin.pm | 72 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/PVE/Storage/FreeNASPlugin.pm b/PVE/Storage/FreeNASPlugin.pm
index 9c0136d..f954dc8 100644
--- a/PVE/Storage/FreeNASPlugin.pm
+++ b/PVE/Storage/FreeNASPlugin.pm
@@ -848,6 +848,24 @@ my $rescan_session = sub {
     $delete_session->($scfg, $sid) unless %$luns_to_keep;
 };
 
+my $freenas_get_latest_snapshot = sub {
+    my ($class, $scfg, $volname) = @_;
+
+    my (undef, $vname) = $class->parse_volname($volname);
+
+    # abort rollback if snapshot is not the latest
+    my $snapshots = $freenas_request->($scfg, 'GET', "storage/snapshot/");
+    
+    my $recentsnap;
+    foreach my $snapshot (@$snapshots) {
+        next unless $snapshot->{filesystem} =~ /$scfg->{pool}\/$vname/ && $snapshot->{mostrecent};
+        $recentsnap = $snapshot->{name};
+        last;
+    }
+
+    return $recentsnap;
+};
+
 # Storage implementation
 
 sub volume_size_info {
@@ -1113,7 +1131,7 @@ sub volume_snapshot {
         dataset => "$scfg->{pool}/$vname",
         name => $snap,
     };
-    $freenas_request->($scfg, 'POST', "storage/snapshot/", encode_json($data));    
+    $freenas_request->($scfg, 'POST', "storage/snapshot/", encode_json($data));
 }
 
 sub volume_snapshot_delete {
@@ -1121,12 +1139,58 @@ sub volume_snapshot_delete {
     
     my (undef, $vname, $vmid) = $class->parse_volname($volname);
 
+    if ($snap eq 'vzdump') {
+        eval {
+            my $target = $freenas_get_target->($scfg, $vmid);
+            die "volume_snapshot_delete-> missing target\n" unless $target;
+            my $extent = $freenas_get_extent->($scfg, "$vname\@$snap");
+            die "volume_snapshot_delete-> missing extent\n" unless $extent;
+            my $tg2exent = $freenas_get_target_to_exent->($scfg, $extent, $target);
+            die "volume_snapshot_delete-> missing target to extent\n" unless $tg2exent;
+            my $lun = $freenas_get_lun_number->($scfg, "$vname\@$snap");
+            die "volume_snapshot_delete-> missing LUN\n" unless defined $lun;
+            $freenas_delete_target_to_exent->($scfg, $tg2exent);
+            $freenas_delete_extent->($scfg, $extent);
+            $class->deactivate_volume($storeid, $scfg, "$vname\@$snap");
+        };
+        warn "$@ - unable to deactivate snapshot from remote FreeNAS storage" if $@;
+    }
+
+    $freenas_request->($scfg, 'DELETE', "storage/snapshot/$scfg->{pool}/$vname\@$snap/");
 }
 
 sub volume_snapshot_rollback {
     my ($class, $scfg, $storeid, $volname, $snap) = @_;
 
     my ($vtype, $name, $vmid) = $class->parse_volname($volname);
+
+    my $target = $freenas_get_target->($scfg, $vmid);
+    die "volume_resize-> Missing target\n" unless $target;
+    my $extent = $freenas_get_extent->($scfg, $name);
+    die "volume_resize-> Missing extent\n" unless $extent;
+    my $tg2exent = $freenas_get_target_to_exent->($scfg, $extent, $target);
+    die "volume_resize-> Missing target to extent\n" unless $tg2exent;
+    my $lunid = $freenas_get_lun_number->($scfg, $name);
+    die "volume_resize-> Missing LUN\n" unless defined $lunid;
+
+    eval {
+        $freenas_delete_target_to_exent->($scfg, $tg2exent);
+        $freenas_delete_extent->($scfg, $extent);
+    };
+    warn "Failed to remove current extent. Trying to proceed anyway: $@\n" if $@;
+    
+    my $data = {
+        force => JSON::false,
+    };
+    $freenas_request->(
+        $scfg, 'POST', "storage/snapshot/$scfg->{pool}/$name\@$snap/rollback/", encode_json($data));
+
+    eval {
+        $extent = $freenas_create_extent->($scfg, $name);
+        $freenas_create_target_to_exent->($scfg, $target, $extent, $lunid);
+        $rescan_session->($class, $storeid, $scfg, $name);
+    };
+    die "Rollback failed: $@\n" if $@;
 }
 
 sub volume_rollback_is_possible {
@@ -1134,6 +1198,12 @@ sub volume_rollback_is_possible {
     
     my (undef, $name) = $class->parse_volname($volname);
 
+    my $recentsnap = $freenas_get_latest_snapshot->($class, $scfg, $name);
+    if ($snap ne $recentsnap) {
+        die "can't rollback, more recent snapshots exist\n";
+    }
+
+    return 1; 
 }
 
 sub volume_snapshot_list {
-- 
2.11.0


----

This mail was virus scanned and spam checked before delivery.
This mail is also DKIM signed. See header dkim-signature.




More information about the pve-devel mailing list