Merge "Fix root disk not be detached after deleting lxc container"
This commit is contained in:
@@ -137,3 +137,34 @@ class TestVirtDisk(test.NoDBTestCase):
|
||||
]
|
||||
|
||||
self.assertEqual(self.executes, expected_commands)
|
||||
|
||||
def test_lxc_teardown_container_with_namespace_cleaned(self):
|
||||
|
||||
def proc_mounts(self, mount_point):
|
||||
return None
|
||||
|
||||
self.stubs.Set(os.path, 'exists', lambda _: True)
|
||||
self.stubs.Set(disk_api._DiskImage, '_device_for_path', proc_mounts)
|
||||
expected_commands = []
|
||||
|
||||
disk_api.teardown_container('/mnt/loop/nopart', '/dev/loop0')
|
||||
expected_commands += [
|
||||
('losetup', '--detach', '/dev/loop0'),
|
||||
]
|
||||
|
||||
disk_api.teardown_container('/mnt/loop/part', '/dev/loop0')
|
||||
expected_commands += [
|
||||
('losetup', '--detach', '/dev/loop0'),
|
||||
]
|
||||
|
||||
disk_api.teardown_container('/mnt/nbd/nopart', '/dev/nbd15')
|
||||
expected_commands += [
|
||||
('qemu-nbd', '-d', '/dev/nbd15'),
|
||||
]
|
||||
|
||||
disk_api.teardown_container('/mnt/nbd/part', '/dev/nbd15')
|
||||
expected_commands += [
|
||||
('qemu-nbd', '-d', '/dev/nbd15'),
|
||||
]
|
||||
|
||||
self.assertEqual(self.executes, expected_commands)
|
||||
|
||||
@@ -208,6 +208,8 @@ class _DiskImage(object):
|
||||
self.mount_dir = mount_dir
|
||||
self.use_cow = use_cow
|
||||
|
||||
self.device = None
|
||||
|
||||
# Internal
|
||||
self._mkdir = False
|
||||
self._mounter = None
|
||||
@@ -239,6 +241,7 @@ class _DiskImage(object):
|
||||
|
||||
mount_name = os.path.basename(self.mount_dir or '')
|
||||
self._mkdir = mount_name.startswith(self.tmp_prefix)
|
||||
self.device = self._mounter.device
|
||||
|
||||
@property
|
||||
def errors(self):
|
||||
@@ -344,6 +347,8 @@ def setup_container(image, container_dir, use_cow=False):
|
||||
|
||||
It will mount the loopback image to the container directory in order
|
||||
to create the root filesystem for the container.
|
||||
|
||||
Returns path of image device which is mounted to the container directory.
|
||||
"""
|
||||
img = _DiskImage(image=image, use_cow=use_cow, mount_dir=container_dir)
|
||||
if not img.mount():
|
||||
@@ -352,9 +357,11 @@ def setup_container(image, container_dir, use_cow=False):
|
||||
{"image": img, "target": container_dir,
|
||||
"errors": img.errors})
|
||||
raise exception.NovaException(img.errors)
|
||||
else:
|
||||
return img.device
|
||||
|
||||
|
||||
def teardown_container(container_dir):
|
||||
def teardown_container(container_dir, container_root_device=None):
|
||||
"""Teardown the container rootfs mounting once it is spawned.
|
||||
|
||||
It will umount the container that is mounted,
|
||||
@@ -363,6 +370,17 @@ def teardown_container(container_dir):
|
||||
try:
|
||||
img = _DiskImage(image=None, mount_dir=container_dir)
|
||||
img.teardown()
|
||||
|
||||
# Make sure container_root_device is released when teardown container.
|
||||
if container_root_device:
|
||||
if 'loop' in container_root_device:
|
||||
LOG.debug(_("Release loop device %s"), container_root_device)
|
||||
utils.execute('losetup', '--detach', container_root_device,
|
||||
run_as_root=True, attempts=3)
|
||||
else:
|
||||
LOG.debug(_('Release nbd device %s'), container_root_device)
|
||||
utils.execute('qemu-nbd', '-d', container_root_device,
|
||||
run_as_root=True)
|
||||
except Exception as exn:
|
||||
LOG.exception(_('Failed to teardown container filesystem: %s'), exn)
|
||||
|
||||
|
||||
@@ -930,6 +930,13 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
disk_dev)
|
||||
|
||||
if destroy_disks:
|
||||
#NOTE(GuanQiang): teardown lxc container to avoid resource leak
|
||||
if CONF.libvirt_type == 'lxc':
|
||||
inst_path = libvirt_utils.get_instance_path(instance)
|
||||
container_dir = os.path.join(inst_path, 'rootfs')
|
||||
container_root_device = instance.get('root_device_name')
|
||||
disk.teardown_container(container_dir, container_root_device)
|
||||
|
||||
self._delete_instance_files(instance)
|
||||
|
||||
self._cleanup_lvm(instance)
|
||||
@@ -3126,9 +3133,17 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
container_dir = os.path.join(inst_path, 'rootfs')
|
||||
fileutils.ensure_tree(container_dir)
|
||||
image = self.image_backend.image(instance, 'disk')
|
||||
disk.setup_container(image.path,
|
||||
container_dir=container_dir,
|
||||
use_cow=CONF.use_cow_images)
|
||||
container_root_device = disk.setup_container(image.path,
|
||||
container_dir=container_dir,
|
||||
use_cow=CONF.use_cow_images)
|
||||
|
||||
#Note(GuanQiang): save container root device name here, used for
|
||||
# detaching the linked image device when deleting
|
||||
# the lxc instance.
|
||||
if container_root_device:
|
||||
self.virtapi.instance_update(
|
||||
nova_context.get_admin_context(), instance['uuid'],
|
||||
{'root_device_name': container_root_device})
|
||||
|
||||
if xml:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user