@cryptotaxi247 / netdata-1 / commits / af8404ceb

go.d add storcli collector (#17454)

Ilya Mashchenko committed Apr 19, 2024 at 17:38 UTC af8404cebb4821e0fa682e27aeb9714278af6096
18 files changed +2390 -2
src/go/collectors/go.d.plugin/README.md
+1 -2
@@ -114,9 +114,8 @@ see the appropriate collector readme.
114 | [redis](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/redis) | Redis |
115 | [scaleio](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/scaleio) | Dell EMC ScaleIO |
116 | [SNMP](https://github.com/netdata/netdata/blob/master/src/go/collectors/go.d.plugin/modules/snmp) | SNMP |
117 -| [solr](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/solr) | Solr |
117 | [squidlog](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/squidlog) | Squid |
119 -| [springboot2](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/springboot2) | Spring Boot2 |
118 +| [storcli](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/storcli) | Broadcom Hardware RAID |
119 | [supervisord](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/supervisord) | Supervisor |
120 | [systemdunits](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/systemdunits) | Systemd unit state |
121 | [tengine](https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/tengine) | Tengine |
src/go/collectors/go.d.plugin/config/go.d.conf
+1
@@ -77,6 +77,7 @@ modules:
77 # scaleio: yes
78 # snmp: yes
79 # squidlog: yes
80 +# storcli: yes
81 # supervisord: yes
82 # systemdunits: yes
83 # tengine: yes
src/go/collectors/go.d.plugin/config/go.d/storcli.conf new
+5
@@ -0,0 +1,5 @@
1 +## All available configuration options, their descriptions and default values:
2 +## https://github.com/netdata/netdata/tree/master/src/go/collectors/go.d.plugin/modules/storcli#readme
3 +
4 +jobs:
5 + - name: storcli
src/go/collectors/go.d.plugin/modules/init.go
+1
@@ -69,6 +69,7 @@ import (
69 _ "github.com/netdata/netdata/go/go.d.plugin/modules/scaleio"
70 _ "github.com/netdata/netdata/go/go.d.plugin/modules/snmp"
71 _ "github.com/netdata/netdata/go/go.d.plugin/modules/squidlog"
72 + _ "github.com/netdata/netdata/go/go.d.plugin/modules/storcli"
73 _ "github.com/netdata/netdata/go/go.d.plugin/modules/supervisord"
74 _ "github.com/netdata/netdata/go/go.d.plugin/modules/systemdunits"
75 _ "github.com/netdata/netdata/go/go.d.plugin/modules/tengine"
src/go/collectors/go.d.plugin/modules/storcli/charts.go new
+171
@@ -0,0 +1,171 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "fmt"
7 + "strconv"
8 + "strings"
9 +
10 + "github.com/netdata/netdata/go/go.d.plugin/agent/module"
11 +)
12 +
13 +const (
14 + prioControllerStatus = module.Priority + iota
15 + prioControllerBBUStatus
16 +
17 + prioPhysDriveErrors
18 + prioPhysDrivePredictiveFailures
19 + prioPhysDriveSmartAlertStatus
20 + prioPhysDriveTemperature
21 +)
22 +
23 +var controllerChartsTmpl = module.Charts{
24 + controllerStatusChartTmpl.Copy(),
25 + controllerBBUStatusChartTmpl.Copy(),
26 +}
27 +
28 +var (
29 + controllerStatusChartTmpl = module.Chart{
30 + ID: "controller_%s_status",
31 + Title: "Controller status",
32 + Units: "status",
33 + Fam: "cntrl status",
34 + Ctx: "storcli.controller_status",
35 + Type: module.Line,
36 + Priority: prioControllerStatus,
37 + Dims: module.Dims{
38 + {ID: "cntrl_%s_status_optimal", Name: "optimal"},
39 + {ID: "cntrl_%s_status_degraded", Name: "degraded"},
40 + {ID: "cntrl_%s_status_partially_degraded", Name: "partially_degraded"},
41 + {ID: "cntrl_%s_status_failed", Name: "failed"},
42 + },
43 + }
44 + controllerBBUStatusChartTmpl = module.Chart{
45 + ID: "controller_%s_bbu_status",
46 + Title: "Controller BBU status",
47 + Units: "status",
48 + Fam: "cntrl status",
49 + Ctx: "storcli.controller_bbu_status",
50 + Type: module.Line,
51 + Priority: prioControllerBBUStatus,
52 + Dims: module.Dims{
53 + {ID: "cntrl_%s_bbu_status_healthy", Name: "healthy"},
54 + {ID: "cntrl_%s_bbu_status_unhealthy", Name: "unhealthy"},
55 + {ID: "cntrl_%s_bbu_status_na", Name: "na"},
56 + },
57 + }
58 +)
59 +
60 +var physDriveChartsTmpl = module.Charts{
61 + physDriveMediaErrorsRateChartTmpl.Copy(),
62 + physDrivePredictiveFailuresRateChartTmpl.Copy(),
63 + physDriveSmartAlertStatusChartTmpl.Copy(),
64 + physDriveTemperatureChartTmpl.Copy(),
65 +}
66 +
67 +var (
68 + physDriveMediaErrorsRateChartTmpl = module.Chart{
69 + ID: "phys_drive_%s_cntrl_%s_media_errors_rate",
70 + Title: "Physical Drive media errors rate",
71 + Units: "errors/s",
72 + Fam: "pd errors",
73 + Ctx: "storcli.phys_drive_errors",
74 + Type: module.Line,
75 + Priority: prioPhysDriveErrors,
76 + Dims: module.Dims{
77 + {ID: "phys_drive_%s_cntrl_%s_media_error_count", Name: "media"},
78 + {ID: "phys_drive_%s_cntrl_%s_other_error_count", Name: "other"},
79 + },
80 + }
81 + physDrivePredictiveFailuresRateChartTmpl = module.Chart{
82 + ID: "phys_drive_%s_cntrl_%s_predictive_failures_rate",
83 + Title: "Physical Drive predictive failures rate",
84 + Units: "failures/s",
85 + Fam: "pd errors",
86 + Ctx: "storcli.phys_drive_predictive_failures",
87 + Type: module.Line,
88 + Priority: prioPhysDrivePredictiveFailures,
89 + Dims: module.Dims{
90 + {ID: "phys_drive_%s_cntrl_%s_predictive_failure_count", Name: "predictive_failures"},
91 + },
92 + }
93 + physDriveSmartAlertStatusChartTmpl = module.Chart{
94 + ID: "phys_drive_%s_cntrl_%s_smart_alert_status",
95 + Title: "Physical Drive SMART alert status",
96 + Units: "status",
97 + Fam: "pd smart",
98 + Ctx: "storcli.phys_drive_smart_alert_status",
99 + Type: module.Line,
100 + Priority: prioPhysDriveSmartAlertStatus,
101 + Dims: module.Dims{
102 + {ID: "phys_drive_%s_cntrl_%s_smart_alert_status_active", Name: "active"},
103 + {ID: "phys_drive_%s_cntrl_%s_smart_alert_status_inactive", Name: "inactive"},
104 + },
105 + }
106 + physDriveTemperatureChartTmpl = module.Chart{
107 + ID: "phys_drive_%s_cntrl_%s_temperature",
108 + Title: "Physical Drive temperature",
109 + Units: "status",
110 + Fam: "pd temperature",
111 + Ctx: "storcli.phys_drive_temperature",
112 + Type: module.Line,
113 + Priority: prioPhysDriveTemperature,
114 + Dims: module.Dims{
115 + {ID: "phys_drive_%s_cntrl_%s_temperature", Name: "temperature"},
116 + },
117 + }
118 +)
119 +
120 +func (s *StorCli) addControllerCharts(cntrl controllerInfo) {
121 + charts := controllerChartsTmpl.Copy()
122 +
123 + num := strconv.Itoa(cntrl.Basics.Controller)
124 +
125 + for _, chart := range *charts {
126 + chart.ID = fmt.Sprintf(chart.ID, num)
127 + chart.Labels = []module.Label{
128 + {Key: "controller_number", Value: num},
129 + {Key: "model", Value: cntrl.Basics.Model},
130 + }
131 + for _, dim := range chart.Dims {
132 + dim.ID = fmt.Sprintf(dim.ID, num)
133 + }
134 + }
135 +
136 + if err := s.Charts().Add(*charts...); err != nil {
137 + s.Warning(err)
138 + }
139 +}
140 +
141 +func (s *StorCli) addPhysDriveCharts(cntrlNum int, di *driveInfo, ds *driveState, da *driveAttrs) {
142 + charts := physDriveChartsTmpl.Copy()
143 +
144 + if _, ok := parseInt(getDriveTemperature(ds.DriveTemperature)); !ok {
145 + _ = charts.Remove(physDriveTemperatureChartTmpl.ID)
146 + }
147 +
148 + num := strconv.Itoa(cntrlNum)
149 +
150 + var enc, slot string
151 + if parts := strings.Split(di.EIDSlt, ":"); len(parts) == 2 { // EID:Slt
152 + enc, slot = parts[0], parts[1]
153 + }
154 +
155 + for _, chart := range *charts {
156 + chart.ID = fmt.Sprintf(chart.ID, da.WWN, num)
157 + chart.Labels = []module.Label{
158 + {Key: "controller_number", Value: num},
159 + {Key: "enclosure_number", Value: enc},
160 + {Key: "slot_number", Value: slot},
161 + {Key: "media_type", Value: di.Med},
162 + }
163 + for _, dim := range chart.Dims {
164 + dim.ID = fmt.Sprintf(dim.ID, da.WWN, num)
165 + }
166 + }
167 +
168 + if err := s.Charts().Add(*charts...); err != nil {
169 + s.Warning(err)
170 + }
171 +}
src/go/collectors/go.d.plugin/modules/storcli/collect.go new
+32
@@ -0,0 +1,32 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import "fmt"
6 +
7 +func (s *StorCli) collect() (map[string]int64, error) {
8 + cntrlResp, err := s.queryControllersInfo()
9 + if err != nil {
10 + return nil, err
11 + }
12 +
13 + mx := make(map[string]int64)
14 +
15 + if err := s.collectControllersInfo(mx, cntrlResp); err != nil {
16 + return nil, fmt.Errorf("error collecting controller info: %s", err)
17 + }
18 +
19 + drives := cntrlResp.Controllers[0].ResponseData.PDList
20 + driver := cntrlResp.Controllers[0].ResponseData.Version.DriverName
21 + if driver == "megaraid_sas" && len(drives) > 0 {
22 + drivesResp, err := s.queryDrivesInfo()
23 + if err != nil {
24 + return nil, fmt.Errorf("error collecting drives info: %s", err)
25 + }
26 + if err := s.collectMegaRaidDrives(mx, drivesResp); err != nil {
27 + return nil, err
28 + }
29 + }
30 +
31 + return mx, nil
32 +}
src/go/collectors/go.d.plugin/modules/storcli/collect_controllers.go new
+101
@@ -0,0 +1,101 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "encoding/json"
7 + "errors"
8 + "fmt"
9 + "strconv"
10 + "strings"
11 +)
12 +
13 +type (
14 + controllersInfoResponse struct {
15 + Controllers []struct {
16 + CommandStatus struct {
17 + Controller int `json:"Controller"`
18 + Status string `json:"Status"`
19 + } `json:"Command Status"`
20 + ResponseData controllerInfo `json:"Response Data"`
21 + } `json:"Controllers"`
22 + }
23 + controllerInfo struct {
24 + Basics struct {
25 + Controller int `json:"Controller"`
26 + Model string `json:"Model"`
27 + SerialNumber string `json:"Serial Number"`
28 + } `json:"Basics"`
29 + Version struct {
30 + DriverName string `json:"Driver Name"`
31 + } `json:"Version"`
32 + Status struct {
33 + ControllerStatus string `json:"Controller Status"`
34 + BBUStatus storNumber `json:"BBU Status"`
35 + } `json:"Status"`
36 + BBUInfo []struct {
37 + Model string `json:"Model"`
38 + State string `json:"State"`
39 + Temp string `json:"Temp"`
40 + } `json:"BBU_Info"`
41 + PDList []struct {
42 + } `json:"PD LIST"`
43 + }
44 +)
45 +
46 +func (s *StorCli) collectControllersInfo(mx map[string]int64, resp *controllersInfoResponse) error {
47 + for _, v := range resp.Controllers {
48 + cntrl := v.ResponseData
49 +
50 + idx := strconv.Itoa(cntrl.Basics.Controller)
51 + if !s.controllers[idx] {
52 + s.controllers[idx] = true
53 + s.addControllerCharts(cntrl)
54 + }
55 +
56 + px := fmt.Sprintf("cntrl_%s_", idx)
57 +
58 + for _, st := range []string{"optimal", "degraded", "partially_degraded", "failed"} {
59 + mx[px+"status_"+st] = 0
60 + }
61 + mx[px+"status_"+strings.ToLower(cntrl.Status.ControllerStatus)] = 1
62 +
63 + for _, st := range []string{"healthy", "unhealthy", "na"} {
64 + mx[px+"bbu_status_"+st] = 0
65 + }
66 + // https://github.com/prometheus-community/node-exporter-textfile-collector-scripts/issues/27
67 + switch cntrl.Status.BBUStatus {
68 + case "0", "8", "4096": // 0 good, 8 charging
69 + mx[px+"bbu_status_healthy"] = 1
70 + case "NA", "N/A":
71 + mx[px+"bbu_status_na"] = 1
72 + default:
73 + mx[px+"bbu_status_unhealthy"] = 1
74 + }
75 + }
76 + return nil
77 +}
78 +
79 +func (s *StorCli) queryControllersInfo() (*controllersInfoResponse, error) {
80 + bs, err := s.exec.controllersInfo()
81 + if err != nil {
82 + return nil, err
83 + }
84 +
85 + if len(bs) == 0 {
86 + return nil, errors.New("empty response")
87 + }
88 +
89 + var resp controllersInfoResponse
90 + if err := json.Unmarshal(bs, &resp); err != nil {
91 + return nil, err
92 + }
93 + if len(resp.Controllers) == 0 {
94 + return nil, errors.New("no controllers found")
95 + }
96 + if st := resp.Controllers[0].CommandStatus.Status; st != "Success" {
97 + return nil, fmt.Errorf("command status error: %s", st)
98 + }
99 +
100 + return &resp, nil
101 +}
src/go/collectors/go.d.plugin/modules/storcli/collect_drives.go new
+231
@@ -0,0 +1,231 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "encoding/json"
7 + "errors"
8 + "fmt"
9 + "strconv"
10 + "strings"
11 +)
12 +
13 +type drivesInfoResponse struct {
14 + Controllers []struct {
15 + CommandStatus struct {
16 + Controller int `json:"Controller"`
17 + Status string `json:"Status"`
18 + } `json:"Command Status"`
19 + ResponseData map[string]json.RawMessage `json:"Response Data"`
20 + } `json:"Controllers"`
21 +}
22 +
23 +type (
24 + driveInfo struct {
25 + EIDSlt string `json:"EID:Slt"`
26 + DID int `json:"DID"`
27 + State string `json:"State"`
28 + DG int `json:"DG"`
29 + Size string `json:"Size"`
30 + Intf string `json:"Intf"`
31 + Med string `json:"Med"`
32 + SED string `json:"SED"`
33 + PI string `json:"PI"`
34 + SeSz string `json:"SeSz"`
35 + Model string `json:"Model"`
36 + Sp string `json:"Sp"`
37 + Type string `json:"Type"`
38 + }
39 + driveState struct {
40 + MediaErrorCount storNumber `json:"Media Error Count"`
41 + OtherErrorCount storNumber `json:"Other Error Count"`
42 + DriveTemperature string `json:"Drive Temperature"`
43 + PredictiveFailureCount storNumber `json:"Predictive Failure Count"`
44 + SmartAlertFlagged string `json:"S.M.A.R.T alert flagged by drive"`
45 + }
46 + driveAttrs struct {
47 + WWN string `json:"WWN"`
48 + DeviceSpeed string `json:"Device Speed"`
49 + LinkSpeed string `json:"Link Speed"`
50 + }
51 +)
52 +
53 +type storNumber string // some int values can be 'N/A'
54 +
55 +func (n *storNumber) UnmarshalJSON(b []byte) error { *n = storNumber(b); return nil }
56 +
57 +func (s *StorCli) collectMegaRaidDrives(mx map[string]int64, resp *drivesInfoResponse) error {
58 + for _, cntrl := range resp.Controllers {
59 + var ids []string
60 + for k := range cntrl.ResponseData {
61 + if !strings.HasSuffix(k, "Detailed Information") {
62 + continue
63 + }
64 + parts := strings.Fields(k) // Drive /c0/e252/s0 - Detailed Information
65 + if len(parts) < 2 {
66 + continue
67 + }
68 + id := parts[1]
69 + if strings.IndexByte(id, '/') == -1 {
70 + continue
71 + }
72 + ids = append(ids, id)
73 + }
74 +
75 + cntrlIdx := cntrl.CommandStatus.Controller
76 +
77 + for _, id := range ids {
78 + info, err := getDriveInfo(cntrl.ResponseData, id)
79 + if err != nil {
80 + return err
81 + }
82 + data, err := getDriveDetailedInfo(cntrl.ResponseData, id)
83 + if err != nil {
84 + return err
85 + }
86 + state, err := getDriveState(data, id)
87 + if err != nil {
88 + return err
89 + }
90 + attrs, err := getDriveAttrs(data, id)
91 + if err != nil {
92 + return err
93 + }
94 +
95 + if attrs.WWN == "" {
96 + continue
97 + }
98 +
99 + if !s.drives[attrs.WWN] {
100 + s.drives[attrs.WWN] = true
101 + s.addPhysDriveCharts(cntrlIdx, info, state, attrs)
102 + }
103 +
104 + px := fmt.Sprintf("phys_drive_%s_cntrl_%d_", attrs.WWN, cntrlIdx)
105 +
106 + if v, ok := parseInt(string(state.MediaErrorCount)); ok {
107 + mx[px+"media_error_count"] = v
108 + }
109 + if v, ok := parseInt(string(state.OtherErrorCount)); ok {
110 + mx[px+"other_error_count"] = v
111 + }
112 + if v, ok := parseInt(string(state.PredictiveFailureCount)); ok {
113 + mx[px+"predictive_failure_count"] = v
114 + }
115 + if v, ok := parseInt(getDriveTemperature(state.DriveTemperature)); ok {
116 + mx[px+"temperature"] = v
117 + }
118 + for _, st := range []string{"active", "inactive"} {
119 + mx[px+"smart_alert_status_"+st] = 0
120 + }
121 + if state.SmartAlertFlagged == "Yes" {
122 + mx[px+"smart_alert_status_active"] = 1
123 + }
124 + }
125 + }
126 +
127 + return nil
128 +}
129 +
130 +func (s *StorCli) queryDrivesInfo() (*drivesInfoResponse, error) {
131 + bs, err := s.exec.drivesInfo()
132 + if err != nil {
133 + return nil, err
134 + }
135 +
136 + if len(bs) == 0 {
137 + return nil, errors.New("empty response")
138 + }
139 +
140 + var resp drivesInfoResponse
141 + if err := json.Unmarshal(bs, &resp); err != nil {
142 + return nil, err
143 + }
144 +
145 + if len(resp.Controllers) == 0 {
146 + return nil, errors.New("no controllers found")
147 + }
148 + if st := resp.Controllers[0].CommandStatus.Status; st != "Success" {
149 + return nil, fmt.Errorf("command status error: %s", st)
150 + }
151 +
152 + return &resp, nil
153 +}
154 +
155 +func getDriveInfo(respData map[string]json.RawMessage, id string) (*driveInfo, error) {
156 + k := fmt.Sprintf("Drive %s", id)
157 + raw, ok := respData[k]
158 + if !ok {
159 + return nil, fmt.Errorf("drive info not found for '%s'", id)
160 + }
161 +
162 + var drive []driveInfo
163 + if err := json.Unmarshal(raw, &drive); err != nil {
164 + return nil, err
165 + }
166 +
167 + if len(drive) == 0 {
168 + return nil, fmt.Errorf("drive info not found for '%s'", id)
169 + }
170 +
171 + return &drive[0], nil
172 +}
173 +
174 +func getDriveDetailedInfo(respData map[string]json.RawMessage, id string) (map[string]json.RawMessage, error) {
175 + k := fmt.Sprintf("Drive %s - Detailed Information", id)
176 + raw, ok := respData[k]
177 + if !ok {
178 + return nil, fmt.Errorf("drive detailed info not found for '%s'", id)
179 + }
180 +
181 + var info map[string]json.RawMessage
182 + if err := json.Unmarshal(raw, &info); err != nil {
183 + return nil, err
184 + }
185 +
186 + return info, nil
187 +}
188 +
189 +func getDriveState(driveDetailedInfo map[string]json.RawMessage, id string) (*driveState, error) {
190 + k := fmt.Sprintf("Drive %s State", id)
191 + raw, ok := driveDetailedInfo[k]
192 + if !ok {
193 + return nil, fmt.Errorf("drive detailed info state not found for '%s'", id)
194 + }
195 +
196 + var state driveState
197 + if err := json.Unmarshal(raw, &state); err != nil {
198 + return nil, err
199 + }
200 +
201 + return &state, nil
202 +}
203 +
204 +func getDriveAttrs(driveDetailedInfo map[string]json.RawMessage, id string) (*driveAttrs, error) {
205 + k := fmt.Sprintf("Drive %s Device attributes", id)
206 + raw, ok := driveDetailedInfo[k]
207 + if !ok {
208 + return nil, fmt.Errorf("drive detailed info state not found for '%s'", id)
209 + }
210 +
211 + var state driveAttrs
212 + if err := json.Unmarshal(raw, &state); err != nil {
213 + return nil, err
214 + }
215 +
216 + return &state, nil
217 +}
218 +
219 +func getDriveTemperature(s string) string {
220 + // ' 28C (82.40 F)'
221 + i := strings.IndexByte(s, 'C')
222 + if i == -1 {
223 + return ""
224 + }
225 + return strings.TrimSpace(s[:i])
226 +}
227 +
228 +func parseInt(s string) (int64, bool) {
229 + i, err := strconv.ParseInt(s, 10, 64)
230 + return i, err == nil
231 +}
src/go/collectors/go.d.plugin/modules/storcli/config_schema.json new
+35
@@ -0,0 +1,35 @@
1 +{
2 + "jsonSchema": {
3 + "$schema": "http://json-schema.org/draft-07/schema#",
4 + "title": "StorCLI collector configuration.",
5 + "type": "object",
6 + "properties": {
7 + "update_every": {
8 + "title": "Update every",
9 + "description": "Data collection interval, measured in seconds.",
10 + "type": "integer",
11 + "minimum": 1,
12 + "default": 10
13 + },
14 + "timeout": {
15 + "title": "Timeout",
16 + "description": "Timeout for executing the binary, specified in seconds.",
17 + "type": "number",
18 + "minimum": 0.5,
19 + "default": 2
20 + }
21 + },
22 + "additionalProperties": false,
23 + "patternProperties": {
24 + "^name$": {}
25 + }
26 + },
27 + "uiSchema": {
28 + "uiOptions": {
29 + "fullPage": true
30 + },
31 + "timeout": {
32 + "ui:help": "Accepts decimals for precise control (e.g., type 1.5 for 1.5 seconds)."
33 + }
34 + }
35 +}
src/go/collectors/go.d.plugin/modules/storcli/exec.go new
+50
@@ -0,0 +1,50 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "context"
7 + "fmt"
8 + "os/exec"
9 + "time"
10 +
11 + "github.com/netdata/netdata/go/go.d.plugin/logger"
12 +)
13 +
14 +func newStorCliExec(ndsudoPath string, timeout time.Duration, log *logger.Logger) *storCliExec {
15 + return &storCliExec{
16 + Logger: log,
17 + ndsudoPath: ndsudoPath,
18 + timeout: timeout,
19 + }
20 +}
21 +
22 +type storCliExec struct {
23 + *logger.Logger
24 +
25 + ndsudoPath string
26 + timeout time.Duration
27 +}
28 +
29 +func (e *storCliExec) controllersInfo() ([]byte, error) {
30 + return e.execute("storcli-controllers-info")
31 +}
32 +
33 +func (e *storCliExec) drivesInfo() ([]byte, error) {
34 + return e.execute("storcli-drives-info")
35 +}
36 +
37 +func (e *storCliExec) execute(args ...string) ([]byte, error) {
38 + ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
39 + defer cancel()
40 +
41 + cmd := exec.CommandContext(ctx, e.ndsudoPath, args...)
42 + e.Debugf("executing '%s'", cmd)
43 +
44 + bs, err := cmd.Output()
45 + if err != nil {
46 + return nil, fmt.Errorf("error on '%s': %v", cmd, err)
47 + }
48 +
49 + return bs, nil
50 +}
src/go/collectors/go.d.plugin/modules/storcli/init.go new
+23
@@ -0,0 +1,23 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "fmt"
7 + "os"
8 + "path/filepath"
9 +
10 + "github.com/netdata/netdata/go/go.d.plugin/agent/executable"
11 +)
12 +
13 +func (s *StorCli) initStorCliExec() (storCli, error) {
14 + ndsudoPath := filepath.Join(executable.Directory, "ndsudo")
15 +
16 + if _, err := os.Stat(ndsudoPath); err != nil {
17 + return nil, fmt.Errorf("ndsudo executable not found: %v", err)
18 + }
19 +
20 + storExec := newStorCliExec(ndsudoPath, s.Timeout.Duration(), s.Logger)
21 +
22 + return storExec, nil
23 +}
src/go/collectors/go.d.plugin/modules/storcli/metadata.yaml new
+153
@@ -0,0 +1,153 @@
1 +plugin_name: go.d.plugin
2 +modules:
3 + - meta:
4 + id: collector-go.d.plugin-storcli
5 + plugin_name: go.d.plugin
6 + module_name: storcli
7 + monitored_instance:
8 + name: StoreCLI RAID
9 + link: "https://docs.broadcom.com/doc/12352476"
10 + icon_filename: "hard-drive.svg"
11 + categories:
12 + - data-collection.storage-mount-points-and-filesystems
13 + keywords:
14 + - storage
15 + - raid-controller
16 + - manage-disks
17 + related_resources:
18 + integrations:
19 + list: []
20 + info_provided_to_referring_integrations:
21 + description: ""
22 + most_popular: false
23 + overview:
24 + data_collection:
25 + metrics_description: |
26 + Monitors the health of StoreCLI Hardware RAID by tracking the status of RAID adapters, physical drives, and backup batteries in your storage system.
27 + It relies on the [`storcli`](https://docs.broadcom.com/doc/12352476) CLI tool but avoids directly executing the binary.
28 + Instead, it utilizes `ndsudo`, a Netdata helper specifically designed to run privileged commands securely within the Netdata environment.
29 + This approach eliminates the need to use `sudo`, improving security and potentially simplifying permission management.
30 +
31 + Executed commands:
32 + - `storcli /cALL show all J nolog`
33 + - `storcli /cALL/eALL/sALL show all J nolog`
34 + method_description: ""
35 + supported_platforms:
36 + include: []
37 + exclude: []
38 + multi_instance: false
39 + additional_permissions:
40 + description: ""
41 + default_behavior:
42 + auto_detection:
43 + description: ""
44 + limits:
45 + description: ""
46 + performance_impact:
47 + description: ""
48 + setup:
49 + prerequisites:
50 + list: []
51 + configuration:
52 + file:
53 + name: go.d/storcli.conf
54 + options:
55 + description: |
56 + The following options can be defined globally: update_every.
57 + folding:
58 + title: Config options
59 + enabled: true
60 + list:
61 + - name: update_every
62 + description: Data collection frequency.
63 + default_value: 10
64 + required: false
65 + - name: timeout
66 + description: storcli binary execution timeout.
67 + default_value: 2
68 + required: false
69 + examples:
70 + folding:
71 + title: Config
72 + enabled: true
73 + list:
74 + - name: Custom update_every
75 + description: Allows you to override the default data collection interval.
76 + config: |
77 + jobs:
78 + - name: storcli
79 + update_every: 5 # Collect StorCLI RAID statistics every 5 seconds
80 + troubleshooting:
81 + problems:
82 + list: []
83 + alerts: []
84 + metrics:
85 + folding:
86 + title: Metrics
87 + enabled: false
88 + description: ""
89 + availability: []
90 + scopes:
91 + - name: controller
92 + description: These metrics refer to the Controller.
93 + labels:
94 + - name: controller_number
95 + description: Controller number (index)
96 + - name: model
97 + description: Controller model
98 + metrics:
99 + - name: storcli.controller_status
100 + description: Controller status
101 + unit: status
102 + chart_type: line
103 + dimensions:
104 + - name: optimal
105 + - name: degraded
106 + - name: partially_degraded
107 + - name: failed
108 + - name: storcli.controller_bbu_status
109 + description: Controller BBU status
110 + unit: status
111 + chart_type: line
112 + dimensions:
113 + - name: healthy
114 + - name: unhealthy
115 + - name: na
116 + - name: physical drive
117 + description: These metrics refer to the Physical Drive.
118 + labels:
119 + - name: controller_number
120 + description: Controller number (index)
121 + - name: enclosure_number
122 + description: Enclosure number (index)
123 + - name: slot_number
124 + description: Slot number (index)
125 + - name: media type
126 + description: Media type (e.g. HDD)
127 + metrics:
128 + - name: storcli.phys_drive_errors
129 + description: Physical Drive media errors rate
130 + unit: errors/s
131 + chart_type: line
132 + dimensions:
133 + - name: media
134 + - name: other
135 + - name: storcli.phys_drive_predictive_failures
136 + description: Physical Drive predictive failures rate
137 + unit: failures/s
138 + chart_type: line
139 + dimensions:
140 + - name: predictive_failures
141 + - name: storcli.phys_drive_smart_alert_status
142 + description: Physical Drive SMART alert status
143 + unit: status
144 + chart_type: line
145 + dimensions:
146 + - name: active
147 + - name: inactive
148 + - name: storcli.phys_drive_temperature
149 + description: Physical Drive temperature
150 + unit: status
151 + chart_type: line
152 + dimensions:
153 + - name: temperature
src/go/collectors/go.d.plugin/modules/storcli/storcli.go new
+109
@@ -0,0 +1,109 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + _ "embed"
7 + "errors"
8 + "time"
9 +
10 + "github.com/netdata/netdata/go/go.d.plugin/agent/module"
11 + "github.com/netdata/netdata/go/go.d.plugin/pkg/web"
12 +)
13 +
14 +//go:embed "config_schema.json"
15 +var configSchema string
16 +
17 +func init() {
18 + module.Register("storcli", module.Creator{
19 + JobConfigSchema: configSchema,
20 + Defaults: module.Defaults{
21 + UpdateEvery: 10,
22 + },
23 + Create: func() module.Module { return New() },
24 + })
25 +}
26 +
27 +func New() *StorCli {
28 + return &StorCli{
29 + Config: Config{
30 + Timeout: web.Duration(time.Second * 2),
31 + },
32 + charts: &module.Charts{},
33 + controllers: make(map[string]bool),
34 + drives: make(map[string]bool),
35 + bbu: make(map[string]bool),
36 + }
37 +}
38 +
39 +type Config struct {
40 + UpdateEvery int `yaml:"update_every" json:"update_every"`
41 + Timeout web.Duration `yaml:"timeout" json:"timeout"`
42 +}
43 +
44 +type (
45 + StorCli struct {
46 + module.Base
47 + Config `yaml:",inline" json:""`
48 +
49 + charts *module.Charts
50 +
51 + exec storCli
52 +
53 + controllers map[string]bool
54 + drives map[string]bool
55 + bbu map[string]bool
56 + }
57 + storCli interface {
58 + controllersInfo() ([]byte, error)
59 + drivesInfo() ([]byte, error)
60 + }
61 +)
62 +
63 +func (s *StorCli) Configuration() any {
64 + return s.Config
65 +}
66 +
67 +func (s *StorCli) Init() error {
68 + storExec, err := s.initStorCliExec()
69 + if err != nil {
70 + s.Errorf("storcli exec initialization: %v", err)
71 + return err
72 + }
73 + s.exec = storExec
74 +
75 + return nil
76 +}
77 +
78 +func (s *StorCli) Check() error {
79 + mx, err := s.collect()
80 + if err != nil {
81 + s.Error(err)
82 + return err
83 + }
84 +
85 + if len(mx) == 0 {
86 + return errors.New("no metrics collected")
87 + }
88 +
89 + return nil
90 +}
91 +
92 +func (s *StorCli) Charts() *module.Charts {
93 + return s.charts
94 +}
95 +
96 +func (s *StorCli) Collect() map[string]int64 {
97 + mx, err := s.collect()
98 + if err != nil {
99 + s.Error(err)
100 + }
101 +
102 + if len(mx) == 0 {
103 + return nil
104 + }
105 +
106 + return mx
107 +}
108 +
109 +func (s *StorCli) Cleanup() {}
src/go/collectors/go.d.plugin/modules/storcli/storcli_test.go new
+289
@@ -0,0 +1,289 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +package storcli
4 +
5 +import (
6 + "errors"
7 + "os"
8 + "testing"
9 +
10 + "github.com/netdata/netdata/go/go.d.plugin/agent/module"
11 +
12 + "github.com/stretchr/testify/assert"
13 + "github.com/stretchr/testify/require"
14 +)
15 +
16 +var (
17 + dataConfigJSON, _ = os.ReadFile("testdata/config.json")
18 + dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
19 +
20 + dataMegaControllerInfo, _ = os.ReadFile("testdata/megaraid-controllers-info.json")
21 + dataMegaDrivesInfo, _ = os.ReadFile("testdata/megaraid-drives-info.json")
22 +)
23 +
24 +func Test_testDataIsValid(t *testing.T) {
25 + for name, data := range map[string][]byte{
26 + "dataConfigJSON": dataConfigJSON,
27 + "dataConfigYAML": dataConfigYAML,
28 +
29 + "dataMegaControllerInfo": dataMegaControllerInfo,
30 + "dataMegaDrivesInfo": dataMegaDrivesInfo,
31 + } {
32 + require.NotNil(t, data, name)
33 + }
34 +}
35 +
36 +func TestStorCli_ConfigurationSerialize(t *testing.T) {
37 + module.TestConfigurationSerialize(t, &StorCli{}, dataConfigJSON, dataConfigYAML)
38 +}
39 +
40 +func TestStorCli_Init(t *testing.T) {
41 + tests := map[string]struct {
42 + config Config
43 + wantFail bool
44 + }{
45 + "fails if 'ndsudo' not found": {
46 + wantFail: true,
47 + config: New().Config,
48 + },
49 + }
50 +
51 + for name, test := range tests {
52 + t.Run(name, func(t *testing.T) {
53 + stor := New()
54 +
55 + if test.wantFail {
56 + assert.Error(t, stor.Init())
57 + } else {
58 + assert.NoError(t, stor.Init())
59 + }
60 + })
61 + }
62 +}
63 +
64 +func TestStorCli_Cleanup(t *testing.T) {
65 + tests := map[string]struct {
66 + prepare func() *StorCli
67 + }{
68 + "not initialized exec": {
69 + prepare: func() *StorCli {
70 + return New()
71 + },
72 + },
73 + "after check": {
74 + prepare: func() *StorCli {
75 + stor := New()
76 + stor.exec = prepareMockMegaRaidOK()
77 + _ = stor.Check()
78 + return stor
79 + },
80 + },
81 + "after collect": {
82 + prepare: func() *StorCli {
83 + stor := New()
84 + stor.exec = prepareMockMegaRaidOK()
85 + _ = stor.Collect()
86 + return stor
87 + },
88 + },
89 + }
90 +
91 + for name, test := range tests {
92 + t.Run(name, func(t *testing.T) {
93 + stor := test.prepare()
94 +
95 + assert.NotPanics(t, stor.Cleanup)
96 + })
97 + }
98 +}
99 +
100 +func TestStorCli_Charts(t *testing.T) {
101 + assert.NotNil(t, New().Charts())
102 +}
103 +
104 +func TestStorCli_Check(t *testing.T) {
105 + tests := map[string]struct {
106 + prepareMock func() *mockStorCliExec
107 + wantFail bool
108 + }{
109 + "success MegaRAID controller": {
110 + wantFail: false,
111 + prepareMock: prepareMockMegaRaidOK,
112 + },
113 + "err on exec": {
114 + wantFail: true,
115 + prepareMock: prepareMockErr,
116 + },
117 + "unexpected response": {
118 + wantFail: true,
119 + prepareMock: prepareMockUnexpectedResponse,
120 + },
121 + "empty response": {
122 + wantFail: true,
123 + prepareMock: prepareMockEmptyResponse,
124 + },
125 + }
126 +
127 + for name, test := range tests {
128 + t.Run(name, func(t *testing.T) {
129 + stor := New()
130 + mock := test.prepareMock()
131 + stor.exec = mock
132 +
133 + if test.wantFail {
134 + assert.Error(t, stor.Check())
135 + } else {
136 + assert.NoError(t, stor.Check())
137 + }
138 + })
139 + }
140 +}
141 +
142 +func TestStorCli_Collect(t *testing.T) {
143 + tests := map[string]struct {
144 + prepareMock func() *mockStorCliExec
145 + wantMetrics map[string]int64
146 + wantCharts int
147 + }{
148 + "success MegaRAID controller": {
149 + prepareMock: prepareMockMegaRaidOK,
150 + wantCharts: len(controllerChartsTmpl)*1 + len(physDriveChartsTmpl)*6,
151 + wantMetrics: map[string]int64{
152 + "cntrl_0_bbu_status_healthy": 1,
153 + "cntrl_0_bbu_status_na": 0,
154 + "cntrl_0_bbu_status_unhealthy": 0,
155 + "cntrl_0_status_degraded": 0,
156 + "cntrl_0_status_failed": 0,
157 + "cntrl_0_status_optimal": 1,
158 + "cntrl_0_status_partially_degraded": 0,
159 + "phys_drive_5000C500C36C8BCD_cntrl_0_media_error_count": 0,
160 + "phys_drive_5000C500C36C8BCD_cntrl_0_other_error_count": 0,
161 + "phys_drive_5000C500C36C8BCD_cntrl_0_predictive_failure_count": 0,
162 + "phys_drive_5000C500C36C8BCD_cntrl_0_smart_alert_status_active": 0,
163 + "phys_drive_5000C500C36C8BCD_cntrl_0_smart_alert_status_inactive": 0,
164 + "phys_drive_5000C500C36C8BCD_cntrl_0_temperature": 28,
165 + "phys_drive_5000C500D59840FE_cntrl_0_media_error_count": 0,
166 + "phys_drive_5000C500D59840FE_cntrl_0_other_error_count": 0,
167 + "phys_drive_5000C500D59840FE_cntrl_0_predictive_failure_count": 0,
168 + "phys_drive_5000C500D59840FE_cntrl_0_smart_alert_status_active": 0,
169 + "phys_drive_5000C500D59840FE_cntrl_0_smart_alert_status_inactive": 0,
170 + "phys_drive_5000C500D59840FE_cntrl_0_temperature": 28,
171 + "phys_drive_5000C500D6061539_cntrl_0_media_error_count": 0,
172 + "phys_drive_5000C500D6061539_cntrl_0_other_error_count": 0,
173 + "phys_drive_5000C500D6061539_cntrl_0_predictive_failure_count": 0,
174 + "phys_drive_5000C500D6061539_cntrl_0_smart_alert_status_active": 0,
175 + "phys_drive_5000C500D6061539_cntrl_0_smart_alert_status_inactive": 0,
176 + "phys_drive_5000C500D6061539_cntrl_0_temperature": 28,
177 + "phys_drive_5000C500DC79B194_cntrl_0_media_error_count": 0,
178 + "phys_drive_5000C500DC79B194_cntrl_0_other_error_count": 0,
179 + "phys_drive_5000C500DC79B194_cntrl_0_predictive_failure_count": 0,
180 + "phys_drive_5000C500DC79B194_cntrl_0_smart_alert_status_active": 0,
181 + "phys_drive_5000C500DC79B194_cntrl_0_smart_alert_status_inactive": 0,
182 + "phys_drive_5000C500DC79B194_cntrl_0_temperature": 28,
183 + "phys_drive_5000C500E54F4EBB_cntrl_0_media_error_count": 0,
184 + "phys_drive_5000C500E54F4EBB_cntrl_0_other_error_count": 0,
185 + "phys_drive_5000C500E54F4EBB_cntrl_0_predictive_failure_count": 0,
186 + "phys_drive_5000C500E54F4EBB_cntrl_0_smart_alert_status_active": 0,
187 + "phys_drive_5000C500E54F4EBB_cntrl_0_smart_alert_status_inactive": 0,
188 + "phys_drive_5000C500E54F4EBB_cntrl_0_temperature": 28,
189 + "phys_drive_5000C500E5659BA7_cntrl_0_media_error_count": 0,
190 + "phys_drive_5000C500E5659BA7_cntrl_0_other_error_count": 0,
191 + "phys_drive_5000C500E5659BA7_cntrl_0_predictive_failure_count": 0,
192 + "phys_drive_5000C500E5659BA7_cntrl_0_smart_alert_status_active": 0,
193 + "phys_drive_5000C500E5659BA7_cntrl_0_smart_alert_status_inactive": 0,
194 + "phys_drive_5000C500E5659BA7_cntrl_0_temperature": 27,
195 + },
196 + },
197 + "err on exec": {
198 + prepareMock: prepareMockErr,
199 + wantMetrics: nil,
200 + },
201 + "unexpected response": {
202 + prepareMock: prepareMockUnexpectedResponse,
203 + wantMetrics: nil,
204 + },
205 + "empty response": {
206 + prepareMock: prepareMockEmptyResponse,
207 + wantMetrics: nil,
208 + },
209 + }
210 +
211 + for name, test := range tests {
212 + t.Run(name, func(t *testing.T) {
213 + stor := New()
214 + mock := test.prepareMock()
215 + stor.exec = mock
216 +
217 + mx := stor.Collect()
218 +
219 + assert.Equal(t, test.wantMetrics, mx)
220 + assert.Len(t, *stor.Charts(), test.wantCharts)
221 + testMetricsHasAllChartsDims(t, stor, mx)
222 + })
223 + }
224 +}
225 +
226 +func prepareMockMegaRaidOK() *mockStorCliExec {
227 + return &mockStorCliExec{
228 + controllersInfoData: dataMegaControllerInfo,
229 + drivesInfoData: dataMegaDrivesInfo,
230 + }
231 +}
232 +
233 +func prepareMockErr() *mockStorCliExec {
234 + return &mockStorCliExec{
235 + errOnInfo: true,
236 + }
237 +}
238 +
239 +func prepareMockUnexpectedResponse() *mockStorCliExec {
240 + resp := []byte(`
241 +Lorem ipsum dolor sit amet, consectetur adipiscing elit.
242 +Nulla malesuada erat id magna mattis, eu viverra tellus rhoncus.
243 +Fusce et felis pulvinar, posuere sem non, porttitor eros.
244 +`)
245 + return &mockStorCliExec{
246 + controllersInfoData: resp,
247 + drivesInfoData: resp,
248 + }
249 +}
250 +
251 +func prepareMockEmptyResponse() *mockStorCliExec {
252 + return &mockStorCliExec{}
253 +}
254 +
255 +type mockStorCliExec struct {
256 + errOnInfo bool
257 + controllersInfoData []byte
258 + drivesInfoData []byte
259 +}
260 +
261 +func (m *mockStorCliExec) controllersInfo() ([]byte, error) {
262 + if m.errOnInfo {
263 + return nil, errors.New("mock.controllerInfo() error")
264 + }
265 + return m.controllersInfoData, nil
266 +}
267 +
268 +func (m *mockStorCliExec) drivesInfo() ([]byte, error) {
269 + if m.errOnInfo {
270 + return nil, errors.New("mock.drivesInfo() error")
271 + }
272 + return m.drivesInfoData, nil
273 +}
274 +
275 +func testMetricsHasAllChartsDims(t *testing.T, stor *StorCli, mx map[string]int64) {
276 + for _, chart := range *stor.Charts() {
277 + if chart.Obsolete {
278 + continue
279 + }
280 + for _, dim := range chart.Dims {
281 + _, ok := mx[dim.ID]
282 + assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID)
283 + }
284 + for _, v := range chart.Vars {
285 + _, ok := mx[v.ID]
286 + assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID)
287 + }
288 + }
289 +}
src/go/collectors/go.d.plugin/modules/storcli/testdata/config.json new
+4
@@ -0,0 +1,4 @@
1 +{
2 + "update_every": 123,
3 + "timeout": 123.123
4 +}
src/go/collectors/go.d.plugin/modules/storcli/testdata/config.yaml new
+2
@@ -0,0 +1,2 @@
1 +update_every: 123
2 +timeout: 123.123
src/go/collectors/go.d.plugin/modules/storcli/testdata/megaraid-controllers-info.json new
+687
@@ -0,0 +1,687 @@
1 +{
2 + "Controllers": [
3 + {
4 + "Command Status": {
5 + "CLI Version": "007.2807.0000.0000 Dec 22, 2023",
6 + "Operating system": "Linux 6.5.13-1-pve",
7 + "Controller": 0,
8 + "Status": "Success",
9 + "Description": "None"
10 + },
11 + "Response Data": {
12 + "Basics": {
13 + "Controller": 0,
14 + "Model": "ServeRAID M5015 SAS/SATA Controller",
15 + "Serial Number": "SV04616189",
16 + "Current Controller Date/Time": "04/17/2024, 18:28:30",
17 + "Current System Date/time": "04/17/2024, 18:30:05",
18 + "SAS Address": "500605b002e04f10",
19 + "PCI Address": "00:0a:00:00",
20 + "Mfg Date": "11/11/10",
21 + "Rework Date": "00/00/00",
22 + "Revision No": ""
23 + },
24 + "Version": {
25 + "Firmware Package Build": "12.15.0-0239",
26 + "Firmware Version": "2.130.403-4660",
27 + "Bios Version": "3.30.02.2_4.16.08.00_0x06060A05",
28 + "Preboot CLI Version": "04.04-020:#%00009",
29 + "WebBIOS Version": "6.0-54-e_50-Rel",
30 + "NVDATA Version": "2.09.03-0058",
31 + "Boot Block Version": "2.02.00.00-0000",
32 + "Bootloader Version": "09.250.01.219",
33 + "Driver Name": "megaraid_sas",
34 + "Driver Version": "07.725.01.00-rc1"
35 + },
36 + "Bus": {
37 + "Vendor Id": 4096,
38 + "Device Id": 121,
39 + "SubVendor Id": 4116,
40 + "SubDevice Id": 946,
41 + "Host Interface": "PCI-E",
42 + "Device Interface": "SAS-6G",
43 + "Bus Number": 10,
44 + "Device Number": 0,
45 + "Function Number": 0,
46 + "Domain ID": 0
47 + },
48 + "Pending Images in Flash": {
49 + "Image name": "No pending images"
50 + },
51 + "Status": {
52 + "Controller Status": "Optimal",
53 + "Memory Correctable Errors": 0,
54 + "Memory Uncorrectable Errors": 0,
55 + "ECC Bucket Count": 0,
56 + "Any Offline VD Cache Preserved": "No",
57 + "BBU Status": 0,
58 + "PD Firmware Download in progress": "No",
59 + "Support PD Firmware Download": "Yes",
60 + "Lock Key Assigned": "No",
61 + "Failed to get lock key on bootup": "No",
62 + "Lock key has not been backed up": "No",
63 + "Bios was not detected during boot": "No",
64 + "Controller must be rebooted to complete security operation": "No",
65 + "A rollback operation is in progress": "No",
66 + "At least one PFK exists in NVRAM": "No",
67 + "SSC Policy is WB": "No",
68 + "Controller has booted into safe mode": "No",
69 + "Controller shutdown required": "No",
70 + "Controller has booted into certificate provision mode": "No"
71 + },
72 + "Supported Adapter Operations": {
73 + "Rebuild Rate": "Yes",
74 + "CC Rate": "Yes",
75 + "BGI Rate ": "Yes",
76 + "Reconstruct Rate": "Yes",
77 + "Patrol Read Rate": "Yes",
78 + "Alarm Control": "Yes",
79 + "Cluster Support": "No",
80 + "BBU": "Yes",
81 + "Spanning": "Yes",
82 + "Dedicated Hot Spare": "Yes",
83 + "Revertible Hot Spares": "Yes",
84 + "Foreign Config Import": "Yes",
85 + "Self Diagnostic": "Yes",
86 + "Allow Mixed Redundancy on Array": "No",
87 + "Global Hot Spares": "Yes",
88 + "Deny SCSI Passthrough": "No",
89 + "Deny SMP Passthrough": "No",
90 + "Deny STP Passthrough": "No",
91 + "Support more than 8 Phys": "Yes",
92 + "FW and Event Time in GMT": "No",
93 + "Support Enhanced Foreign Import": "Yes",
94 + "Support Enclosure Enumeration": "Yes",
95 + "Support Allowed Operations": "Yes",
96 + "Abort CC on Error": "Yes",
97 + "Support Multipath": "Yes",
98 + "Support Odd & Even Drive count in RAID1E": "No",
99 + "Support Security": "Yes",
100 + "Support Config Page Model": "Yes",
101 + "Support the OCE without adding drives": "Yes",
102 + "Support EKM": "Yes",
103 + "Snapshot Enabled": "Yes",
104 + "Support PFK": "No",
105 + "Support PI": "No",
106 + "Support Ld BBM Info": "No",
107 + "Support Shield State": "No",
108 + "Block SSD Write Disk Cache Change": "No",
109 + "Support Suspend Resume BG ops": "No",
110 + "Support Emergency Spares": "Yes",
111 + "Support Set Link Speed": "No",
112 + "Support Boot Time PFK Change": "No",
113 + "Support JBOD": "No",
114 + "Disable Online PFK Change": "No",
115 + "Support Perf Tuning": "No",
116 + "Support SSD PatrolRead": "Yes",
117 + "Real Time Scheduler": "Yes",
118 + "Support Reset Now": "Yes",
119 + "Support Emulated Drives": "No",
120 + "Headless Mode": "Yes",
121 + "Dedicated HotSpares Limited": "No",
122 + "Point In Time Progress": "No",
123 + "Extended LD": "No",
124 + "Support Uneven span ": "No",
125 + "Support Config Auto Balance": "No",
126 + "Support Maintenance Mode": "No",
127 + "Support Diagnostic results": "No",
128 + "Support Ext Enclosure": "No",
129 + "Support Sesmonitoring": "No",
130 + "Support SecurityonJBOD": "No",
131 + "Support ForceFlash": "No",
132 + "Support DisableImmediateIO": "Yes",
133 + "Support LargeIOSupport": "No",
134 + "Support DrvActivityLEDSetting": "Yes",
135 + "Support FlushWriteVerify": "No",
136 + "Support CPLDUpdate": "No",
137 + "Support ForceTo512e": "No",
138 + "Support discardCacheDuringLDDelete": "No",
139 + "Support JBOD Write cache": "No",
140 + "Support Large QD Support": "No",
141 + "Support Ctrl Info Extended": "No",
142 + "Support IButton less": "No",
143 + "Support AES Encryption Algorithm": "No",
144 + "Support Encrypted MFC": "No",
145 + "Support Snapdump": "No",
146 + "Support Force Personality Change": "No",
147 + "Support Dual Fw Image": "No",
148 + "Support PSOC Update": "No",
149 + "Support Secure Boot": "No",
150 + "Support Debug Queue": "No",
151 + "Support Least Latency Mode": "Yes",
152 + "Support OnDemand Snapdump": "No",
153 + "Support Clear Snapdump": "No",
154 + "Support PHY current speed": "No",
155 + "Support Lane current speed": "No",
156 + "Support NVMe Width": "No",
157 + "Support Lane DeviceType": "No",
158 + "Support Extended Drive performance Monitoring": "No",
159 + "Support NVMe Repair": "No",
160 + "Support Platform Security": "No",
161 + "Support None Mode Params": "No",
162 + "Support Extended Controller Property": "No",
163 + "Support Smart Poll Interval for DirectAttached": "No",
164 + "Support Write Journal Pinning": "No",
165 + "Support SMP Passthru with Port Number": "No",
166 + "Support SnapDump Preboot Trace Buffer Toggle": "No",
167 + "Support Parity Read Cache Bypass": "No",
168 + "Support NVMe Init Error Device ConnectorIndex": "No",
169 + "Support VolatileKey": "No",
170 + "Support PSOC Part Information": "No",
171 + "Support Slow array threshold calculation": "No",
172 + "Support PCIe Reference Clock override": "No",
173 + "Support PCIe PERST override": "No",
174 + "Support Drive FW Download Mask": "No",
175 + "Support Start of day PL log capture": "No",
176 + "Support Drive Unrecovered Medium Error Count": "No"
177 + },
178 + "Enterprise Key management": {
179 + "Capability": "Supported",
180 + "Boot Agent": "Not Available",
181 + "Configured": "No"
182 + },
183 + "Supported PD Operations": {
184 + "Force Online": "Yes",
185 + "Force Offline": "Yes",
186 + "Force Rebuild": "Yes",
187 + "Deny Force Failed": "No",
188 + "Deny Force Good/Bad": "No",
189 + "Deny Missing Replace": "No",
190 + "Deny Clear": "No",
191 + "Deny Locate": "No",
192 + "Support Power State": "No",
193 + "Set Power State For Cfg": "No",
194 + "Support T10 Power State": "No",
195 + "Support Temperature": "Yes",
196 + "NCQ": "No",
197 + "Support Max Rate SATA": "No",
198 + "Support Degraded Media": "No",
199 + "Support Parallel FW Update": "No",
200 + "Support Drive Crypto Erase": "No",
201 + "Support SSD Wear Gauge": "No",
202 + "Support Sanitize": "No",
203 + "Support Extended Sanitize": "No"
204 + },
205 + "Supported VD Operations": {
206 + "Read Policy": "Yes",
207 + "Write Policy": "Yes",
208 + "IO Policy": "Yes",
209 + "Access Policy": "Yes",
210 + "Disk Cache Policy": "Yes",
211 + "Reconstruction": "Yes",
212 + "Deny Locate": "No",
213 + "Deny CC": "No",
214 + "Allow Ctrl Encryption": "No",
215 + "Enable LDBBM": "No",
216 + "Support FastPath": "Yes",
217 + "Performance Metrics": "Yes",
218 + "Power Savings": "No",
219 + "Support Powersave Max With Cache": "No",
220 + "Support Breakmirror": "No",
221 + "Support SSC WriteBack": "Yes",
222 + "Support SSC Association": "Yes",
223 + "Support VD Hide": "No",
224 + "Support VD Cachebypass": "No",
225 + "Support VD discardCacheDuringLDDelete": "No",
226 + "Support VD Scsi Unmap": "No"
227 + },
228 + "HwCfg": {
229 + "ChipRevision": " B2",
230 + "BatteryFRU": "N/A",
231 + "Front End Port Count": 0,
232 + "Backend Port Count": 8,
233 + "BBU": "Present",
234 + "Alarm": "Disable",
235 + "Serial Debugger": "Present",
236 + "NVRAM Size": "32KB",
237 + "Flash Size": "8MB",
238 + "On Board Memory Size": "512MB",
239 + "CacheVault Flash Size": "NA",
240 + "TPM": "Absent",
241 + "Upgrade Key": "Present",
242 + "On Board Expander": "Absent",
243 + "Temperature Sensor for ROC": "Absent",
244 + "Temperature Sensor for Controller": "Absent",
245 + "Upgradable CPLD": "Absent",
246 + "Upgradable PSOC": "Absent",
247 + "Current Size of CacheCade (GB)": 0,
248 + "Current Size of FW Cache (MB)": 349
249 + },
250 + "Policies": {
251 + "Policies Table": [
252 + {
253 + "Policy": "Predictive Fail Poll Interval",
254 + "Current": "300 sec",
255 + "Default": ""
256 + },
257 + {
258 + "Policy": "Interrupt Throttle Active Count",
259 + "Current": "16",
260 + "Default": ""
261 + },
262 + {
263 + "Policy": "Interrupt Throttle Completion",
264 + "Current": "50 us",
265 + "Default": ""
266 + },
267 + {
268 + "Policy": "Rebuild Rate",
269 + "Current": "30 %",
270 + "Default": "30%"
271 + },
272 + {
273 + "Policy": "PR Rate",
274 + "Current": "30 %",
275 + "Default": "30%"
276 + },
277 + {
278 + "Policy": "BGI Rate",
279 + "Current": "30 %",
280 + "Default": "30%"
281 + },
282 + {
283 + "Policy": "Check Consistency Rate",
284 + "Current": "30 %",
285 + "Default": "30%"
286 + },
287 + {
288 + "Policy": "Reconstruction Rate",
289 + "Current": "30 %",
290 + "Default": "30%"
291 + },
292 + {
293 + "Policy": "Cache Flush Interval",
294 + "Current": "4s",
295 + "Default": ""
296 + }
297 + ],
298 + "Flush Time(Default)": "4s",
299 + "Drive Coercion Mode": "1GB",
300 + "Auto Rebuild": "On",
301 + "Battery Warning": "On",
302 + "ECC Bucket Size": 15,
303 + "ECC Bucket Leak Rate (hrs)": 24,
304 + "Restore Hot Spare on Insertion": "Off",
305 + "Expose Enclosure Devices": "On",
306 + "Maintain PD Fail History": "On",
307 + "Reorder Host Requests": "On",
308 + "Auto detect BackPlane": "SGPIO/i2c SEP",
309 + "Load Balance Mode": "Auto",
310 + "Security Key Assigned": "Off",
311 + "Disable Online Controller Reset": "Off",
312 + "Use drive activity for locate": "Off"
313 + },
314 + "Boot": {
315 + "BIOS Enumerate VDs": 1,
316 + "Stop BIOS on Error": "On",
317 + "Delay during POST": 4,
318 + "Spin Down Mode": "None",
319 + "Enable Ctrl-R": "No",
320 + "Enable Web BIOS": "Yes",
321 + "Enable PreBoot CLI": "Yes",
322 + "Enable BIOS": "Yes",
323 + "Max Drives to Spinup at One Time": 4,
324 + "Maximum number of direct attached drives to spin up in 1 min": 20,
325 + "Delay Among Spinup Groups (sec)": 12,
326 + "Allow Boot with Preserved Cache": "Off"
327 + },
328 + "High Availability": {
329 + "Topology Type": "None",
330 + "Cluster Permitted": "No",
331 + "Cluster Active": "No"
332 + },
333 + "Defaults": {
334 + "Phy Polarity": 0,
335 + "Phy PolaritySplit": 0,
336 + "Strip Size": "128 KB",
337 + "Write Policy": "WB",
338 + "Read Policy": "No Read Ahead",
339 + "Cache When BBU Bad": "Off",
340 + "Cached IO": "Off",
341 + "VD PowerSave Policy": "Controller Defined",
342 + "Default spin down time (mins)": 30,
343 + "Coercion Mode": "1 GB",
344 + "ZCR Config": "Unknown",
345 + "Max Chained Enclosures": 16,
346 + "Direct PD Mapping": "No",
347 + "Restore Hot Spare on Insertion": "No",
348 + "Expose Enclosure Devices": "Yes",
349 + "Maintain PD Fail History": "Yes",
350 + "Zero Based Enclosure Enumeration": "No",
351 + "Disable Puncturing": "Yes",
352 + "EnableLDBBM": "No",
353 + "DisableHII": "No",
354 + "Un-Certified Hard Disk Drives": "Allow",
355 + "SMART Mode": "Mode 6",
356 + "Enable LED Header": "No",
357 + "LED Show Drive Activity": "No",
358 + "Dirty LED Shows Drive Activity": "No",
359 + "EnableCrashDump": "No",
360 + "Disable Online Controller Reset": "No",
361 + "Treat Single span R1E as R10": "No",
362 + "Power Saving option": "Enabled",
363 + "TTY Log In Flash": "No",
364 + "Auto Enhanced Import": "No",
365 + "BreakMirror RAID Support": "No",
366 + "Disable Join Mirror": "No",
367 + "Enable Shield State": "No",
368 + "Time taken to detect CME": "60 sec"
369 + },
370 + "Capabilities": {
371 + "Supported Drives": "SAS, SATA",
372 + "RAID Level Supported": "RAID0, RAID1(2 or more drives), RAID5, RAID6, RAID00, RAID10(2 or more drives per span), RAID50, RAID60",
373 + "Enable JBOD": "No",
374 + "Mix in Enclosure": "Allowed",
375 + "Mix of SAS/SATA of HDD type in VD": "Not Allowed",
376 + "Mix of SAS/SATA of SSD type in VD": "Not Allowed",
377 + "Mix of SSD/HDD in VD": "Not Allowed",
378 + "SAS Disable": "No",
379 + "Max Arms Per VD": 32,
380 + "Max Spans Per VD": 8,
381 + "Max Arrays": 128,
382 + "Max VD per array": 16,
383 + "Max Number of VDs": 64,
384 + "Max Parallel Commands": 1008,
385 + "Max SGE Count": 60,
386 + "Max Data Transfer Size": "8192 sectors",
387 + "Max Strips PerIO": 42,
388 + "Max Configurable CacheCade Size(GB)": 512,
389 + "Max Transportable DGs": 0,
390 + "Enable Snapdump": "No",
391 + "Enable SCSI Unmap": "Yes",
392 + "Read cache bypass enabled for Parity RAID LDs": "No",
393 + "FDE Drive Mix Support": "No",
394 + "Min Strip Size": "8 KB",
395 + "Max Strip Size": "1.000 MB"
396 + },
397 + "Scheduled Tasks": {
398 + "Consistency Check Reoccurrence": "168 hrs",
399 + "Next Consistency check launch": "04/20/2024, 03:00:00",
400 + "Patrol Read Reoccurrence": "168 hrs",
401 + "Next Patrol Read launch": "04/20/2024, 03:00:00",
402 + "Battery learn Reoccurrence": "672 hrs",
403 + "Next Battery Learn": "04/18/2024, 18:32:56",
404 + "OEMID": "Lenovo"
405 + },
406 + "Security Protocol properties": {
407 + "Security Protocol": "None"
408 + },
409 + "Drive Groups": 1,
410 + "TOPOLOGY": [
411 + {
412 + "DG": 0,
413 + "Arr": "-",
414 + "Row": "-",
415 + "EID:Slot": "-",
416 + "DID": "-",
417 + "Type": "RAID6",
418 + "State": "Optl",
419 + "BT": "N",
420 + "Size": "58.207 TB",
421 + "PDC": "dsbl",
422 + "PI": "N",
423 + "SED": "N",
424 + "DS3": "none",
425 + "FSpace": "N",
426 + "TR": "N"
427 + },
428 + {
429 + "DG": 0,
430 + "Arr": 0,
431 + "Row": "-",
432 + "EID:Slot": "-",
433 + "DID": "-",
434 + "Type": "RAID6",
435 + "State": "Optl",
436 + "BT": "N",
437 + "Size": "58.207 TB",
438 + "PDC": "dsbl",
439 + "PI": "N",
440 + "SED": "N",
441 + "DS3": "none",
442 + "FSpace": "N",
443 + "TR": "N"
444 + },
445 + {
446 + "DG": 0,
447 + "Arr": 0,
448 + "Row": 0,
449 + "EID:Slot": "252:3",
450 + "DID": 35,
451 + "Type": "DRIVE",
452 + "State": "Onln",
453 + "BT": "N",
454 + "Size": "14.551 TB",
455 + "PDC": "dsbl",
456 + "PI": "N",
457 + "SED": "N",
458 + "DS3": "none",
459 + "FSpace": "-",
460 + "TR": "N"
461 + },
462 + {
463 + "DG": 0,
464 + "Arr": 0,
465 + "Row": 1,
466 + "EID:Slot": "252:5",
467 + "DID": 31,
468 + "Type": "DRIVE",
469 + "State": "Onln",
470 + "BT": "N",
471 + "Size": "14.551 TB",
472 + "PDC": "dsbl",
473 + "PI": "N",
474 + "SED": "N",
475 + "DS3": "none",
476 + "FSpace": "-",
477 + "TR": "N"
478 + },
479 + {
480 + "DG": 0,
481 + "Arr": 0,
482 + "Row": 2,
483 + "EID:Slot": "252:4",
484 + "DID": 30,
485 + "Type": "DRIVE",
486 + "State": "Onln",
487 + "BT": "N",
488 + "Size": "14.551 TB",
489 + "PDC": "dsbl",
490 + "PI": "N",
491 + "SED": "N",
492 + "DS3": "none",
493 + "FSpace": "-",
494 + "TR": "N"
495 + },
496 + {
497 + "DG": 0,
498 + "Arr": 0,
499 + "Row": 3,
500 + "EID:Slot": "252:7",
501 + "DID": 32,
502 + "Type": "DRIVE",
503 + "State": "Onln",
504 + "BT": "N",
505 + "Size": "14.551 TB",
506 + "PDC": "dsbl",
507 + "PI": "N",
508 + "SED": "N",
509 + "DS3": "none",
510 + "FSpace": "-",
511 + "TR": "N"
512 + },
513 + {
514 + "DG": 0,
515 + "Arr": 0,
516 + "Row": 4,
517 + "EID:Slot": "252:0",
518 + "DID": 34,
519 + "Type": "DRIVE",
520 + "State": "Onln",
521 + "BT": "N",
522 + "Size": "14.551 TB",
523 + "PDC": "dsbl",
524 + "PI": "N",
525 + "SED": "N",
526 + "DS3": "none",
527 + "FSpace": "-",
528 + "TR": "N"
529 + },
530 + {
531 + "DG": 0,
532 + "Arr": 0,
533 + "Row": 5,
534 + "EID:Slot": "252:1",
535 + "DID": 33,
536 + "Type": "DRIVE",
537 + "State": "Onln",
538 + "BT": "N",
539 + "Size": "14.551 TB",
540 + "PDC": "dsbl",
541 + "PI": "N",
542 + "SED": "N",
543 + "DS3": "none",
544 + "FSpace": "-",
545 + "TR": "N"
546 + }
547 + ],
548 + "Virtual Drives": 1,
549 + "VD LIST": [
550 + {
551 + "DG/VD": "0/0",
552 + "TYPE": "RAID6",
553 + "State": "Optl",
554 + "Access": "RW",
555 + "Consist": "Yes",
556 + "Cache": "RWBD",
557 + "Cac": "-",
558 + "sCC": "ON",
559 + "Size": "58.207 TB",
560 + "Name": "Sluthub"
561 + }
562 + ],
563 + "Physical Drives": 6,
564 + "PD LIST": [
565 + {
566 + "EID:Slt": "252:0",
567 + "DID": 34,
568 + "State": "Onln",
569 + "DG": 0,
570 + "Size": "14.551 TB",
571 + "Intf": "SATA",
572 + "Med": "HDD",
573 + "SED": "N",
574 + "PI": "N",
575 + "SeSz": "512B",
576 + "Model": "ST16000NM001G-2KK103",
577 + "Sp": "U",
578 + "Type": "-"
579 + },
580 + {
581 + "EID:Slt": "252:1",
582 + "DID": 33,
583 + "State": "Onln",
584 + "DG": 0,
585 + "Size": "14.551 TB",
586 + "Intf": "SATA",
587 + "Med": "HDD",
588 + "SED": "N",
589 + "PI": "N",
590 + "SeSz": "512B",
591 + "Model": "ST16000NM001G-2KK103",
592 + "Sp": "U",
593 + "Type": "-"
594 + },
595 + {
596 + "EID:Slt": "252:3",
597 + "DID": 35,
598 + "State": "Onln",
599 + "DG": 0,
600 + "Size": "14.551 TB",
601 + "Intf": "SATA",
602 + "Med": "HDD",
603 + "SED": "N",
604 + "PI": "N",
605 + "SeSz": "512B",
606 + "Model": "ST16000NM001G-2KK103",
607 + "Sp": "U",
608 + "Type": "-"
609 + },
610 + {
611 + "EID:Slt": "252:4",
612 + "DID": 30,
613 + "State": "Onln",
614 + "DG": 0,
615 + "Size": "14.551 TB",
616 + "Intf": "SATA",
617 + "Med": "HDD",
618 + "SED": "N",
619 + "PI": "N",
620 + "SeSz": "512B",
621 + "Model": "ST16000NM001G-2KK103",
622 + "Sp": "U",
623 + "Type": "-"
624 + },
625 + {
626 + "EID:Slt": "252:5",
627 + "DID": 31,
628 + "State": "Onln",
629 + "DG": 0,
630 + "Size": "14.551 TB",
631 + "Intf": "SATA",
632 + "Med": "HDD",
633 + "SED": "N",
634 + "PI": "N",
635 + "SeSz": "512B",
636 + "Model": "ST16000NM001G-2KK103",
637 + "Sp": "U",
638 + "Type": "-"
639 + },
640 + {
641 + "EID:Slt": "252:7",
642 + "DID": 32,
643 + "State": "Onln",
644 + "DG": 0,
645 + "Size": "14.551 TB",
646 + "Intf": "SATA",
647 + "Med": "HDD",
648 + "SED": "N",
649 + "PI": "N",
650 + "SeSz": "512B",
651 + "Model": "ST16000NM001G-2KK103",
652 + "Sp": "U",
653 + "Type": "-"
654 + }
655 + ],
656 + "Enclosures": 1,
657 + "Enclosure LIST": [
658 + {
659 + "EID": 252,
660 + "State": "OK",
661 + "Slots": 8,
662 + "PD": 6,
663 + "PS": 0,
664 + "Fans": 0,
665 + "TSs": 0,
666 + "Alms": 0,
667 + "SIM": 1,
668 + "Port#": "-",
669 + "ProdID": "SGPIO",
670 + "VendorSpecific": " "
671 + }
672 + ],
673 + "BBU_Info": [
674 + {
675 + "Model": "iBBU08",
676 + "State": "Optimal",
677 + "RetentionTime": "48 hours +",
678 + "Temp": "34C",
679 + "Mode": "4",
680 + "MfgDate": "2011/03/18",
681 + "Next Learn": "2024/04/18 18:32:56"
682 + }
683 + ]
684 + }
685 + }
686 + ]
687 +}
src/go/collectors/go.d.plugin/modules/storcli/testdata/megaraid-drives-info.json new
+495
@@ -0,0 +1,495 @@
1 +{
2 + "Controllers": [
3 + {
4 + "Command Status": {
5 + "CLI Version": "007.2807.0000.0000 Dec 22, 2023",
6 + "Operating system": "Linux 6.5.13-1-pve",
7 + "Controller": 0,
8 + "Status": "Success",
9 + "Description": "Show Drive Information Succeeded."
10 + },
11 + "Response Data": {
12 + "Drive /c0/e252/s0": [
13 + {
14 + "EID:Slt": "252:0",
15 + "DID": 34,
16 + "State": "Onln",
17 + "DG": 0,
18 + "Size": "14.551 TB",
19 + "Intf": "SATA",
20 + "Med": "HDD",
21 + "SED": "N",
22 + "PI": "N",
23 + "SeSz": "512B",
24 + "Model": "ST16000NM001G-2KK103",
25 + "Sp": "U",
26 + "Type": "-"
27 + }
28 + ],
29 + "Drive /c0/e252/s0 - Detailed Information": {
30 + "Drive /c0/e252/s0 State": {
31 + "Shield Counter": 0,
32 + "Media Error Count": 0,
33 + "Other Error Count": 0,
34 + "BBM Error Count": 0,
35 + "Drive Temperature": " 28C (82.40 F)",
36 + "Predictive Failure Count": 0,
37 + "S.M.A.R.T alert flagged by drive": "No"
38 + },
39 + "Drive /c0/e252/s0 Device attributes": {
40 + "SN": " ZL2PVFA8",
41 + "Manufacturer Id": "ATA ",
42 + "Model Number": "ST16000NM001G-2KK103",
43 + "NAND Vendor": "NA",
44 + "WWN": "5000C500E54F4EBB",
45 + "Firmware Revision": "SN03 ",
46 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
47 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
48 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
49 + "Device Speed": "6.0Gb/s",
50 + "Link Speed": "6.0Gb/s",
51 + "NCQ setting": "N/A",
52 + "Write Cache": "N/A",
53 + "Logical Sector Size": "512B",
54 + "Physical Sector Size": "512B",
55 + "Connector Name": ""
56 + },
57 + "Drive /c0/e252/s0 Policies/Settings": {
58 + "Drive position": "DriveGroup:0, Span:0, Row:4",
59 + "Enclosure position": "1",
60 + "Connected Port Number": "1(path0) ",
61 + "Sequence Number": 2,
62 + "Commissioned Spare": "No",
63 + "Emergency Spare": "No",
64 + "Last Predictive Failure Event Sequence Number": 0,
65 + "Successful diagnostics completion on": "N/A",
66 + "FDE Type": "None",
67 + "SED Capable": "No",
68 + "SED Enabled": "No",
69 + "Secured": "No",
70 + "Cryptographic Erase Capable": "No",
71 + "Sanitize Support": "Not supported",
72 + "Locked": "No",
73 + "Needs EKM Attention": "No",
74 + "PI Eligible": "No",
75 + "Drive is formatted for PI": "No",
76 + "PI type": "No PI",
77 + "Number of bytes of user data in LBA": "512B",
78 + "Certified": "No",
79 + "Wide Port Capable": "No",
80 + "Multipath": "No",
81 + "Port Information": [
82 + {
83 + "Port": 0,
84 + "Status": "Active",
85 + "Linkspeed": "6.0Gb/s",
86 + "SAS address": "0x4433221103000000"
87 + }
88 + ]
89 + },
90 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 5a 50 32 46 56 38 41 00 00 00 00 00 00 4e 53 33 30 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
91 + },
92 + "Drive /c0/e252/s1": [
93 + {
94 + "EID:Slt": "252:1",
95 + "DID": 33,
96 + "State": "Onln",
97 + "DG": 0,
98 + "Size": "14.551 TB",
99 + "Intf": "SATA",
100 + "Med": "HDD",
101 + "SED": "N",
102 + "PI": "N",
103 + "SeSz": "512B",
104 + "Model": "ST16000NM001G-2KK103",
105 + "Sp": "U",
106 + "Type": "-"
107 + }
108 + ],
109 + "Drive /c0/e252/s1 - Detailed Information": {
110 + "Drive /c0/e252/s1 State": {
111 + "Shield Counter": 0,
112 + "Media Error Count": 0,
113 + "Other Error Count": 0,
114 + "BBM Error Count": 0,
115 + "Drive Temperature": " 27C (80.60 F)",
116 + "Predictive Failure Count": 0,
117 + "S.M.A.R.T alert flagged by drive": "No"
118 + },
119 + "Drive /c0/e252/s1 Device attributes": {
120 + "SN": " ZL2PY6LF",
121 + "Manufacturer Id": "ATA ",
122 + "Model Number": "ST16000NM001G-2KK103",
123 + "NAND Vendor": "NA",
124 + "WWN": "5000C500E5659BA7",
125 + "Firmware Revision": "SN03 ",
126 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
127 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
128 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
129 + "Device Speed": "6.0Gb/s",
130 + "Link Speed": "6.0Gb/s",
131 + "NCQ setting": "N/A",
132 + "Write Cache": "N/A",
133 + "Logical Sector Size": "512B",
134 + "Physical Sector Size": "512B",
135 + "Connector Name": ""
136 + },
137 + "Drive /c0/e252/s1 Policies/Settings": {
138 + "Drive position": "DriveGroup:0, Span:0, Row:5",
139 + "Enclosure position": "1",
140 + "Connected Port Number": "2(path0) ",
141 + "Sequence Number": 2,
142 + "Commissioned Spare": "No",
143 + "Emergency Spare": "No",
144 + "Last Predictive Failure Event Sequence Number": 0,
145 + "Successful diagnostics completion on": "N/A",
146 + "FDE Type": "None",
147 + "SED Capable": "No",
148 + "SED Enabled": "No",
149 + "Secured": "No",
150 + "Cryptographic Erase Capable": "No",
151 + "Sanitize Support": "Not supported",
152 + "Locked": "No",
153 + "Needs EKM Attention": "No",
154 + "PI Eligible": "No",
155 + "Drive is formatted for PI": "No",
156 + "PI type": "No PI",
157 + "Number of bytes of user data in LBA": "512B",
158 + "Certified": "No",
159 + "Wide Port Capable": "No",
160 + "Multipath": "No",
161 + "Port Information": [
162 + {
163 + "Port": 0,
164 + "Status": "Active",
165 + "Linkspeed": "6.0Gb/s",
166 + "SAS address": "0x4433221102000000"
167 + }
168 + ]
169 + },
170 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 5a 50 32 36 59 46 4c 00 00 00 00 00 00 4e 53 33 30 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
171 + },
172 + "Drive /c0/e252/s3": [
173 + {
174 + "EID:Slt": "252:3",
175 + "DID": 35,
176 + "State": "Onln",
177 + "DG": 0,
178 + "Size": "14.551 TB",
179 + "Intf": "SATA",
180 + "Med": "HDD",
181 + "SED": "N",
182 + "PI": "N",
183 + "SeSz": "512B",
184 + "Model": "ST16000NM001G-2KK103",
185 + "Sp": "U",
186 + "Type": "-"
187 + }
188 + ],
189 + "Drive /c0/e252/s3 - Detailed Information": {
190 + "Drive /c0/e252/s3 State": {
191 + "Shield Counter": 0,
192 + "Media Error Count": 0,
193 + "Other Error Count": 0,
194 + "BBM Error Count": 0,
195 + "Drive Temperature": " 28C (82.40 F)",
196 + "Predictive Failure Count": 0,
197 + "S.M.A.R.T alert flagged by drive": "No"
198 + },
199 + "Drive /c0/e252/s3 Device attributes": {
200 + "SN": " ZL2M2WQ3",
201 + "Manufacturer Id": "ATA ",
202 + "Model Number": "ST16000NM001G-2KK103",
203 + "NAND Vendor": "NA",
204 + "WWN": "5000C500DC79B194",
205 + "Firmware Revision": "SN03 ",
206 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
207 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
208 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
209 + "Device Speed": "6.0Gb/s",
210 + "Link Speed": "6.0Gb/s",
211 + "NCQ setting": "N/A",
212 + "Write Cache": "N/A",
213 + "Logical Sector Size": "512B",
214 + "Physical Sector Size": "512B",
215 + "Connector Name": ""
216 + },
217 + "Drive /c0/e252/s3 Policies/Settings": {
218 + "Drive position": "DriveGroup:0, Span:0, Row:0",
219 + "Enclosure position": "1",
220 + "Connected Port Number": "0(path0) ",
221 + "Sequence Number": 2,
222 + "Commissioned Spare": "No",
223 + "Emergency Spare": "No",
224 + "Last Predictive Failure Event Sequence Number": 0,
225 + "Successful diagnostics completion on": "N/A",
226 + "FDE Type": "None",
227 + "SED Capable": "No",
228 + "SED Enabled": "No",
229 + "Secured": "No",
230 + "Cryptographic Erase Capable": "No",
231 + "Sanitize Support": "Not supported",
232 + "Locked": "No",
233 + "Needs EKM Attention": "No",
234 + "PI Eligible": "No",
235 + "Drive is formatted for PI": "No",
236 + "PI type": "No PI",
237 + "Number of bytes of user data in LBA": "512B",
238 + "Certified": "No",
239 + "Wide Port Capable": "No",
240 + "Multipath": "No",
241 + "Port Information": [
242 + {
243 + "Port": 0,
244 + "Status": "Active",
245 + "Linkspeed": "6.0Gb/s",
246 + "SAS address": "0x4433221100000000"
247 + }
248 + ]
249 + },
250 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 5a 4d 32 57 32 33 51 00 00 00 00 00 00 4e 53 33 30 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
251 + },
252 + "Drive /c0/e252/s4": [
253 + {
254 + "EID:Slt": "252:4",
255 + "DID": 30,
256 + "State": "Onln",
257 + "DG": 0,
258 + "Size": "14.551 TB",
259 + "Intf": "SATA",
260 + "Med": "HDD",
261 + "SED": "N",
262 + "PI": "N",
263 + "SeSz": "512B",
264 + "Model": "ST16000NM001G-2KK103",
265 + "Sp": "U",
266 + "Type": "-"
267 + }
268 + ],
269 + "Drive /c0/e252/s4 - Detailed Information": {
270 + "Drive /c0/e252/s4 State": {
271 + "Shield Counter": 0,
272 + "Media Error Count": 0,
273 + "Other Error Count": 0,
274 + "BBM Error Count": 0,
275 + "Drive Temperature": " 28C (82.40 F)",
276 + "Predictive Failure Count": 0,
277 + "S.M.A.R.T alert flagged by drive": "No"
278 + },
279 + "Drive /c0/e252/s4 Device attributes": {
280 + "SN": " WL201HYL",
281 + "Manufacturer Id": "ATA ",
282 + "Model Number": "ST16000NM001G-2KK103",
283 + "NAND Vendor": "NA",
284 + "WWN": "5000C500D59840FE",
285 + "Firmware Revision": "SN04 ",
286 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
287 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
288 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
289 + "Device Speed": "6.0Gb/s",
290 + "Link Speed": "6.0Gb/s",
291 + "NCQ setting": "N/A",
292 + "Write Cache": "N/A",
293 + "Logical Sector Size": "512B",
294 + "Physical Sector Size": "512B",
295 + "Connector Name": ""
296 + },
297 + "Drive /c0/e252/s4 Policies/Settings": {
298 + "Drive position": "DriveGroup:0, Span:0, Row:2",
299 + "Enclosure position": "1",
300 + "Connected Port Number": "3(path0) ",
301 + "Sequence Number": 2,
302 + "Commissioned Spare": "No",
303 + "Emergency Spare": "No",
304 + "Last Predictive Failure Event Sequence Number": 0,
305 + "Successful diagnostics completion on": "N/A",
306 + "FDE Type": "None",
307 + "SED Capable": "No",
308 + "SED Enabled": "No",
309 + "Secured": "No",
310 + "Cryptographic Erase Capable": "No",
311 + "Sanitize Support": "Not supported",
312 + "Locked": "No",
313 + "Needs EKM Attention": "No",
314 + "PI Eligible": "No",
315 + "Drive is formatted for PI": "No",
316 + "PI type": "No PI",
317 + "Number of bytes of user data in LBA": "512B",
318 + "Certified": "No",
319 + "Wide Port Capable": "No",
320 + "Multipath": "No",
321 + "Port Information": [
322 + {
323 + "Port": 0,
324 + "Status": "Active",
325 + "Linkspeed": "6.0Gb/s",
326 + "SAS address": "0x4433221104000000"
327 + }
328 + ]
329 + },
330 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 57 30 32 48 31 4c 59 00 00 00 00 00 00 4e 53 34 30 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
331 + },
332 + "Drive /c0/e252/s5": [
333 + {
334 + "EID:Slt": "252:5",
335 + "DID": 31,
336 + "State": "Onln",
337 + "DG": 0,
338 + "Size": "14.551 TB",
339 + "Intf": "SATA",
340 + "Med": "HDD",
341 + "SED": "N",
342 + "PI": "N",
343 + "SeSz": "512B",
344 + "Model": "ST16000NM001G-2KK103",
345 + "Sp": "U",
346 + "Type": "-"
347 + }
348 + ],
349 + "Drive /c0/e252/s5 - Detailed Information": {
350 + "Drive /c0/e252/s5 State": {
351 + "Shield Counter": 0,
352 + "Media Error Count": 0,
353 + "Other Error Count": 0,
354 + "BBM Error Count": 0,
355 + "Drive Temperature": " 28C (82.40 F)",
356 + "Predictive Failure Count": 0,
357 + "S.M.A.R.T alert flagged by drive": "No"
358 + },
359 + "Drive /c0/e252/s5 Device attributes": {
360 + "SN": " ZL21DC50",
361 + "Manufacturer Id": "ATA ",
362 + "Model Number": "ST16000NM001G-2KK103",
363 + "NAND Vendor": "NA",
364 + "WWN": "5000C500C36C8BCD",
365 + "Firmware Revision": "SN04 ",
366 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
367 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
368 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
369 + "Device Speed": "6.0Gb/s",
370 + "Link Speed": "6.0Gb/s",
371 + "NCQ setting": "N/A",
372 + "Write Cache": "N/A",
373 + "Logical Sector Size": "512B",
374 + "Physical Sector Size": "512B",
375 + "Connector Name": ""
376 + },
377 + "Drive /c0/e252/s5 Policies/Settings": {
378 + "Drive position": "DriveGroup:0, Span:0, Row:1",
379 + "Enclosure position": "1",
380 + "Connected Port Number": "4(path0) ",
381 + "Sequence Number": 2,
382 + "Commissioned Spare": "No",
383 + "Emergency Spare": "No",
384 + "Last Predictive Failure Event Sequence Number": 0,
385 + "Successful diagnostics completion on": "N/A",
386 + "FDE Type": "None",
387 + "SED Capable": "No",
388 + "SED Enabled": "No",
389 + "Secured": "No",
390 + "Cryptographic Erase Capable": "No",
391 + "Sanitize Support": "Not supported",
392 + "Locked": "No",
393 + "Needs EKM Attention": "No",
394 + "PI Eligible": "No",
395 + "Drive is formatted for PI": "No",
396 + "PI type": "No PI",
397 + "Number of bytes of user data in LBA": "512B",
398 + "Certified": "No",
399 + "Wide Port Capable": "No",
400 + "Multipath": "No",
401 + "Port Information": [
402 + {
403 + "Port": 0,
404 + "Status": "Active",
405 + "Linkspeed": "6.0Gb/s",
406 + "SAS address": "0x4433221105000000"
407 + }
408 + ]
409 + },
410 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 5a 31 32 43 44 30 35 00 00 00 00 00 00 4e 53 34 30 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
411 + },
412 + "Drive /c0/e252/s7": [
413 + {
414 + "EID:Slt": "252:7",
415 + "DID": 32,
416 + "State": "Onln",
417 + "DG": 0,
418 + "Size": "14.551 TB",
419 + "Intf": "SATA",
420 + "Med": "HDD",
421 + "SED": "N",
422 + "PI": "N",
423 + "SeSz": "512B",
424 + "Model": "ST16000NM001G-2KK103",
425 + "Sp": "U",
426 + "Type": "-"
427 + }
428 + ],
429 + "Drive /c0/e252/s7 - Detailed Information": {
430 + "Drive /c0/e252/s7 State": {
431 + "Shield Counter": 0,
432 + "Media Error Count": 0,
433 + "Other Error Count": 0,
434 + "BBM Error Count": 0,
435 + "Drive Temperature": " 28C (82.40 F)",
436 + "Predictive Failure Count": 0,
437 + "S.M.A.R.T alert flagged by drive": "No"
438 + },
439 + "Drive /c0/e252/s7 Device attributes": {
440 + "SN": " WL204LF2",
441 + "Manufacturer Id": "ATA ",
442 + "Model Number": "ST16000NM001G-2KK103",
443 + "NAND Vendor": "NA",
444 + "WWN": "5000C500D6061539",
445 + "Firmware Revision": "SB30 ",
446 + "Raw size": "14.552 TB [0x746c00000 Sectors]",
447 + "Coerced size": "14.551 TB [0x746a52800 Sectors]",
448 + "Non Coerced size": "14.551 TB [0x746b00000 Sectors]",
449 + "Device Speed": "6.0Gb/s",
450 + "Link Speed": "6.0Gb/s",
451 + "NCQ setting": "N/A",
452 + "Write Cache": "N/A",
453 + "Logical Sector Size": "512B",
454 + "Physical Sector Size": "512B",
455 + "Connector Name": ""
456 + },
457 + "Drive /c0/e252/s7 Policies/Settings": {
458 + "Drive position": "DriveGroup:0, Span:0, Row:3",
459 + "Enclosure position": "1",
460 + "Connected Port Number": "5(path0) ",
461 + "Sequence Number": 4,
462 + "Commissioned Spare": "No",
463 + "Emergency Spare": "No",
464 + "Last Predictive Failure Event Sequence Number": 0,
465 + "Successful diagnostics completion on": "N/A",
466 + "FDE Type": "None",
467 + "SED Capable": "No",
468 + "SED Enabled": "No",
469 + "Secured": "No",
470 + "Cryptographic Erase Capable": "No",
471 + "Sanitize Support": "Not supported",
472 + "Locked": "No",
473 + "Needs EKM Attention": "No",
474 + "PI Eligible": "No",
475 + "Drive is formatted for PI": "No",
476 + "PI type": "No PI",
477 + "Number of bytes of user data in LBA": "512B",
478 + "Certified": "No",
479 + "Wide Port Capable": "No",
480 + "Multipath": "No",
481 + "Port Information": [
482 + {
483 + "Port": 0,
484 + "Status": "Active",
485 + "Linkspeed": "6.0Gb/s",
486 + "SAS address": "0x4433221107000000"
487 + }
488 + ]
489 + },
490 + "Inquiry Data": "5a 0c ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 20 20 20 20 20 20 20 20 4c 57 30 32 4c 34 32 46 00 00 00 00 00 00 42 53 30 33 20 20 20 20 54 53 36 31 30 30 4e 30 30 4d 31 30 2d 47 4b 32 31 4b 33 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 00 40 00 2f 00 40 00 02 00 02 07 00 ff 3f 10 00 3f 00 10 fc fb 00 10 5d ff ff ff 0f 00 00 07 00 "
491 + }
492 + }
493 + }
494 + ]
495 +}