Skip to content

Commit f8af350

Browse files
authored
Merge pull request #346 from mcdan/people/mcdan/issues/219
Fix additional mdadm parsing cases
2 parents 4fd03c3 + 13aa370 commit f8af350

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

collector/fixtures/e2e-output.txt

+10
Original file line numberDiff line numberDiff line change
@@ -713,10 +713,12 @@ node_load5 0.37
713713
# HELP node_md_blocks Total number of blocks on device.
714714
# TYPE node_md_blocks gauge
715715
node_md_blocks{device="md0"} 248896
716+
node_md_blocks{device="md00"} 4.186624e+06
716717
node_md_blocks{device="md10"} 3.14159265e+08
717718
node_md_blocks{device="md11"} 4.190208e+06
718719
node_md_blocks{device="md12"} 3.886394368e+09
719720
node_md_blocks{device="md127"} 3.12319552e+08
721+
node_md_blocks{device="md219"} 7932
720722
node_md_blocks{device="md3"} 5.853468288e+09
721723
node_md_blocks{device="md4"} 4.883648e+06
722724
node_md_blocks{device="md6"} 1.95310144e+08
@@ -726,10 +728,12 @@ node_md_blocks{device="md9"} 523968
726728
# HELP node_md_blocks_synced Number of blocks synced on device.
727729
# TYPE node_md_blocks_synced gauge
728730
node_md_blocks_synced{device="md0"} 248896
731+
node_md_blocks_synced{device="md00"} 4.186624e+06
729732
node_md_blocks_synced{device="md10"} 3.14159265e+08
730733
node_md_blocks_synced{device="md11"} 4.190208e+06
731734
node_md_blocks_synced{device="md12"} 3.886394368e+09
732735
node_md_blocks_synced{device="md127"} 3.12319552e+08
736+
node_md_blocks_synced{device="md219"} 7932
733737
node_md_blocks_synced{device="md3"} 5.853468288e+09
734738
node_md_blocks_synced{device="md4"} 4.883648e+06
735739
node_md_blocks_synced{device="md6"} 1.6775552e+07
@@ -739,10 +743,12 @@ node_md_blocks_synced{device="md9"} 523968
739743
# HELP node_md_disks Total number of disks of device.
740744
# TYPE node_md_disks gauge
741745
node_md_disks{device="md0"} 2
746+
node_md_disks{device="md00"} 1
742747
node_md_disks{device="md10"} 2
743748
node_md_disks{device="md11"} 2
744749
node_md_disks{device="md12"} 2
745750
node_md_disks{device="md127"} 2
751+
node_md_disks{device="md219"} 2
746752
node_md_disks{device="md3"} 8
747753
node_md_disks{device="md4"} 2
748754
node_md_disks{device="md6"} 2
@@ -752,10 +758,12 @@ node_md_disks{device="md9"} 4
752758
# HELP node_md_disks_active Number of active disks of device.
753759
# TYPE node_md_disks_active gauge
754760
node_md_disks_active{device="md0"} 2
761+
node_md_disks_active{device="md00"} 1
755762
node_md_disks_active{device="md10"} 2
756763
node_md_disks_active{device="md11"} 2
757764
node_md_disks_active{device="md12"} 2
758765
node_md_disks_active{device="md127"} 2
766+
node_md_disks_active{device="md219"} 2
759767
node_md_disks_active{device="md3"} 8
760768
node_md_disks_active{device="md4"} 2
761769
node_md_disks_active{device="md6"} 1
@@ -765,10 +773,12 @@ node_md_disks_active{device="md9"} 4
765773
# HELP node_md_is_active Indicator whether the md-device is active or not.
766774
# TYPE node_md_is_active gauge
767775
node_md_is_active{device="md0"} 1
776+
node_md_is_active{device="md00"} 1
768777
node_md_is_active{device="md10"} 1
769778
node_md_is_active{device="md11"} 1
770779
node_md_is_active{device="md12"} 1
771780
node_md_is_active{device="md127"} 1
781+
node_md_is_active{device="md219"} 0
772782
node_md_is_active{device="md3"} 1
773783
node_md_is_active{device="md4"} 0
774784
node_md_is_active{device="md6"} 1

collector/fixtures/proc/mdstat

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
22
md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9]
33
5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU]
4-
4+
55
md127 : active raid1 sdi2[0] sdj2[1]
66
312319552 blocks [2/2] [UU]
7-
7+
88
md0 : active raid1 sdi1[0] sdj1[1]
99
248896 blocks [2/2] [UU]
10-
10+
1111
md4 : inactive raid1 sda3[0] sdb3[1]
1212
4883648 blocks [2/2] [UU]
1313

@@ -18,7 +18,7 @@ md6 : active raid1 sdb2[2] sda2[0]
1818
md8 : active raid1 sdb1[1] sda1[0]
1919
195310144 blocks [2/2] [UU]
2020
[=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec
21-
21+
2222
md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1]
2323
7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU]
2424
bitmap: 0/30 pages [0KB], 65536KB chunk
@@ -37,4 +37,10 @@ md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1]
3737
md12 : active raid0 sdc2[0] sdd2[1]
3838
3886394368 blocks super 1.2 512k chunks
3939

40+
md219 : inactive sdb[2](S) sdc[1](S) sda[0](S)
41+
7932 blocks super external:imsm
42+
43+
md00 : active raid0 xvdb[0]
44+
4186624 blocks super 1.2 256k chunks
45+
4046
unused devices: <none>

collector/mdadm_linux.go

+34-8
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ import (
2828
)
2929

3030
var (
31-
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
32-
raid0lineRE = regexp.MustCompile(`(\d+) blocks .*\d+k chunks`)
33-
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
31+
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
32+
raid0lineRE = regexp.MustCompile(`(\d+) blocks( super ([0-9\.])*)? \d+k chunks`)
33+
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
34+
unknownPersonalityLineRE = regexp.MustCompile(`(\d+) blocks (.*)`)
35+
raidPersonalityRE = regexp.MustCompile(`raid[0-9]+`)
3436
)
3537

3638
type mdStatus struct {
@@ -80,7 +82,7 @@ func evalStatusline(statusline string) (active, total, size int64, err error) {
8082
func evalRaid0line(statusline string) (size int64, err error) {
8183
matches := raid0lineRE.FindStringSubmatch(statusline)
8284

83-
if len(matches) != 2 {
85+
if len(matches) < 2 {
8486
return 0, fmt.Errorf("invalid raid0 status line: %s", statusline)
8587
}
8688

@@ -92,6 +94,21 @@ func evalRaid0line(statusline string) (size int64, err error) {
9294
return size, nil
9395
}
9496

97+
func evalUnknownPersonalitylineRE(statusline string) (size int64, err error) {
98+
matches := unknownPersonalityLineRE.FindStringSubmatch(statusline)
99+
100+
if len(matches) != 2+1 {
101+
return 0, fmt.Errorf("invalid unknown personality status line: %s", statusline)
102+
}
103+
104+
size, err = strconv.ParseInt(matches[1], 10, 64)
105+
if err != nil {
106+
return 0, fmt.Errorf("%s in statusline: %s", err, statusline)
107+
}
108+
109+
return size, nil
110+
}
111+
95112
// Gets the size that has already been synced out of the sync-line.
96113
func evalBuildline(buildline string) (int64, error) {
97114
matches := buildlineRE.FindStringSubmatch(buildline)
@@ -158,19 +175,28 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
158175
}
159176
currentMD = mainLine[0] // The name of the md-device.
160177
isActive := (mainLine[2] == "active") // The activity status of the md-device.
161-
personality = mainLine[3] // The personality type of the md-device.
178+
personality = ""
179+
for _, possiblePersonality := range mainLine[3:] {
180+
if raidPersonalityRE.MatchString(possiblePersonality) {
181+
personality = possiblePersonality
182+
break
183+
}
184+
}
162185

163186
if len(lines) <= i+3 {
164187
return mdStates, fmt.Errorf("error parsing mdstat: entry for %s has fewer lines than expected", currentMD)
165188
}
166189

167-
switch personality {
168-
case "raid0":
190+
switch {
191+
case personality == "raid0":
169192
active = int64(len(mainLine) - 4) // Get the number of devices from the main line.
170193
total = active // Raid0 active and total is always the same if active.
171194
size, err = evalRaid0line(lines[i+1]) // Parse statusline, always present.
172-
default:
195+
case raidPersonalityRE.MatchString(personality):
173196
active, total, size, err = evalStatusline(lines[i+1]) // Parse statusline, always present.
197+
default:
198+
log.Infof("Personality unknown: %s\n", mainLine)
199+
size, err = evalUnknownPersonalitylineRE(lines[i+1]) // Parse statusline, always present.
174200
}
175201

176202
if err != nil {

collector/mdadm_linux_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func TestMdadm(t *testing.T) {
2525
}
2626

2727
refs := map[string]mdStatus{
28+
// { "<name>", <active?>, <numDisksActive>, <totalNumDisks>, <amountSynced>, <totalSize>}
2829
"md3": {"md3", true, 8, 8, 5853468288, 5853468288},
2930
"md127": {"md127", true, 2, 2, 312319552, 312319552},
3031
"md0": {"md0", true, 2, 2, 248896, 248896},
@@ -36,6 +37,8 @@ func TestMdadm(t *testing.T) {
3637
"md10": {"md10", true, 2, 2, 314159265, 314159265},
3738
"md11": {"md11", true, 2, 2, 4190208, 4190208},
3839
"md12": {"md12", true, 2, 2, 3886394368, 3886394368},
40+
"md219": {"md219", false, 2, 2, 7932, 7932},
41+
"md00": {"md00", true, 1, 1, 4186624, 4186624},
3942
}
4043

4144
for _, md := range mdStates {

0 commit comments

Comments
 (0)