From: Michael Rasmussen <m...@datanom.net>

Signed-off-by: Michael Rasmussen <m...@datanom.net>
---
 PVE/Storage/FreeNASPlugin.pm | 129 +++++++++++++++++++++++++------------------
 1 file changed, 74 insertions(+), 55 deletions(-)

diff --git a/PVE/Storage/FreeNASPlugin.pm b/PVE/Storage/FreeNASPlugin.pm
index 0f2a56d..fee3d27 100644
--- a/PVE/Storage/FreeNASPlugin.pm
+++ b/PVE/Storage/FreeNASPlugin.pm
@@ -427,40 +427,38 @@ sub freenas_find_free_diskname {
 }
 
 sub freenas_get_lun_number {
-    my ($scfg, $volname, $snap) = @_;
+    my ($scfg, $volname) = @_;
     my $lunid = undef;
     
-    if ($volname =~ /^(vm|base)-\d+-disk-(\d+)$/ && ! defined $snap) {
+    if ($volname =~ /^(vm|base)-\d+-disk-(\d+)$/) {
        $lunid = $2 - 1;
     } elsif ($volname =~ /^vm-(\d+)-state/) {
        # Find id for temporary LUN
-       if ($snap) {
-               # TODO
-               # Required to be able to exposed read-only LUNs for snapshot 
backup CT
-       } else {
-               my $target = freenas_get_target($scfg, $1);
-               my $id = $max_luns;
-                       my $response = freenas_request($scfg, 'GET', 
"services/iscsi/targettoextent?limit=$limit");
-                       die HTTP::Status::status_message($response) if 
$response =~ /^\d+$/;
-                       my $t2extents = decode_json($response);
-
-                       foreach my $t2extent (@$t2extents) {
-                               next unless $t2extent->{iscsi_target} == 
$target &&
-                                                       
$t2extent->{iscsi_lunid} + 1 > $max_luns &&
-                                                       
$t2extent->{iscsi_lunid} < $max_luns + $active_snaps;
-                               my $eid = freenas_get_extent($scfg, $volname);
-                               if ($eid) {
-                                       $response = freenas_request($scfg, 
'GET', "services/iscsi/extent/$eid");
-                                       die 
HTTP::Status::status_message($response) if $response =~ /^\d+$/;
-                                       my $extent = decode_json($response);
-                                       # Request to get lunid for an existing 
lun
-                                       last if $t2extent->{iscsi_extent} eq 
$eid;
-                               }
-                               $id++;
+               my $target = freenas_get_target($scfg, $1);
+               my $id = $max_luns;
+               my $response = freenas_request($scfg, 'GET', 
"services/iscsi/targettoextent?limit=$limit");
+               die HTTP::Status::status_message($response) if $response =~ 
/^\d+$/;
+               my $t2extents = decode_json($response);
+
+               foreach my $t2extent (@$t2extents) {
+                       next unless $t2extent->{iscsi_target} == $target &&
+                                               $t2extent->{iscsi_lunid} + 1 > 
$max_luns &&
+                                               $t2extent->{iscsi_lunid} < 
$max_luns + $active_snaps;
+                       my $eid = freenas_get_extent($scfg, $volname);
+                       if ($eid) {
+                               $response = freenas_request($scfg, 'GET', 
"services/iscsi/extent/$eid");
+                               die HTTP::Status::status_message($response) if 
$response =~ /^\d+$/;
+                               my $extent = decode_json($response);
+                               # Request to get lunid for an existing lun
+                               last if $t2extent->{iscsi_extent} eq $eid;
                        }
-                       die "Max snapshots (4) is reached" unless ($id - 
$max_luns) < $active_snaps;
-                       $lunid = $id;
-       }
+                       $id++;
+               }
+               die "Max snapshots (4) is reached" unless ($id - $max_luns) < 
$active_snaps;
+               $lunid = $id;
+    } elsif ($volname =~ /^(vm|base)-\d+-disk-\d+\@vzdump$/) {
+        # Required to be able to exposed read-only LUNs for snapshot backup CT
+        $lunid = $max_luns + $active_snaps;
     }
     
     return $lunid;
@@ -891,12 +889,13 @@ sub list_images {
 
 sub path {
     my ($class, $scfg, $volname, $storeid, $snapname) = @_;
-
-    die "direct access to snapshots not implemented"
-       if defined($snapname);
+    #die "direct access to snapshots not implemented"
+       #if defined($snapname);
 
     my ($vtype, $vname, $vmid) = $class->parse_volname($volname);
 
+       $vname = "$vname\@$snapname" if $snapname;
+
        my $luns = get_active_luns($class, $storeid, $scfg, $vname);
        my $path = disk_by_path($scfg, $vname);
        
@@ -1116,24 +1115,54 @@ sub volume_resize {
 
 sub volume_snapshot {
     my ($class, $scfg, $storeid, $volname, $snap) = @_;
-
-    my $vname = ($class->parse_volname($volname))[1];
-
+    
+       my (undef, $vname, $vmid) = $class->parse_volname($volname);
+       
     my $data = {
        dataset => "$scfg->{pool}/$vname",
        name => $snap,
     };
-       my $response = freenas_request($scfg, 'POST', "storage/snapshot", 
encode_json($data));
+       my $response = freenas_request($scfg, 'POST', "storage/snapshot/", 
encode_json($data));
        die HTTP::Status::status_message($response) if $response =~ /^\d+$/;
+       
+       if ($snap) {
+           eval {
+               freenas_create_lun($scfg, $vmid, "$vname\@$snap");
+               $class->activate_volume($storeid, $scfg, "$vname\@$snap");
+           };
+           if ($@) {
+               die "$@ - unable to activate snapshot from remote FreeNAS 
storage";
+           }
+    }
 }
 
 sub volume_snapshot_delete {
     my ($class, $scfg, $storeid, $volname, $snap, $running) = @_;
     
-    my $vname = ($class->parse_volname($volname))[1];
-    
+    my (undef, $vname, $vmid) = $class->parse_volname($volname);
+
+       if ($snap) {
+           eval {
+               my $target = freenas_get_target($scfg, $vmid);
+               die "volume_snapshot_delete-> missing target" unless $target;
+               my $extent = freenas_get_extent($scfg, "$vname\@$snap");
+               die "volume_snapshot_delete-> missing extent" unless $extent;
+               my $tg2exent = freenas_get_target_to_exent($scfg, $extent, 
$target);
+               die "volume_snapshot_delete-> missing target to extent" unless 
$tg2exent;
+               my $lun = freenas_get_lun_number($scfg, "$vname\@$snap");
+               die "volume_snapshot_delete-> missing LUN" unless defined $lun;
+               freenas_delete_target_to_exent($scfg, $tg2exent);
+               freenas_delete_extent($scfg, $extent);
+           };
+           warn "$@ - unable to deactivate snapshot from remote FreeNAS 
storage" if $@;
+       }
+
     my $response = freenas_request($scfg, 'DELETE', 
"storage/snapshot/$scfg->{pool}/$vname\@$snap");
        die HTTP::Status::status_message($response) if $response =~ /^\d+$/;
+
+       if ($snap) {
+           $class->deactivate_volume($storeid, $scfg, "$vname\@$snap");
+    }
 }
 
 sub volume_snapshot_rollback {
@@ -1232,16 +1261,11 @@ sub deactivate_storage {
 sub activate_volume {
     my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
 
-       # TODO: FreeNAS supports exposing a ro LUN from a snapshot
-       # ERROR: Backup of VM xyz failed - unable to activate snapshot from 
remote zfs storage
-       # at /usr/share/perl5/PVE/Storage/ZFSPlugin.pm line 418.
-       # $vname\@$snapname
-       die "mode failure - unable to activate snapshot from remote zfs 
storage" if $snapname;
-
-       my (undef, $name) = $class->parse_volname($volname);
+       return if $snapname; # Activated when creating snapshot
+       
+       my $name = ($class->parse_volname($volname))[1];
 
        my $active_luns = get_active_luns($class, $storeid, $scfg, $name);
-       
     my $lun = freenas_get_lun_number($scfg, $name);
        $active_luns->{$lun} = "0:0:0:$lun";
 
@@ -1266,18 +1290,13 @@ sub activate_volume {
 #      deactivate lun
 sub deactivate_volume {
     my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
-
-       # TODO: FreeNAS supports exposing a ro LUN from a snapshot
-       # ERROR: Backup of VM xyz failed - unable to activate snapshot from 
remote zfs storage
-       # at /usr/share/perl5/PVE/Storage/ZFSPlugin.pm line 418.
-       # $vname\@$snapname
-    die "mode failure - unable to deactivate snapshot from remote zfs storage" 
if $snapname;
-
-       my (undef, $name) = $class->parse_volname($volname);
+    
+    return if $snapname; # Deactivated when deleting snapshot
+    
+    my $name = ($class->parse_volname($volname))[1];
 
        my $active_luns = get_active_luns($class, $storeid, $scfg, $name);
-       
-    my $lun = freenas_get_lun_number($scfg, $name);
+       my $lun = freenas_get_lun_number($scfg, $name);
        delete $active_luns->{$lun};
 
        eval {
-- 
2.11.0


----

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

_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to