Fixes #219 - use the default to catch personalities that are unknown
Assumes all raid configurations start with raid and that anything else is unknown.pull/346/head
parent
bb2b984030
commit
00c9a88a55
|
@ -37,4 +37,7 @@ md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1]
|
||||||
md12 : active raid0 sdc2[0] sdd2[1]
|
md12 : active raid0 sdc2[0] sdd2[1]
|
||||||
3886394368 blocks super 1.2 512k chunks
|
3886394368 blocks super 1.2 512k chunks
|
||||||
|
|
||||||
|
md219 : inactive sdb[2](S) sdc[1](S) sda[0](S)
|
||||||
|
7932 blocks super external:imsm
|
||||||
|
|
||||||
unused devices: <none>
|
unused devices: <none>
|
||||||
|
|
|
@ -31,6 +31,8 @@ var (
|
||||||
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
|
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
|
||||||
raid0lineRE = regexp.MustCompile(`(\d+) blocks .*\d+k chunks`)
|
raid0lineRE = regexp.MustCompile(`(\d+) blocks .*\d+k chunks`)
|
||||||
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
|
||||||
|
unknownPersonalityLine = regexp.MustCompile(`(\d+) blocks (.*)`)
|
||||||
|
raidPersonalityRE = regexp.MustCompile(`raid[0-9]+`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type mdStatus struct {
|
type mdStatus struct {
|
||||||
|
@ -92,6 +94,21 @@ func evalRaid0line(statusline string) (size int64, err error) {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func evalUnknownPersonalityline(statusline string) (size int64, err error) {
|
||||||
|
matches := unknownPersonalityLine.FindStringSubmatch(statusline)
|
||||||
|
|
||||||
|
if len(matches) != 2+1 {
|
||||||
|
return 0, fmt.Errorf("invalid unknown personality status line: %s", statusline)
|
||||||
|
}
|
||||||
|
|
||||||
|
size, err = strconv.ParseInt(matches[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("%s in statusline: %s", err, statusline)
|
||||||
|
}
|
||||||
|
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gets the size that has already been synced out of the sync-line.
|
// Gets the size that has already been synced out of the sync-line.
|
||||||
func evalBuildline(buildline string) (int64, error) {
|
func evalBuildline(buildline string) (int64, error) {
|
||||||
matches := buildlineRE.FindStringSubmatch(buildline)
|
matches := buildlineRE.FindStringSubmatch(buildline)
|
||||||
|
@ -158,19 +175,27 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
|
||||||
}
|
}
|
||||||
currentMD = mainLine[0] // The name of the md-device.
|
currentMD = mainLine[0] // The name of the md-device.
|
||||||
isActive := (mainLine[2] == "active") // The activity status of the md-device.
|
isActive := (mainLine[2] == "active") // The activity status of the md-device.
|
||||||
personality = mainLine[3] // The personality type of the md-device.
|
personality = ""
|
||||||
|
for _, possiblePersonality := range mainLine {
|
||||||
|
if raidPersonalityRE.MatchString(possiblePersonality) {
|
||||||
|
personality = possiblePersonality
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(lines) <= i+3 {
|
if len(lines) <= i+3 {
|
||||||
return mdStates, fmt.Errorf("error parsing mdstat: entry for %s has fewer lines than expected", currentMD)
|
return mdStates, fmt.Errorf("error parsing mdstat: entry for %s has fewer lines than expected", currentMD)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch personality {
|
switch {
|
||||||
case "raid0":
|
case personality == "raid0":
|
||||||
active = int64(len(mainLine) - 4) // Get the number of devices from the main line.
|
active = int64(len(mainLine) - 4) // Get the number of devices from the main line.
|
||||||
total = active // Raid0 active and total is always the same if active.
|
total = active // Raid0 active and total is always the same if active.
|
||||||
size, err = evalRaid0line(lines[i+1]) // Parse statusline, always present.
|
size, err = evalRaid0line(lines[i+1]) // Parse statusline, always present.
|
||||||
default:
|
case raidPersonalityRE.MatchString(personality):
|
||||||
active, total, size, err = evalStatusline(lines[i+1]) // Parse statusline, always present.
|
active, total, size, err = evalStatusline(lines[i+1]) // Parse statusline, always present.
|
||||||
|
default:
|
||||||
|
log.Infof("Personality unknown: %s\n", mainLine)
|
||||||
|
size, err = evalUnknownPersonalityline(lines[i+1]) // Parse statusline, always present.
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -36,6 +36,7 @@ func TestMdadm(t *testing.T) {
|
||||||
"md10": {"md10", true, 2, 2, 314159265, 314159265},
|
"md10": {"md10", true, 2, 2, 314159265, 314159265},
|
||||||
"md11": {"md11", true, 2, 2, 4190208, 4190208},
|
"md11": {"md11", true, 2, 2, 4190208, 4190208},
|
||||||
"md12": {"md12", true, 2, 2, 3886394368, 3886394368},
|
"md12": {"md12", true, 2, 2, 3886394368, 3886394368},
|
||||||
|
"md219": {"md219", false, 2, 2, 7932, 7932},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, md := range mdStates {
|
for _, md := range mdStates {
|
||||||
|
|
Loading…
Reference in New Issue