From d0003d6bf67775b9bebfcc18a6177dba6fe5cf71 Mon Sep 17 00:00:00 2001 From: melanie witt Date: Mon, 14 Jul 2025 21:44:22 +0000 Subject: [PATCH] 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 (cherry picked from commit 668d9d37f8ec1e8c9729c13f4d9f0435303a22fb) --- nova/tests/unit/virt/libvirt/test_driver.py | 2 +- nova/virt/libvirt/driver.py | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index c81fb832732e..f5506eb281b4 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -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) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 3fd028993f01..040c2a6adcfe 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -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)