[pve-devel] [PATCH pve-storage 4/4] Add support for creating LXC snapshot backup

Andreas Steinel a.steinel at gmail.com
Thu Jun 15 10:20:32 CEST 2017


Hi mir,

have you a public git with all the changes? I'd like to try but I
don't want to extract all the patches from this list, try to figure
out which ones are already taken care of and manually apply them.

Best,
LnxBil

On Wed, Jun 14, 2017 at 9:55 PM, Michael Rasmussen <mir at datanom.net> wrote:
> Signed-off-by: Michael Rasmussen <mir at 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.1.4
>
>
> ----
>
> 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 at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



More information about the pve-devel mailing list