-
Notifications
You must be signed in to change notification settings - Fork 9
/
megaraid.go
143 lines (116 loc) · 3.22 KB
/
megaraid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package megaraid
import (
"encoding/json"
"errors"
)
// Controller - a Megaraid controller
type Controller struct {
ID int
Drives DriveSet
DriveGroups DriveGroupSet
VirtDrives VirtDriveSet
}
// VirtDrive - represents a virtual drive.
type VirtDrive struct {
// the Virtual Drive Number / ID
ID int
// the Drive Group ID
DriveGroup int
// Path in linux - may be empty if "Exposed to OS" != "Yes"
Path string
// "Name" in output - exposed in cimc UI
RaidName string
// Type RAID type (RAID0, RAID1...)
Type string
// /c0/v0 data as a string map
Raw map[string]string
// "VD0 Properties" as a map
Properties map[string]string
}
// VirtDriveSet - a map of VirtDrives by their Number.
type VirtDriveSet map[int]*VirtDrive
// DriveGroup - a megaraid "Drive Group". These really have nothing
// that is their own other than their ID.
type DriveGroup struct {
ID int
Drives DriveSet
}
// IsSSD - is this drive group composed of all SSD
func (dg *DriveGroup) IsSSD() bool {
if len(dg.Drives) == 0 {
return false
}
for _, drive := range dg.Drives {
if drive.MediaType != SSD {
return false
}
}
return true
}
// DriveGroupSet - map of DriveGroups by their ID
type DriveGroupSet map[int]*DriveGroup
// MarshalJSON - serialize to json. Custom Marshal to only reference Disks
// by ID not by full dump.
func (dgs DriveGroupSet) MarshalJSON() ([]byte, error) {
type terseDriveGroupSet struct {
ID int
Drives []int
}
var mySet = []terseDriveGroupSet{}
for id, driveSet := range dgs {
drives := []int{}
for drive := range driveSet.Drives {
drives = append(drives, drive)
}
mySet = append(mySet, terseDriveGroupSet{ID: id, Drives: drives})
}
return json.Marshal(&mySet)
}
// Drive - a megaraid (physical) Drive.
type Drive struct {
ID int
DriveGroup int
EID int
Slot int
State string
MediaType MediaType
Model string
Raw map[string]string
}
// DriveSet - just a map of Drives by ID
type DriveSet map[int]*Drive
// IsEqual - compare the two drives (does not compare Raw)
func (d *Drive) IsEqual(d2 Drive) bool {
return (d.ID == d2.ID && d.EID == d2.EID && d.Slot == d2.Slot &&
d.DriveGroup == d2.DriveGroup && d.State == d2.State &&
d.MediaType == d2.MediaType &&
d.Model == d2.Model)
}
// MediaType - a disk "Media"
type MediaType int
const (
// UnknownMedia - indicates an unknown media
UnknownMedia MediaType = iota
// HDD - Spinning hard disk.
HDD
// SSD - Solid State Disk
SSD
)
func (t MediaType) String() string {
return []string{"UNKNOWN", "HDD", "SSD"}[t]
}
// MarshalJSON for string output rather than int
func (t MediaType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
// MegaRaid - basic interface
type MegaRaid interface {
// Query - Query the controller provided
Query(int) (Controller, error)
}
// ErrNoController - Error reported by Query if no controller is found.
var ErrNoController = errors.New("megaraid Controller not found")
// ErrUnsupported - Error reported by Query if controller is not supported.
var ErrUnsupported = errors.New("megaraid Controller unsupported")
// ErrNoStorcli - Error reported by Query if no storcli binary in PATH
var ErrNoStorcli = errors.New("no 'storcli' command in PATH")