From: Zongmei Gou <gouzongmei(a)ourfuture.cn>
Deactive logical pool cause vm failed to start while storage of the vm is in this logical
pool.
Storage pool's "deactive" action call libvirt "StoragePoolDestroy"
function which causes different result on different pool type.Once the pool is destroyed,
the 'dir' type pool remains its target path and images while the 'logical'
type pool deletes its target path and images.
This patch make deactive logical pool action failed while exists vm(s) linked to this
pool.
---
src/kimchi/i18n.py | 1 +
src/kimchi/model/storagepools.py | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 4eccc3e..4d84837 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -187,6 +187,7 @@ messages = {
"KCHPOOL0035E": _("Unable to delete pool %(name)s as it is associated
with some templates"),
"KCHPOOL0036E": _("A volume group named '%(name)s' already
exists. Please, choose another name to create the logical pool."),
"KCHPOOL0037E": _("Unable to update database with deep scan
information due error: %(err)s"),
+ "KCHPOOL0038E": _("Unable to deactivate pool %(name)s. There are some
virtual machines %(vms)s linked to this pool."),
"KCHVOL0001E": _("Storage volume %(name)s already exists"),
"KCHVOL0002E": _("Storage volume %(name)s does not exist in storage
pool %(pool)s"),
diff --git a/src/kimchi/model/storagepools.py b/src/kimchi/model/storagepools.py
index e03c6bb..6aa2c58 100644
--- a/src/kimchi/model/storagepools.py
+++ b/src/kimchi/model/storagepools.py
@@ -18,6 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import libvirt
+import os
from kimchi.scan import Scanner
from kimchi.exception import InvalidOperation, MissingParameter
@@ -27,6 +28,8 @@ from kimchi.model.host import DeviceModel
from kimchi.model.libvirtstoragepool import StoragePoolDef
from kimchi.utils import add_task, kimchi_log, pool_name_from_uri, run_command
from kimchi.xmlutils.utils import xpath_get_text
+from kimchi.model.vms import VMModel, VMsModel
+from kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
ISO_POOL_NAME = u'kimchi_isos'
@@ -230,6 +233,24 @@ class StoragePoolModel(object):
source[key] = res
return source
+ def _get_vms_attach_to_a_storagepool(self, pool_name):
+ # find out vm(s) the vol(s) of this pool attached to.
+ pool = self.get_storagepool(pool_name, self.conn)
+ xml = pool.XMLDesc(0)
+
+ vms = []
+ pool_path = xpath_get_text(xml, "/pool/target/path")[0]
+ vms_list = VMsModel.get_vms(self.conn)
+ for vm in vms_list:
+ dom = VMModel.get_vm(vm, self.conn)
+ storages = get_vm_disks(dom)
+ for disk in storages.keys():
+ d_info = get_vm_disk_info(dom, disk)
+ if pool_path == os.path.split(d_info['path'])[0]:
+ vms.append(vm)
+ break
+ return sorted(vms)
+
def _nfs_status_online(self, pool, poolArgs=None):
if not poolArgs:
xml = pool.XMLDesc(0)
@@ -378,6 +399,13 @@ class StoragePoolModel(object):
raise OperationFailed("KCHPOOL0033E",
{'name': name, 'server':
source['addr']})
return
+ elif (pool_type == 'logical' and
+ self._get_storagepool_vols_num(pool) > 0):
+ # can not deactive if vol(s) exists, because destroy
+ # logical pool will cause the vol deleted.
+ vms = self._get_vms_attach_to_a_storagepool(name)
+ raise InvalidOperation('KCHPOOL0038E', {'name': name,
+ 'vms': ',
'.join(vms)})
try:
persistent = pool.isPersistent()
pool.destroy()
--
1.8.3.1