Do not use qemu-img --backing-chain or --output=json

Initial code for GlusterFS snapshot support in Havana
used qemu-img arguments which are too new to run in many
environments.  Run qemu-img using only arguments which
will exist on older platforms.

Partial-Bug: #1224030
Change-Id: I5155dac492da67a951ede978c2c46a54c239eb04
This commit is contained in:
Eric Harney 2013-09-06 23:26:46 -04:00
parent e34ab12fbf
commit bd1a8482c5
2 changed files with 82 additions and 14 deletions

View File

@ -808,7 +808,6 @@ class GlusterFsDriverTestCase(test.TestCase):
"""
(mox, drv) = self._mox, self._driver
#volume = DumbVolume()
volume = self._simple_volume()
hashed = drv._get_hash_str(self.TEST_EXPORT1)
@ -873,7 +872,8 @@ class GlusterFsDriverTestCase(test.TestCase):
'backing-filename': volume_file}]
drv.get_active_image_from_info(volume).AndReturn(snap_file_2)
drv._get_backing_chain_for_path(snap_path_2).AndReturn(snap_path_chain)
drv._get_backing_chain_for_path(volume, snap_path_2).\
AndReturn(snap_path_chain)
drv._read_info_file(info_path).AndReturn(info_file_dict)
@ -1375,3 +1375,46 @@ class GlusterFsDriverTestCase(test.TestCase):
self.assertRaises(exception.GlusterfsException,
drv.delete_snapshot,
snap_ref)
def test_get_backing_chain_for_path(self):
(mox, drv) = self._mox, self._driver
glusterfs.CONF.glusterfs_mount_point_base = self.TEST_MNT_POINT_BASE
volume = self._simple_volume()
vol_filename = volume['name']
vol_filename_2 = volume['name'] + '.asdfjkl'
vol_filename_3 = volume['name'] + 'qwertyuiop'
hashed = drv._get_hash_str(self.TEST_EXPORT1)
vol_dir = '%s/%s' % (self.TEST_MNT_POINT_BASE, hashed)
vol_path = '%s/%s' % (vol_dir, vol_filename)
vol_path_2 = '%s/%s' % (vol_dir, vol_filename_2)
vol_path_3 = '%s/%s' % (vol_dir, vol_filename_3)
mox.StubOutWithMock(drv, '_execute')
mox.StubOutWithMock(drv, '_local_volume_dir')
qemu_img_output_base = """image: %s
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 173K
"""
qemu_img_output = qemu_img_output_base + 'backing file: %s\n'
qemu_img_output_1 = qemu_img_output % (vol_filename, vol_filename_2)
qemu_img_output_2 = qemu_img_output % (vol_filename_2, vol_filename_3)
qemu_img_output_3 = qemu_img_output_base % (vol_filename_3)
drv._local_volume_dir(volume).AndReturn(vol_dir)
drv._execute('qemu-img', 'info', vol_path).\
AndReturn((qemu_img_output_1, None))
drv._local_volume_dir(volume).AndReturn(vol_dir)
drv._execute('qemu-img', 'info', vol_path_2).\
AndReturn((qemu_img_output_2, None))
drv._local_volume_dir(volume).AndReturn(vol_dir)
drv._execute('qemu-img', 'info', vol_path_3).\
AndReturn((qemu_img_output_3, None))
mox.ReplayAll()
drv._get_backing_chain_for_path(volume, vol_path)

View File

@ -603,7 +603,8 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
# exist, not | | exist, being |needs ptr update
# used here) | | committed down)| if so)
backing_chain = self._get_backing_chain_for_path(active_file_path)
backing_chain = self._get_backing_chain_for_path(
snapshot['volume'], active_file_path)
# This file is guaranteed to exist since we aren't operating on
# the active file.
higher_file = next((os.path.basename(f['filename'])
@ -781,19 +782,43 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
run_as_root=True)
return self._get_file_format(out)
def _get_backing_chain_for_path(self, path):
"""Returns dict containing backing-chain information."""
def _get_backing_chain_for_path(self, volume, path):
"""Returns list of dicts containing backing-chain information.
# TODO(eharney): these args aren't available on el6.4's qemu-img
# Need to rewrite
# --backing-chain added in qemu 1.3.0
# --output=json added in qemu 1.5.0
Includes 'filename', and 'backing-filename' for each
applicable entry.
(out, err) = self._execute('qemu-img', 'info',
'--backing-chain',
'--output=json',
path)
return json.loads(out)
Consider converting this to use --backing-chain and --output=json
when environment supports qemu-img 1.5.0.
:param volume: volume reference
:param path: path to image file at top of chain
"""
output = []
(out, _err) = self._execute('qemu-img', 'info', path)
new_info = {}
new_info['filename'] = os.path.basename(path)
new_info['backing-filename'] = self._get_backing_file(out)
output.append(new_info)
while True:
filename = new_info['backing-filename']
path = os.path.join(self._local_volume_dir(volume), filename)
(out, _err) = self._execute('qemu-img', 'info', path)
backing_filename = self._get_backing_file(out)
if backing_filename is None:
break
new_info = {}
new_info['filename'] = filename
new_info['backing-filename'] = backing_filename
output.append(new_info)
return output
def _get_file_format(self, output):
for line in output.split('\n'):