fix(collector): recover storage model for NVMe drives exposed as SCSI
An NVMe SSD passed through a RAID/HBA as /dev/sdX (not /dev/nvmeX) gets smartctl'd over the SCSI protocol, which reports its model in scsi_model_name/scsi_vendor/scsi_product instead of the ATA/NVMe model_name field. smartctlInfo only mapped model_name, so the drive's model was silently dropped from reanimator.json even though smartctl ran successfully and the serial number came through fine — caught via a support bundle where lsblk showed "SSSTC CA6-8D1024" for a drive but reanimator.json's storage entry had no model at all. Add scsi_model_name/scsi_vendor/scsi_product to smartctlInfo and fall back to them, in that order, when model_name is empty. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9add5616dd
commit
a09201c7ab
@@ -99,3 +99,51 @@ func TestApplySCSISmartctlTelemetryDoesNotOverwriteExistingValues(t *testing.T)
|
||||
t.Fatalf("life_used_pct=%v want 50", disk.LifeUsedPct)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmartctlModelNamePrefersATAModelName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
info := smartctlInfo{
|
||||
ModelName: "Samsung SSD 970 EVO",
|
||||
ScsiModelName: "should not be used",
|
||||
}
|
||||
if got := smartctlModelName(info); got != "Samsung SSD 970 EVO" {
|
||||
t.Fatalf("model=%q want %q", got, "Samsung SSD 970 EVO")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmartctlModelNameFallsBackToScsiModelName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// NVMe drive exposed through a RAID/HBA passthrough as /dev/sdX:
|
||||
// smartctl reports it over the SCSI protocol, so model_name is empty
|
||||
// and the model only shows up as scsi_model_name.
|
||||
info := smartctlInfo{
|
||||
ScsiModelName: "NVMe SSSTC CA6-8D1024",
|
||||
ScsiVendor: "NVMe",
|
||||
ScsiProduct: "SSSTC CA6-8D1024",
|
||||
}
|
||||
if got := smartctlModelName(info); got != "NVMe SSSTC CA6-8D1024" {
|
||||
t.Fatalf("model=%q want %q", got, "NVMe SSSTC CA6-8D1024")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmartctlModelNameFallsBackToScsiVendorProduct(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
info := smartctlInfo{
|
||||
ScsiVendor: "NVMe",
|
||||
ScsiProduct: "SSSTC CA6-8D1024",
|
||||
}
|
||||
if got := smartctlModelName(info); got != "NVMe SSSTC CA6-8D1024" {
|
||||
t.Fatalf("model=%q want %q", got, "NVMe SSSTC CA6-8D1024")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmartctlModelNameEmptyWhenNoFieldsSet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if got := smartctlModelName(smartctlInfo{}); got != "" {
|
||||
t.Fatalf("model=%q want empty", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user