Copilot commented on code in PR #12981:
URL: https://github.com/apache/cloudstack/pull/12981#discussion_r3050683197


##########
scripts/vm/hypervisor/kvm/gpudiscovery.sh:
##########
@@ -882,10 +989,7 @@ for LINE in "${LINES[@]}"; do
        if [[ ${#vlist[@]} -eq 0 && ${#flist[@]} -eq 0 ]]; then
                FP_ENABLED=1
        fi

Review Comment:
   `parse_pci_address` assigns `DOMAIN/BUS/SLOT/FUNC` via bash dynamic scoping; 
these call sites don’t declare those variables `local` first, so the values can 
leak into the global scope (and between loop iterations), making future 
changes/debugging brittle. Declare `local DOMAIN BUS SLOT FUNC` in the 
immediate scope before calling `parse_pci_address` (as is already done in 
`process_mdev_instances`), or refactor `parse_pci_address` to return values 
explicitly (e.g., via stdout or nameref parameters).
   ```suggestion
        fi
        local DOMAIN BUS SLOT FUNC
   ```



##########
scripts/vm/hypervisor/kvm/gpudiscovery.sh:
##########
@@ -791,36 +892,35 @@ for LINE in "${LINES[@]}"; do
        PF_MAX_RESOLUTION_Y=$MAX_RESOLUTION_Y
 
        # === full_passthrough usage ===
-       raw="${pci_to_vm[$PCI_ADDR]:-}"
+       # pci_to_vm is keyed by the full domain-qualified form, so normalize the
+       # lspci-style PCI_ADDR (which may be short for domain 0) before lookup.
+       raw="${pci_to_vm[$(normalize_pci_address "$PCI_ADDR")]:-}"
        FULL_USED_JSON=$(to_json_vm "$raw")
 
        # === vGPU (MDEV) instances ===
        VGPU_ARRAY="[]"
        declare -a vlist=()
        # Process mdev on the Physical Function
-       MDEV_BASE="/sys/bus/pci/devices/0000:$PCI_ADDR/mdev_supported_types"
+       MDEV_BASE="/sys/bus/pci/devices/$SYSFS_ADDR/mdev_supported_types"
        process_mdev_instances "$MDEV_BASE" "$PCI_ADDR"
 
        # === VF instances (SR-IOV / MIG) ===
        VF_ARRAY="[]"
        declare -a flist=()
        if ((TOTALVFS > 0)); then
-               for VF_LINK in /sys/bus/pci/devices/0000:"$PCI_ADDR"/virtfn*; do
+               for VF_LINK in /sys/bus/pci/devices/"$SYSFS_ADDR"/virtfn*; do
                        [[ -L $VF_LINK ]] || continue
                        VF_PATH=$(readlink -f "$VF_LINK")
-                       VF_ADDR=${VF_PATH##*/} # e.g. "0000:65:00.2"
-                       VF_BDF="${VF_ADDR:5}"  # "65:00.2"
+                       # Keep the full domain-qualified address (e.g. 
"0000:65:00.2")
+                       VF_BDF=${VF_PATH##*/}
 
                        # For NVIDIA SR-IOV, check for vGPU (mdev) on the VF 
itself
                        if [[ "$VENDOR_ID" == "10de" ]]; then
                                VF_MDEV_BASE="$VF_PATH/mdev_supported_types"
                                process_mdev_instances "$VF_MDEV_BASE" "$VF_BDF"
                        fi
 

Review Comment:
   `parse_pci_address` assigns `DOMAIN/BUS/SLOT/FUNC` via bash dynamic scoping; 
these call sites don’t declare those variables `local` first, so the values can 
leak into the global scope (and between loop iterations), making future 
changes/debugging brittle. Declare `local DOMAIN BUS SLOT FUNC` in the 
immediate scope before calling `parse_pci_address` (as is already done in 
`process_mdev_instances`), or refactor `parse_pci_address` to return values 
explicitly (e.g., via stdout or nameref parameters).
   ```suggestion
   
                        local DOMAIN BUS SLOT FUNC
   ```



##########
scripts/vm/hypervisor/kvm/gpudiscovery.sh:
##########
@@ -613,16 +701,21 @@ for VM in "${VMS[@]}"; do
                continue
        fi
 
-       # -- PCI hostdevs: use xmlstarlet to extract BDF for all PCI host 
devices --
-       while read -r bus slot func; do
+       # -- PCI hostdevs: use xmlstarlet to extract the full 
domain:bus:slot.func
+       # for all PCI host devices. libvirt's <address> element may omit the 
domain
+       # attribute, in which case we default to 0.
+       while read -r dom bus slot func; do
                [[ -n "$bus" && -n "$slot" && -n "$func" ]] || continue
-               # Format to match lspci output (e.g., 01:00.0) by padding with 
zeros
+               [[ -n "$dom" ]] || dom="0"
+               # Format to match lspci -D output (e.g., 0000:01:00.0) by 
padding with zeros
+               dom_fmt=$(printf "%04x" "0x$dom")
                bus_fmt=$(printf "%02x" "0x$bus")
                slot_fmt=$(printf "%02x" "0x$slot")
                func_fmt=$(printf "%x" "0x$func")
-               BDF="$bus_fmt:$slot_fmt.$func_fmt"
+               BDF="${dom_fmt}:${bus_fmt}:${slot_fmt}.${func_fmt}"
                pci_to_vm["$BDF"]="$VM"
        done < <(echo "$xml" | xmlstarlet sel -T -t -m 
"//hostdev[@type='pci']/source/address" \
+               -v "substring-after(@domain, '0x')" -o " " \
                -v "substring-after(@bus, '0x')" -o " " \
                -v "substring-after(@slot, '0x')" -o " " \
                -v "substring-after(@function, '0x')" -n 2>/dev/null || true)

Review Comment:
   `xmlstarlet` emits an empty first field when `@domain` is missing; because 
`read` collapses leading whitespace, `dom` will incorrectly receive the bus 
value and `func` becomes empty, causing `[[ -n "$bus" && -n "$slot" && -n 
"$func" ]]` to fail and the hostdev mapping to be skipped. Fix by making the 
selector always output a domain token (e.g., defaulting to `0000` in the XPath 
output), or by adjusting the parsing logic to detect the 3-field case and treat 
it as “domain missing”.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to