diff options
| author | Josh Durgin <joshd@hq.newdream.net> | 2011-01-12 19:39:25 +0000 |
|---|---|---|
| committer | Tarmac <> | 2011-01-12 19:39:25 +0000 |
| commit | 67307428d6d6f47f3215f485a1af720013a5c2ae (patch) | |
| tree | cb022e23c61b106bbda5712f604b535668180dbc /nova | |
| parent | 0a0f966fc7e31099574a3fc8eeaf30ac7fc151ad (diff) | |
| parent | 70ac0dfea7a55c3580d4a9cd65752f894dfaa222 (diff) | |
| download | nova-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.py | 23 | ||||
| -rw-r--r-- | nova/volume/driver.py | 57 |
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 |
