use strict;
use warnings;
+
use IO::File;
use Net::DBus;
-use Data::Dumper;
use PVE::Tools qw(run_command trim);
use PVE::INotify;
sub plugindata {
return {
- content => [ {images => 1}, { images => 1 }],
+ content => [ {images => 1, rootdir => 1}, { images => 1 }],
};
}
sub options {
return {
redundancy => { optional => 1 },
+ content => { optional => 1 },
nodes => { optional => 1 },
disable => { optional => 1 },
+ bwlimit => { optional => 1 },
};
}
die "got undefined drbd result\n" if !$rc;
+ # Messages for return codes 1 to 99 are not considered an error.
foreach my $res (@$rc) {
- my ($code, $msg, $details) = @$res;
+ my ($code, $format, $details) = @$res;
+
+ next if $code < 100;
- return undef if $code == 0;
+ my $msg;
+ if (defined($format)) {
+ my @args = ();
+ push @args, $details->{$1} // ""
+ while $format =~ s,\%\((\w+)\),%,;
- $msg = "drbd error: got error code $code" if !$msg;
+ $msg = sprintf($format, @args);
+
+ } else {
+ $msg = "drbd error: got error code $code";
+ }
+
chomp $msg;
-
- # fixme: add error details?
- #print Dumper($details);
-
die "drbd error: $msg\n";
}
my ($class, $volname) = @_;
if ($volname =~ m/^(vm-(\d+)-[a-z][a-z0-9\-\_\.]*[a-z0-9]+)$/) {
- return ('images', $1, $2);
+ return ('images', $1, $2, undef, undef, undef, 'raw');
}
die "unable to parse lvm volume name '$volname'\n";
}
sub filesystem_path {
- my ($class, $scfg, $volname) = @_;
+ my ($class, $scfg, $volname, $snapname) = @_;
+
+ die "drbd snapshot is not implemented\n" if defined($snapname);
my ($vtype, $name, $vmid) = $class->parse_volname($volname);
my $hdl = connect_drbdmanage_service();
my $volumes = drbd_list_volumes($hdl);
+ my $disk_list = [ keys %$volumes ];
die "volume '$name' already exists\n" if defined($name) && $volumes->{$name};
-
- if (!defined($name)) {
- for (my $i = 1; $i < 100; $i++) {
- my $tn = "vm-$vmid-disk-$i";
- if (!defined ($volumes->{$tn})) {
- $name = $tn;
- last;
- }
- }
- }
+ $name //= PVE::Storage::Plugin::get_next_vm_diskname($disk_list, $storeid, $vmid, undef, $scfg);
- die "unable to allocate an image name for VM $vmid in storage '$storeid'\n"
- if !defined($name);
-
my ($rc, $res) = $hdl->create_resource($name, {});
check_drbd_res($rc);
'allow-two-primaries' => 'yes',
});
check_drbd_res($rc);
-
+
my $redundancy = get_redundancy($scfg);;
($rc, $res) = $hdl->auto_deploy($name, $redundancy, 0, 0);
eval {
my $hdl = connect_drbdmanage_service();
my $redundancy = get_redundancy($scfg);;
- my ($rc, $res) = $hdl->cluster_free_query($redundancy);
+ my ($rc, $free_space, $total_space) = $hdl->cluster_free_query($redundancy);
check_drbd_res($rc);
- $avail = $res;
- $used = 0; # fixme
- $total = $used + $avail;
+ $avail = $free_space*1024;
+ $total = $total_space*1024;
+ $used = $total - $avail;
};
if (my $err = $@) {
}
sub activate_volume {
- my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_;
+ my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
+
+ die "Snapshot not implemented on DRBD\n" if $snapname;
my $path = $class->path($scfg, $volname);
my $hdl = connect_drbdmanage_service();
my $nodename = PVE::INotify::nodename();
- my ($rc, $res) = $hdl->list_assignments([$nodename], [], 0, {}, []);
+ my ($rc, $res) = $hdl->list_assignments([$nodename], [$volname], 0, {}, []);
check_drbd_res($rc);
- foreach my $entry (@$res) {
- my ($node, $res_name, $props, $voldata) = @$entry;
- if (($node eq $nodename) && ($res_name eq $volname)) {
- return undef; # assignment already exists
- }
- }
+# assignment already exists?
+ return undef if @$res;
# create diskless assignment
($rc, $res) = $hdl->assign($nodename, $volname, { diskless => 'true' });
check_drbd_res($rc);
- # wait until device is acessitble
+ # wait until device is accessible
my $print_warning = 1;
my $max_wait_time = 20;
for (my $i = 0;; $i++) {
}
sub deactivate_volume {
- my ($class, $storeid, $scfg, $volname, $cache) = @_;
+ my ($class, $storeid, $scfg, $volname, $snapname, $cache) = @_;
- # fixme: remove diskless assdignments
-
+ die "Snapshot not implemented on DRBD\n" if $snapname;
+
+ return undef; # fixme: should we unassign ?
+
+ # remove above return to enable this code
+ my $hdl = connect_drbdmanage_service();
+ my $nodename = PVE::INotify::nodename();
+ my ($rc, $res) = $hdl->list_assignments([$nodename], [$volname], 0,
+ { "cstate:diskless" => "true" }, []);
+ check_drbd_res($rc);
+ if (scalar(@$res)) {
+ my ($rc, $res) = $hdl->unassign($nodename, $volname,0);
+ check_drbd_res($rc);
+ }
+
return undef;
}