[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