Reviewed-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
On 03/10/2014 05:05 PM, lvroyce(a)linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce(a)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(a)linux.vnet.ibm.com>
---
src/kimchi/mockmodel.py | 3 +++
src/kimchi/model/storagevolumes.py | 29 +++++++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
index 4ead84b..1460d67 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)
@@ -890,6 +891,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
@@ -1009,6 +1011,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 6811e15..3b4da82 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -28,6 +28,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',
@@ -58,6 +60,7 @@ class StorageVolumesModel(object):
params.setdefault('format', 'qcow2')
name = params['name']
+ vol_id = '%s:%s' % (pool_name, name)
try:
pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
xml = vol_xml % params
@@ -75,6 +78,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):
@@ -108,6 +115,26 @@ 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.get_vms(self.conn)
+ 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()
@@ -121,10 +148,12 @@ class StorageVolumeModel(object):
# infomation. When there is no format information, we assume
# it's 'raw'.
fmt = 'raw'
+ 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):
--
Thanks and best regards!
Sheldon Feng(冯少合)<shaohef(a)linux.vnet.ibm.com>
IBM Linux Technology Center