fix: PCI summary JSON parser to match real QEMU info pci output
The awk patterns in hw_gen_pci_json() targeted a hypothetical output format that never matched QEMU's actual HMP 'info pci' response: - /^Bus / anchored to line start, but QEMU outputs ' Bus ' (2 leading spaces) - /vendor_id = / expected 'vendor_id = 0x8086', but QEMU prints 'PCI device 8086:2922' - /device_id = / expected separate line, but vendor:device are on the same line - /class = / expected 'class = 0x010601', but QEMU prints 'SATA controller:' or 'Class 0106:' - IRQ field expected 'IRQ 0.' but QEMU prints 'IRQ 5, pin A' Result: pci_summary.json was always invalid JSON with orphaned key-value pairs. Fix verified against QEMU source (pci-hmp-cmds.c:31-51) and tested with realistic 4-device output: all devices correctly parsed with bus/dev/fn, vendor_id, device_id, and IRQ fields. Found by: 5-agent parallel review (QA execution agent)
This commit is contained in:
@@ -444,29 +444,37 @@ hw_gen_pci_json() {
|
||||
printf ' "devices": [\n'
|
||||
|
||||
awk '
|
||||
/^Bus / {
|
||||
# Device header: " Bus 0, device 1, function 0:"
|
||||
# (QEMU outputs 2 leading spaces — no ^ anchor)
|
||||
/Bus .*device .*function/ {
|
||||
if (found) printf " },\n"
|
||||
found = 1
|
||||
bus = $2; gsub(/,/, "", bus)
|
||||
dev = $4; gsub(/,/, "", dev)
|
||||
fn = $6; gsub(/:/, "", fn)
|
||||
printf " {\"bus\": %s, \"device\": %s, \"function\": %s", bus, dev, fn
|
||||
next
|
||||
}
|
||||
/vendor_id = / {
|
||||
gsub(/.*= /, "", $0)
|
||||
printf ", \"vendor_id\": \"%s\"", $NF
|
||||
# Vendor/device line: " SATA controller: PCI device 8086:2922"
|
||||
# or: " Class 0106: PCI device 8086:2922"
|
||||
/PCI device/ {
|
||||
for (i = 1; i <= NF; i++) {
|
||||
if (index($i, ":") > 0) {
|
||||
split($i, vd, ":")
|
||||
if (length(vd[1]) == 4 && length(vd[2]) == 4 && \
|
||||
vd[1] ~ /^[0-9a-fA-F]+$/ && vd[2] ~ /^[0-9a-fA-F]+$/) {
|
||||
printf ", \"vendor_id\": \"0x%s\", \"device_id\": \"0x%s\"", vd[1], vd[2]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
next
|
||||
}
|
||||
/device_id = / {
|
||||
gsub(/.*= /, "", $0)
|
||||
printf ", \"device_id\": \"%s\"", $NF
|
||||
}
|
||||
/class = / {
|
||||
gsub(/.*= /, "", $0)
|
||||
printf ", \"class\": \"%s\"", $NF
|
||||
}
|
||||
/IRQ / {
|
||||
_irq = $2; gsub(/\./, "", _irq)
|
||||
# IRQ line: " IRQ 5, pin A"
|
||||
/IRQ [0-9]/ {
|
||||
_irq = $2; gsub(/,/, "", _irq)
|
||||
printf ", \"irq\": \"%s\"", _irq
|
||||
next
|
||||
}
|
||||
END { if (found) printf " }"; printf "\n" }
|
||||
' "$_pci" 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user