* Python part:
* New python method: lsm.Client.pool_member_info(pool,flags)
Query the member information for certain pool.
Returns [raid_type, member_type, member_ids]
* For sub-pool which allocated space from other pool(like NetApp ONTAP
volume which allocate space from ONTAP aggregate), the member_type
will be lsm.Pool.MEMBER_TYPE_POOL.
* For disk RAID pool which use the whole disk as RAID member(like NetApp
ONTAP aggregate or EMC VNX pool) which the member_type will be
lsm.Pool.MEMBER_TYPE_DISK.
* New constants:
* lsm.Pool.MEMBER_TYPE_POOL
* lsm.Pool.MEMBER_TYPE_DISK
* lsm.Pool.MEMBER_TYPE_OTHER
* lsm.Pool.MEMBER_TYPE_UNKNOWN
* New capability for this new method:
* lsm.Capabilities.POOL_MEMBER_INFO
* C part:
* New C functions:
* lsm_pool_member_info()
For API user.
* lsm_plug_pool_member_info()
For plugin.
* New constants:
* LSM_POOL_MEMBER_TYPE_POOL
* LSM_POOL_MEMBER_TYPE_DISK
* LSM_POOL_MEMBER_TYPE_OTHER
* LSM_POOL_MEMBER_TYPE_UNKNOWN
* LSM_CAP_POOL_MEMBER_INFO
* For detail information, please refer to docstring of
lsm.Client.pool_member_info() method in python_binding/lsm/_client.py file
and lsm_pool_member_info() method in
c_binding/include/libstoragemgmt/libstoragemgmt.h.
Changes in V2:
* Use lsm_string_list instead of 'char **' for 'member_ids' argument in C
library.
* Removed 'member_count' argument as lsm_string_list has
lsm_string_list_size() function.
* Fix the incorrect comment of plugin interface 'lsm_plug_volume_raid_info'.
Changes in V3:
* Method name changed to lsm.Client.pool_member_info() and
lsm_pool_member_info().
Changes in V4:
* Fix typo 'memership' in libstoragemgmt.h.
* Handle 'member_ids' conversion errors in lsm_pool_member_info() of
lsm_mgmt.cpp:
* Raise LSM_ERR_NO_MEMORY when value_to_string_list() failed to
convert value to string list.
* Raise LSM_ERR_LIB_BUG if got member_ids not as an array.
* Initialized return data just in case plugin didn't touch the values
in handle_pool_member_info() of lsm_plugin_ipc.cpp.
* Update docstring of lsm.Client.pool_member_info().
Changes in V5:
* Update commit notes to use new method name: pool_member_info.
Changes in V6:
* Fix memory leak 'member_ids' in handle_pool_member_info() of
lsm_plugin_ipc.cpp.
Signed-off-by: Gris Ge <fge(a)redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt.h | 27 ++++++
.../libstoragemgmt/libstoragemgmt_capabilities.h | 4 +-
.../libstoragemgmt/libstoragemgmt_plug_interface.h | 27 ++++++
.../include/libstoragemgmt/libstoragemgmt_types.h | 17 ++++
c_binding/lsm_mgmt.cpp | 60 +++++++++++++
c_binding/lsm_plugin_ipc.cpp | 47 ++++++++++-
python_binding/lsm/_client.py | 98 ++++++++++++++++++++++
python_binding/lsm/_data.py | 6 ++
8 files changed, 284 insertions(+), 2 deletions(-)
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt.h
b/c_binding/include/libstoragemgmt/libstoragemgmt.h
index 3d34f75..85022b4 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt.h
@@ -864,6 +864,33 @@ int LSM_DLL_EXPORT lsm_volume_raid_info(
uint32_t *strip_size, uint32_t *disk_count,
uint32_t *min_io_size, uint32_t *opt_io_size, lsm_flag flags);
+/**
+ * Retrieves the membership of given pool. New in version 1.2.
+ * @param[in] c Valid connection
+ * @param[in] pool The lsm_pool ptr.
+ * @param[out] raid_type
+ * Enum of lsm_volume_raid_type.
+ * @param[out] member_type
+ * Enum of lsm_pool_member_type.
+ * @param[out] member_ids
+ * The pointer to lsm_string_list pointer.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_POOL,
+ * the 'member_ids' will contain a list of parent Pool
+ * IDs.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_DISK,
+ * the 'member_ids' will contain a list of disk IDs.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_OTHER or
+ * LSM_POOL_MEMBER_TYPE_UNKNOWN, the member_ids should
+ * be NULL.
+ * Need to use lsm_string_list_free() to free this memory.
+ * @param[in] flags Reserved, set to 0
+ * @return LSM_ERR_OK on success else error reason.
+ */
+int LSM_DLL_EXPORT lsm_pool_member_info(
+ lsm_connect *c, lsm_pool *pool, lsm_volume_raid_type *raid_type,
+ lsm_pool_member_type *member_type, lsm_string_list **member_ids,
+ lsm_flag flags);
+
#ifdef __cplusplus
}
#endif
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
b/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
index 18490f3..943f4a4 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_capabilities.h
@@ -113,7 +113,9 @@ typedef enum {
LSM_CAP_TARGET_PORTS = 216, /**< List target ports
*/
LSM_CAP_TARGET_PORTS_QUICK_SEARCH = 217, /**< Filtering occurs
on array */
- LSM_CAP_DISKS = 220 /**< List disk drives
*/
+ LSM_CAP_DISKS = 220, /**< List disk drives
*/
+ LSM_CAP_POOL_MEMBER_INFO = 221,
+ /**^ Query pool member information */
} lsm_capability_type;
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
b/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
index b36586c..cdc8dc9 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
@@ -827,6 +827,32 @@ typedef int (*lsm_plug_volume_raid_info)(lsm_plugin_ptr c, lsm_volume
*volume,
uint32_t *disk_count, uint32_t *min_io_size, uint32_t *opt_io_size,
lsm_flag flags);
+/**
+ * Retrieves the membership of given pool. New in version 1.2.
+ * @param[in] c Valid lsm plug-in pointer
+ * @param[in] pool The lsm_pool ptr.
+ * @param[out] raid_type
+ * Enum of lsm_volume_raid_type.
+ * @param[out] member_type
+ * Enum of lsm_pool_member_type.
+ * @param[out] member_ids
+ * The pointer of lsm_string_list pointer.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_POOL,
+ * the 'member_ids' will contain a list of parent Pool
+ * IDs.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_DISK,
+ * the 'member_ids' will contain a list of disk IDs.
+ * When 'member_type' is LSM_POOL_MEMBER_TYPE_OTHER or
+ * LSM_POOL_MEMBER_TYPE_UNKNOWN, the member_ids should
+ * be NULL.
+ * @param[in] flags Reserved, set to 0
+ * @return LSM_ERR_OK on success else error reason.
+ */
+typedef int (*lsm_plug_pool_member_info)(
+ lsm_plugin_ptr c, lsm_pool *pool, lsm_volume_raid_type *raid_type,
+ lsm_pool_member_type *member_type, lsm_string_list **member_ids,
+ lsm_flag flags);
+
/** \struct lsm_ops_v1_2
* \brief Functions added in version 1.2
* NOTE: This structure will change during the developement util version 1.2
@@ -835,6 +861,7 @@ typedef int (*lsm_plug_volume_raid_info)(lsm_plugin_ptr c, lsm_volume
*volume,
struct lsm_ops_v1_2 {
lsm_plug_volume_raid_info vol_raid_info;
/**^ Query volume RAID information*/
+ lsm_plug_pool_member_info pool_member_info;
};
/**
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
index c5607c1..115ec5a 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_types.h
@@ -169,6 +169,23 @@ typedef enum {
/**^ Vendor specific RAID type */
} lsm_volume_raid_type;
+/**< \enum lsm_pool_member_type Different types of Pool member*/
+typedef enum {
+ LSM_POOL_MEMBER_TYPE_UNKNOWN = 0,
+ /**^ Plugin failed to detect the RAID member type. */
+ LSM_POOL_MEMBER_TYPE_OTHER = 1,
+ /**^ Vendor specific RAID member type. */
+ LSM_POOL_MEMBER_TYPE_DISK = 2,
+ /**^ Pool is created from RAID group using whole disks. */
+ LSM_POOL_MEMBER_TYPE_POOL = 3,
+ /**^
+ * Current pool(also known as sub-pool) is allocated from other
+ * pool(parent pool).
+ * The 'raid_type' will set to RAID_TYPE_OTHER unless certain RAID system
+ * support RAID using space of parent pools.
+ */
+} lsm_pool_member_type;
+
#define LSM_VOLUME_STRIP_SIZE_UNKNOWN 0
#define LSM_VOLUME_DISK_COUNT_UNKNOWN 0
#define LSM_VOLUME_MIN_IO_SIZE_UNKNOWN 0
diff --git a/c_binding/lsm_mgmt.cpp b/c_binding/lsm_mgmt.cpp
index e6a254f..7469127 100644
--- a/c_binding/lsm_mgmt.cpp
+++ b/c_binding/lsm_mgmt.cpp
@@ -802,6 +802,66 @@ int lsm_pool_list(lsm_connect *c, char *search_key, char
*search_value,
return rc;
}
+int lsm_pool_member_info(lsm_connect *c, lsm_pool *pool,
+ lsm_volume_raid_type * raid_type,
+ lsm_pool_member_type *member_type,
+ lsm_string_list **member_ids, lsm_flag flags)
+{
+ if( LSM_FLAG_UNUSED_CHECK(flags) ) {
+ return LSM_ERR_INVALID_ARGUMENT;
+ }
+
+ int rc = LSM_ERR_OK;
+ CONN_SETUP(c);
+
+ if( !LSM_IS_POOL(pool) ) {
+ return LSM_ERR_INVALID_ARGUMENT;
+ }
+
+ if( !raid_type || !member_type || !member_ids) {
+ return LSM_ERR_INVALID_ARGUMENT;
+ }
+
+ std::map<std::string, Value> p;
+ p["pool"] = pool_to_value(pool);
+ p["flags"] = Value(flags);
+ Value parameters(p);
+ try {
+
+ Value response;
+
+ rc = rpc(c, "pool_member_info", parameters, response);
+ if( LSM_ERR_OK == rc ) {
+ std::vector<Value> j = response.asArray();
+ *raid_type = (lsm_volume_raid_type) j[0].asInt32_t();
+ *member_type = (lsm_pool_member_type) j[1].asInt32_t();
+ *member_ids = NULL;
+ if (Value::array_t == j[2].valueType()){
+ if (j[2].asArray().size()){
+ *member_ids = value_to_string_list(j[2]);
+ if ( *member_ids == NULL ){
+ return LSM_ERR_NO_MEMORY;
+ }else if( lsm_string_list_size(*member_ids) !=
+ j[2].asArray().size() ){
+
+ lsm_string_list_free(*member_ids);
+ return LSM_ERR_NO_MEMORY;
+ }
+ }
+ }else{
+ rc = logException(
+ c, LSM_ERR_LIB_BUG, "member_ids data is not an array",
+ "member_ids data is not an array");
+ }
+ }
+ } catch( const ValueException &ve ) {
+ rc = logException(c, LSM_ERR_LIB_BUG, "Unexpected type",
+ ve.what());
+ }
+ return rc;
+
+}
+
int lsm_target_port_list(lsm_connect *c, const char *search_key,
const char *search_value,
lsm_target_port **target_ports[],
diff --git a/c_binding/lsm_plugin_ipc.cpp b/c_binding/lsm_plugin_ipc.cpp
index d2a43d4..dcae563 100644
--- a/c_binding/lsm_plugin_ipc.cpp
+++ b/c_binding/lsm_plugin_ipc.cpp
@@ -1015,6 +1015,50 @@ static int handle_volume_raid_info(lsm_plugin_ptr p, Value
¶ms,
return rc;
}
+static int handle_pool_member_info(lsm_plugin_ptr p, Value ¶ms,
+ Value &response)
+{
+ int rc = LSM_ERR_NO_SUPPORT;
+ if( p && p->ops_v1_2 && p->ops_v1_2->pool_member_info) {
+ Value v_pool = params["pool"];
+
+ if(IS_CLASS_POOL(v_pool) &&
+ LSM_FLAG_EXPECTED_TYPE(params) ) {
+ lsm_pool *pool = value_to_pool(v_pool);
+ std::vector<Value> result;
+
+ if( pool ) {
+ lsm_volume_raid_type raid_type = LSM_VOLUME_RAID_TYPE_UNKNOWN;
+ lsm_pool_member_type member_type =
+ LSM_POOL_MEMBER_TYPE_UNKNOWN;
+ lsm_string_list *member_ids = NULL;
+
+ rc = p->ops_v1_2->pool_member_info(
+ p, pool, &raid_type, &member_type,
+ &member_ids, LSM_FLAG_GET_VALUE(params));
+
+ if( LSM_ERR_OK == rc ) {
+ result.push_back(Value((int32_t)raid_type));
+ result.push_back(Value((int32_t)member_type));
+ result.push_back(string_list_to_value(member_ids));
+ if ( member_ids != NULL ) {
+ lsm_string_list_free(member_ids);
+ }
+ response = Value(result);
+ }
+
+ lsm_pool_record_free(pool);
+ } else {
+ rc = LSM_ERR_NO_MEMORY;
+ }
+
+ } else {
+ rc = LSM_ERR_TRANSPORT_INVALID_ARG;
+ }
+ }
+ return rc;
+}
+
static int ag_list(lsm_plugin_ptr p, Value ¶ms, Value &response)
{
int rc = LSM_ERR_NO_SUPPORT;
@@ -2213,7 +2257,8 @@ static std::map<std::string,handler> dispatch =
static_map<std::string,handler>
("volume_resize", handle_volume_resize)
("volumes_accessible_by_access_group", vol_accessible_by_ag)
("volumes", handle_volumes)
- ("volume_raid_info", handle_volume_raid_info);
+ ("volume_raid_info", handle_volume_raid_info)
+ ("pool_member_info", handle_pool_member_info);
static int process_request(lsm_plugin_ptr p, const std::string &method, Value
&request,
Value &response)
diff --git a/python_binding/lsm/_client.py b/python_binding/lsm/_client.py
index a641b1d..f3c9e6c 100644
--- a/python_binding/lsm/_client.py
+++ b/python_binding/lsm/_client.py
@@ -1074,3 +1074,101 @@ def volume_raid_info(self, volume, flags=FLAG_RSVD):
No support.
"""
return self._tp.rpc('volume_raid_info', _del_self(locals()))
+
+ @_return_requires([int, int, [unicode]])
+ def pool_member_info(self, pool, flags=FLAG_RSVD):
+ """
+ lsm.Client.pool_member_info(self, pool, flags=lsm.Client.FLAG_RSVD)
+
+ Version:
+ 1.2
+ Usage:
+ Query the membership information of certain pool:
+ RAID type, member type and member ids.
+ Currently, LibStorageMgmt supports two types of pool:
+ * Sub-pool -- Pool.MEMBER_TYPE_POOL
+ Pool space is allocated from parent pool.
+ Example:
+ * NetApp ONTAP volume
+
+ * Disk RAID pool -- Pool.MEMBER_TYPE_DISK
+ Pool is a RAID group assembled by disks.
+ Example:
+ * LSI MegaRAID disk group
+ * EMC VNX pool
+ * NetApp ONTAP aggregate
+ Parameters:
+ pool (lsm.Pool object)
+ Pool to query
+ flags (int)
+ Optional. Reserved for future use.
+ Should be set as lsm.Client.FLAG_RSVD.
+ Returns:
+ [raid_type, member_type, member_ids]
+
+ raid_type (int)
+ RAID Type of requested pool.
+ Could be one of these values:
+ Volume.RAID_TYPE_RAID0
+ Stripe
+ Volume.RAID_TYPE_RAID1
+ Two disks Mirror
+ Volume.RAID_TYPE_RAID3
+ Byte-level striping with dedicated parity
+ Volume.RAID_TYPE_RAID4
+ Block-level striping with dedicated parity
+ Volume.RAID_TYPE_RAID5
+ Block-level striping with distributed parity
+ Volume.RAID_TYPE_RAID6
+ Block-level striping with two distributed parities,
+ aka, RAID-DP
+ Volume.RAID_TYPE_RAID10
+ Stripe of mirrors
+ Volume.RAID_TYPE_RAID15
+ Parity of mirrors
+ Volume.RAID_TYPE_RAID16
+ Dual parity of mirrors
+ Volume.RAID_TYPE_RAID50
+ Stripe of parities Volume.RAID_TYPE_RAID60
+ Stripe of dual parities
+ Volume.RAID_TYPE_RAID51
+ Mirror of parities
+ Volume.RAID_TYPE_RAID61
+ Mirror of dual parities
+ Volume.RAID_TYPE_JBOD
+ Just bunch of disks, no parity, no striping.
+ Volume.RAID_TYPE_UNKNOWN
+ The plugin failed to detect the volume's RAID type.
+ Volume.RAID_TYPE_MIXED
+ This pool contains multiple RAID settings.
+ Volume.RAID_TYPE_OTHER
+ Vendor specific RAID type
+ member_type (int)
+ Could be one of these values:
+ Pool.MEMBER_TYPE_POOL
+ Current pool(also known as sub-pool) is allocated from
+ other pool(parent pool). The 'raid_type' will set to
+ RAID_TYPE_OTHER unless certain RAID system support RAID
+ using space of parent pools.
+ Pool.MEMBER_TYPE_DISK
+ Pool is created from RAID group using whole disks.
+ Pool.MEMBER_TYPE_OTHER
+ Vendor specific RAID member type.
+ Pool.MEMBER_TYPE_UNKNOWN
+ Plugin failed to detect the RAID member type.
+ member_ids (list of strings)
+ When 'member_type' is Pool.MEMBER_TYPE_POOL,
+ the 'member_ids' will contain a list of parent Pool IDs.
+ When 'member_type' is Pool.MEMBER_TYPE_DISK,
+ the 'member_ids' will contain a list of disk IDs.
+ When 'member_type' is Pool.MEMBER_TYPE_OTHER or
+ Pool.MEMBER_TYPE_UNKNOWN, the member_ids should be an empty
+ list.
+ SpecialExceptions:
+ LsmError
+ ErrorNumber.NO_SUPPORT
+ ErrorNumber.NOT_FOUND_POOL
+ Capability:
+ lsm.Capabilities.POOL_MEMBER_INFO
+ """
+ return self._tp.rpc('pool_member_info', _del_self(locals()))
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
index 23681dd..2f42eaf 100644
--- a/python_binding/lsm/_data.py
+++ b/python_binding/lsm/_data.py
@@ -412,6 +412,11 @@ class Pool(IData):
STATUS_INITIALIZING = 1 << 14
STATUS_GROWING = 1 << 15
+ MEMBER_TYPE_UNKNOWN = 0
+ MEMBER_TYPE_OTHER = 1
+ MEMBER_TYPE_DISK = 2
+ MEMBER_TYPE_POOL = 3
+
def __init__(self, _id, _name, _element_type, _unsupported_actions,
_total_space, _free_space,
_status, _status_info, _system_id, _plugin_data=None):
@@ -754,6 +759,7 @@ class Capabilities(IData):
TARGET_PORTS_QUICK_SEARCH = 217
DISKS = 220
+ POOL_MEMBER_INFO = 221
def _to_dict(self):
return {'class': self.__class__.__name__,
--
1.8.3.1