summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-02-14 21:44:45 +0000
committerGerrit Code Review <review@openstack.org>2012-02-14 21:44:45 +0000
commit028c62f378d06ffbae8f698611e1d1ce80f1ede2 (patch)
treedaae10bb19cbdc7e7ec61da22f4398b1e1da65ae /nova/virt
parenta8795a40fd8f4ba42fde1cc4c3c3f0494850f12f (diff)
parente40b659d320b3c6894862b87adf1011e31cbf8fc (diff)
Merge "Add support for LXC volumes."
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/disk/api.py20
-rw-r--r--nova/virt/libvirt/connection.py60
2 files changed, 78 insertions, 2 deletions
diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py
index fd0eec79d..f1f60414b 100644
--- a/nova/virt/disk/api.py
+++ b/nova/virt/disk/api.py
@@ -106,6 +106,26 @@ def extend(image, size):
utils.execute('resize2fs', image, check_exit_code=False)
+def bind(src, target, instance_name):
+ """Bind device to a filesytem"""
+ if src:
+ utils.execute('touch', target, run_as_root=True)
+ utils.execute('mount', '-o', 'bind', src, target,
+ run_as_root=True)
+ s = os.stat(src)
+ cgroup_info = "c %s:%s rwm" % (os.major(s.st_rdev),
+ os.minor(s.st_rdev))
+ cgroups_path = \
+ "/sys/fs/cgroup/devices/sysdefault/libvirt/lxc/%s/devices.allow" \
+ % instance_name
+ utils.execute('echo', '>', cgroup_info, cgroups_path, run_as_root=True)
+
+
+def unbind(target):
+ if target:
+ utils.execute('umount', target, run_as_root=True)
+
+
class _DiskImage(object):
"""Provide operations on a disk image file."""
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index adf7aa295..efd972b4b 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -453,7 +453,11 @@ class LibvirtConnection(driver.ComputeDriver):
xml = self.volume_driver_method('connect_volume',
connection_info,
mount_device)
- virt_dom.attachDevice(xml)
+
+ if FLAGS.libvirt_type == 'lxc':
+ self._attach_lxc_volume(xml, virt_dom, instance_name)
+ else:
+ virt_dom.attachDevice(xml)
@staticmethod
def _get_disk_xml(xml, device):
@@ -480,13 +484,65 @@ class LibvirtConnection(driver.ComputeDriver):
xml = self._get_disk_xml(virt_dom.XMLDesc(0), mount_device)
if not xml:
raise exception.DiskNotFound(location=mount_device)
- virt_dom.detachDevice(xml)
+ if FLAGS.libvirt_type == 'lxc':
+ self._detach_lxc_volume(xml, vort_dom, instance_name)
+ else:
+ virt_dom.detachDevice(xml)
finally:
self.volume_driver_method('disconnect_volume',
connection_info,
mount_device)
@exception.wrap_exception()
+ def _attach_lxc_volume(self, xml, virt_dom, instance_name):
+ LOG.info(_('attaching LXC block device'))
+
+ lxc_container_root = self.get_lxc_container_root(virt_dom)
+ lxc_host_volume = self.get_lxc_host_device(xml)
+ lxc_container_device = self.get_lxc_container_target(xml)
+ lxc_container_target = "%s/%s" % (lxc_container_root,
+ lxc_container_device)
+
+ if lxc_container_target:
+ disk.bind(lxc_host_volume, lxc_container_target, instance_name)
+
+ @exception.wrap_exception()
+ def _detach_lxc_volume(self, xml, virt_dom, instance_name):
+ LOG.info(_('detaching LXC block device'))
+
+ lxc_container_root = self.get_lxc_container_root(virt_dom)
+ lxc_host_volume = self.get_lxc_host_device(xml)
+ lxc_container_device = self.get_lxc_container_target(xml)
+ lxc_container_target = "%s/%s" % (lxc_container_root,
+ lxc_container_device)
+
+ if lxc_container_target:
+ disk.unbind(lxc_container_target)
+
+ @staticmethod
+ def get_lxc_container_root(virt_dom):
+ xml = virt_dom.XMLDesc(0)
+ doc = ElementTree.fromstring(xml)
+ filesystem_block = doc.findall('./devices/filesystem')
+ for cnt, filesystem_nodes in enumerate(filesystem_block):
+ return filesystem_nodes[cnt].get('dir')
+
+ @staticmethod
+ def get_lxc_host_device(xml):
+ dom = minidom.parseString(xml)
+
+ for device in dom.getElementsByTagName('source'):
+ return device.getAttribute('dev')
+
+ @staticmethod
+ def get_lxc_container_target(xml):
+ dom = minidom.parseString(xml)
+
+ for device in dom.getElementsByTagName('target'):
+ filesystem = device.getAttribute('dev')
+ return 'dev/%s' % filesystem
+
+ @exception.wrap_exception()
def snapshot(self, context, instance, image_href):
"""Create snapshot from a running VM instance.