[Kimchi-devel] [PATCH] Issue #569: Deactive logical pool cause vm failed to start

Aline Manera alinefm at linux.vnet.ibm.com
Fri Feb 6 13:27:59 UTC 2015


On 05/02/2015 08:09, gouzongmei at 163.com wrote:
> From: Zongmei Gou <gouzongmei at 163.com>
>
> 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 4ab08d1..08bfe38 100644
> --- a/src/kimchi/i18n.py
> +++ b/src/kimchi/i18n.py
> @@ -188,6 +188,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 b85f3b4..c42b62e 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)
> +

Maybe would be better to use the objstore data.
There is an entry there for each storage volume in use.

Something like below:

with self.objstore as session:
     paths = [path for path in session.get_list('storagevolume') if 
path['ref_cnt'] > 0]
     pool_re = '^' + pool_path
     res = [re.match(pool_re, path) for path in paths if 
re.match(pool_re, path) is not None]
     if len(res) > 0:
         #pool in use.

>       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()




More information about the Kimchi-devel mailing list