"""
(mox, drv) = self._mox, self._driver
- #volume = DumbVolume()
volume = self._simple_volume()
hashed = drv._get_hash_str(self.TEST_EXPORT1)
'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)
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)
# 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'])
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'):