* Remove lsm.Initiator and related methods from plugins.
* Update iscsi_chap_auth().
* SMI-S plugin now fully support interop namespace.
* Removed some unused methods from SMI-S plugin.
* Tested by these commands:
lsmcli list --type access_groups
lsmcli ag-add-init --ag <AG_ID> --init <INIT_ID> --init-type WWPN|iSCSI
lsmcli ag-del-init --ag <AG_ID> --init <INIT_ID>
lsmcli volume-mask --vol <VOL_ID> --ag <AG_ID>
lsmcli list --type volumes --ag <AG_ID>
lsmcli list --type access_groups --vol <VOL_ID>
lsmcli volume-unmask --vol <VOL_ID> --ag <AG_ID>
* Tested on these plugin:
nstor:
Nexentastor 3.1.5
ONTAP:
ONTAP 8.1.2 7-mode
Simulator:
SimArray 2.4
SMI-S:
EMC VNX(full test)
SMI-S access group query test:
EMC VMAX, FUJITSU ETERNUS, HDS AMS[1], IBM XIV, NetApp ONTAP[2]
SMI-S NetApp E-Serial:
'Masking and Mapping' not supported.
Targetd:
lsmcli volume-mask --vol <VOL_ID> --init <INIT_ID> --init-type iSCSI
lsmcli list --type volumes --ag <AG_ID>
lsmcli list --type access_groups --vol <VOL_ID>
lsmcli volume-unmask --vol <VOL_ID> --ag <AG_ID>
[1] HDS AMS marked 'other' type of access_group, need investigation, might be
iSCSI target port.
[2] NetApp ONTAP SMI-S provider does not provider initiator ID when call
access_groups(), need investigation.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/nstor/nstor.py | 91 +------
plugin/ontap/na.py | 2 +-
plugin/ontap/ontap.py | 74 ++----
plugin/sim/simarray.py | 196 ++++-----------
plugin/sim/simulator.py | 28 +--
plugin/smispy/eseries.py | 65 -----
plugin/smispy/smis.py | 622 ++++++++++++++++------------------------------
plugin/targetd/targetd.py | 69 +----
plugin/v7k/ibmv7k.py | 150 +----------
9 files changed, 302 insertions(+), 995 deletions(-)
diff --git a/plugin/nstor/nstor.py b/plugin/nstor/nstor.py
index f655a5e..c47a670 100644
--- a/plugin/nstor/nstor.py
+++ b/plugin/nstor/nstor.py
@@ -30,7 +30,7 @@ import time
import traceback
from lsm import (AccessGroup, Capabilities, ErrorNumber, FileSystem, INfs,
- IStorageAreaNetwork, Initiator, LsmError, NfsExport, Pool,
+ IStorageAreaNetwork, LsmError, NfsExport, Pool,
FsSnapshot, System, VERSION, Volume, md5, Error,
common_urllib2_error_handler, search_property)
@@ -502,18 +502,6 @@ class NexentaStor(INfs, IStorageAreaNetwork):
return search_property(vol_list, search_key, search_value)
@handle_nstor_errors
- def initiators(self, flags=0):
- """
- Return an array of initiator objects
- """
- i_list = []
- for ag in self.access_groups():
- for initiator_id in ag.init_ids:
- i_list.append(Initiator(initiator_id,
- Initiator.TYPE_ISCSI, initiator_id))
- return i_list
-
- @handle_nstor_errors
def volume_create(self, pool, volume_name, size_bytes, provisioning,
flags=0):
"""
@@ -633,7 +621,7 @@ class NexentaStor(INfs, IStorageAreaNetwork):
# return
@handle_nstor_errors
- def iscsi_chap_auth(self, initiator, in_user, in_password, out_user,
+ def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
out_password, flags=0):
"""
Register a user/password for the specified initiator for CHAP
@@ -652,60 +640,25 @@ class NexentaStor(INfs, IStorageAreaNetwork):
try:
self._request("create_initiator", "iscsitarget",
- [initiator.name,
+ [init_id,
{'initiatorchapuser': in_user,
'initiatorchapsecret': in_password}])
except:
self._request("modify_initiator", "iscsitarget",
- [initiator.name,
+ [init_id,
{'initiatorchapuser': in_user,
'initiatorchapsecret': in_password}])
self._request("modify_initiator", "iscsitarget",
- [initiator.name,
+ [init_id,
{'initiatorchapuser': in_user,
'initiatorchapsecret': in_password}])
return
- @handle_nstor_errors
- def initiator_grant(self, initiator_id, initiator_type, volume, access,
- flags=0):
- """
- Allows an initiator to access a volume.
- """
- hg_name = NexentaStor._calc_group(initiator_id)
- try:
- self.access_group_create(hg_name, initiator_id, initiator_type,
- 'NA')
- except:
- pass
- self._volume_mask(hg_name, volume.name)
- return
-
def _get_views(self, volume_name):
return self._request("list_lun_mapping_entries", "scsidisk",
[volume_name])
- @handle_nstor_errors
- def initiator_revoke(self, initiator, volume, flags=0):
- """
- Revokes access to a volume for the specified initiator
- """
- ag_name = NexentaStor._calc_group(initiator.name)
- views = self._get_views(volume.name)
- view_number = -1
- for view in views:
- if view['host_group'] == ag_name:
- view_number = view['entry_number']
- if view_number == -1:
- raise LsmError(ErrorNumber.NO_MAPPING, "There is no such mapping "
- "for volume %s" %
- volume.name)
- self._request("remove_lun_mapping_entry", "scsidisk",
- [volume.name, view_number])
- self._request("destroy_hostgroup", "stmf", [ag_name])
- return
-
def _volume_mask(self, group_name, volume_name):
self._request("add_lun_mapping_entry", "scsidisk",
[volume_name, {'host_group': group_name}])
@@ -800,7 +753,7 @@ class NexentaStor(INfs, IStorageAreaNetwork):
"""
Adds an initiator to an access group
"""
- if init_type != Initiator.TYPE_ISCSI:
+ if init_type != AccessGroup.INIT_TYPE_ISCSI_IQN:
raise LsmError(ErrorNumber.NO_SUPPORT,
"Nstor only support iSCSI Access Group")
@@ -869,35 +822,3 @@ class NexentaStor(INfs, IStorageAreaNetwork):
clone_name = dep.split('@')[0]
self._request("promote", "volume", [clone_name])
return None
-
- @handle_nstor_errors
- def volumes_accessible_by_initiator(self, initiator, flags=0):
- """
- Returns a list of volumes that the initiator has access to.
- """
- ag_name = NexentaStor._calc_group(initiator.name)
- volumes = []
- all_volumes_list = self.volumes()
- for vol in all_volumes_list:
- for view in self._get_views(vol.name):
- if view['host_group'] == ag_name:
- volumes.append(vol)
- return volumes
-
- @handle_nstor_errors
- def initiators_granted_to_volume(self, volume, flags=0):
- """
- Returns a list of initiators that have access to the specified volume.
- """
- ag_list = self.access_groups()
- i_list = self.initiators()
- initiators_id = []
- for view in self._get_views(volume.name):
- for ag in ag_list:
- if ag.name == view['host_group']:
- initiators_id.extend(ag.initiators)
- initiators = []
- for i in i_list:
- if i.name in initiators_id:
- initiators.append(i)
- return initiators
diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
index 0986a9c..214cc0d 100644
--- a/plugin/ontap/na.py
+++ b/plugin/ontap/na.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2013 Red Hat, Inc.
+# Copyright (C) 2012-2014 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index cde128f..203dfe7 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -23,7 +23,7 @@ import urlparse
import sys
import na
-from lsm import (Volume, Initiator, FileSystem, FsSnapshot, NfsExport,
+from lsm import (Volume, FileSystem, FsSnapshot, NfsExport,
AccessGroup, System, Capabilities, Disk, Pool, OptionalData,
IStorageAreaNetwork, INfs, LsmError, ErrorNumber, JobStatus,
md5, Error, VERSION, common_urllib2_error_handler,
@@ -519,32 +519,6 @@ class Ontap(IStorageAreaNetwork, INfs):
def systems(self, flags=0):
return [self.sys_info]
- @handle_ontap_errors
- def initiators(self, flags=0):
- """
- We will list all the initiators that are in all the groups.
- """
- rc = []
- groups = self.f.igroups()
-
- for g in groups:
- #Get the initiator in the group
- if g['initiators']:
- inits = na.to_list(g['initiators']['initiator-info'])
-
- for i in inits:
- init = i['initiator-name']
-
- if g['initiator-group-type'] == 'iscsi':
- init_type = Initiator.TYPE_ISCSI
- else:
- init_type = Initiator.TYPE_PORT_WWN
-
- name = init
- rc.append(Initiator(init, init_type, name))
-
- return rc
-
def _get_volume(self, vol_name, pool_id):
return self._lun(self.f.luns_get_specific(pool_id, vol_name, None)[0])
@@ -735,13 +709,13 @@ class Ontap(IStorageAreaNetwork, INfs):
return self.f.lun_offline(volume.name)
@handle_ontap_errors
- def volume_mask(self, group, volume, flags=0):
- self.f.lun_map(group.name, volume.name)
+ def volume_mask(self, access_group, volume, flags=0):
+ self.f.lun_map(access_group.name, volume.name)
return None
@handle_ontap_errors
- def volume_unmask(self, group, volume, flags=0):
- self.f.lun_unmap(group.name, volume.name)
+ def volume_unmask(self, access_group, volume, flags=0):
+ self.f.lun_unmap(access_group.name, volume.name)
return None
@staticmethod
@@ -772,20 +746,24 @@ class Ontap(IStorageAreaNetwork, INfs):
[self._access_group(g) for g in groups], search_key, search_value)
@handle_ontap_errors
- def access_group_create(self, name, initiator_id, id_type, system_id,
+ def access_group_create(self, name, init_id, init_type, system_id,
flags=0):
cur_groups = self.access_groups()
for cg in cur_groups:
if cg.name == name:
raise LsmError(ErrorNumber.EXISTS_ACCESS_GROUP,
- "Access group exists!")
+ "Access group with the same name exists!")
- if id_type == Initiator.TYPE_ISCSI:
+ if init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
self.f.igroup_create(name, 'iscsi')
- else:
+ elif init_type == AccessGroup.INIT_TYPE_WWPN:
self.f.igroup_create(name, 'fcp')
+ else:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "ONTAP only support iSCSI and FC/FCoE, but got "
+ "init_type: %d" % init_type)
- self.f.igroup_add_initiator(name, initiator_id)
+ self.f.igroup_add_initiator(name, init_id)
groups = self.access_groups()
for g in groups:
@@ -796,25 +774,25 @@ class Ontap(IStorageAreaNetwork, INfs):
"Unable to find group just created!")
@handle_ontap_errors
- def access_group_delete(self, group, flags=0):
- return self.f.igroup_delete(group.name)
+ def access_group_delete(self, access_group, flags=0):
+ return self.f.igroup_delete(access_group.name)
@handle_ontap_errors
- def access_group_initiator_add(self, group, initiator_id, id_type,
+ def access_group_initiator_add(self, access_group, init_id, init_type,
flags=0):
- return self.f.igroup_add_initiator(group.name, initiator_id)
+ return self.f.igroup_add_initiator(access_group.name, init_id)
@handle_ontap_errors
- def access_group_initiator_delete(self, group, initiator_id, flags=0):
- return self.f.igroup_del_initiator(group.name, initiator_id)
+ def access_group_initiator_delete(self, access_group, init_id, flags=0):
+ return self.f.igroup_del_initiator(access_group.name, init_id)
@handle_ontap_errors
- def volumes_accessible_by_access_group(self, group, flags=0):
+ def volumes_accessible_by_access_group(self, access_group, flags=0):
rc = []
- if len(group.initiators):
- luns = self.f.lun_initiator_list_map_info(group.initiators[0],
- group.name)
+ if len(access_group.init_ids):
+ luns = self.f.lun_initiator_list_map_info(access_group.init_ids[0],
+ access_group.name)
rc = [self._lun(l) for l in luns]
return rc
@@ -825,7 +803,7 @@ class Ontap(IStorageAreaNetwork, INfs):
return [self._access_group(g) for g in groups]
@handle_ontap_errors
- def iscsi_chap_auth(self, initiator, in_user, in_password, out_user,
+ def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
out_password, flags=0):
if out_user and out_password and \
(in_user is None or in_password is None):
@@ -833,7 +811,7 @@ class Ontap(IStorageAreaNetwork, INfs):
"out_user and out_password only supported if "
"inbound is supplied")
- self.f.iscsi_initiator_add_auth(initiator.id, in_user, in_password,
+ self.f.iscsi_initiator_add_auth(init_id, in_user, in_password,
out_user, out_password)
@staticmethod
diff --git a/plugin/sim/simarray.py b/plugin/sim/simarray.py
index c7cc2cc..0ccc4dc 100644
--- a/plugin/sim/simarray.py
+++ b/plugin/sim/simarray.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2013 Red Hat, Inc.
+# Copyright (C) 2011-2014 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
@@ -27,8 +27,8 @@ import time
from lsm import (size_human_2_size_bytes, size_bytes_2_size_human)
from lsm import (System, Volume, Disk, Pool, FileSystem, AccessGroup,
- Initiator, FsSnapshot, NfsExport, OptionalData, md5,
- LsmError, ErrorNumber, JobStatus)
+ FsSnapshot, NfsExport, OptionalData, md5, LsmError,
+ ErrorNumber, JobStatus)
# Used for format width for disks
D_FMT = 5
@@ -387,30 +387,6 @@ class SimArray(object):
sim_ags = self.data.access_groups_granted_to_volume(vol_id, flags)
return [SimArray._sim_ag_2_lsm(a) for a in sim_ags]
- @staticmethod
- def _sim_init_2_lsm(sim_init):
- return Initiator(sim_init['init_id'], sim_init['init_type'],
- sim_init['name'])
-
- def inits(self, flags=0):
- sim_inits = self.data.inits()
- return [SimArray._sim_init_2_lsm(a) for a in sim_inits]
-
- def initiator_grant(self, init_id, init_type, vol_id, access, flags=0):
- return self.data.initiator_grant(
- init_id, init_type, vol_id, access, flags)
-
- def initiator_revoke(self, init_id, vol_id, flags=0):
- return self.data.initiator_revoke(init_id, vol_id, flags)
-
- def volumes_accessible_by_initiator(self, init_id, flags=0):
- sim_vols = self.data.volumes_accessible_by_initiator(init_id, flags)
- return [SimArray._sim_vol_2_lsm(v) for v in sim_vols]
-
- def initiators_granted_to_volume(self, vol_id, flags=0):
- sim_inits = self.data.initiators_granted_to_volume(vol_id, flags)
- return [SimArray._sim_init_2_lsm(i) for i in sim_inits]
-
def iscsi_chap_auth(self, init_id, in_user, in_pass, out_user, out_pass,
flags=0):
return self.data.iscsi_chap_auth(init_id, in_user, in_pass, out_user,
@@ -453,16 +429,6 @@ class SimData(object):
}
}
- self.init_dict = {
- Initiator.id = sim_init,
- }
- sim_init = {
- 'init_id': Initiator.id,
- 'init_type': Initiator.TYPE_XXXX,
- 'name': SimData.SIM_DATA_INIT_NAME,
- 'sys_id': SimData.SIM_DATA_SYS_ID,
- }
-
self.ag_dict ={
AccessGroup.id = sim_ag,
}
@@ -536,7 +502,7 @@ class SimData(object):
}
"""
SIM_DATA_BLK_SIZE = 512
- SIM_DATA_VERSION = "2.3"
+ SIM_DATA_VERSION = "2.4"
SIM_DATA_SYS_ID = 'sim-01'
SIM_DATA_INIT_NAME = 'NULL'
SIM_DATA_TMO = 30000 # ms
@@ -869,6 +835,8 @@ class SimData(object):
return self.ag_dict.values()
def volume_create(self, pool_id, vol_name, size_bytes, thinp, flags=0):
+ self._check_dup_name(
+ self.vol_dict.values(), vol_name, ErrorNumber.EXISTS_VOLUME)
size_bytes = SimData._block_rounding(size_bytes)
# check free size
free_space = self.pool_free_space(pool_id)
@@ -1033,16 +1001,23 @@ class SimData(object):
def ags(self, flags=0):
return self.ag_dict.values()
+ def _check_dup_init(self, init_id):
+ for sim_ag in self.ag_dict.values():
+ if init_id in sim_ag['init_ids']:
+ raise LsmError(ErrorNumber.EXISTS_INITIATOR,
+ "init_id %s already exist in other "
+ % init_id +
+ "access group %s" % sim_ag['ag_id'])
+ def _check_dup_name(self, sim_list, name, error_num):
+ used_names = [x['name'] for x in sim_list]
+ if name in used_names:
+ raise LsmError(error_num, "Name '%s' already in use" % name)
+
def access_group_create(self, name, init_id, init_type, sys_id, flags=0):
+ self._check_dup_name(
+ self.ag_dict.values(), name, ErrorNumber.EXISTS_ACCESS_GROUP)
+ self._check_dup_init(init_id)
sim_ag = dict()
- if init_id not in self.init_dict.keys():
- sim_init = dict()
- sim_init['init_id'] = init_id
- sim_init['init_type'] = init_type
- sim_init['name'] = SimData.SIM_DATA_INIT_NAME
- sim_init['sys_id'] = SimData.SIM_DATA_SYS_ID
- self.init_dict[init_id] = sim_init
-
sim_ag['init_ids'] = [init_id]
sim_ag['init_type'] = init_type
sim_ag['sys_id'] = SimData.SIM_DATA_SYS_ID
@@ -1062,26 +1037,18 @@ class SimData(object):
if ag_id not in self.ag_dict.keys():
raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
"Access group not found")
- if init_id not in self.init_dict.keys():
- sim_init = dict()
- sim_init['init_id'] = init_id
- sim_init['init_type'] = init_type
- sim_init['name'] = SimData.SIM_DATA_INIT_NAME
- sim_init['sys_id'] = SimData.SIM_DATA_SYS_ID
- self.init_dict[init_id] = sim_init
if init_id in self.ag_dict[ag_id]['init_ids']:
- return self.ag_dict[ag_id]
+ return None
- self.ag_dict[ag_id]['init_ids'].extend([init_id])
+ self._check_dup_init(init_id)
+ self.ag_dict[ag_id]['init_ids'].extend([init_id])
return None
def access_group_initiator_delete(self, ag_id, init_id, flags=0):
if ag_id not in self.ag_dict.keys():
raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
"Access group not found: %s" % ag_id)
- if init_id not in self.init_dict.keys():
- return None
if init_id in self.ag_dict[ag_id]['init_ids']:
new_init_ids = []
@@ -1122,9 +1089,7 @@ class SimData(object):
return None
def volumes_accessible_by_access_group(self, ag_id, flags=0):
- if ag_id not in self.ag_dict.keys():
- raise LsmError(ErrorNumber.NOT_FOUND_ACCESS_GROUP,
- "Access group not found: %s" % ag_id)
+ # We don't check wether ag_id is valid
rc = []
for sim_vol in self.vol_dict.values():
if 'mask' not in sim_vol:
@@ -1134,9 +1099,7 @@ class SimData(object):
return rc
def access_groups_granted_to_volume(self, vol_id, flags=0):
- if vol_id not in self.vol_dict.keys():
- raise LsmError(ErrorNumber.INVALID_VOLUME,
- "No such Volume: %s" % vol_id)
+ # We don't check wether vold_id is valid
sim_ags = []
if 'mask' in self.vol_dict[vol_id].keys():
ag_ids = self.vol_dict[vol_id]['mask'].keys()
@@ -1144,40 +1107,6 @@ class SimData(object):
sim_ags.extend([self.ag_dict[ag_id]])
return sim_ags
- def inits(self, flags=0):
- return self.init_dict.values()
-
- def initiator_grant(self, init_id, init_type, vol_id, access, flags):
- if vol_id not in self.vol_dict.keys():
- raise LsmError(ErrorNumber.INVALID_VOLUME,
- "No such Volume: %s" % vol_id)
- if init_id not in self.init_dict.keys():
- sim_init = dict()
- sim_init['init_id'] = init_id
- sim_init['init_type'] = init_type
- sim_init['name'] = SimData.SIM_DATA_INIT_NAME
- sim_init['sys_id'] = SimData.SIM_DATA_SYS_ID
- self.init_dict[init_id] = sim_init
- if 'mask_init' not in self.vol_dict[vol_id].keys():
- self.vol_dict[vol_id]['mask_init'] = dict()
-
- self.vol_dict[vol_id]['mask_init'][init_id] = access
- return None
-
- def initiator_revoke(self, init_id, vol_id, flags=0):
- if vol_id not in self.vol_dict.keys():
- raise LsmError(ErrorNumber.INVALID_VOLUME,
- "No such Volume: %s" % vol_id)
- if init_id not in self.init_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such Initiator: %s" % init_id)
-
- if 'mask_init' in self.vol_dict[vol_id].keys():
- if init_id in self.vol_dict[vol_id]['mask_init'].keys():
- del self.vol_dict[vol_id]['mask_init'][init_id]
-
- return None
-
def _ag_ids_of_init(self, init_id):
"""
Find out the access groups defined initiator belong to.
@@ -1189,44 +1118,9 @@ class SimData(object):
rc.extend([sim_ag['ag_id']])
return rc
- def volumes_accessible_by_initiator(self, init_id, flags=0):
- if init_id not in self.init_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such Initiator: %s" % init_id)
- rc_dedup_dict = dict()
- ag_ids = self._ag_ids_of_init(init_id)
- for ag_id in ag_ids:
- sim_vols = self.volumes_accessible_by_access_group(ag_id)
- for sim_vol in sim_vols:
- rc_dedup_dict[sim_vol['vol_id']] = sim_vol
-
- for sim_vol in self.vol_dict.values():
- if 'mask_init' in sim_vol:
- if init_id in sim_vol['mask_init'].keys():
- rc_dedup_dict[sim_vol['vol_id']] = sim_vol
- return rc_dedup_dict.values()
-
- def initiators_granted_to_volume(self, vol_id, flags=0):
- if vol_id not in self.vol_dict.keys():
- raise LsmError(ErrorNumber.INVALID_VOLUME,
- "No such Volume: %s" % vol_id)
- rc_dedup_dict = dict()
- sim_ags = self.access_groups_granted_to_volume(vol_id, flags)
- for sim_ag in sim_ags:
- for init_id in sim_ag['init_ids']:
- rc_dedup_dict[init_id] = self.init_dict[init_id]
-
- if 'mask_init' in self.vol_dict[vol_id].keys():
- for init_id in self.vol_dict[vol_id]['mask_init']:
- rc_dedup_dict[init_id] = self.init_dict[init_id]
-
- return rc_dedup_dict.values()
-
def iscsi_chap_auth(self, init_id, in_user, in_pass, out_user, out_pass,
flags=0):
- if init_id not in self.init_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such Initiator: %s" % init_id)
+ # to_code
if self.init_dict[init_id]['init_type'] != Initiator.TYPE_ISCSI:
raise LsmError(ErrorNumber.UNSUPPORTED_INITIATOR_TYPE,
"Initiator %s is not an iSCSI IQN" % init_id)
@@ -1280,8 +1174,8 @@ class SimData(object):
def fs_clone(self, src_fs_id, dst_fs_name, snap_id, flags=0):
if src_fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % src_fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % src_fs_id)
if snap_id and snap_id not in self.snap_dict.keys():
raise LsmError(ErrorNumber.INVALID_SS,
"No such Snapshot: %s" % snap_id)
@@ -1297,8 +1191,8 @@ class SimData(object):
def fs_file_clone(self, fs_id, src_fs_name, dst_fs_name, snap_id, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if snap_id and snap_id not in self.snap_dict.keys():
raise LsmError(ErrorNumber.INVALID_SS,
"No such Snapshot: %s" % snap_id)
@@ -1307,8 +1201,8 @@ class SimData(object):
def fs_snapshots(self, fs_id, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
rc = []
if 'snaps' in self.fs_dict[fs_id].keys():
for snap_id in self.fs_dict[fs_id]['snaps']:
@@ -1317,8 +1211,8 @@ class SimData(object):
def fs_snapshot_create(self, fs_id, snap_name, files, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if 'snaps' not in self.fs_dict[fs_id].keys():
self.fs_dict[fs_id]['snaps'] = []
@@ -1337,8 +1231,8 @@ class SimData(object):
def fs_snapshot_delete(self, fs_id, snap_id, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if snap_id not in self.snap_dict.keys():
raise LsmError(ErrorNumber.INVALID_SS,
"No such Snapshot: %s" % snap_id)
@@ -1353,8 +1247,8 @@ class SimData(object):
def fs_snapshot_restore(self, fs_id, snap_id, files, restore_files,
flag_all_files, flags):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if snap_id not in self.snap_dict.keys():
raise LsmError(ErrorNumber.INVALID_SS,
"No such Snapshot: %s" % snap_id)
@@ -1363,8 +1257,8 @@ class SimData(object):
def fs_child_dependency(self, fs_id, files, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if 'snaps' not in self.fs_dict[fs_id].keys():
return False
if files is None or len(files) == 0:
@@ -1382,8 +1276,8 @@ class SimData(object):
def fs_child_dependency_rm(self, fs_id, files, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
if 'snaps' not in self.fs_dict[fs_id].keys():
return None
if files is None or len(files) == 0:
@@ -1431,8 +1325,8 @@ class SimData(object):
def fs_export(self, fs_id, exp_path, root_hosts, rw_hosts, ro_hosts,
anon_uid, anon_gid, auth_type, options, flags=0):
if fs_id not in self.fs_dict.keys():
- raise LsmError(ErrorNumber.INVALID_INIT,
- "No such File System: %s" % fs_id)
+ raise LsmError(ErrorNumber.NOT_FOUND_FS,
+ "File System: %s not found" % fs_id)
sim_exp = dict()
sim_exp['exp_id'] = self._next_exp_id()
sim_exp['fs_id'] = fs_id
diff --git a/plugin/sim/simulator.py b/plugin/sim/simulator.py
index cb3f08a..b452b6a 100644
--- a/plugin/sim/simulator.py
+++ b/plugin/sim/simulator.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2013 Red Hat, Inc.
+# Copyright (C) 2011-2014 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
@@ -14,6 +14,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Author: tasleson
+# Gris Ge <***@redhat.com>
from lsm import (uri_parse, VERSION, Capabilities, Pool, INfs,
IStorageAreaNetwork, Error, search_property)
@@ -218,31 +219,10 @@ class SimPlugin(INfs, IStorageAreaNetwork):
volume.id, flags)
return [SimPlugin._sim_data_2_lsm(v) for v in sim_vols]
- def initiators(self, flags=0):
- return self.sim_array.inits(flags)
-
- def initiator_grant(self, initiator_id, initiator_type, volume, access,
- flags=0):
- return self.sim_array.initiator_grant(
- initiator_id, initiator_type, volume.id, access, flags)
-
- def initiator_revoke(self, initiator, volume, flags=0):
- return self.sim_array.initiator_revoke(initiator.id, volume.id, flags)
-
- def volumes_accessible_by_initiator(self, initiator, flags=0):
- sim_vols = self.sim_array.volumes_accessible_by_initiator(
- initiator.id, flags)
- return [SimPlugin._sim_data_2_lsm(v) for v in sim_vols]
-
- def initiators_granted_to_volume(self, volume, flags=0):
- sim_inits = self.sim_array.initiators_granted_to_volume(
- volume.id, flags)
- return [SimPlugin._sim_data_2_lsm(i) for i in sim_inits]
-
- def iscsi_chap_auth(self, initiator, in_user, in_password,
+ def iscsi_chap_auth(self, init_id, in_user, in_password,
out_user, out_password, flags=0):
return self.sim_array.iscsi_chap_auth(
- initiator.id, in_user, in_password, out_user, out_password, flags)
+ init_id, in_user, in_password, out_user, out_password, flags)
def volume_child_dependency(self, volume, flags=0):
return self.sim_array.volume_child_dependency(volume.id, flags)
diff --git a/plugin/smispy/eseries.py b/plugin/smispy/eseries.py
index 8aa3d18..2160159 100644
--- a/plugin/smispy/eseries.py
+++ b/plugin/smispy/eseries.py
@@ -81,71 +81,6 @@ class ESeries(Smis):
#doesn't work
return cap
- def _get_initiators_in_group(self, cim_grp):
- ag_init_ids = []
- cim_st_hwid_pros = self._property_list_of_id('Initiator')
- cim_st_hwids = self._get_cim_st_hwid_in_spc(cim_grp, cim_st_hwid_pros)
- ag_init_ids = [self._init_id(i) for i in cim_st_hwids]
- return ag_init_ids
-
- def _get_group_initiator_is_in(self, initiator_id):
- groups = self._get_access_groups()
-
- for g in groups:
- initiators = self._get_initiators_in_group(g)
- for i in initiators:
- if i == initiator_id:
- return g
-
- return None
-
- @handle_cim_errors
- def initiator_grant(self, initiator_id, initiator_type, volume, access,
- flags=0):
- ccs = self._get_class_instance('CIM_ControllerConfigurationService')
- lun = self._get_cim_instance_by_id('Volume', volume.id)
-
- #Need to check for existence of initiator, else create one
- initiator = self._initiator_lookup(initiator_id)
-
- in_params = {'LUNames': [lun['DeviceID']],
- 'DeviceAccesses': [pywbem.Uint16(2)]}
-
- if initiator is not None:
- #In this case we need to find the access group that contains the
- #initiator and then pass the
- group = self._get_group_initiator_is_in(initiator_id)
-
- if group is None:
- raise LsmError(ErrorNumber.UNSUPPORTED_PROVISIONING,
- "Unsupported provisioning")
-
- in_params['ProtocolControllers'] = [group.path]
- else:
- in_params['InitiatorPortIDs'] = [initiator_id]
-
- #Returns None or job id
- return self._pi("initiator_grant", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('ExposePaths', ccs.path,
- **in_params)))[0]
-
- @handle_cim_errors
- def initiator_revoke(self, initiator, volume, flags=0):
- (found, spc) = self._get_spc(initiator.id, volume.id)
-
- if found:
- ccs = self._get_class_instance(
- 'CIM_ControllerConfigurationService')
-
- in_params = dict(ProtocolController=spc.path,
- DeleteChildrenProtocolControllers=True,
- DeleteUnits=True)
-
- #Returns None or job id
- return self._pi("access_revoke", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('DeleteProtocolController',
- ccs.path, **in_params)))[0]
-
def _detach(self, vol, sync):
#Get the Configuration service for the system we are interested in.
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index a596ca5..6d10973 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -25,7 +25,7 @@ import pywbem
from pywbem import CIMError
from lsm import (IStorageAreaNetwork, Error, uri_parse, LsmError, ErrorNumber,
- JobStatus, md5, Pool, Initiator, Volume, AccessGroup, System,
+ JobStatus, md5, Pool, Volume, AccessGroup, System,
Capabilities, Disk, OptionalData, txt_a, VERSION,
search_property)
@@ -71,7 +71,7 @@ def handle_cim_errors(method):
if 'Errno 113' in desc:
raise LsmError(ErrorNumber.NETWORK_HOSTDOWN,
'Host is down')
- raise LsmError(ErrorNumber.PLUGIN_ERROR, desc)
+ raise LsmError(ErrorNumber.LSM_BUG, desc)
except pywbem.cim_http.AuthError as ae:
raise LsmError(ErrorNumber.PLUGIN_AUTH_FAILED, "Unauthorized user")
except pywbem.cim_http.Error as te:
@@ -100,13 +100,19 @@ def _spec_ver_str_to_num(spec_ver_str):
return None
+def _merge_list(list_a, list_b):
+ return list(set(list_a + list_b))
+
+
class DMTF(object):
+ # CIM_StorageHardwareID['IDType']
ID_TYPE_OTHER = pywbem.Uint16(1)
ID_TYPE_WWPN = pywbem.Uint16(2)
ID_TYPE_WWNN = pywbem.Uint16(3)
ID_TYPE_HOSTNAME = pywbem.Uint16(4)
ID_TYPE_ISCSI = pywbem.Uint16(5)
ID_TYPE_SW_WWN = pywbem.Uint16(6)
+ ID_TYPE_SAS = pywbem.Uint16(7)
_INIT_TYPE_CONV = {
@@ -116,6 +122,7 @@ _INIT_TYPE_CONV = {
DMTF.ID_TYPE_HOSTNAME: AccessGroup.INIT_TYPE_HOSTNAME,
DMTF.ID_TYPE_ISCSI: AccessGroup.INIT_TYPE_ISCSI_IQN,
DMTF.ID_TYPE_SW_WWN: AccessGroup.INIT_TYPE_OTHER,
+ DMTF.ID_TYPE_SAS: AccessGroup.INIT_TYPE_SAS,
}
@@ -124,6 +131,8 @@ def _dmtf_init_type_to_lsm(cim_init):
return _INIT_TYPE_CONV[cim_init['IDType']]
return AccessGroup.INIT_TYPE_UNKNOWN
+def _lsm_init_type_to_dmtf(lsm_init_type):
+ return _get_key(_INIT_TYPE_CONV, lsm_init_type)
def _get_key(dictionary, value):
keys = [k for k, v in dictionary.items() if v == value]
@@ -433,111 +442,69 @@ class Smis(IStorageAreaNetwork):
self.cim_rps = []
self.cim_root_profile_dict = dict()
self.fallback_mode = True # Means we cannot use profile register
+ self.all_vendor_namespaces = []
def _get_cim_instance_by_id(self, class_type, requested_id,
- flag_full_info=True, property_list=None):
+ property_list=None, raise_error=True):
"""
Find out the CIM_XXXX Instance which holding the requested_id
- If flag_full_info == True, we return a Instance with full info.
- If you want to save some query time, try set it as False
+ Return None when error and raise_error is False
"""
class_name = Smis._cim_class_name_of(class_type)
- property_list = Smis._property_list_of_id(class_type, property_list)
+ error_numer = Smis._not_found_error_of_class(class_type)
+ id_pros = Smis._property_list_of_id(class_type, property_list)
- cim_xxxs = self._c.EnumerateInstances(class_name,
- PropertyList=property_list,
- LocalOnly=False)
+ if property_list is None:
+ property_list = id_pros
+ else:
+ property_list = _merge_list(property_list, id_pros)
+
+ cim_xxxs = self._enumerate(class_name, property_list)
org_requested_id = requested_id
if class_type == 'Job':
(requested_id, ignore) = self._parse_job_id(requested_id)
for cim_xxx in cim_xxxs:
if self._id(class_type, cim_xxx) == requested_id:
- if flag_full_info:
- cim_xxx = self._c.GetInstance(cim_xxx.path,
- LocalOnly=False)
return cim_xxx
+ if raise_error is False:
+ return None
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
+ raise LsmError(error_numer,
"Cannot find %s Instance with " % class_name +
"%s ID '%s'" % (class_type, org_requested_id))
- def _get_class_instance(self, class_name, prop_name=None, prop_value=None,
- no_throw_on_missing=False):
+ def _get_class_instance(self, class_name, prop_name, prop_value,
+ raise_error=True, property_list=None):
"""
Gets an instance of a class that optionally matches a specific
property name and value
"""
instances = None
+ if property_list is None:
+ property_list = [prop_name]
+ else:
+ property_list = _merge_list(property_list, [prop_name])
try:
- if prop_name:
- instances = self._c.EnumerateInstances(
- class_name, PropertyList=[prop_name], LocalOnly=False)
- else:
- instances = self._c.EnumerateInstances(class_name,
- LocalOnly=False)
+ cim_xxxs = self._enumerate(class_name, property_list)
except CIMError as ce:
error_code = tuple(ce)[0]
- if error_code == pywbem.CIM_ERR_INVALID_CLASS \
- and no_throw_on_missing:
+ if error_code == pywbem.CIM_ERR_INVALID_CLASS and \
+ raise_error is False:
return None
else:
raise ce
- if prop_name is None:
- if len(instances) != 1:
- class_names = " ".join([x.classname for x in instances])
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
- "Expecting one instance of %s and got %s" %
- (class_name, class_names))
-
- return instances[0]
- else:
- for i in instances:
- if prop_name in i and i[prop_name] == prop_value:
- return i
-
- if no_throw_on_missing:
- return None
+ for cim_xxx in cim_xxxs:
+ if prop_name in cim_xxx and cim_xxx[prop_name] == prop_value:
+ return cim_xxx
- raise LsmError(ErrorNumber.INVALID_ARGUMENT,
- "Unable to find class instance %s " % class_name +
- "with property %s " % prop_name +
- "with value %s" % prop_value)
-
- def _get_spc(self, initiator_id, volume_id):
- """
- Retrieve the SCSIProtocolController for a given initiator and volume.
- This will return a non-none value when there is a mapping between the
- initiator and the volume.
- """
- init = self._get_class_instance('CIM_StorageHardwareID', 'StorageID',
- initiator_id)
-
- # Look at page 151 (1.5 smi-s spec.) in the block services books for
- # the SNIA_MappingProtocolControllerView
-
- if init:
- auths = self._c.Associators(init.path,
- AssocClass='CIM_AuthorizedSubject')
-
- if auths:
- for a in auths:
- spc = self._c.Associators(
- a.path, AssocClass='CIM_AuthorizedTarget')
- if spc and len(spc) > 0:
- logical_device = \
- self._c.Associators(
- spc[0].path,
- AssocClass='CIM_ProtocolControllerForUnit')
-
- if logical_device and len(logical_device) > 0:
- vol = self._c.GetInstance(logical_device[0].path,
- LocalOnly=False)
- if 'DeviceID' in vol and \
- md5(vol.path) == volume_id:
- return spc[0]
+ if raise_error:
+ raise LsmError(ErrorNumber.LSM_BUG,
+ "Unable to find class instance %s " % class_name +
+ "with property %s " % prop_name +
+ "with value %s" % prop_value)
return None
def _pi(self, msg, retrieve_data, rc, out):
@@ -595,6 +562,7 @@ class Smis(IStorageAreaNetwork):
namespace = None
if 'namespace' in u['parameters']:
namespace = u['parameters']['namespace']
+ self.all_vendor_namespaces = [namespace]
else:
namespace = Smis.SMIS_DEFAULT_NAMESPACE
@@ -650,6 +618,7 @@ class Smis(IStorageAreaNetwork):
if len(self.cim_rps) >= 1:
self.fallback_mode = False
+ self.all_vendor_namespaces = []
# Support 'Array' profile is step 0 for this whole plugin.
# We find out all 'Array' CIM_RegisteredProfile and stored
# them into self.cim_root_profile_dict
@@ -658,7 +627,7 @@ class Smis(IStorageAreaNetwork):
SNIA.SMIS_SPEC_VER_1_4,
strict=False):
raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S provider does not support "
+ "Target SMI-S provider does not support "
"SNIA SMI-S SPEC %s '%s' profile" %
(SNIA.SMIS_SPEC_VER_1_4,
SNIA.BLK_ROOT_PROFILE))
@@ -725,7 +694,7 @@ class Smis(IStorageAreaNetwork):
Interrogate the supported features of the replication service
"""
rs = self._get_class_instance("CIM_ReplicationService", 'SystemName',
- system.id, True)
+ system.id, raise_error=False)
if rs:
rs_cap = self._c.Associators(
rs.path,
@@ -758,7 +727,7 @@ class Smis(IStorageAreaNetwork):
rs = self._get_class_instance("CIM_StorageConfigurationService",
'SystemName',
- system.id, True)
+ system.id, raise_error=False)
if rs:
rs_cap = self._c.Associators(
@@ -796,7 +765,7 @@ class Smis(IStorageAreaNetwork):
# Get the cim object that represents the system
cim_sys = None
cim_pcms = None
- cim_sys = self._cim_sys_of_id(system.id)
+ cim_sys = self._get_cim_instance_by_id('System', system.id)
if self.fallback_mode:
# Using 'ExposePathsSupported of
@@ -840,7 +809,6 @@ class Smis(IStorageAreaNetwork):
# Assume that the SMI-S we are talking to supports blocks
cap.set(Capabilities.BLOCK_SUPPORT)
- cap.set(Capabilities.INITIATORS)
self._scs_supported_capabilities(system, cap)
self._rs_supported_capabilities(system, cap)
@@ -885,8 +853,7 @@ class Smis(IStorageAreaNetwork):
'OperationalStatus']
cim_job_pros = self._property_list_of_id('Job', props)
- cim_job = self._get_cim_instance_by_id('Job', job_id, False,
- cim_job_pros)
+ cim_job = self._get_cim_instance_by_id('Job', job_id, cim_job_pros)
job_state = cim_job['JobState']
@@ -934,12 +901,33 @@ class Smis(IStorageAreaNetwork):
return 'CIM_SCSIProtocolController'
if class_type == 'Initiator':
return 'CIM_StorageHardwareID'
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Smis._cim_class_name_of() got unknown " +
"class_type %s" % class_type)
@staticmethod
- def _property_list_of_id(class_type, requested_properties=None):
+ def _not_found_error_of_class(class_type):
+ if class_type == 'Volume':
+ return ErrorNumber.NOT_FOUND_VOLUME
+ if class_type == 'System':
+ return ErrorNumber.NOT_FOUND_SYSTEM
+ if class_type == 'Pool':
+ return ErrorNumber.NOT_FOUND_POOL
+ if class_type == 'Disk':
+ return ErrorNumber.NOT_FOUND_DISK
+ if class_type == 'Job':
+ return ErrorNumber.NOT_FOUND_JOB
+ if class_type == 'AccessGroup':
+ return ErrorNumber.NOT_FOUND_ACCESS_GROUP
+ if class_type == 'Initiator':
+ return ErrorNumber.INVALID_ARGUMENT
+ raise LsmError(ErrorNumber.LSM_BUG,
+ "Smis._cim_class_name_of() got unknown " +
+ "class_type %s" % class_type)
+
+
+ @staticmethod
+ def _property_list_of_id(class_type, extra_properties=None):
"""
Return a PropertyList which the ID of current class is basing on
"""
@@ -961,14 +949,12 @@ class Smis(IStorageAreaNetwork):
elif class_type == 'Initiator':
rc = ['StorageID']
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Smis._cim_class_name_of() got unknown " +
"class_type %s" % class_type)
- if requested_properties:
- for p in requested_properties:
- if p not in rc:
- rc.extend([p])
+ if extra_properties:
+ rc = _merge_list(rc, extra_properties)
return rc
def _sys_id_child(self, cim_xxx):
@@ -1289,7 +1275,7 @@ class Smis(IStorageAreaNetwork):
PropertyList=pool_pros, LocalOnly=False)
return self._new_pool(cim_new_pool)
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Got not new Pool from out of InvokeMethod" +
"when CreateOrModifyElementFromStoragePool")
@@ -1399,72 +1385,16 @@ class Smis(IStorageAreaNetwork):
rc.extend([vol])
return search_property(rc, search_key, search_value)
- def _systems(self, system_name=None):
- """
- Returns a list of system objects (CIM)
- """
- cim_syss = []
- cim_scss_path = []
- try:
- # Note: Please be informed, if PropertyList is an empty list,
- # XIV will return NOTHING, so use EnumerateInstanceNames()
- # when you need nothing but the CIMInstanceName
- cim_scss_path = \
- self._c.EnumerateInstanceNames(
- 'CIM_StorageConfigurationService')
- except CIMError as e:
- # If array does not support CIM_StorageConfigurationService
- # we use CIM_ComputerSystem which is mandatory.
- # We might get some non-storage array listed as system.
- # but we would like to take that risk instead of
- # skipping basic support of old SMIS provider.
- if e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem',
- PropertyList=['Name', 'ElementName', 'OperationalStatus'],
- LocalOnly=False)
- else:
- raise e
- if not cim_syss:
- for cim_scs_path in cim_scss_path:
- cim_tmp = \
- self._c.Associators(cim_scs_path,
- AssocClass='CIM_HostedService',
- ResultClass='CIM_ComputerSystem',
- PropertyList=['Name',
- 'ElementName',
- 'OperationalStatus'])
- if cim_tmp and cim_tmp[0]:
- cim_syss.extend([cim_tmp[0]])
-
- # Filtering
- if system_name is not None:
- for cim_sys in cim_syss:
- if cim_sys['Name'] == system_name:
- return [cim_sys]
-
- elif self.system_list:
- cim_filterd_syss = []
- for cim_sys in cim_syss:
- if cim_sys['Name'] in self.system_list:
- cim_filterd_syss.extend([cim_sys])
- return cim_filterd_syss
- else:
- return cim_syss
-
def _cim_pools_of(self, cim_sys_path, property_list=None):
- pros = []
if property_list is None:
- pros = ['Primordial']
+ property_list = ['Primordial']
else:
- pros = property_list
- if 'Primordial' not in pros:
- pros.extend(['Primordial'])
+ property_list = _merge_list(property_list, ['Primordial'])
cim_pools = self._c.Associators(cim_sys_path,
AssocClass='CIM_HostedStoragePool',
ResultClass='CIM_StoragePool',
- PropertyList=pros)
+ PropertyList=property_list)
return [p for p in cim_pools if not p["Primordial"]]
@@ -1540,7 +1470,7 @@ class Smis(IStorageAreaNetwork):
for key, value in opt_pro_dict.items():
pool.optional_data.set(key, value)
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Failed to retrieve pool information " +
"from CIM_StoragePool: %s" % cim_pool.path)
return search_property(rc, search_key, search_value)
@@ -1631,61 +1561,6 @@ class Smis(IStorageAreaNetwork):
return [Smis._cim_sys_2_lsm_sys(s) for s in cim_syss]
- def _new_init(self, cim_init):
- """
- Generate Initiator object from CIM_StorageHardwareID
- """
- init_id = self._init_id(cim_init)
- init_type = cim_init['IDType']
- init_name = cim_init['ElementName']
- return Initiator(init_id, init_type, init_name)
-
- def _new_init_pros(self):
- """
- Return a list of properties needed to created Initiator from
- CIM_StorageHardwareID
- """
- cim_init_pros = self._property_list_of_id('Initiator',
- ['IDType', 'ElementName'])
- return cim_init_pros
-
- @handle_cim_errors
- def initiators(self, flags=0):
- """
- Return all initiators generated from CIM_StorageHardwareID.
- Following SNIA SMI-S 'Masking and Mapping Profile':
- CIM_ComputerSystem
- | (CIM_HostedService)
- v
- CIM_StorageHardwareIDManagementService
- | (CIM_ConcreteDependency)
- v
- CIM_StorageHardwareID
- This is supported from SNIA SMI-S 1.3rev6 to latest(1.6rev4).
- """
- rc_inits = []
- cim_init_pros = self._new_init_pros()
- try:
- for cim_sys in self._systems():
- cim_init_mss_path = self._c.AssociatorNames(
- cim_sys.path,
- AssocClass='CIM_HostedService',
- ResultClass='CIM_StorageHardwareIDManagementService')
- for cim_init_ms_path in cim_init_mss_path:
- cim_inits = self._c.Associators(
- cim_init_ms_path,
- AssocClass='CIM_ConcreteDependency',
- ResultClass='CIM_StorageHardwareID',
- PropertyList=cim_init_pros)
- rc_inits.extend([self._new_init(i) for i in cim_inits])
- except CIMError as ce:
- error_code = tuple(ce)[0]
- if error_code == pywbem.CIM_ERR_INVALID_CLASS or \
- error_code == pywbem.CIM_ERR_INVALID_PARAMETER:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- 'Initiator is not supported by this array')
- return rc_inits
-
@handle_cim_errors
def volume_create(self, pool, volume_name, size_bytes, provisioning,
flags=0):
@@ -1699,7 +1574,7 @@ class Smis(IStorageAreaNetwork):
# Get the Configuration service for the system we are interested in.
scs = self._get_class_instance('CIM_StorageConfigurationService',
'SystemName', pool.system_id)
- sp = self._get_cim_instance_by_id('Pool', pool.id, False)
+ sp = self._get_cim_instance_by_id('Pool', pool.id)
in_params = {'ElementName': volume_name,
'ElementType': pywbem.Uint16(2),
@@ -1728,7 +1603,7 @@ class Smis(IStorageAreaNetwork):
def _detach(self, vol, sync):
rs = self._get_class_instance("CIM_ReplicationService", 'SystemName',
- vol.system_id, True)
+ vol.system_id, raise_error=False)
if rs:
in_params = {'Operation': pywbem.Uint16(8),
@@ -1845,7 +1720,7 @@ class Smis(IStorageAreaNetwork):
rc = [None, None]
rs = self._get_class_instance("CIM_ReplicationService", 'SystemName',
- system_id, True)
+ system_id, raise_error=False)
if rs:
rs_cap = self._c.Associators(
@@ -1901,7 +1776,7 @@ class Smis(IStorageAreaNetwork):
volume_src.system_id, True)
if pool is not None:
- cim_pool = self._get_cim_instance_by_id('Pool', pool.id, False)
+ cim_pool = self._get_cim_instance_by_id('Pool', pool.id)
else:
cim_pool = None
@@ -1928,7 +1803,7 @@ class Smis(IStorageAreaNetwork):
# Check for storage configuration service
rs = self._get_class_instance("CIM_StorageConfigurationService",
'SystemName', volume_src.system_id,
- True)
+ raise_error=False)
ct = Volume.REPLICATE_CLONE
if rep_type == Volume.REPLICATE_CLONE:
@@ -1963,35 +1838,15 @@ class Smis(IStorageAreaNetwork):
def volume_offline(self, volume, flags=0):
return None
- def _initiator_create(self, name, init_id, id_type):
- """
- Create initiator object
- """
- hardware = self._get_class_instance(
- 'CIM_StorageHardwareIDManagementService')
-
- in_params = {'ElementName': name,
- 'StorageID': init_id,
- 'IDType': pywbem.Uint16(id_type)}
-
- (rc, out) = self._c.InvokeMethod('CreateStorageHardwareID',
- hardware.path, **in_params)
- if not rc:
- init = self._get_class_instance('CIM_StorageHardwareID',
- 'StorageID', init_id)
- return self._new_init(init)
-
- raise LsmError(ErrorNumber.PLUGIN_ERROR, 'Error: ' + str(rc) +
- ' on initiator_create!')
-
@handle_cim_errors
def volume_mask(self, access_group, volume, flags=0):
"""
Grant access to a volume to an group
"""
- ccs = self._get_class_instance('CIM_ControllerConfigurationService',
- 'SystemName', access_group.system_id)
- lun = self._get_cim_instance_by_id('Volume', volume.id)
+ cim_ccs = self._get_class_instance(
+ 'CIM_ControllerConfigurationService',
+ 'SystemName', access_group.system_id)
+ lun = self._get_cim_instance_by_id('Volume', volume.id, ['Name'])
spc = self._get_cim_instance_by_id('AccessGroup', access_group.id)
if not lun:
@@ -2009,7 +1864,7 @@ class Smis(IStorageAreaNetwork):
# Returns None or job id
return self._pi("access_grant", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('ExposePaths', ccs.path,
+ *(self._c.InvokeMethod('ExposePaths', cim_ccs.path,
**in_params)))[0]
def _wait(self, job):
@@ -2026,9 +1881,10 @@ class Smis(IStorageAreaNetwork):
@handle_cim_errors
def volume_unmask(self, access_group, volume, flags=0):
- ccs = self._get_class_instance('CIM_ControllerConfigurationService',
- 'SystemName', volume.system_id)
- lun = self._get_cim_instance_by_id('Volume', volume.id)
+ cim_ccs = self._get_class_instance(
+ 'CIM_ControllerConfigurationService',
+ 'SystemName', access_group.system_id)
+ lun = self._get_cim_instance_by_id('Volume', volume.id, ['Name'])
spc = self._get_cim_instance_by_id('AccessGroup', access_group.id)
if not lun:
@@ -2041,7 +1897,7 @@ class Smis(IStorageAreaNetwork):
hide_params = {'LUNames': [lun['Name']],
'ProtocolControllers': [spc.path]}
return self._pi("HidePaths", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('HidePaths', ccs.path,
+ *(self._c.InvokeMethod('HidePaths', cim_ccs.path,
**hide_params)))[0]
def _is_access_group(self, cim_ag):
@@ -2096,7 +1952,7 @@ class Smis(IStorageAreaNetwork):
raise LsmError(ErrorNumber.NO_SUPPORT,
'AccessGroup is not supported by this array')
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Got %d instance of " % len(cim_ccss_path) +
"ControllerConfigurationService from %s" %
cim_sys.path + " in _cim_ags_of()")
@@ -2220,55 +2076,91 @@ class Smis(IStorageAreaNetwork):
return search_property(rc, search_key, search_value)
- def _initiator_lookup(self, initiator_id):
+ def _initiator_create(self, cim_sys_path, init_id, dmtf_id_type):
"""
- Looks up an initiator by initiator id
- returns None or object instance
+ Create a CIM_StorageHardwareID.
+ Raise error if failed. Return if pass.
"""
- initiator = None
- for i in self.initiators():
- if i.id == initiator_id:
- initiator = i
- break
- return initiator
+ cim_hw_srvs = self._c.AssociatorNames(
+ cim_sys_path,
+ ResultClass='CIM_StorageHardwareIDManagementService',
+ AssocClass='CIM_HostedService')
+ if len(cim_hw_srvs) == 0:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "Target SMI-S provider does not support "
+ "access_group_initiator_add(): No "
+ "CIM_StorageHardwareIDManagementService to create"
+ "new initiator")
+ if len(cim_hw_srvs) != 1:
+ raise LsmError(ErrorNumber.LSM_BUG,
+ "_initiator_create(): Got more than one "
+ "CIM_StorageHardwareIDManagementService")
+
+ in_params = {#'ElementName': init_id,
+ 'StorageID': init_id,
+ 'IDType': pywbem.Uint16(dmtf_id_type)}
+ print in_params
+
+ (rc, out) = self._c.InvokeMethod('CreateStorageHardwareID',
+ cim_hw_srvs[0], **in_params)
+ if not rc:
+ return
+
+ # Ideally, we should handle CIM Error here in stead of raise
+ # LSM_BUG error. Let's wait user report on bug.
+ raise LsmError(ErrorNumber.LSM_BUG,
+ 'Error on _initiator_create(): rc: "%s", out: "%s"'
+ % (str(rc), out))
@handle_cim_errors
def access_group_initiator_add(self, access_group, init_id, init_type,
flags=0):
- # Check to see if we have this initiator already, if we don't create
- # it and then add to the view.
-
- spc = self._get_cim_instance_by_id('AccessGroup', access_group.id)
+ # CIM_StorageHardwareIDManagementService.CreateStorageHardwareID()
+ # is mandatory since 1.4rev6
+ if not self.fallback_mode:
+ self._profile_is_supported(SNIA.MASK_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False,
+ raise_error=True)
- # This need rework when removing lsm.Initiator class
- initiator = self._initiator_lookup(init_id)
- lsm_init_type = _lsm_init_type_to_dmtf(init_type)
+ cim_sys = self._get_cim_instance_by_id('System',
+ access_group.system_id)
- if not initiator:
- initiator = self._initiator_create(init_id, init_id,
- lsm_init_type)
+ # Check to see if we have this initiator already, if we don't create
+ # it and then add to the view.
+ if self._get_cim_instance_by_id(
+ 'Initiator', init_id, raise_error=False) is None:
+ dmtf_id_type = _lsm_init_type_to_dmtf(init_type)
+ if dmtf_id_type is None:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "SMI-S Plugin does not support init_type %d"
+ % init_type)
+ self._initiator_create(cim_sys.path, init_id, dmtf_id_type)
- ccs = self._get_class_instance('CIM_ControllerConfigurationService',
- 'SystemName', access_group.system_id)
+ cim_ag = self._get_cim_instance_by_id('AccessGroup', access_group.id)
+ cim_ccs = self._get_class_instance(
+ 'CIM_ControllerConfigurationService',
+ 'SystemName', access_group.system_id)
- in_params = {'InitiatorPortIDs': [initiator.id],
- 'ProtocolControllers': [spc.path]}
+ in_params = {'InitiatorPortIDs': [init_id],
+ 'ProtocolControllers': [cim_ag.path]}
# Returns None or job id
return self._pi("access_group_initiator_add", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('ExposePaths', ccs.path,
+ *(self._c.InvokeMethod('ExposePaths', cim_ccs.path,
**in_params)))[0]
@handle_cim_errors
def access_group_initiator_delete(self, access_group, init_id, flags=0):
- spc = self._get_cim_instance_by_id('AccessGroup', access_group.id)
- ccs = self._get_class_instance('CIM_ControllerConfigurationService',
- 'SystemName', access_group.system_id)
+ cim_ag = self._get_cim_instance_by_id('AccessGroup', access_group.id)
+ cim_ccs = self._get_class_instance(
+ 'CIM_ControllerConfigurationService',
+ 'SystemName', access_group.system_id)
hide_params = {'InitiatorPortIDs': [init_id],
- 'ProtocolControllers': [spc.path]}
+ 'ProtocolControllers': [cim_ag.path]}
return self._pi("HidePaths", Smis.JOB_RETRIEVE_NONE,
- *(self._c.InvokeMethod('HidePaths', ccs.path,
+ *(self._c.InvokeMethod('HidePaths', cim_ccs.path,
**hide_params)))[0]
@handle_cim_errors
@@ -2276,7 +2168,8 @@ class Smis(IStorageAreaNetwork):
"""
Frees the resources given a job number.
"""
- cim_job = self._get_cim_instance_by_id('Job', job_id)
+ cim_job = self._get_cim_instance_by_id('Job', job_id,
+ ['DeleteOnCompletion'])
# See if we should delete the job
if not cim_job['DeleteOnCompletion']:
@@ -2285,6 +2178,30 @@ class Smis(IStorageAreaNetwork):
except CIMError:
pass
+ def _enumerate(self, class_name, property_list):
+ """
+ Please do the filter of "sytems=" in URI by yourself.
+ """
+ if len(self.all_vendor_namespaces) == 0:
+ # We need to find out the vendor spaces.
+ # We do it here to save plugin_register() time.
+ # Only non-fallback mode can goes there.
+ cim_syss = self._root_cim_syss()
+ all_vendor_namespaces = []
+ for cim_sys in cim_syss:
+ if cim_sys.path.namespace not in all_vendor_namespaces:
+ all_vendor_namespaces.extend([cim_sys.path.namespace])
+ self.all_vendor_namespaces = all_vendor_namespaces
+ rc = []
+ for vendor_namespace in self.all_vendor_namespaces:
+ rc.extend(
+ self._c.EnumerateInstances(
+ class_name,
+ namespace=vendor_namespace,
+ PropertyList=property_list,
+ LocalOnly=False))
+ return rc
+
@handle_cim_errors
def disks(self, search_key=None, search_value=None, flags=0):
"""
@@ -2300,37 +2217,22 @@ class Smis(IStorageAreaNetwork):
by ourself in case URI contain 'system=xxx'.
"""
rc = []
- cim_sys_pros = self._property_list_of_id("System")
if not self.fallback_mode:
self._profile_is_supported(SNIA.DISK_LITE_PROFILE,
SNIA.SMIS_SPEC_VER_1_4,
strict=False,
raise_error=True)
- cim_syss = self._root_cim_syss(cim_sys_pros)
-
- if len(cim_syss) < 1:
- return []
-
- all_vendor_namespaces = []
- for cim_sys in cim_syss:
- if cim_sys.path.namespace not in all_vendor_namespaces:
- all_vendor_namespaces.extend([cim_sys.path.namespace])
-
cim_disk_pros = Smis._new_disk_cim_disk_pros(flags)
- for vendor_namespace in all_vendor_namespaces:
- cim_disks = self._c.EnumerateInstances(
- 'CIM_DiskDrive',
- namespace=vendor_namespace,
- PropertyList=cim_disk_pros)
- for cim_disk in cim_disks:
- if self.system_list:
- if self._sys_id_child(cim_disk) not in self.system_list:
- continue
- cim_ext_pros = Smis._new_disk_cim_ext_pros(flags)
- cim_ext = self._pri_cim_ext_of_cim_disk(cim_disk.path,
- cim_ext_pros)
-
- rc.extend([self._new_disk(cim_disk, cim_ext, flags)])
+ cim_disks = self._enumerate('CIM_DiskDrive', cim_disk_pros)
+ for cim_disk in cim_disks:
+ if self.system_list:
+ if self._sys_id_child(cim_disk) not in self.system_list:
+ continue
+ cim_ext_pros = Smis._new_disk_cim_ext_pros(flags)
+ cim_ext = self._pri_cim_ext_of_cim_disk(cim_disk.path,
+ cim_ext_pros)
+
+ rc.extend([self._new_disk(cim_disk, cim_ext, flags)])
return search_property(rc, search_key, search_value)
@staticmethod
@@ -2459,7 +2361,7 @@ class Smis(IStorageAreaNetwork):
ResultClass='CIM_PhysicalPackage',
PropertyList=cim_phy_pkg_pros)
if not (cim_phy_pkgs and cim_phy_pkgs[0]):
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Failed to find out the CIM_PhysicalPackage " +
"of CIM_DiskDrive %s" % cim_disk.path)
cim_phy_pkg = cim_phy_pkgs[0]
@@ -2478,7 +2380,7 @@ class Smis(IStorageAreaNetwork):
status_info,
cim_disk['ErrorDescription'])
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"CIM_DiskDrive %s " % cim_disk.id +
"has ErrorCleared == False but " +
"does not have " +
@@ -2511,13 +2413,12 @@ class Smis(IStorageAreaNetwork):
cim_pri_ext # The CIM_Instance of Primordial CIM_StorageExtent
Exceptions:
LsmError
- ErrorNumber.INTERNAL_ERROR # Failed to find out pri cim_ext
+ ErrorNumber.LSM_BUG # Failed to find out pri cim_ext
"""
if property_list is None:
property_list = ['Primordial']
else:
- if 'Primordial' not in property_list:
- property_list.extend(['Primordial'])
+ property_list = _merge_list(property_list, ['Primordial'])
cim_exts = self._c.Associators(
cim_disk_path,
@@ -2530,7 +2431,7 @@ class Smis(IStorageAreaNetwork):
# each CIM_DiskDrive
return cim_exts[0]
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Failed to find out Primordial " +
"CIM_StorageExtent for CIM_DiskDrive %s " %
cim_disk_path)
@@ -2748,7 +2649,7 @@ class Smis(IStorageAreaNetwork):
elif len(cim_disks) == 2:
return None
else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
+ raise LsmError(ErrorNumber.LSM_BUG,
"Found two or more CIM_DiskDrive associated to " +
"requested CIM_StorageExtent %s" %
cim_pri_ext_path)
@@ -2990,7 +2891,6 @@ class Smis(IStorageAreaNetwork):
"""
Delete a Pool via CIM_StorageConfigurationService.DeleteStoragePool
"""
- cim_sys_pros = self._property_list_of_id("System")
if not self.fallback_mode and \
self._profile_is_supported(SNIA.BLK_SRVS_PROFILE,
SNIA.SMIS_SPEC_VER_1_4,
@@ -3000,9 +2900,10 @@ class Smis(IStorageAreaNetwork):
(SNIA.BLK_SRVS_PROFILE,
SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._cim_sys_of_id(pool.system_id)
- cim_pool = self._get_cim_pool_by_id(cim_sys.path, pool.id)
- cim_scs = self._get_cim_scs(cim_sys.path)
+ cim_pool = self._get_cim_instance_by_id('Pool', pool.id)
+ cim_scs = self._get_class_instance(
+ 'CIM_StorageConfigurationService',
+ 'SystemName', pool.system_id)
in_params = {'Pool': cim_pool.path}
@@ -3031,7 +2932,7 @@ class Smis(IStorageAreaNetwork):
(SNIA.BLK_SRVS_PROFILE,
SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._cim_sys_of_id(system.id)
+ cim_sys = self._get_cim_instance_by_id('System', system.id)
# we does not support defining thinp_type yet.
# just using whatever provider set.
@@ -3082,7 +2983,9 @@ class Smis(IStorageAreaNetwork):
in_params['Goal'] = self._cim_st_path_for_goal(
raid_type, cim_sys.path)
- cim_scs = self._get_cim_scs(cim_sys.path)
+ cim_scs = self._get_class_instance(
+ 'CIM_StorageConfigurationService',
+ 'SystemName', system.id)
in_params = self._pool_chg_paras_check(in_params, cim_sys.path)
return self._pi("pool_create", Smis.JOB_RETRIEVE_POOL,
@@ -3091,46 +2994,6 @@ class Smis(IStorageAreaNetwork):
cim_scs.path, **in_params)))
@handle_cim_errors
- def _pri_cim_ext_of_disk_ids(self, disk_ids):
- """
- Usage:
- Find out the Primordial CIM_StorageSetting of Disk.
- Parameter:
- disk_ids # a list of Disk.id
- Returns:
- [a , b] # a list of items.
- or
- [] # disk_ids is NULL
- Exception:
- LsmError
- ErrorNumber.INVALID_DISK # Disk ID invalid.
- ErrorNumber.INVALID_DISK # No Disk found.
- """
- if len(disk_ids) == 0:
- return []
- cim_disks = self._c.EnumerateInstances('CIM_DiskDrive',
- PropertyList=['SystemName',
- 'DeviceID'],
- LocalOnly=False)
- if len(cim_disks) == 0:
- raise LsmError(ErrorNumber.INVALID_DISK, "No disk found")
-
- disk_id_2_cim = {}
- for cim_disk in cim_disks:
- disk_id_2_cim[self._disk_id(cim_disk)] = cim_disk
-
- cim_pri_exts = []
- for disk_id in disk_ids:
- if disk_id in disk_id_2_cim.keys():
- cim_disk = disk_id_2_cim[disk_id]
- cim_pri_ext = self._pri_cim_ext_of_cim_disk(cim_disk.path)
- cim_pri_exts.extend([cim_pri_ext])
- else:
- raise LsmError(ErrorNumber.INVALID_DISK,
- "Disk with ID %s cannot be found\n" % disk_id)
- return cim_pri_exts
-
- @handle_cim_errors
def _find_preset_cim_st(self, cim_cap_path, raid_type):
"""
Usage:
@@ -3324,37 +3187,6 @@ class Smis(IStorageAreaNetwork):
"type or add different RAID type tier")
return new_in_params
- def _get_cim_scs(self, cim_sys_path, property_list=None):
- """
- Usage:
- Find out the CIM_StorageConfigurationService base on
- CIM_ComputerSystem
- Base on SNIA SMI-S 1.6rev4, Block book, Clause 5: Block Services
- Package, Figure 8 - StoragePool Manipulation Instance Diagram
- This is only one CIM_StorageConfigurationService associated to
- CIM_ComputerSystem
- Parameter:
- cim_sys_path # CIMInstanceName of CIM_ComputerSystem
- property_list # the list of properties required in return
- # CIMInstance
- Returns:
- cim_scs
- """
- pros = []
- if property_list is not None:
- pros = property_list
- cim_scss = self._c.Associators(
- cim_sys_path,
- ResultClass='CIM_StorageConfigurationService',
- PropertyList=pros)
- if cim_scss and len(cim_scss) >= 0:
- return cim_scss[0]
- else:
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
- "Failed to find out " +
- "CIM_StorageConfigurationService of " +
- "CIM_ComputerSystem %s" % cim_sys_path)
-
def _profile_is_supported(self, profile_name, spec_ver, strict=False,
raise_error=False):
"""
@@ -3426,7 +3258,11 @@ class Smis(IStorageAreaNetwork):
this is assumption should work. Tested on EMC SMI-S provider which
provide 1.4, 1.5, 1.6 root profile.
"""
- property_list = self._property_list_of_id('System', property_list)
+ id_pros = self._property_list_of_id('System', property_list)
+ if property_list is None:
+ property_list = id_pros
+ else:
+ property_list = _merge_list(property_list, id_pros)
cim_syss = []
if self.fallback_mode:
@@ -3497,29 +3333,3 @@ class Smis(IStorageAreaNetwork):
return needed_cim_syss
else:
return cim_syss
-
- def _cim_sys_of_id(self, system_id, property_list=None):
- """
- Return a CIMInstance of CIM_ComputerSystem for given system id.
- """
- property_list = self._property_list_of_id("System", property_list)
- cim_syss = self._root_cim_syss(property_list)
-
- for cim_sys in cim_syss:
- if self._sys_id(cim_sys) == system_id:
- return cim_sys
- raise LsmError(ErrorNumber.NOT_FOUND_SYSTEM,
- "System %s not found" % system_id)
-
- def _get_cim_pool_by_id(self, cim_sys_path, pool_id, property_list=None):
- """
- Return a CIMInstance of CIM_StoragePool for given pool id.
- """
- property_list = self._property_list_of_id("Pool", property_list)
- cim_pools = self._cim_pools_of(cim_sys_path, property_list)
- for cim_pool in cim_pools:
- if self._pool_id(cim_pool) == pool_id:
- return cim_pool
-
- raise LsmError(ErrorNumber.NOT_FOUND_POOL,
- "System %s not found" % pool_id)
diff --git a/plugin/targetd/targetd.py b/plugin/targetd/targetd.py
index a996d95..ed4c945 100644
--- a/plugin/targetd/targetd.py
+++ b/plugin/targetd/targetd.py
@@ -20,7 +20,7 @@
import copy
-from lsm import (Pool, Volume, System, Capabilities, Initiator,
+from lsm import (Pool, Volume, System, Capabilities,
IStorageAreaNetwork, INfs, FileSystem, FsSnapshot, NfsExport,
LsmError, ErrorNumber, uri_parse, md5, VERSION,
common_urllib2_error_handler, search_property,
@@ -260,15 +260,6 @@ class TargetdStorage(IStorageAreaNetwork, INfs):
lsm_ags = self.access_groups(flags=flags)
return [x for x in lsm_ags if x.id in ag_ids]
- @handle_errors
- def initiators(self, flags=0):
- inits = []
- for init in set(i['initiator_wwn']
- for i in self._jsonrequest("export_list")):
- inits.append(Initiator(init, Initiator.TYPE_ISCSI, init))
-
- return inits
-
def _get_volume(self, pool_id, volume_name):
vol = [v for v in self._jsonrequest("vol_list", dict(pool=pool_id))
if v['name'] == volume_name][0]
@@ -336,10 +327,10 @@ class TargetdStorage(IStorageAreaNetwork, INfs):
return not self.volume_online(volume)
@handle_errors
- def iscsi_chap_auth(self, initiator, in_user, in_password, out_user,
+ def iscsi_chap_auth(self, init_id, in_user, in_password, out_user,
out_password, flags=0):
self._jsonrequest("initiator_set_auth",
- dict(initiator_wwn=initiator.id,
+ dict(initiator_wwn=init_id,
in_user=in_user,
in_pass=in_password,
out_user=out_user,
@@ -348,60 +339,6 @@ class TargetdStorage(IStorageAreaNetwork, INfs):
return None
@handle_errors
- def initiator_grant(self, initiator_id, initiator_type, volume, access,
- flags=0):
- if initiator_type != Initiator.TYPE_ISCSI:
- raise LsmError(ErrorNumber.NO_SUPPORT, "Not supported")
-
- # find lowest unused lun and use that
- used_luns = [x['lun'] for x in self._jsonrequest("export_list")]
- lun = 0
- while True:
- if lun in used_luns:
- lun += 1
- else:
- break
-
- self._jsonrequest("export_create",
- dict(pool=volume.pool_id,
- vol=volume.name,
- initiator_wwn=initiator_id, lun=lun))
-
- @handle_errors
- def initiator_revoke(self, initiator, volume, flags=0):
- self._jsonrequest("export_destroy",
- dict(pool=volume.pool_id,
- vol=volume.name,
- initiator_wwn=initiator.id))
-
- @handle_errors
- def volumes_accessible_by_initiator(self, initiator, flags=0):
- exports = [x for x in self._jsonrequest("export_list")
- if initiator.id == x['initiator_wwn']]
-
- vols = []
- for export in exports:
- vols.append(Volume(export['vol_uuid'], export['vol_name'],
- export['vol_uuid'], 512,
- export['vol_size'] / 512,
- Volume.STATUS_OK, self.system.id,
- export['pool']))
-
- return vols
-
- @handle_errors
- def initiators_granted_to_volume(self, volume, flags=0):
- exports = [x for x in self._jsonrequest("export_list")
- if volume.id == x['vol_uuid']]
-
- inits = []
- for export in exports:
- name = export['initiator_wwn']
- inits.append(Initiator(name, Initiator.TYPE_ISCSI, name))
-
- return inits
-
- @handle_errors
def fs(self, search_key=None, search_value=None, flags=0):
rc = []
for fs in self._jsonrequest("fs_list"):
diff --git a/plugin/v7k/ibmv7k.py b/plugin/v7k/ibmv7k.py
index bfe17ef..de63a99 100644
--- a/plugin/v7k/ibmv7k.py
+++ b/plugin/v7k/ibmv7k.py
@@ -17,7 +17,7 @@
import paramiko
-from lsm import (Capabilities, ErrorNumber, IStorageAreaNetwork, Initiator,
+from lsm import (Capabilities, ErrorNumber, IStorageAreaNetwork,
LsmError, Pool, System, VERSION, Volume, uri_parse,
search_property, AccessGroup)
@@ -278,102 +278,6 @@ class IbmV7k(IStorageAreaNetwork):
return Initiator(lsm_init_id, lsm_init_type, v7k_init['name'])
- def _map_lsm_init_id_to_v7k(self, lsm_init_id):
- gi = self._get_initiators()
-
- v7k_init_id = None
- for i in gi.itervalues():
- v7kinit = self._get_initiator(i['id'])
- if 'WWPN' in v7kinit and v7kinit['WWPN'] == lsm_init_id:
- v7k_init_id = v7kinit['id']
-
- if 'iscsi_name' in v7kinit and v7kinit['iscsi_name'] == \
- lsm_init_id:
- v7k_init_id = v7kinit['id']
-
- if not v7k_init_id:
- raise LsmError(ErrorNumber.NOT_FOUND_INITIATOR,
- "Initiator not found")
-
- return v7k_init_id
-
- def _get_volumes_accessible_by_initiator(self, init_id):
- # init_id passed is the lsm's init id. Convert it to v7k id.
- v7k_init_id = self._map_lsm_init_id_to_v7k(init_id)
-
- ssh_cmd = 'lshostvdiskmap -delim ! %s' % v7k_init_id
- return self._execute_command_and_parse_concise(ssh_cmd)
-
- def _get_initiators_granted_to_volume(self, v):
- ssh_cmd = 'lsvdiskhostmap -delim ! %s' % v
- return self._execute_command_and_parse_concise(ssh_cmd)
-
- def _initiator_create(self, init_id, init_type):
- if init_type == Initiator.TYPE_PORT_WWN:
- type_option = '-hbawwpn'
- elif init_type == Initiator.TYPE_ISCSI:
- type_option = '-iscsiname'
- else:
- raise LsmError(ErrorNumber.UNSUPPORTED_INITIATOR_TYPE,
- "Initiator type not supported")
-
- ssh_cmd = 'mkhost %s %s' % (type_option, init_id)
- return self._execute_command(ssh_cmd)
-
- def _initiator_create_is_success(self, stdout):
- if 'successfully created' in stdout:
- return True
- return False
-
- def _initiator_grant(self, init_id, init_type, vol_id, force):
- # init_id passed is the lsm's init id. Convert it to v7k id.
- try:
- v7k_init_id = self._map_lsm_init_id_to_v7k(init_id)
- except LsmError as le:
- if le.code == ErrorNumber.NOT_FOUND_INITIATOR:
- # Auto add the initiator
- exit_code, stdout, stderr = self._initiator_create(init_id,
- init_type)
- if self._initiator_create_is_success(stdout):
- # If success, get the v7k id for the new init
- # This should not cause an exception this time!
- v7k_init_id = self._map_lsm_init_id_to_v7k(init_id)
- else:
- raise LsmError(ErrorNumber.PLUGIN_ERROR,
- "Error creating initiator")
- else:
- raise le
-
- ssh_cmd = 'mkvdiskhostmap %s -host %s %s' % \
- ('-force' if force else '', v7k_init_id, vol_id)
- return self._execute_command(ssh_cmd)
-
- def _initiator_grant_is_success(self, stdout):
- if 'successfully created' in stdout:
- return True
- return False
-
- def _initiator_delete(self, v7k_init_id, force=True):
- ssh_cmd = 'rmhost %s %s' % ('-force' if force else '', v7k_init_id)
- self._execute_command(ssh_cmd)
-
- def _initiator_revoke(self, init_id, vol_id):
- # init_id passed is the lsm's init id. Convert it to v7k id.
- v7k_init_id = self._map_lsm_init_id_to_v7k(init_id)
-
- ssh_cmd = 'rmvdiskhostmap -host %s %s' % (v7k_init_id, vol_id)
- self._execute_command(ssh_cmd)
-
- # Auto remove initiator (if no mapping present)
- # v7k rmhost raises exception, if host is being removed with mappings
- # present... unless -force is specified. So exploit that fact here.
- try:
- self._initiator_delete(v7k_init_id, force=False)
- except LsmError:
- pass
-
- return
-
def plugin_register(self, uri, password, timeout, flags=0):
self.password = password
self.tmo = timeout
@@ -440,14 +344,6 @@ class IbmV7k(IStorageAreaNetwork):
[self._volume(v) for v in gv.itervalues()],
search_key, search_value)
- def initiators(self, flags=0):
- init_list = []
- gi = self._get_initiators()
- for i in gi.itervalues():
- init = self._get_initiator(i['id'])
- init_list.append(self._initiator(init))
- return init_list
-
@staticmethod
def _v7k_init_to_lsm_ag(v7k_init, system_id):
lsm_init_id = None
@@ -498,47 +394,3 @@ class IbmV7k(IStorageAreaNetwork):
# TODO: How to pass -force param ? For now, assume -force
self._delete_volume(volume.id, force=True)
return None
-
- def initiator_grant(self, initiator_id, initiator_type, volume, access,
- flags=0):
- # TODO: How to pass -force param ? For now, assume -force.
- # -force allows multiple vdisk-to-host assignments,
- # which are not normally allowed
-
- # NOTE: V7000 doesn't provide a way to pass access param,
- # access is always rw, if ro, raise error.
- if access != Volume.ACCESS_READ_WRITE:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Only RW access to the volume is supported")
-
- exit_code, stdout, stderr = self._initiator_grant(initiator_id,
- initiator_type,
- volume.id,
- force=True)
- return self._initiator_grant_is_success(stdout)
-
- def initiator_revoke(self, initiator, volume, flags=0):
- self._initiator_revoke(initiator.id, volume.id)
- return
-
- def volumes_accessible_by_initiator(self, initiator, flags=0):
- gvabi = self._get_volumes_accessible_by_initiator(initiator.id)
-
- vol_list = []
- for vol in gvabi.itervalues():
- gv = self._get_volume(vol['vdisk_id'])
- v = self._volume(gv)
- vol_list.append(v)
-
- return vol_list
-
- def initiators_granted_to_volume(self, volume, flags=0):
- gigtv = self._get_initiators_granted_to_volume(volume.id)
-
- init_list = []
- for init in gigtv.itervalues():
- gi = self._get_initiator(init['host_id'])
- i = self._initiator(gi)
- init_list.append(i)
-
- return init_list
--
1.8.3.1