1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package sysfs
18
19 import (
20 "fmt"
21 "path/filepath"
22 "strings"
23
24 "github.com/prometheus/procfs/internal/util"
25 )
26
27
28 type Mdraid struct {
29 Device string
30 Level string
31 ArrayState string
32 MetadataVersion string
33 Disks uint64
34 Components []MdraidComponent
35 UUID string
36
37
38 ChunkSize uint64
39
40
41 DegradedDisks uint64
42 SyncAction string
43 SyncCompleted float64
44 }
45
46 type MdraidComponent struct {
47 Device string
48 State string
49 }
50
51
52
53 func (fs FS) Mdraids() ([]Mdraid, error) {
54 matches, err := filepath.Glob(fs.sys.Path("block/md*/md"))
55 if err != nil {
56 return nil, err
57 }
58
59 mdraids := make([]Mdraid, 0)
60
61 for _, m := range matches {
62 md := Mdraid{Device: filepath.Base(filepath.Dir(m))}
63 path := fs.sys.Path("block", md.Device, "md")
64
65 if val, err := util.SysReadFile(filepath.Join(path, "level")); err == nil {
66 md.Level = val
67 } else {
68 return mdraids, err
69 }
70
71
72
73 if val, err := util.SysReadFile(filepath.Join(path, "array_state")); err == nil {
74 md.ArrayState = val
75 } else {
76 return mdraids, err
77 }
78
79 if val, err := util.SysReadFile(filepath.Join(path, "metadata_version")); err == nil {
80 md.MetadataVersion = val
81 } else {
82 return mdraids, err
83 }
84
85 if val, err := util.ReadUintFromFile(filepath.Join(path, "raid_disks")); err == nil {
86 md.Disks = val
87 } else {
88 return mdraids, err
89 }
90
91 if val, err := util.SysReadFile(filepath.Join(path, "uuid")); err == nil {
92 md.UUID = val
93 } else {
94 return mdraids, err
95 }
96
97 if devs, err := filepath.Glob(filepath.Join(path, "dev-*")); err == nil {
98 for _, dev := range devs {
99 comp := MdraidComponent{Device: strings.TrimPrefix(filepath.Base(dev), "dev-")}
100
101
102
103 if val, err := util.SysReadFile(filepath.Join(dev, "state")); err == nil {
104 comp.State = val
105 } else {
106 return mdraids, err
107 }
108
109 md.Components = append(md.Components, comp)
110 }
111 } else {
112 return mdraids, err
113 }
114
115 switch md.Level {
116 case "raid0", "raid4", "raid5", "raid6", "raid10":
117 if val, err := util.ReadUintFromFile(filepath.Join(path, "chunk_size")); err == nil {
118 md.ChunkSize = val
119 } else {
120 return mdraids, err
121 }
122 }
123
124 switch md.Level {
125 case "raid1", "raid4", "raid5", "raid6", "raid10":
126 if val, err := util.ReadUintFromFile(filepath.Join(path, "degraded")); err == nil {
127 md.DegradedDisks = val
128 } else {
129 return mdraids, err
130 }
131
132
133 if val, err := util.SysReadFile(filepath.Join(path, "sync_action")); err == nil {
134 md.SyncAction = val
135 } else {
136 return mdraids, err
137 }
138
139 if val, err := util.SysReadFile(filepath.Join(path, "sync_completed")); err == nil {
140 if val != "none" {
141 var a, b uint64
142
143
144
145 if _, err := fmt.Sscanf(val, "%d / %d", &a, &b); err == nil {
146 md.SyncCompleted = float64(a) / float64(b)
147 } else {
148 return mdraids, err
149 }
150 }
151 } else {
152 return mdraids, err
153 }
154 }
155
156 mdraids = append(mdraids, md)
157 }
158
159 return mdraids, nil
160 }
161
View as plain text