[pve-devel] [PATCH] Add rados block plugin storage
Alexandre Derumier
aderumier at odiso.com
Thu May 31 10:31:01 CEST 2012
This add rados plugin storage.
We need rbd command from ceph repository (ceph-common package) to create/delete volumes,I didn't have add depends for the moment.
/etc/pve/storage.cfg sample config
rbd: rbdtest
rbd_monhost 10.3.94.27:6789;10.3.94.28:6789;10.3.94.29:6789
rbd_pool pool2
rbd_id admin
rbd_key AQAmOcZPwNY7GRAAuvJjVAKIm1r3JKqLCa4LGQ==
rbd_authsupported cephx;none
content images
Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
PVE/Storage.pm | 3 +
PVE/Storage/Makefile | 2 +-
PVE/Storage/RBDPlugin.pm | 247 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 251 insertions(+), 1 deletions(-)
create mode 100644 PVE/Storage/RBDPlugin.pm
diff --git a/PVE/Storage.pm b/PVE/Storage.pm
index 99f09da..ffe2456 100755
--- a/PVE/Storage.pm
+++ b/PVE/Storage.pm
@@ -21,12 +21,15 @@ use PVE::Storage::DirPlugin;
use PVE::Storage::LVMPlugin;
use PVE::Storage::NFSPlugin;
use PVE::Storage::ISCSIPlugin;
+use PVE::Storage::RBDPlugin;
# load and initialize all plugins
PVE::Storage::DirPlugin->register();
PVE::Storage::LVMPlugin->register();
PVE::Storage::NFSPlugin->register();
PVE::Storage::ISCSIPlugin->register();
+PVE::Storage::RBDPlugin->register();
+
PVE::Storage::Plugin->init();
my $UDEVADM = '/sbin/udevadm';
diff --git a/PVE/Storage/Makefile b/PVE/Storage/Makefile
index 1d2322f..0f9950a 100644
--- a/PVE/Storage/Makefile
+++ b/PVE/Storage/Makefile
@@ -1,4 +1,4 @@
-SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm ISCSIPlugin.pm
+SOURCES=Plugin.pm DirPlugin.pm LVMPlugin.pm NFSPlugin.pm ISCSIPlugin.pm RBDPlugin.pm
.PHONY: install
install:
diff --git a/PVE/Storage/RBDPlugin.pm b/PVE/Storage/RBDPlugin.pm
new file mode 100644
index 0000000..7edbbeb
--- /dev/null
+++ b/PVE/Storage/RBDPlugin.pm
@@ -0,0 +1,247 @@
+package PVE::Storage::RBDPlugin;
+
+use strict;
+use warnings;
+use IO::File;
+use PVE::Tools qw(run_command trim);
+use PVE::Storage::Plugin;
+use PVE::JSONSchema qw(get_standard_option);
+
+use base qw(PVE::Storage::Plugin);
+
+
+sub rbd_ls{
+ my ($scfg) = @_;
+
+ my $rbdpool = $scfg->{rbd_pool};
+ my $monhost = $scfg->{rbd_monhost};
+ $monhost =~ s/;/,/g;
+
+ my $cmd = ['/usr/bin/rbd', '-p', $rbdpool, '-m', $monhost, '-n', "client.".$scfg->{rbd_id} ,'--key',$scfg->{rbd_key} ,'ls' ];
+ my $list = {};
+ run_command($cmd, errfunc => sub {},outfunc => sub {
+ my $line = shift;
+
+ $line = trim($line);
+ my ($image) = $line;
+
+ $list->{$rbdpool}->{$image} = {
+ name => $image,
+ size => "",
+ };
+
+ });
+
+
+ return $list;
+
+}
+
+sub addslashes {
+ my $text = shift;
+ $text =~ s/;/\\;/g;
+ $text =~ s/:/\\:/g;
+ return $text;
+}
+
+# Configuration
+
+PVE::JSONSchema::register_format('pve-storage-rbd-mon', \&parse_rbd_mon);
+sub parse_rbd_mon {
+ my ($name, $noerr) = @_;
+
+ if ($name !~ m/^[a-z][a-z0-9\-\_\.]*[a-z0-9]$/i) {
+ return undef if $noerr;
+ die "lvm name '$name' contains illegal characters\n";
+ }
+
+ return $name;
+}
+
+
+sub type {
+ return 'rbd';
+}
+
+sub plugindata {
+ return {
+ content => [ {images => 1}, { images => 1 }],
+ };
+}
+
+sub properties {
+ return {
+ rbd_monhost => {
+ description => "Monitors daemon ips.",
+ type => 'string',
+ },
+ rbd_pool => {
+ description => "RBD Pool.",
+ type => 'string',
+ },
+ rbd_id => {
+ description => "RBD Id.",
+ type => 'string',
+ },
+ rbd_key => {
+ description => "Key.",
+ type => 'string',
+ },
+ rbd_authsupported => {
+ description => "Authsupported.",
+ type => 'string',
+ },
+ };
+}
+
+sub options {
+ return {
+ rbd_monhost => { fixed => 1 },
+ rbd_pool => { fixed => 1 },
+ rbd_id => { fixed => 1 },
+ rbd_key => { fixed => 1 },
+ rbd_authsupported => { fixed => 1 },
+ content => { optional => 1 },
+ };
+}
+
+# Storage implementation
+
+sub parse_volname {
+ my ($class, $volname) = @_;
+
+ if ($volname =~ m/^(vm-(\d+)-\S+)$/) {
+ return ('images', $1, $2);
+ }
+
+ die "unable to parse rbd volume name '$volname'\n";
+}
+
+sub path {
+ my ($class, $scfg, $volname) = @_;
+
+ my ($vtype, $name, $vmid) = $class->parse_volname($volname);
+
+ my $monhost = addslashes($scfg->{rbd_monhost});
+ my $pool = $scfg->{rbd_pool};
+ my $id = $scfg->{rbd_id};
+ my $key = $scfg->{rbd_key};
+ my $authsupported = addslashes($scfg->{rbd_authsupported});
+
+ my $path = "rbd:$pool/$name:id=$id:key=$key:auth_supported=$authsupported:mon_host=$monhost";
+
+ return ($path, $vmid, $vtype);
+}
+
+sub alloc_image {
+ my ($class, $storeid, $scfg, $vmid, $fmt, $name, $size) = @_;
+
+
+ die "illegal name '$name' - sould be 'vm-$vmid-*'\n"
+ if $name && $name !~ m/^vm-$vmid-/;
+ my $rbdpool = $scfg->{rbd_pool};
+ my $monhost = $scfg->{rbd_monhost};
+ $monhost =~ s/;/,/g;
+
+ if (!$name) {
+ my $rdb = rbd_ls($scfg);
+
+ for (my $i = 1; $i < 100; $i++) {
+ my $tn = "vm-$vmid-disk-$i";
+ if (!defined ($rdb->{$rbdpool}->{$tn})) {
+ $name = $tn;
+ last;
+ }
+ }
+ }
+
+ die "unable to allocate an image name for VM $vmid in storage '$storeid'\n"
+ if !$name;
+
+ my $cmd = ['/usr/bin/rbd', '-p', $rbdpool, '-m', $monhost, '-n', "client.".$scfg->{rbd_id}, '--key', $scfg->{rbd_key}, 'create', '--size', ($size/1024), $name ];
+ run_command($cmd, errmsg => "rbd create $name' error");
+
+ return $name;
+}
+
+sub free_image {
+ my ($class, $storeid, $scfg, $volname) = @_;
+
+ my $rbdpool = $scfg->{rbd_pool};
+ my $monhost = $scfg->{rbd_monhost};
+ $monhost =~ s/;/,/g;
+
+ my $cmd = ['/usr/bin/rbd', '-p', $rbdpool, '-m', $monhost, '-n', "client.".$scfg->{rbd_id}, '--key',$scfg->{rbd_key}, 'rm', $volname ];
+ run_command($cmd, errmsg => "rbd rm $volname' error");
+
+ return undef;
+}
+
+sub list_images {
+ my ($class, $storeid, $scfg, $vmid, $vollist, $cache) = @_;
+
+ $cache->{rbd} = rbd_ls($scfg) if !$cache->{rbd};
+ my $rbdpool = $scfg->{rbd_pool};
+ my $res = [];
+
+ if (my $dat = $cache->{rbd}->{$rbdpool}) {
+ foreach my $image (keys %$dat) {
+
+ my $volname = $dat->{$image}->{name};
+
+ my $volid = "$storeid:$volname";
+
+
+ my $owner = $dat->{$volname}->{vmid};
+ if ($vollist) {
+ my $found = grep { $_ eq $volid } @$vollist;
+ next if !$found;
+ } else {
+ next if defined ($vmid) && ($owner ne $vmid);
+ }
+
+ my $info = $dat->{$volname};
+ $info->{volid} = $volid;
+
+ push @$res, $info;
+ }
+ }
+
+ return $res;
+}
+
+
+sub status {
+ my ($class, $storeid, $scfg, $cache) = @_;
+
+
+ my $total = 0;
+ my $free = 0;
+ my $used = 0;
+ my $active = 1;
+ return ($total,$free,$used,$active);
+
+ return undef;
+}
+
+sub activate_storage {
+ my ($class, $storeid, $scfg, $cache) = @_;
+ return 1;
+}
+
+sub deactivate_storage {
+ my ($class, $storeid, $scfg, $cache) = @_;
+ return 1;
+}
+
+sub activate_volume {
+ my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_;
+ return 1;
+}
+
+sub deactivate_volume {
+ my ($class, $storeid, $scfg, $volname, $exclusive, $cache) = @_;
+ return 1;
+}
+
+1;
--
1.7.2.5
More information about the pve-devel
mailing list