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'
|
printf ' "devices": [\n'
|
||||||
|
|
||||||
awk '
|
awk '
|
||||||
/^Bus / {
|
# Device header: " Bus 0, device 1, function 0:"
|
||||||
|
# (QEMU outputs 2 leading spaces — no ^ anchor)
|
||||||
|
/Bus .*device .*function/ {
|
||||||
if (found) printf " },\n"
|
if (found) printf " },\n"
|
||||||
found = 1
|
found = 1
|
||||||
bus = $2; gsub(/,/, "", bus)
|
bus = $2; gsub(/,/, "", bus)
|
||||||
dev = $4; gsub(/,/, "", dev)
|
dev = $4; gsub(/,/, "", dev)
|
||||||
fn = $6; gsub(/:/, "", fn)
|
fn = $6; gsub(/:/, "", fn)
|
||||||
printf " {\"bus\": %s, \"device\": %s, \"function\": %s", bus, dev, fn
|
printf " {\"bus\": %s, \"device\": %s, \"function\": %s", bus, dev, fn
|
||||||
|
next
|
||||||
}
|
}
|
||||||
/vendor_id = / {
|
# Vendor/device line: " SATA controller: PCI device 8086:2922"
|
||||||
gsub(/.*= /, "", $0)
|
# or: " Class 0106: PCI device 8086:2922"
|
||||||
printf ", \"vendor_id\": \"%s\"", $NF
|
/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
|
||||||
}
|
}
|
||||||
/device_id = / {
|
|
||||||
gsub(/.*= /, "", $0)
|
|
||||||
printf ", \"device_id\": \"%s\"", $NF
|
|
||||||
}
|
}
|
||||||
/class = / {
|
|
||||||
gsub(/.*= /, "", $0)
|
|
||||||
printf ", \"class\": \"%s\"", $NF
|
|
||||||
}
|
}
|
||||||
/IRQ / {
|
next
|
||||||
_irq = $2; gsub(/\./, "", _irq)
|
}
|
||||||
|
# IRQ line: " IRQ 5, pin A"
|
||||||
|
/IRQ [0-9]/ {
|
||||||
|
_irq = $2; gsub(/,/, "", _irq)
|
||||||
printf ", \"irq\": \"%s\"", _irq
|
printf ", \"irq\": \"%s\"", _irq
|
||||||
|
next
|
||||||
}
|
}
|
||||||
END { if (found) printf " }"; printf "\n" }
|
END { if (found) printf " }"; printf "\n" }
|
||||||
' "$_pci" 2>/dev/null
|
' "$_pci" 2>/dev/null
|
||||||
|
|||||||
Reference in New Issue
Block a user