* The _parse_hpssacli_output() method will fail if got free disks detected.
   This fix is removing list used in _parse_hpssacli_output(), every line
   will be stored as an dictionary key.
   If current line is not 'key: value' format, the value will be set as None.
   Also skipped the incorrect indented 'Physical Drives' line, in the seek
   of avoiding duplication dictionary key.

 * Also fix the incorrect 'flag_free' argument used for
   SmartArray._hp_disk_to_lsm_disk() when facing free disks.

 * Tested on HP P410i with one free disk, hence updated the TODO line about
   free disks.

Signed-off-by: Gris Ge <f...@redhat.com>
---
 plugin/hpsa/hpsa.py | 72 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 58 insertions(+), 14 deletions(-)

diff --git a/plugin/hpsa/hpsa.py b/plugin/hpsa/hpsa.py
index 60d87cc..743cbcc 100644
--- a/plugin/hpsa/hpsa.py
+++ b/plugin/hpsa/hpsa.py
@@ -75,9 +75,20 @@ def _sys_status_of(hp_ctrl_status):
 def _parse_hpssacli_output(output):
     """
     Got a output string of hpssacli to dictionary(nested).
+    Skipped these line:
+        1. Starts with 'Note:'
+           This is just a message right after controller. We don't neet it
+           yet.
+        2. The 'Physical Drives' line.
+           It should indented after 'Internal Drive Cage' like.
+           If not ignored, we might got duplication line error.
+           After ignored, it's phsycial disks will directly stored as
+           key of 'Internal Drive Cage' dictionary.
     """
     output_lines = [
-        l for l in output.split("\n") if l and not l.startswith('Note:')]
+        l for l in output.split("\n")
+        if l and not l.startswith('Note:') and
+           not l.strip() == 'Physical Drives']
 
     data = {}
 
@@ -108,24 +119,19 @@ def _parse_hpssacli_output(output):
 
         if nxt_indent_count > cur_indent_count:
             nxt_line_splitted = nxt_line.split(": ")
-            if len(nxt_line_splitted) == 1:
-                new_data = []
-            else:
-                new_data = {}
+            new_data = {}
 
             if cur_line.lstrip() not in cur_data_pointer:
                 cur_data_pointer[cur_line.lstrip()] = new_data
                 indent_2_data[nxt_indent_count] = new_data
-            elif type(cur_data_pointer[cur_line.lstrip()]) != type(new_data):
+            else:
                 raise LsmError(
                     ErrorNumber.PLUGIN_BUG,
-                    "_parse_hpssacli_output(): Unexpected line '%s%s\n'" %
-                    (cur_line, nxt_line))
+                    "_parse_hpssacli_output(): Found duplicate line %s" %
+                    cur_line)
         else:
             if len(cur_line_splitted) == 1:
-                if type(indent_2_data[cur_indent_count]) != list:
-                    raise Exception("not a list: '%s'" % cur_line)
-                cur_data_pointer.append(cur_line.lstrip())
+                cur_data_pointer[cur_line.lstrip()] = None
             else:
                 cur_data_pointer[cur_line_splitted[0].lstrip()] = \
                     ": ".join(cur_line_splitted[1:]).strip()
@@ -279,6 +285,7 @@ def capabilities(self, system, flags=Client.FLAG_RSVD):
         cap.set(Capabilities.VOLUMES)
         cap.set(Capabilities.DISKS)
         cap.set(Capabilities.VOLUME_RAID_INFO)
+        cap.set(Capabilities.POOL_RAID_INFO)
         return cap
 
     def _sacli_exec(self, sacli_cmds, flag_convert=True):
@@ -450,8 +457,7 @@ def disks(self, search_key=None, search_value=None,
         Depend on command:
             hpssacli ctrl all show config detail
         """
-        # TODO(Gris Ge): Need real test on spare disk and free disk.
-        #                The free disks is purely base on HP document.
+        # TODO(Gris Ge): Need real test on spare disk.
         rc_lsm_disks = []
         ctrl_all_conf = self._sacli_exec(
             ["ctrl", "all", "show", "config", "detail"])
@@ -475,7 +481,7 @@ def disks(self, search_key=None, search_value=None,
                                 SmartArray._hp_disk_to_lsm_disk(
                                     ctrl_data[key_name][array_key_name],
                                     sys_id, ctrl_num, array_key_name,
-                                    flag_free=False))
+                                    flag_free=True))
 
         return search_property(rc_lsm_disks, search_key, search_value)
 
@@ -526,3 +532,41 @@ def volume_raid_info(self, volume, flags=Client.FLAG_RSVD):
                 "Volume not found")
 
         return [raid_type, strip_size, disk_count, strip_size, stripe_size]
+
+    @_handle_errors
+    def pool_raid_info(self, pool, flags=Client.FLAG_RSVD):
+        """
+        Depend on command:
+            hpssacli ctrl slot=0 show config detail
+        """
+        if not pool.plugin_data:
+            raise LsmError(
+                ErrorNumber.INVALID_ARGUMENT,
+                "Ilegal input volume argument: missing plugin_data property")
+
+        (ctrl_num, array_num) = pool.plugin_data.split(":")
+        ctrl_data = self._sacli_exec(
+            ["ctrl", "slot=%s" % ctrl_num, "show", "config", "detail"]
+            ).values()[0]
+
+        disk_ids = []
+        raid_type = Volume.RAID_TYPE_UNKNOWN
+        for key_name in ctrl_data.keys():
+            if key_name == "Array: %s" % array_num:
+                for array_key_name in ctrl_data[key_name].keys():
+                    if array_key_name.startswith("Logical Drive: ") and \
+                       raid_type == Volume.RAID_TYPE_UNKNOWN:
+                        raid_type = _hp_raid_type_to_lsm(
+                            ctrl_data[key_name][array_key_name])
+                    elif array_key_name.startswith("physicaldrive"):
+                        hp_disk = ctrl_data[key_name][array_key_name]
+                        if hp_disk['Drive Type'] == 'Data Drive':
+                            disk_ids.append(hp_disk['Serial Number'])
+                break
+
+        if len(disk_ids) == 0:
+            raise LsmError(
+                ErrorNumber.NOT_FOUND_POOL,
+                "Pool not found")
+
+        return raid_type, Pool.MEMBER_TYPE_DISK, disk_ids
-- 
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