[pve-devel] [PATCH 5/5] DRBD: Implement snapshots.

Dietmar Maurer dietmar at proxmox.com
Thu Oct 15 09:53:59 CEST 2015


First, code looks reasonable to me, but I am unable to test
without a working rollback. Some comments inline:

> On October 8, 2015 at 10:24 AM Philipp Marek <philipp.marek at linbit.com> wrote:
> 
> 
> ---
>  PVE/Storage/DRBDPlugin.pm | 88
> ++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 84 insertions(+), 4 deletions(-)
> 
> diff --git a/PVE/Storage/DRBDPlugin.pm b/PVE/Storage/DRBDPlugin.pm
> index 14f232b..3cc7f0b 100644
> --- a/PVE/Storage/DRBDPlugin.pm
> +++ b/PVE/Storage/DRBDPlugin.pm
> @@ -5,6 +5,8 @@ use warnings;
>  use IO::File;
>  use Net::DBus;
>  use Data::Dumper;
> +use Digest::SHA;
> +use Time::HiRes;
>  
>  use PVE::Tools qw(run_command trim);
>  use PVE::INotify;
> @@ -17,6 +19,10 @@ use base qw(PVE::Storage::Plugin);
>  
>  my $default_redundancy = 2;
>  
> +# constants to use as DRBDmanage property keys
> +our $PN_IS_TEMP_RES = "aux:proxmox:is-temp-resource";
> +
> +
>  sub type {
>      return 'drbd';
>  }
> @@ -298,7 +304,7 @@ sub deactivate_storage {
>  sub activate_volume {
>      my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
>  
> -    die "Snapshot not implemented on DRBD\n" if $snapname;
> +    return activate_volume_from_snapshot(@_) if $snapname;

I would prefer to list all parameters by name (instead of using @_)

>      my $path = $class->path($scfg, $volname);
>      
> @@ -340,7 +346,7 @@ sub activate_volume {
>  sub deactivate_volume {
>      my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
>  
> -    die "Snapshot not implemented on DRBD\n" if $snapname;
> +    return deactivate_volume_from_snapshot(@_) if $snapname;

same here

>  
>      return undef; # fixme: should we unassign ?
>  
> @@ -358,6 +364,58 @@ sub deactivate_volume {
>      return undef;    
>  }
>  
> +sub activate_volume_from_snapshot {
> +    my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
> +
> +    my $hdl = connect_drbdmanage_service();
> +
> +# create a new temporary resource, with an optional DRBD client on this node.
> +
> +# If the snapshot would be activated multiple times, and perhaps even
> +# concurrently, we might benefit from a "shared" resource.
> +# (That might need to do some reference counting and/or make the DRBD
> +# device read-only, to avoid data divergence for multiple accessing nodes
> +# that might all try to replay the journals, etc.)
> +
> +# start with volume- and snapshotname, but get a unique ID.
> +    my $new_name = sprintf("%.32s-%.12s",
> +		    sprintf("%.24s-%.24s", $volname, $snapname),
> +		    Digest::SHA::sha1_base64($volname, $snapname,
> +			    $$, Time::HiRes::gettimeofday()));
> +
> +    my $r_prop = { $PN_IS_TEMP_RES => '1', };
> +
> +    my ($rc) = $hdl->restore_snapshot($new_name, $volname, $snapname,
> $r_prop, []);
> +    check_drbd_res($rc);
> +
> +# now get a local assignment...
> +    return activate_volume($class, $storeid, $scfg, $new_name, undef,
> $cache);
> +}
> +
> +sub deactivate_volume_from_snapshot {
> +    my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
> +
> +    my $hdl = connect_drbdmanage_service();
> +    my $nodename = PVE::INotify::nodename();
> +
> +    my ($rc, $res) = $hdl->list_resources([$volname], 0, {}, {});
> +    check_drbd_res($rc);
> +
> +# TODO: should we throw an error if that doesn't exist anymore?
> +    warn("Resource '$volname' doesn't exist anymore?"),return undef if !$res;
> +    die("Multiple resources with name '$volname'?"),return undef if @$res !=
> 1;
> +
> +    my $prop = $res->[0][1];
> +
> +    if ($prop->{$PN_IS_TEMP_RES}) {
> +        my ($rc) = $hdl->remove_resource($volname, 0);
> +        check_drbd_res($rc);
> +    }
> +
> +
> +    return undef;
> +}
> +
>  sub volume_resize {
>      my ($class, $scfg, $storeid, $volname, $size, $running) = @_;
>  
> @@ -374,19 +432,40 @@ sub volume_resize {
>  sub volume_snapshot {
>      my ($class, $scfg, $storeid, $volname, $snap, $running) = @_;
>  
> -    die "drbd snapshot is not implemented";
> +    my $hdl = connect_drbdmanage_service();
> +
> +    my ($rc) = $hdl->create_snapshot($volname, $snap, [], {});
> +    check_drbd_res($rc);
> +    return undef;
>  }
>  
>  sub volume_snapshot_rollback {
>      my ($class, $scfg, $storeid, $volname, $snap) = @_;
>  
>      die "drbd snapshot rollback is not implemented";
> +# FIXME: inplace?
> +}
> +
> +sub volume_rollback_is_possible {
> +    my ($class, $scfg, $storeid, $volname, $snap) = @_; 
> +
> +    my $hdl = connect_drbdmanage_service();
> +
> +# just check for existance, no other restrictions
> +    my ($rc) = $hdl->list_snapshots([$volname], [], [$snap], [], {});
> +    check_drbd_res($rc);
> +
> +    return 1;
>  }
>  
>  sub volume_snapshot_delete {
>      my ($class, $scfg, $storeid, $volname, $snap) = @_;
>  
> -    die "drbd snapshot delete is not implemented";
> +    my $hdl = connect_drbdmanage_service();
> +
> +    my ($rc) = $hdl->remove_snapshot($volname, $snap, 0);
> +    check_drbd_res($rc);
> +    return undef;
>  }
>  
>  sub volume_has_feature {
> @@ -394,6 +473,7 @@ sub volume_has_feature {
>  
>      my $features = {
>          copy => { base => 1, current => 1},
> +        snapshot => { current => 1, snap => 1}, ## what's the difference?

just use

+  snapshot => { current => 1 },



More information about the pve-devel mailing list