libvirt: Get info with abs path, rebase with rel path

When a boot-from-volume instance with Cinder backed by NFS, when
attempting to delete a volume snapshot after deleting a newer volume
snapshot while the instance is stopped, the delete fails when Cinder
raises RemoteFSInvalidBackingFile.

The root cause is Nova using an absolute file path when specifying the
backing file when rebasing the qcow2 image during the deletion of the
newer volume snapshot. Then when the older volume snapshot is requested
to be deleted, on the Cinder side it fails because Cinder detects the
absolute path from Nova.

Originally, Nova used a relative file back for the backing file path
but it was changed to address a past bug #1885528 where an absolute
file path was needed in order to call qemu_img_info().

This changes to using an absolute path only for the qemu_img_info()
call and retain the relative path for the actual 'qemu-img rebase'
command invocation. The 'qemu-img rebase' command is designed to work
with both relative paths and absolute paths [1].

Closes-Bug: #2119353

[1] https://qemu-project.gitlab.io/qemu/tools/qemu-img.html#cmdoption-qemu-img-commands-arg-rebase

Change-Id: I6b5fe3bba49461fb10bc81e19bd16acf39e84ec6
Signed-off-by: melanie witt <melwittt@gmail.com>
(cherry picked from commit 668d9d37f8)
This commit is contained in:
melanie witt
2025-07-14 21:44:22 +00:00
parent c4b58648ee
commit d0003d6bf6
2 changed files with 12 additions and 5 deletions

View File

@@ -29894,7 +29894,7 @@ class LibvirtVolumeSnapshotTestCase(test.NoDBTestCase):
"/var/lib/nova/instances/%s/snap.img" % instance.uuid)
mock_execute.assert_called_once_with(
'qemu-img', 'rebase',
'-b', '/var/lib/nova/instances/%s/snap.img' % instance.uuid,
'-b', 'snap.img',
'-F', 'fake_fmt',
'/var/lib/nova/instances/%s/disk1_file' % instance.uuid)

View File

@@ -3820,17 +3820,24 @@ class LibvirtDriver(driver.ComputeDriver):
# If the rebased image is going to have a backing file then
# explicitly set the backing file format to avoid any security
# concerns related to file format auto detection.
if os.path.isabs(rebase_base):
backing_file = rebase_base
backing_file = rebase_base
# We will need the absolute path to the backing file in order to
# call images.qemu_img_info() as it checks for path existence.
# We still want to do the rebase itself with a relative path if a
# relative path was given, so that Cinder will also be able to
# successfully reference the backing file in its environment.
if os.path.isabs(backing_file):
backing_file_abs = backing_file
else:
# this is a probably a volume snapshot case where the
# rebase_base is relative. See bug
# https://bugs.launchpad.net/nova/+bug/1885528
backing_file_name = os.path.basename(rebase_base)
volume_path = os.path.dirname(source_path)
backing_file = os.path.join(volume_path, backing_file_name)
backing_file_abs = os.path.join(volume_path, backing_file_name)
b_file_fmt = images.qemu_img_info(backing_file).file_format
b_file_fmt = images.qemu_img_info(backing_file_abs).file_format
qemu_img_extra_arg = ['-F', b_file_fmt]
qemu_img_extra_arg.append(source_path)