diff --git a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py index 352cf6576940..23fdef591175 100644 --- a/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py +++ b/nova/tests/unit/virt/libvirt/fake_libvirt_utils.py @@ -32,11 +32,11 @@ def create_cow_image(backing_file, path): pass -def get_disk_size(path): +def get_disk_size(path, format=None): return 0 -def get_disk_backing_file(path): +def get_disk_backing_file(path, format=None): return disk_backing_files.get(path, None) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 510f08c19d7f..e7d88c25e5b8 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -12558,7 +12558,7 @@ class LibvirtConnTestCase(test.NoDBTestCase): image_meta = objects.ImageMeta.from_dict(self.test_image_meta) drvr._live_snapshot(self.context, self.test_instance, guest, - srcfile, dstfile, "qcow2", image_meta) + srcfile, dstfile, "qcow2", "qcow2", image_meta) mock_dom.XMLDesc.assert_called_once_with(flags=( fakelibvirt.VIR_DOMAIN_XML_INACTIVE | @@ -12569,8 +12569,9 @@ class LibvirtConnTestCase(test.NoDBTestCase): fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT | fakelibvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW)) - mock_size.assert_called_once_with(srcfile) - mock_backing.assert_called_once_with(srcfile, basename=False) + mock_size.assert_called_once_with(srcfile, format="qcow2") + mock_backing.assert_called_once_with(srcfile, basename=False, + format="qcow2") mock_create_cow.assert_called_once_with(bckfile, dltfile, 1004009) mock_chown.assert_called_once_with(dltfile, os.getuid()) mock_snapshot.assert_called_once_with(dltfile, "qcow2", diff --git a/nova/virt/images.py b/nova/virt/images.py index 902da6835a96..adaa00975406 100644 --- a/nova/virt/images.py +++ b/nova/virt/images.py @@ -45,7 +45,7 @@ CONF.register_opts(image_opts) IMAGE_API = image.API() -def qemu_img_info(path): +def qemu_img_info(path, format=None): """Return an object containing the parsed output from qemu-img info.""" # TODO(mikal): this code should not be referring to a libvirt specific # flag. @@ -58,8 +58,10 @@ def qemu_img_info(path): raise exception.InvalidDiskInfo(reason=msg) try: - out, err = utils.execute('env', 'LC_ALL=C', 'LANG=C', - 'qemu-img', 'info', path) + cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path) + if format is not None: + cmd = cmd + ('-f', format) + out, err = utils.execute(*cmd) except processutils.ProcessExecutionError as exp: msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") % {'path': path, 'exp': exp}) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 787cba7595ad..c520c3d9e782 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1498,7 +1498,8 @@ class LibvirtDriver(driver.ComputeDriver): # NOTE(xqueralt): libvirt needs o+x in the temp directory os.chmod(tmpdir, 0o701) self._live_snapshot(context, instance, guest, disk_path, - out_path, image_format, image_meta) + out_path, source_format, image_format, + image_meta) else: snapshot_backend.snapshot_extract(out_path, image_format) finally: @@ -1599,7 +1600,7 @@ class LibvirtDriver(driver.ComputeDriver): self._set_quiesced(context, instance, image_meta, False) def _live_snapshot(self, context, instance, guest, disk_path, out_path, - image_format, image_meta): + source_format, image_format, image_meta): """Snapshot an instance without downtime.""" dev = guest.get_block_device(disk_path) @@ -1617,9 +1618,11 @@ class LibvirtDriver(driver.ComputeDriver): # in QEMU 1.3. In order to do this, we need to create # a destination image with the original backing file # and matching size of the instance root disk. - src_disk_size = libvirt_utils.get_disk_size(disk_path) + src_disk_size = libvirt_utils.get_disk_size(disk_path, + format=source_format) src_back_path = libvirt_utils.get_disk_backing_file(disk_path, - basename=False) + format=source_format, + basename=False) disk_delta = out_path + '.delta' libvirt_utils.create_cow_image(src_back_path, disk_delta, src_disk_size) diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 1e93a8e1f834..8d2d295bdd3f 100644 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -161,24 +161,25 @@ def pick_disk_driver_name(hypervisor_version, is_block_dev=False): return None -def get_disk_size(path): +def get_disk_size(path, format=None): """Get the (virtual) size of a disk image :param path: Path to the disk image + :param format: the on-disk format of path :returns: Size (in bytes) of the given disk image as it would be seen by a virtual machine. """ - size = images.qemu_img_info(path).virtual_size + size = images.qemu_img_info(path, format).virtual_size return int(size) -def get_disk_backing_file(path, basename=True): +def get_disk_backing_file(path, basename=True, format=None): """Get the backing file of a disk image :param path: Path to the disk image :returns: a path to the image's backing store """ - backing_file = images.qemu_img_info(path).backing_file + backing_file = images.qemu_img_info(path, format).backing_file if backing_file and basename: backing_file = os.path.basename(backing_file)