summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJosh Durgin <joshd@hq.newdream.net>2011-01-12 19:39:25 +0000
committerTarmac <>2011-01-12 19:39:25 +0000
commit67307428d6d6f47f3215f485a1af720013a5c2ae (patch)
treecb022e23c61b106bbda5712f604b535668180dbc /nova
parent0a0f966fc7e31099574a3fc8eeaf30ac7fc151ad (diff)
parent70ac0dfea7a55c3580d4a9cd65752f894dfaa222 (diff)
downloadnova-67307428d6d6f47f3215f485a1af720013a5c2ae.tar.gz
nova-67307428d6d6f47f3215f485a1af720013a5c2ae.tar.xz
nova-67307428d6d6f47f3215f485a1af720013a5c2ae.zip
This branch adds a backend for using RBD (RADOS Block Device) volumes in nova via libvirt/qemu.
This is described in the blueprint here: https://blueprints.launchpad.net/nova/+spec/ceph-block-driver Testing requires Ceph and the latest qemu and libvirt from git. Instructions for installing these can be found on the Ceph wiki (http://ceph.newdream.net/wiki/#Getting_Ceph and http://ceph.newdream.net/wiki/QEMU-RBD).
Diffstat (limited to 'nova')
-rw-r--r--nova/virt/libvirt_conn.py23
-rw-r--r--nova/volume/driver.py57
2 files changed, 75 insertions, 5 deletions
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 655c55fa1..bd863b3a2 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -243,11 +243,24 @@ class LibvirtConnection(object):
def attach_volume(self, instance_name, device_path, mountpoint):
virt_dom = self._conn.lookupByName(instance_name)
mount_device = mountpoint.rpartition("/")[2]
- xml = """<disk type='block'>
- <driver name='qemu' type='raw'/>
- <source dev='%s'/>
- <target dev='%s' bus='virtio'/>
- </disk>""" % (device_path, mount_device)
+ if device_path.startswith('/dev/'):
+ xml = """<disk type='block'>
+ <driver name='qemu' type='raw'/>
+ <source dev='%s'/>
+ <target dev='%s' bus='virtio'/>
+ </disk>""" % (device_path, mount_device)
+ elif ':' in device_path:
+ (protocol, name) = device_path.split(':')
+ xml = """<disk type='network'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='%s' name='%s'/>
+ <target dev='%s' bus='virtio'/>
+ </disk>""" % (protocol,
+ name,
+ mount_device)
+ else:
+ raise exception.Invalid(_("Invalid device path %s") % device_path)
+
virt_dom.attachDevice(xml)
def _get_disk_xml(self, xml, device):
diff --git a/nova/volume/driver.py b/nova/volume/driver.py
index 6bc925f3e..44bfeaf0c 100644
--- a/nova/volume/driver.py
+++ b/nova/volume/driver.py
@@ -49,6 +49,8 @@ flags.DEFINE_string('iscsi_target_prefix', 'iqn.2010-10.org.openstack:',
'prefix for iscsi volumes')
flags.DEFINE_string('iscsi_ip_prefix', '127.0',
'discover volumes on the ip that starts with this prefix')
+flags.DEFINE_string('rbd_pool', 'rbd',
+ 'the rbd pool in which volumes are stored')
class VolumeDriver(object):
@@ -314,3 +316,58 @@ class FakeISCSIDriver(ISCSIDriver):
"""Execute that simply logs the command."""
LOG.debug(_("FAKE ISCSI: %s"), cmd)
return (None, None)
+
+
+class RBDDriver(VolumeDriver):
+ """Implements RADOS block device (RBD) volume commands"""
+
+ def check_for_setup_error(self):
+ """Returns an error if prerequisites aren't met"""
+ (stdout, stderr) = self._execute("rados lspools")
+ pools = stdout.split("\n")
+ if not FLAGS.rbd_pool in pools:
+ raise exception.Error(_("rbd has no pool %s") %
+ FLAGS.rbd_pool)
+
+ def create_volume(self, volume):
+ """Creates a logical volume."""
+ if int(volume['size']) == 0:
+ size = 100
+ else:
+ size = int(volume['size']) * 1024
+ self._try_execute("rbd --pool %s --size %d create %s" %
+ (FLAGS.rbd_pool,
+ size,
+ volume['name']))
+
+ def delete_volume(self, volume):
+ """Deletes a logical volume."""
+ self._try_execute("rbd --pool %s rm %s" %
+ (FLAGS.rbd_pool,
+ volume['name']))
+
+ def local_path(self, volume):
+ """Returns the path of the rbd volume."""
+ # This is the same as the remote path
+ # since qemu accesses it directly.
+ return self.discover_volume(volume)
+
+ def ensure_export(self, context, volume):
+ """Synchronously recreates an export for a logical volume."""
+ pass
+
+ def create_export(self, context, volume):
+ """Exports the volume"""
+ pass
+
+ def remove_export(self, context, volume):
+ """Removes an export for a logical volume"""
+ pass
+
+ def discover_volume(self, volume):
+ """Discover volume on a remote host"""
+ return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name'])
+
+ def undiscover_volume(self, volume):
+ """Undiscover volume on a remote host"""
+ pass