package collector // Package-level IPMI tuning profiles. // // Each profile is matched by board manufacturer (already known before PSU // collection runs). The profile drives two things: // - Per-command timeouts — prevents infinite hangs on slow BMCs. // - FRU early-exit — streaming parser stops reading once all PSU entries // are found, avoiding the tail of non-PSU FRU records. // // To add a new vendor: append to ipmiProfiles. The first matching entry wins. import ( "strings" "time" ) // ipmiProfile holds tuning parameters for one or more board manufacturers. type ipmiProfile struct { // name is shown in log messages. name string // manufacturers is a list of lowercase substrings matched against the // board manufacturer string from dmidecode type 1. manufacturers []string // fruTimeout is the hard deadline for the entire `ipmitool fru print` // command. Zero means no timeout (not recommended). fruTimeout time.Duration // sdrTimeout is the hard deadline for `ipmitool sdr`. sdrTimeout time.Duration // mcInfoTimeout is the hard deadline for `ipmitool mc info`. mcInfoTimeout time.Duration // fruEarlyExit instructs the streaming FRU parser to stop reading // after it has found at least one PSU entry and the current block is // complete. Useful on servers with many non-PSU FRU devices. fruEarlyExit bool } // ipmiProfiles is the ordered list of profiles. First match wins. var ipmiProfiles = []ipmiProfile{ { // Lenovo XCC-based servers (ThinkSystem SR6xx / SR8xx / ST series). // SR650 V3 has 54 FRU devices; each IPMI read takes ~2 s, so the // full `fru print` scan takes ~108 s on a loaded BMC. Enable early // exit so collection stops once PSU records are found. name: "lenovo", manufacturers: []string{"lenovo"}, fruTimeout: 90 * time.Second, sdrTimeout: 45 * time.Second, mcInfoTimeout: 15 * time.Second, fruEarlyExit: true, }, { // HPE iLO-based servers (ProLiant DL/ML/BL). name: "hpe", manufacturers: []string{"hp", "hewlett packard"}, fruTimeout: 60 * time.Second, sdrTimeout: 30 * time.Second, mcInfoTimeout: 10 * time.Second, fruEarlyExit: false, }, { // Dell iDRAC-based servers. name: "dell", manufacturers: []string{"dell"}, fruTimeout: 60 * time.Second, sdrTimeout: 30 * time.Second, mcInfoTimeout: 10 * time.Second, fruEarlyExit: false, }, } // defaultIPMIProfile is used when no vendor profile matches. var defaultIPMIProfile = ipmiProfile{ name: "default", fruTimeout: 60 * time.Second, sdrTimeout: 30 * time.Second, mcInfoTimeout: 10 * time.Second, fruEarlyExit: false, } // selectIPMIProfile returns the profile for the given board manufacturer. func selectIPMIProfile(manufacturer string) ipmiProfile { mfgLower := strings.ToLower(strings.TrimSpace(manufacturer)) for _, p := range ipmiProfiles { for _, m := range p.manufacturers { if strings.Contains(mfgLower, m) { return p } } } return defaultIPMIProfile }