[Kimchi-devel] [PATCHv5 4/6] Add volume ref_cnt: Add model and mockmodel implementation

lvroyce at linux.vnet.ibm.com lvroyce at linux.vnet.ibm.com
Tue Mar 4 07:38:46 UTC 2014


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

Set ref_cnt to 0 when new volume created,
if the ref_cnt cannot be found,
which means it is created outside of kimchi scope,
report it when lookup storage volume,
search info about storage volumes used by vms and count the ref_cnt.

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 src/kimchi/mockmodel.py            |  3 +++
 src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index f99b4cd..d69a58a 100644
--- a/src/kimchi/mockmodel.py
+++ b/src/kimchi/mockmodel.py
@@ -426,6 +426,7 @@ class MockModel(object):
             name = params['name']
             volume = MockStorageVolume(pool, name, params)
             volume.info['type'] = params['type']
+            volume.info['ref_cnt'] = params.get('ref_cnt', 0)
             volume.info['format'] = params['format']
             volume.info['path'] = os.path.join(
                 pool.info['path'], name)
@@ -887,6 +888,7 @@ class MockVMTemplate(VMTemplate):
         disk_paths = []
         for vol_info in volumes:
             vol_info['capacity'] = vol_info['capacity'] << 10
+            vol_info['ref_cnt'] = 1
             self.model.storagevolumes_create(pool.name, vol_info)
             disk_paths.append({'pool': pool.name, 'volume': vol_info['name']})
         return disk_paths
@@ -1005,6 +1007,7 @@ class MockStorageVolume(object):
                      'capacity': capacity << 20,
                      'allocation': params.get('allocation', '512'),
                      'path': params.get('path'),
+                     'ref_cnt': params.get('ref_cnt'),
                      'format': fmt}
         if fmt == 'iso':
             self.info['allocation'] = self.info['capacity']
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index a031eb0..e9ce736 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -27,6 +27,8 @@ from kimchi.exception import MissingParameter, NotFoundError, OperationFailed
 from kimchi.isoinfo import IsoImage
 from kimchi.model.storagepools import StoragePoolModel
 from kimchi.utils import kimchi_log
+from kimchi.model.vms import VMsModel
+from kimchi.model.vmstorages import VMStoragesModel, VMStorageModel
 
 
 VOLUME_TYPE_MAP = {0: 'file',
@@ -38,6 +40,7 @@ VOLUME_TYPE_MAP = {0: 'file',
 class StorageVolumesModel(object):
     def __init__(self, **kargs):
         self.conn = kargs['conn']
+        self.objstore = kargs['objstore']
 
     def create(self, pool, params):
         vol_xml = """
@@ -56,6 +59,7 @@ class StorageVolumesModel(object):
         params.setdefault('format', 'qcow2')
 
         name = params['name']
+        vol_id = '%s:%s' % (pool, name)
         try:
             pool = StoragePoolModel.get_storagepool(pool, self.conn)
             xml = vol_xml % params
@@ -69,6 +73,10 @@ class StorageVolumesModel(object):
             raise OperationFailed("KCHVOL0007E",
                                   {'name': name, 'pool': pool,
                                    'err': e.get_error_message()})
+
+        with self.objstore as session:
+            session.store('storagevolume', vol_id, {'ref_cnt': 0})
+
         return name
 
     def get_list(self, pool_name):
@@ -87,6 +95,7 @@ class StorageVolumesModel(object):
 class StorageVolumeModel(object):
     def __init__(self, **kargs):
         self.conn = kargs['conn']
+        self.objstore = kargs['objstore']
 
     def _get_storagevolume(self, pool, name):
         pool = StoragePoolModel.get_storagepool(pool, self.conn)
@@ -101,16 +110,38 @@ class StorageVolumeModel(object):
             else:
                 raise
 
+    def _get_ref_cnt(self, pool, name, path):
+        vol_id = '%s:%s' % (pool, name)
+        with self.objstore as session:
+            try:
+                ref_cnt = session.get('storagevolume', vol_id)['ref_cnt']
+            except NotFoundError:
+                # Fix storage volume created outside kimchi scope
+                ref_cnt = 0
+                args = {'conn': self.conn, 'objstore': self.objstore}
+                # try to find this volume in exsisted vm
+                vms = VMsModel(**args).get_list()
+                for vm in vms:
+                    storages = VMStoragesModel(**args).get_list(vm)
+                    for disk in storages:
+                        if path == VMStorageModel(**args).lookup(vm, disk)['path']:
+                            ref_cnt = ref_cnt + 1
+                session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt})
+
+        return ref_cnt
+
     def lookup(self, pool, name):
         vol = self._get_storagevolume(pool, name)
         path = vol.path()
         info = vol.info()
         xml = vol.XMLDesc(0)
         fmt = xmlutils.xpath_get_text(xml, "/volume/target/format/@type")[0]
+        ref_cnt = self._get_ref_cnt(pool, name, path)
         res = dict(type=VOLUME_TYPE_MAP[info[0]],
                    capacity=info[1],
                    allocation=info[2],
                    path=path,
+                   ref_cnt=ref_cnt,
                    format=fmt)
         if fmt == 'iso':
             if os.path.islink(path):
-- 
1.8.1.2




More information about the Kimchi-devel mailing list