* Python part:
* New python method: lsm.Client.pool_raid_info(pool,flags)
Query the RAID information for certain volume.
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_RAID_INFO
* C part:
* New C functions:
* lsm_pool_raid_info()
For API user.
* lsm_plug_pool_raid_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_RAID_INFO
* For detail information, please refer to docstring of
lsm.Client.pool_raid_info() method in python_binding/lsm/_client.py file
and lsm_pool_raid_info() method in
c_binding/include/libstoragemgmt/libstoragemgmt.h.
Signed-off-by: Gris Ge <***@redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt.h | 30 ++++++++
.../libstoragemgmt/libstoragemgmt_capabilities.h | 4 +-
.../libstoragemgmt/libstoragemgmt_plug_interface.h | 29 ++++++++
.../include/libstoragemgmt/libstoragemgmt_types.h | 17 +++++
c_binding/lsm_mgmt.cpp | 56 ++++++++++++++
c_binding/lsm_plugin_ipc.cpp | 48 +++++++++++-
python_binding/lsm/_client.py | 85 ++++++++++++++++++++++
python_binding/lsm/_data.py | 6 ++
8 files changed, 273 insertions(+), 2 deletions(-)
diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt.h b/c_binding/include/libstoragemgmt/libstoragemgmt.h
index 6e03f78..26c9701 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt.h
@@ -864,6 +864,36 @@ 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 RAID info 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_count
+ * Count of pool RAID members.
+ * @param[out] member_ids
+ * Array of string(char *).
+ * 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 and member_count should be 0.
+ * This memory of this array is allocated by malloc,
+ * user should free this array of string by themselves.
+ * @param[in] flags Reserved, set to 0
+ * @return LSM_ERR_OK on success else error reason.
+ */
+int LSM_DLL_EXPORT lsm_pool_raid_info(
+ lsm_connect *c, lsm_pool *pool, lsm_volume_raid_type *raid_type,
+ lsm_pool_member_type *member_type, uint32_t *member_count,
+ char **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..9e96035 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_RAID_INFO = 221,
+ /**^ Query pool RAID 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..259b631 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_plug_interface.h
@@ -827,6 +827,34 @@ 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 RAID info 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_count
+ * Count of pool RAID members.
+ * @param[out] member_ids
+ * Array of string(char *).
+ * 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 and member_count should be 0.
+ * @param[in] flags Reserved, set to 0
+ * @return LSM_ERR_OK on success else error reason.
+ */
+typedef int (*lsm_plug_pool_raid_info)(
+ lsm_plugin_ptr c, lsm_pool *pool, lsm_volume_raid_type *raid_type,
+ lsm_pool_member_type *member_type, uint32_t *member_count,
+ char **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 +863,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_raid_info pool_raid_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..3dc0755 100644
--- a/c_binding/lsm_mgmt.cpp
+++ b/c_binding/lsm_mgmt.cpp
@@ -802,6 +802,62 @@ int lsm_pool_list(lsm_connect *c, char *search_key, char *search_value,
return rc;
}
+int lsm_pool_raid_info(lsm_connect *c, lsm_pool *pool,
+ lsm_volume_raid_type * raid_type,
+ lsm_pool_member_type *member_type,
+ uint32_t *member_count, char **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_count || !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_raid_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();
+ if (Value::array_t == j[2].valueType()){
+ std::vector<Value> member_ids_value = j[2].asArray();
+ *member_count = member_ids_value.size();
+ if (*member_count){
+ uint32_t i;
+ *member_ids = (char **) malloc(
+ *member_count * sizeof(char *));
+ for(i = 0; i < *member_count; ++i ) {
+ (*member_ids)[i] = strdup(
+ member_ids_value[i].asString().c_str());
+ }
+ }
+ }
+ }
+ } 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..1b608e6 100644
--- a/c_binding/lsm_plugin_ipc.cpp
+++ b/c_binding/lsm_plugin_ipc.cpp
@@ -1015,6 +1015,51 @@ static int handle_volume_raid_info(lsm_plugin_ptr p, Value ¶ms,
return rc;
}
+static int handle_pool_raid_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_raid_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_pool_member_type member_type;
+ uint32_t member_count;
+ char **member_ids;
+
+ rc = p->ops_v1_2->pool_raid_info(
+ p, pool, &raid_type, &member_type, &member_count,
+ &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));
+ std::vector<Value> v_member_ids;
+ for (uint32_t i = 0; i < member_count; i++){
+ v_member_ids.push_back(Value(member_ids[i]));
+ }
+ result.push_back(v_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 +2258,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_raid_info", handle_pool_raid_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..1ed6e1e 100644
--- a/python_binding/lsm/_client.py
+++ b/python_binding/lsm/_client.py
@@ -1074,3 +1074,88 @@ 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_raid_info(self, pool, flags=FLAG_RSVD):
+ """Query the RAID information of certain pool.
+
+ New in version 1.2.
+
+ Query the RAID type, RAID member type, RAID member ids
+
+ This method requires this capability:
+ lsm.Capabilities.POOL_RAID_INFO
+
+ Args:
+ pool (lsm.Pool object): Pool to query
+ flags (int): 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 volume 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(string)):
+ 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.
+ Raises:
+ LsmError:
+ ErrorNumber.NO_SUPPORT
+ No support.
+ ErrorNumber.NOT_FOUND_POOL
+ Pool not found.
+ """
+ return self._tp.rpc('pool_raid_info', _del_self(locals()))
diff --git a/python_binding/lsm/_data.py b/python_binding/lsm/_data.py
index 23681dd..2d60562 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_RAID_INFO = 221
def _to_dict(self):
return {'class': self.__class__.__name__,
--
1.8.3.1