mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	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:
		
							parent
							
								
									bb2b984030
								
							
						
					
					
						commit
						00c9a88a55
					
				|  | @ -1,13 +1,13 @@ | |||
| Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] | ||||
| md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] | ||||
|       5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU] | ||||
|        | ||||
| 
 | ||||
| md127 : active raid1 sdi2[0] sdj2[1] | ||||
|       312319552 blocks [2/2] [UU] | ||||
|        | ||||
| 
 | ||||
| md0 : active raid1 sdi1[0] sdj1[1] | ||||
|       248896 blocks [2/2] [UU] | ||||
|        | ||||
| 
 | ||||
| md4 : inactive raid1 sda3[0] sdb3[1] | ||||
|       4883648 blocks [2/2] [UU] | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ md6 : active raid1 sdb2[2] sda2[0] | |||
| md8 : active raid1 sdb1[1] sda1[0] | ||||
| 	  195310144 blocks [2/2] [UU] | ||||
| 	  [=>...................]  resync =  8.5% (16775552/195310144) finish=17.0min speed=259783K/sec | ||||
| 	   | ||||
| 
 | ||||
| md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1] | ||||
|       7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU] | ||||
|       bitmap: 0/30 pages [0KB], 65536KB chunk | ||||
|  | @ -37,4 +37,7 @@ md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1] | |||
| md12 : active raid0 sdc2[0] sdd2[1] | ||||
|       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> | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ func TestMdadm(t *testing.T) { | |||
| 		"md10":  {"md10", true, 2, 2, 314159265, 314159265}, | ||||
| 		"md11":  {"md11", true, 2, 2, 4190208, 4190208}, | ||||
| 		"md12":  {"md12", true, 2, 2, 3886394368, 3886394368}, | ||||
| 		"md219": {"md219", false, 2, 2, 7932, 7932}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, md := range mdStates { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue