[pve-devel] [PATCH 5/5] DRBD: Implement snapshots.
Philipp Marek
philipp.marek at linbit.com
Thu Oct 8 10:24:49 CEST 2015
---
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;
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;
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?
};
my ($vtype, $name, $vmid, $basename, $basevmid, $isBase) =
--
2.6.1
More information about the pve-devel
mailing list