-
Notifications
You must be signed in to change notification settings - Fork 179
LIBVIRTAT-20967: Add multiple VFIO interfaces in vIOMMU test #6590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
bdce0d5
213aba1
7f94c7e
8c2b566
19b1adb
31b0139
869b90c
c771b29
a5be1ec
23db7a5
75e1f85
ecf63c8
9e1b307
5f587be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -58,9 +58,16 @@ def run(test, params, env): | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| iface_dict = test_obj.parse_iface_dict() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cleanup_ifaces: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| libvirt_vmxml.modify_vm_device( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vm_xml.VMXML.new_from_dumpxml(vm.name), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "interface", iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Handle both single dict and list of dicts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(iface_dict, list): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for single_iface_dict in iface_dict: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| libvirt_vmxml.modify_vm_device( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vm_xml.VMXML.new_from_dumpxml(vm.name), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "interface", single_iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| libvirt_vmxml.modify_vm_device( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vm_xml.VMXML.new_from_dumpxml(vm.name), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "interface", iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
68
to
80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainConsider error handling for multi-interface cleanup. The current implementation iterates through interface dicts without error handling. If Consider wrapping the cleanup calls in a try-except block to ensure all interfaces are attempted: if cleanup_ifaces:
# Handle both single dict and list of dicts
if isinstance(iface_dict, list):
for single_iface_dict in iface_dict:
- libvirt_vmxml.modify_vm_device(
- vm_xml.VMXML.new_from_dumpxml(vm.name),
- "interface", single_iface_dict)
+ try:
+ libvirt_vmxml.modify_vm_device(
+ vm_xml.VMXML.new_from_dumpxml(vm.name),
+ "interface", single_iface_dict)
+ except Exception as e:
+ test.log.warning(f"Failed to cleanup interface: {e}")
else:
libvirt_vmxml.modify_vm_device(
vm_xml.VMXML.new_from_dumpxml(vm.name),
"interface", iface_dict)Additionally, verify that 🏁 Script executed: #!/bin/bash
# Description: Verify parse_iface_dict() implementation and its validation logic
# Search for the parse_iface_dict method definition
ast-grep --pattern $'def parse_iface_dict($$$) {
$$$
}'
# Also search for type validation or list handling in parse_iface_dict
rg -n -C5 'def parse_iface_dict' --type=pyLength of output: 4071 🏁 Script executed: #!/bin/bash
sed -n '110,200p' provider/viommu/viommu_base.pyLength of output: 4517 Isolate interface cleanup failures and validate types if cleanup_ifaces:
# Handle both single dict and list of dicts
if isinstance(iface_dict, list):
for single_iface_dict in iface_dict:
+ if not isinstance(single_iface_dict, dict):
+ test.log.warning(f"Skipping invalid iface entry: {single_iface_dict!r}")
+ continue
+ try:
libvirt_vmxml.modify_vm_device(
vm_xml.VMXML.new_from_dumpxml(vm.name),
"interface", single_iface_dict)
+ except Exception as e:
+ test.log.warning(f"Failed to cleanup interface: {e}")
else:
libvirt_vmxml.modify_vm_device(
vm_xml.VMXML.new_from_dumpxml(vm.name),
"interface", iface_dict)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test.log.info("TEST_STEP: Start the VM.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vm.start() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -111,13 +111,30 @@ def __init__(self, vm, test, params, session=None): | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| def parse_iface_dict(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Parse iface_dict from params | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Parse iface_dict from params, supporting both single dict and list of dicts | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| :return: The updated iface_dict | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| :return: The updated iface_dict or list of iface_dicts based on type of input | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # generate mac address, if it is needed in iface_dict | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| mac_addr = utils_net.generate_mac_address_simple() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hholoubk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| iface_dict = eval(self.params.get("iface_dict", "{}")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
hholoubk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(iface_dict, list): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| for single_iface_dict in iface_dict: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._update_iface_dict_with_controller_info(single_iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| result.append(single_iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return result | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._update_iface_dict_with_controller_info(iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return iface_dict | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+123
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add input validation and error handling. The code assumes Consider adding validation: iface_dict = literal_eval(self.params.get("iface_dict", "{}"))
+
+ if not isinstance(iface_dict, (dict, list)):
+ raise ValueError(f"iface_dict must be dict or list, got {type(iface_dict).__name__}")
if isinstance(iface_dict, list):
+ if not all(isinstance(item, dict) for item in iface_dict):
+ raise ValueError("All items in iface_dict list must be dicts")
result = []
for single_iface_dict in iface_dict:
self._update_iface_dict_with_controller_info(single_iface_dict)
result.append(single_iface_dict)
return result
else:
self._update_iface_dict_with_controller_info(iface_dict)
return iface_dict📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _update_iface_dict_with_controller_info(self, iface_dict): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Update interface dictionary with controller addressing information | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| :param iface_dict: Interface dictionary to update with controller info | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.controller_dicts and iface_dict: | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| iface_bus = "%0#4x" % int(self.controller_dicts[-1].get("index")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| iface_attrs = {"bus": iface_bus} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -129,7 +146,6 @@ def parse_iface_dict(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| iface_dict.update({"address": {"attrs": iface_attrs}}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.test.log.debug("iface_dict: %s.", iface_dict) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return iface_dict | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| def prepare_controller(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify controller count and device placement.
The ASCII diagram in lines 103-107 suggests 4 pcie-root-ports are needed (one each for: virtio network interface, two VFIO interfaces, and virtio disk), but
controller_dictsat line 112 only defines 3 root-ports (root_port1,root_port2,root_port3).Additionally, this variant introduces:
iface_dict(line 115): one virtio network and two VFIO hostdevsvf_pci_addr2for the second VFIO interfacePlease clarify:
vf_pci_addr2is properly defined in the test environmentparse_iface_dict()and related functions) correctly handles a list with mixed interface types (virtio network + hostdev)Consider updating the comment or adding a 4th root-port to match the described topology:
root_port1 = {'type': 'pci', 'model': 'pcie-root-port', 'pre_controller': 'pcie-expander-bus'} root_port2 = {'type': 'pci', 'model': 'pcie-root-port', 'pre_controller': 'pcie-expander-bus'} root_port3 = {'type': 'pci', 'model': 'pcie-root-port', 'pre_controller': 'pcie-expander-bus'} - controller_dicts = [${expander_bus}, ${root_port1}, ${root_port2}, ${root_port3}] + root_port4 = {'type': 'pci', 'model': 'pcie-root-port', 'pre_controller': 'pcie-expander-bus'} + controller_dicts = [${expander_bus}, ${root_port1}, ${root_port2}, ${root_port3}, ${root_port4}]📝 Committable suggestion
🤖 Prompt for AI Agents