Fixes #219 - use the default to catch personalities that are unknown

Assumes all raid configurations start with raid and that anything
else is unknown.
This commit is contained in:
dan mcweeney 2016-09-20 10:22:34 -04:00
commit 00c9a88a55
3 changed files with 37 additions and 8 deletions

View file

@ -31,6 +31,8 @@ var (
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
raid0lineRE = regexp.MustCompile(`(\d+) blocks .*\d+k chunks`)
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
unknownPersonalityLine = regexp.MustCompile(`(\d+) blocks (.*)`)
raidPersonalityRE = regexp.MustCompile(`raid[0-9]+`)
)
type mdStatus struct {
@ -92,6 +94,21 @@ func evalRaid0line(statusline string) (size int64, err error) {
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.
func evalBuildline(buildline string) (int64, error) {
matches := buildlineRE.FindStringSubmatch(buildline)
@ -158,19 +175,27 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
}
currentMD = mainLine[0] // The name 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 {
return mdStates, fmt.Errorf("error parsing mdstat: entry for %s has fewer lines than expected", currentMD)
}
switch personality {
case "raid0":
switch {
case personality == "raid0":
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.
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.
default:
log.Infof("Personality unknown: %s\n", mainLine)
size, err = evalUnknownPersonalityline(lines[i+1]) // Parse statusline, always present.
}
if err != nil {