File nova-rbd-use-local-devices.patch of Package openstack-nova
From e9c36242bc3a5addad26cd622f35706d55a3f6c5 Mon Sep 17 00:00:00 2001
From: Ralf Haferkamp <rhafer@suse.de>
Date: Tue, 3 Jul 2012 17:42:06 +0200
Subject: [PATCH] Use local rbd devices (/dev/rbd*) for rbd volumes
This adds a new LibirtVolumeDriver to nova-compute that will take care to
map/unmap local block devices for rbd volumes. The original approach for rbd
volumes required rbd-enabled libvirt and kvm/qemu. Which we currently don't
have on SLES-11-SP2.
Change-Id: I62e7664200bc83b948e19a65a3cbda81ebb0470e
---
nova/rootwrap/compute.py | 3 ++
nova/virt/libvirt/connection.py | 2 +-
nova/virt/libvirt/volume.py | 58 +++++++++++++++++++++++++++++++++++++++
nova/volume/driver.py | 6 ++++
4 files changed, 68 insertions(+), 1 deletions(-)
Index: nova-2012.2+git.1349813491.b7e509a/nova/virt/libvirt/volume.py
===================================================================
--- nova-2012.2+git.1349813491.b7e509a.orig/nova/virt/libvirt/volume.py
+++ nova-2012.2+git.1349813491.b7e509a/nova/virt/libvirt/volume.py
@@ -30,6 +30,8 @@ from nova.virt.libvirt import utils as v
LOG = logging.getLogger(__name__)
FLAGS = flags.FLAGS
flags.DECLARE('num_iscsi_scan_tries', 'nova.volume.driver')
+flags.DECLARE('rbd_secret_file', 'nova.volume.driver')
+flags.DECLARE('rbd_user', 'nova.volume.driver')
class LibvirtVolumeDriver(object):
@@ -71,6 +73,62 @@ class LibvirtFakeVolumeDriver(LibvirtVol
conf.serial = connection_info.get('serial')
return conf
+class LibvirtRbdVolumeDriver(LibvirtVolumeDriver):
+ """Driver to attach RBD volumes to libvirt."""
+
+ def _rbd_get_mapped_device(self, pool, image):
+ (out, err) = utils.execute('rbd', 'showmapped')
+ lines = out.split('\n')
+ del(lines[0])
+ device_path=""
+ for line in lines:
+ elements = line.split('\t')
+ # elements is now [ id, pool, image, snap, device ]
+ if len(elements) == 5 and elements[1] == pool and elements[2] == image:
+ device_path = elements[4]
+ break
+ LOG.debug("device path: %s" % ( device_path))
+ if len(device_path) == 0:
+ LOG.info("No host device found for rbd image %s/%s" % (pool, image))
+ return device_path
+
+ def _rbd_map_volume(self, connection_info):
+ pool = connection_info['data']['pool']
+ image = connection_info['data']['image']
+ (out, err) = utils.execute('rbd', 'map', '-p', pool, image,
+ '--secret', FLAGS.rbd_secret_file,
+ '--user', FLAGS.rbd_user,
+ run_as_root=True)
+ LOG.debug("rbd map: stdout=%s stderr=%s" % ( out, err))
+ return self._rbd_get_mapped_device(pool, image)
+
+ def _rbd_unmap_volume(self, connection_info):
+ pool = connection_info['data']['pool']
+ image = connection_info['data']['image']
+ host_device = self._rbd_get_mapped_device(pool, image)
+ if len(host_device) > 0:
+ (out, err) = utils.execute('rbd', 'unmap', host_device,
+ '--secret', FLAGS.rbd_secret_file,
+ '--user', FLAGS.rbd_user,
+ run_as_root=True)
+ LOG.debug("rbd unmap: stdout=%s stderr=%s" % ( out, err))
+
+
+ def connect_volume(self, connection_info, mount_device):
+ """Connect the volume. Returns xml for libvirt."""
+ driver = self._pick_volume_driver()
+ host_device = self._rbd_map_volume(connection_info)
+
+ connection_info['data']['device_path'] = host_device
+ sup = super(LibvirtRbdVolumeDriver, self)
+ return sup.connect_volume(connection_info, mount_device)
+
+ def disconnect_volume(self, connection_info, mount_device):
+ """Detach the volume from instance_name"""
+ sup = super(LibvirtRbdVolumeDriver, self)
+ sup.disconnect_volume(connection_info, mount_device)
+ self._rbd_unmap_volume(connection_info)
+
class LibvirtNetVolumeDriver(LibvirtVolumeDriver):
"""Driver to attach Network volumes to libvirt."""
Index: nova-2012.2+git.1349813491.b7e509a/nova/volume/driver.py
===================================================================
--- nova-2012.2+git.1349813491.b7e509a.orig/nova/volume/driver.py
+++ nova-2012.2+git.1349813491.b7e509a/nova/volume/driver.py
@@ -67,6 +67,10 @@ volume_opts = [
default=None,
help='the libvirt uuid of the secret for the rbd_user'
'volumes'),
+ cfg.StrOpt('rbd_secret_file',
+ default=None,
+ help='path the file containing the secret for the rbd_user'
+ 'volumes'),
cfg.StrOpt('volume_tmp_dir',
default=None,
help='where to store temporary image files if the volume '
@@ -724,6 +728,8 @@ class RBDDriver(VolumeDriver):
'driver_volume_type': 'rbd',
'data': {
'name': '%s/%s' % (FLAGS.rbd_pool, volume['name']),
+ 'pool': FLAGS.rbd_pool,
+ 'image' : volume['name'],
'auth_enabled': FLAGS.rbd_secret_uuid is not None,
'auth_username': FLAGS.rbd_user,
'secret_type': 'ceph',
Index: nova-2012.2+git.1349813491.b7e509a/etc/nova/rootwrap.d/compute.filters
===================================================================
--- nova-2012.2+git.1349813491.b7e509a.orig/etc/nova/rootwrap.d/compute.filters
+++ nova-2012.2+git.1349813491.b7e509a/etc/nova/rootwrap.d/compute.filters
@@ -101,6 +101,9 @@ ovs-ofctl: CommandFilter, /usr/bin/ovs-o
# nova/virt/libvirt/connection.py: 'dd', if=%s % virsh_output, ...
dd: CommandFilter, /bin/dd, root
+# nova/virt/libvirt/volume.py: 'rbd', "map/showmapped", ...
+rbd: CommandFilter, /usr/bin/rbd, root
+
# nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ...
iscsiadm: CommandFilter, /sbin/iscsiadm, root
iscsiadm_usr: CommandFilter, /usr/bin/iscsiadm, root