fix(collector): recover GPUs/NICs dropped on xFusion G5500 Redfish exports
looksLikeGPU now falls back to resolving VendorId/DeviceId through the pci.ids database when the BMC leaves Name/Model/Manufacturer/ClassCode empty, so GPUs identifiable only by raw PCI IDs (e.g. NVIDIA H100 SXM5 0x10de/0x2330) are no longer misclassified as generic PCIe devices. The replay pipeline's "backed by canonical NIC" dedup used to trust a PCIeDevice's Links.NetworkDeviceFunctions reference at face value and drop the device, assuming a NetworkAdapters record existed elsewhere. On BMCs that expose resource IDs with characters (parentheses) that 404 on fetch, that canonical NIC never gets captured, so the device carrying its actual hardware identity vanished from the export entirely. hasResolvableLinkedMember now verifies the linked resource is actually present in the snapshot before treating it as authoritative. Also normalize PartNumber through normalizeRedfishIdentityField in the GPU/PCIe parsers so a BMC-supplied literal "null" string doesn't leak into exports verbatim. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2c3072cf10
commit
a3567dd5f6
@@ -4355,7 +4355,7 @@ func parseGPUWithSupplementalDocs(doc map[string]interface{}, functionDocs []map
|
||||
Model: firstNonEmpty(asString(doc["Model"]), asString(doc["Name"])),
|
||||
Manufacturer: asString(doc["Manufacturer"]),
|
||||
SerialNumber: findFirstNormalizedStringByKeys(doc, "SerialNumber"),
|
||||
PartNumber: asString(doc["PartNumber"]),
|
||||
PartNumber: normalizeRedfishIdentityField(asString(doc["PartNumber"])),
|
||||
Firmware: asString(doc["FirmwareVersion"]),
|
||||
Status: mapStatus(doc["Status"]),
|
||||
Details: redfishPCIeDetailsWithSupplementalDocs(doc, functionDocs, supplementalDocs),
|
||||
@@ -4439,7 +4439,7 @@ func parsePCIeDeviceWithSupplementalDocs(doc map[string]interface{}, functionDoc
|
||||
BDF: sanitizeRedfishBDF(asString(doc["BDF"])),
|
||||
DeviceClass: asString(doc["DeviceType"]),
|
||||
Manufacturer: asString(doc["Manufacturer"]),
|
||||
PartNumber: asString(doc["PartNumber"]),
|
||||
PartNumber: normalizeRedfishIdentityField(asString(doc["PartNumber"])),
|
||||
SerialNumber: findFirstNormalizedStringByKeys(doc, "SerialNumber"),
|
||||
VendorID: asHexOrInt(doc["VendorId"]),
|
||||
DeviceID: asHexOrInt(doc["DeviceId"]),
|
||||
@@ -5084,6 +5084,32 @@ func looksLikeGPU(doc map[string]interface{}, functionDocs []map[string]interfac
|
||||
}
|
||||
}
|
||||
|
||||
// Some BMCs (e.g. xFusion) leave Name/Model/Manufacturer/ClassCode empty on
|
||||
// the PCIeDevice and its PCIeFunctions, exposing only raw VendorId/DeviceId.
|
||||
// Resolve those through the pci.ids database so GH100/GA100/etc. GPUs are
|
||||
// still recognized even without vendor-supplied model text.
|
||||
vendorID := asHexOrInt(doc["VendorId"])
|
||||
deviceID := asHexOrInt(doc["DeviceId"])
|
||||
for _, fn := range functionDocs {
|
||||
if vendorID == 0 {
|
||||
vendorID = asHexOrInt(fn["VendorId"])
|
||||
}
|
||||
if deviceID == 0 {
|
||||
deviceID = asHexOrInt(fn["DeviceId"])
|
||||
}
|
||||
}
|
||||
if vendorID != 0 || deviceID != 0 {
|
||||
resolvedText := strings.ToLower(strings.Join([]string{
|
||||
pciids.VendorName(vendorID),
|
||||
pciids.DeviceName(vendorID, deviceID),
|
||||
}, " "))
|
||||
for _, hint := range gpuHints {
|
||||
if strings.Contains(resolvedText, hint) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user