* 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 <f...@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 &params,
     return rc;
 }
 
+static int handle_pool_raid_info(lsm_plugin_ptr p, Value &params,
+                                 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 &params, 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


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Libstoragemgmt-devel mailing list
Libstoragemgmt-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libstoragemgmt-devel

Reply via email to