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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user