@@ -142,6 +142,8 @@ func Command(cliContext *cli.Context) error {
142142 nvlinkExpectedLinkStates := cliContext .String ("nvlink-expected-link-states" )
143143 nfsCheckerConfigs := cliContext .String ("nfs-checker-configs" )
144144 xidRebootThreshold := cliContext .Int ("xid-reboot-threshold" )
145+ xidThresholds := cliContext .String ("xid-thresholds" )
146+ sxidThresholds := cliContext .String ("sxid-thresholds" )
145147 temperatureMarginThresholdCelsius := cliContext .Int ("threshold-celsius-slowdown-margin" )
146148
147149 if len (infinibandExpectedPortStates ) > 0 {
@@ -174,16 +176,42 @@ func Command(cliContext *cli.Context) error {
174176 log .Logger .Infow ("set nfs checker group configs" , "groupConfigs" , groupConfigs )
175177 }
176178
179+ xidThresholdsChanged := false
177180 if cliContext .IsSet ("xid-reboot-threshold" ) {
178181 if xidRebootThreshold > 0 {
179- componentsxid .SetDefaultRebootThreshold (componentsxid.RebootThreshold {
180- Threshold : xidRebootThreshold ,
181- })
182- log .Logger .Infow ("set xid reboot threshold" , "xidRebootThreshold" , xidRebootThreshold )
182+ componentsxid .SetDefaultRebootThreshold (xidRebootThreshold )
183+ xidThresholdsChanged = true
183184 } else {
184185 log .Logger .Warnw ("ignoring xid reboot threshold override, value must be positive" , "xidRebootThreshold" , xidRebootThreshold )
185186 }
186187 }
188+ if strings .TrimSpace (xidThresholds ) != "" {
189+ thresholds , err := parseXIDThresholds (xidThresholds )
190+ if err != nil {
191+ return err
192+ }
193+ componentsxid .SetDefaultThresholds (thresholds )
194+ xidThresholdsChanged = true
195+ }
196+ if xidThresholdsChanged {
197+ xidThresholdConfig := componentsxid .GetDefaultThresholds ()
198+ log .Logger .Infow (
199+ "set xid thresholds" ,
200+ "xidDefaultRebootThreshold" ,
201+ componentsxid .GetDefaultRebootThreshold (),
202+ "xidOverrides" ,
203+ xidThresholdConfig .Overrides ,
204+ )
205+ }
206+
207+ if strings .TrimSpace (sxidThresholds ) != "" {
208+ thresholds , err := parseSXIDThresholds (sxidThresholds )
209+ if err != nil {
210+ return err
211+ }
212+ componentssxid .SetDefaultThresholds (thresholds )
213+ log .Logger .Infow ("set sxid thresholds" , "sxidOverrides" , thresholds .Overrides )
214+ }
187215
188216 if eventsRetentionPeriod > 0 && ! cliContext .IsSet ("xid-lookback-period" ) {
189217 componentsxid .SetLookbackPeriod (eventsRetentionPeriod )
@@ -438,6 +466,79 @@ func parseRetentionPeriods(cliContext *cli.Context) (metricsRetentionPeriod, eve
438466 return metricsRetentionPeriod , eventsRetentionPeriod
439467}
440468
469+ type thresholdOverrideJSON struct {
470+ RebootThreshold int `json:"rebootThreshold"`
471+ }
472+
473+ type thresholdsJSON struct {
474+ Overrides map [int ]thresholdOverrideJSON `json:"overrides"`
475+ }
476+
477+ func parseXIDThresholds (raw string ) (componentsxid.Thresholds , error ) {
478+ thresholds , err := parseThresholds (raw , "xid thresholds" )
479+ if err != nil {
480+ return componentsxid.Thresholds {}, err
481+ }
482+
483+ ret := make (map [int ]componentsxid.ThresholdOverride , len (thresholds ))
484+ for xid , threshold := range thresholds {
485+ ret [xid ] = componentsxid.ThresholdOverride {
486+ RebootThreshold : threshold .RebootThreshold ,
487+ }
488+ }
489+ return componentsxid.Thresholds {Overrides : ret }, nil
490+ }
491+
492+ func parseSXIDThresholds (raw string ) (componentssxid.Thresholds , error ) {
493+ thresholds , err := parseThresholds (raw , "sxid thresholds" )
494+ if err != nil {
495+ return componentssxid.Thresholds {}, err
496+ }
497+
498+ ret := make (map [int ]componentssxid.ThresholdOverride , len (thresholds ))
499+ for sxid , threshold := range thresholds {
500+ ret [sxid ] = componentssxid.ThresholdOverride {
501+ RebootThreshold : threshold .RebootThreshold ,
502+ }
503+ }
504+ return componentssxid.Thresholds {Overrides : ret }, nil
505+ }
506+
507+ func parseThresholds (raw string , name string ) (map [int ]thresholdOverrideJSON , error ) {
508+ raw = strings .TrimSpace (raw )
509+ if raw == "" {
510+ return nil , nil
511+ }
512+
513+ var fields map [string ]json.RawMessage
514+ if err := json .Unmarshal ([]byte (raw ), & fields ); err != nil {
515+ return nil , fmt .Errorf ("invalid %s: %w" , name , err )
516+ }
517+ if fields == nil {
518+ return nil , fmt .Errorf ("invalid %s: expected JSON object" , name )
519+ }
520+ for field := range fields {
521+ if field != "overrides" {
522+ return nil , fmt .Errorf ("invalid %s: unknown field %q" , name , field )
523+ }
524+ }
525+
526+ var thresholds thresholdsJSON
527+ if err := json .Unmarshal ([]byte (raw ), & thresholds ); err != nil {
528+ return nil , fmt .Errorf ("invalid %s: %w" , name , err )
529+ }
530+
531+ for id , threshold := range thresholds .Overrides {
532+ if id < 0 {
533+ return nil , fmt .Errorf ("invalid %s for %d: event ID must be non-negative" , name , id )
534+ }
535+ if threshold .RebootThreshold <= 0 {
536+ return nil , fmt .Errorf ("invalid %s for %d: rebootThreshold must be positive" , name , id )
537+ }
538+ }
539+ return thresholds .Overrides , nil
540+ }
541+
441542func parseInfinibandExcludeDevices (s string ) []string {
442543 if s == "" {
443544 return nil
0 commit comments