From 37e35047062b66321f9af6393b2b1c609af54e1a Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanino Date: Thu, 18 Dec 2014 09:07:24 -0500 Subject: [PATCH] LVM: Volume is deleted unexpectedly during volume migration When using LVMISCSIDriver, a volume is unexpectedly deleted during volume migration operation. This problem only occurs when the volume_group of backend A and backend B is same value such as misconfiguration. Even if the configuration is wrong, cinder should not delete the volume unexpectedly for user. Closes-Bug: 1404013 Change-Id: I010be0c70589459a488cdef7cd83380eab27c61c --- cinder/tests/test_volume.py | 17 +++++++++++++++++ cinder/volume/drivers/lvm.py | 23 +++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index 5af42eef517..807e2bfed3b 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -3752,6 +3752,23 @@ class LVMISCSIVolumeDriverTestCase(DriverTestCase): self.assertEqual(moved, False) self.assertIsNone(model_update) + @mock.patch.object(volutils, 'get_all_volume_groups', + return_value=[{'name': 'cinder-volumes'}]) + def test_lvm_migrate_volume_same_volume_group(self, vgs): + hostname = socket.gethostname() + capabilities = {'location_info': 'LVMVolumeDriver:%s:' + 'cinder-volumes:default:0' % hostname} + host = {'capabilities': capabilities} + vol = {'name': 'test', 'id': 1, 'size': 1, 'status': 'available'} + self.volume.driver.vg = FakeBrickLVM('cinder-volumes', + False, + None, + 'default') + + self.assertRaises(exception.VolumeBackendAPIException, + self.volume.driver.migrate_volume, self.context, + vol, host) + def test_lvm_volume_group_missing(self): hostname = socket.gethostname() capabilities = {'location_info': 'LVMVolumeDriver:%s:' diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py index 3bd67b94dad..8c143443b15 100644 --- a/cinder/volume/drivers/lvm.py +++ b/cinder/volume/drivers/lvm.py @@ -609,15 +609,22 @@ class LVMISCSIDriver(LVMVolumeDriver, driver.ISCSIDriver): lvm_mirrors, dest_vg_ref) - volutils.copy_volume(self.local_path(volume), - self.local_path(volume, vg=dest_vg), - volume['size'], - self.configuration.volume_dd_blocksize, - execute=self._execute) - self._delete_volume(volume) - model_update = self._create_export(ctxt, volume, vg=dest_vg) + volutils.copy_volume(self.local_path(volume), + self.local_path(volume, vg=dest_vg), + volume['size'], + self.configuration.volume_dd_blocksize, + execute=self._execute) + self._delete_volume(volume) + model_update = self._create_export(ctxt, volume, vg=dest_vg) - return (True, model_update) + return (True, model_update) + else: + message = (_("Refusing to migrate volume ID: %(id)s. Please " + "check your configuration because source and " + "destination are the same Volume Group: %(name)s.") + % {'id': volume['id'], 'name': self.vg.vg_name}) + LOG.exception(message) + raise exception.VolumeBackendAPIException(data=message) def _iscsi_location(self, ip, target, iqn, lun=None): return "%s:%s,%s %s %s" % (ip, self.configuration.iscsi_port,