From: Eric Harney Date: Thu, 19 Dec 2013 00:11:44 +0000 (-0500) Subject: GlusterFS: Use correct base argument when deleting attached snaps X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=186221779a92002ff9fa13c254710c0abb3803be;p=openstack-build%2Fcinder-build.git GlusterFS: Use correct base argument when deleting attached snaps When deleting the most recent snapshot, the 'file_to_merge' field which translates into the base= field for libvirt's blockRebase call in Nova must be set depending on whether other snapshots exist. If there are no other snapshots, base = None, which results in libvirt clearing the qcow2 backing file pointer for the active disk image. If there are other snapshots, pass the parent of the file being deleted as the new base file. The snapshot info pointer for the prior base file must also be updated in this case. Closes-Bug: #1262880 Change-Id: If7bc8259b031d0406346caafb8f688e65a38dba6 --- diff --git a/cinder/tests/test_glusterfs.py b/cinder/tests/test_glusterfs.py index 23874a9b4..69a616e09 100644 --- a/cinder/tests/test_glusterfs.py +++ b/cinder/tests/test_glusterfs.py @@ -1175,7 +1175,7 @@ class GlusterFsDriverTestCase(test.TestCase): snap_ref) def test_delete_snapshot_online_1(self): - """Delete the newest snapshot.""" + """Delete the newest snapshot, with only one snap present.""" (mox, drv) = self._mox, self._driver volume = self._simple_volume() @@ -1226,15 +1226,25 @@ class GlusterFsDriverTestCase(test.TestCase): backing file: %s """ % (snap_file, volume_file) img_info = imageutils.QemuImgInfo(qemu_img_info_output) + + vol_qemu_img_info_output = """image: %s + file format: raw + virtual size: 1.0G (1073741824 bytes) + disk size: 173K + """ % volume_file + volume_img_info = imageutils.QemuImgInfo(vol_qemu_img_info_output) + image_utils.qemu_img_info(snap_path).AndReturn(img_info) + image_utils.qemu_img_info(volume_path).AndReturn(volume_img_info) + drv._read_info_file(info_path, empty_if_missing=True).\ AndReturn(snap_info) delete_info = { 'type': 'qcow2', 'merge_target_file': None, - 'file_to_merge': volume_file, + 'file_to_merge': None, 'volume_id': self.VOLUME_UUID } @@ -1265,7 +1275,7 @@ class GlusterFsDriverTestCase(test.TestCase): drv.delete_snapshot(snap_ref) def test_delete_snapshot_online_2(self): - """Delete the middle snapshot.""" + """Delete the middle of 3 snapshots.""" (mox, drv) = self._mox, self._driver volume = self._simple_volume() @@ -1320,8 +1330,17 @@ class GlusterFsDriverTestCase(test.TestCase): """ % (snap_file, volume_file) img_info = imageutils.QemuImgInfo(qemu_img_info_output) + vol_qemu_img_info_output = """image: %s + file format: raw + virtual size: 1.0G (1073741824 bytes) + disk size: 173K + """ % volume_file + volume_img_info = imageutils.QemuImgInfo(vol_qemu_img_info_output) + image_utils.qemu_img_info(snap_path).AndReturn(img_info) + image_utils.qemu_img_info(volume_path).AndReturn(volume_img_info) + drv._read_info_file(info_path, empty_if_missing=True).\ AndReturn(snap_info) diff --git a/cinder/volume/drivers/glusterfs.py b/cinder/volume/drivers/glusterfs.py index 927969216..a7d276211 100644 --- a/cinder/volume/drivers/glusterfs.py +++ b/cinder/volume/drivers/glusterfs.py @@ -596,6 +596,12 @@ class GlusterfsDriver(nfs.RemoteFsDriver): # file as base. msg = _('No base file found for %s.') % snapshot_path raise exception.GlusterfsException(msg) + + base_path = os.path.join( + self._local_volume_dir(snapshot['volume']), base_file) + base_file_img_info = self._qemu_img_info(base_path) + new_base_file = base_file_img_info.backing_file + base_id = None info_path = self._local_path_volume(snapshot['volume']) + '.info' snap_info = self._read_info_file(info_path) @@ -614,7 +620,8 @@ class GlusterfsDriver(nfs.RemoteFsDriver): 'active_file': active_file, 'snapshot_file': snapshot_file, 'base_file': base_file, - 'base_id': base_id + 'base_id': base_id, + 'new_base_file': new_base_file } return self._delete_snapshot_online(context, @@ -724,8 +731,15 @@ class GlusterfsDriver(nfs.RemoteFsDriver): # info['base'] => snapshot_file file_to_delete = info['base_file'] + if info['base_id'] is None: + # Passing base=none to blockRebase ensures that + # libvirt blanks out the qcow2 backing file pointer + new_base = None + else: + new_base = info['new_base_file'] + snap_info[info['base_id']] = info['snapshot_file'] - delete_info = {'file_to_merge': info['base_file'], + delete_info = {'file_to_merge': new_base, 'merge_target_file': None, # current 'type': 'qcow2', 'volume_id': snapshot['volume']['id']}