libvirt: do relative block rebase only with non-null base
You can't use VIR_DOMAIN_BLOCK_REBASE_RELATIVE with null
base, libvirt reports error in this case, so check if
base is non-null before setting this flag (relative argument
of BlockDevice.rebase method).
The error was introduced by commit
e963991329
Change-Id: Ife50f211fd54190a2665ad090f6208048b841690
Closes-Bug: #1475202
This commit is contained in:
parent
6098f4727c
commit
45d73c49bd
|
@ -108,6 +108,7 @@ VIR_FROM_NWFILTER = 330
|
|||
VIR_FROM_REMOTE = 340
|
||||
VIR_FROM_RPC = 345
|
||||
VIR_FROM_NODEDEV = 666
|
||||
VIR_ERR_INVALID_ARG = 8
|
||||
VIR_ERR_NO_SUPPORT = 3
|
||||
VIR_ERR_XML_DETAIL = 350
|
||||
VIR_ERR_NO_DOMAIN = 420
|
||||
|
@ -739,7 +740,14 @@ class Domain(object):
|
|||
def blockResize(self, disk, size):
|
||||
pass
|
||||
|
||||
def blockRebase(self, disk, base, flags):
|
||||
def blockRebase(self, disk, base, bandwidth=0, flags=0):
|
||||
if (not base) and (flags and VIR_DOMAIN_BLOCK_REBASE_RELATIVE):
|
||||
raise make_libvirtError(
|
||||
libvirtError,
|
||||
'flag VIR_DOMAIN_BLOCK_REBASE_RELATIVE is '
|
||||
'valid only with non-null base',
|
||||
error_code=VIR_ERR_INVALID_ARG,
|
||||
error_domain=VIR_FROM_QEMU)
|
||||
return 0
|
||||
|
||||
def blockCommit(self, disk, base, top, flags):
|
||||
|
|
|
@ -13118,6 +13118,10 @@ class LibvirtVolumeSnapshotTestCase(test.NoDBTestCase):
|
|||
'file_to_merge': 'snap.img',
|
||||
'merge_target_file': 'other-snap.img'}
|
||||
|
||||
self.delete_info_3 = {'type': 'qcow2',
|
||||
'file_to_merge': None,
|
||||
'merge_target_file': None}
|
||||
|
||||
self.delete_info_netdisk = {'type': 'qcow2',
|
||||
'file_to_merge': 'snap.img',
|
||||
'merge_target_file': 'root.img'}
|
||||
|
@ -13480,6 +13484,38 @@ class LibvirtVolumeSnapshotTestCase(test.NoDBTestCase):
|
|||
|
||||
self.mox.VerifyAll()
|
||||
|
||||
def test_volume_snapshot_delete_nonrelative_null_base(self):
|
||||
# Deleting newest and last snapshot of a volume
|
||||
# with blockRebase. So base of the new image will be null.
|
||||
|
||||
instance = objects.Instance(**self.inst)
|
||||
snapshot_id = 'snapshot-1234'
|
||||
|
||||
domain = FakeVirtDomain(fake_xml=self.dom_xml)
|
||||
guest = libvirt_guest.Guest(domain)
|
||||
|
||||
with contextlib.nested(
|
||||
mock.patch.object(domain, 'XMLDesc', return_value=self.dom_xml),
|
||||
mock.patch.object(self.drvr._host, 'get_guest',
|
||||
return_value=guest),
|
||||
mock.patch.object(self.drvr._host, 'has_min_version',
|
||||
return_value=True),
|
||||
mock.patch.object(domain, 'blockRebase'),
|
||||
mock.patch.object(domain, 'blockJobInfo',
|
||||
return_value={'cur': 1000, 'end': 1000})
|
||||
) as (mock_xmldesc, mock_get_guest, mock_has_min_version,
|
||||
mock_rebase, mock_job_info):
|
||||
|
||||
self.drvr._volume_snapshot_delete(self.c, instance,
|
||||
self.volume_uuid, snapshot_id,
|
||||
self.delete_info_3)
|
||||
|
||||
mock_xmldesc.assert_called_once_with(flags=0)
|
||||
mock_get_guest.assert_called_once_with(instance)
|
||||
mock_has_min_version.assert_called_once_with((1, 1, 1,))
|
||||
mock_rebase.assert_called_once_with('vda', None, 0, flags=0)
|
||||
mock_job_info.assert_called_once_with('vda', flags=0)
|
||||
|
||||
def test_volume_snapshot_delete_outer_success(self):
|
||||
instance = objects.Instance(**self.inst)
|
||||
snapshot_id = 'snapshot-1234'
|
||||
|
|
|
@ -1887,7 +1887,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
# (relative backing path seems to work for this case)
|
||||
try:
|
||||
libvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE
|
||||
relative = True
|
||||
relative = rebase_base is not None
|
||||
except AttributeError:
|
||||
LOG.warn(_LW("Relative blockrebase support was not detected. "
|
||||
"Continuing with old behaviour."))
|
||||
|
|
Loading…
Reference in New Issue