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