From b3969a6ce091e52512a40b30bad0f1c2a2d72dbe Mon Sep 17 00:00:00 2001 From: m0duspwnens Date: Fri, 24 Jan 2025 17:19:41 -0500 Subject: [PATCH] fix hardware passthrough for pci devices --- salt/_modules/qcow2.py | 21 +++++++++--- salt/hypervisor/defaults.brainstorm.yaml | 0 .../tools/sbin/so-kvm-modify-hardware | 33 ++++++++++++------- salt/manager/tools/sbin/so-salt-cloud | 19 ++++++----- 4 files changed, 48 insertions(+), 25 deletions(-) delete mode 100644 salt/hypervisor/defaults.brainstorm.yaml diff --git a/salt/_modules/qcow2.py b/salt/_modules/qcow2.py index 37858484e..d1de6756a 100644 --- a/salt/_modules/qcow2.py +++ b/salt/_modules/qcow2.py @@ -131,7 +131,7 @@ def modify_network_config(image, interface, mode, ip4=None, gw4=None, dns4=None, def modify_hardware_config(vm_name, cpu=None, memory=None, pci=None, start=False): ''' Usage: - salt '*' qcow2.modify_hardware_config vm_name= [cpu=] [memory=] [pci=] [start=] + salt '*' qcow2.modify_hardware_config vm_name= [cpu=] [memory=] [pci=] [pci=] [start=] Options: vm_name @@ -143,7 +143,8 @@ def modify_hardware_config(vm_name, cpu=None, memory=None, pci=None, start=False Amount of memory to assign in MiB (positive integer) Optional - VM's current memory size retained if not specified pci - PCI hardware ID to passthrough to the VM (e.g., '0000:00:1f.2') + PCI hardware ID(s) to passthrough to the VM (e.g., '0000:c7:00.0') + Can be specified multiple times for multiple devices Optional - no PCI passthrough if not specified start Boolean flag to start the VM after modification @@ -158,13 +159,13 @@ def modify_hardware_config(vm_name, cpu=None, memory=None, pci=None, start=False 2. **Enable PCI Passthrough:** ```bash - salt '*' qcow2.modify_hardware_config vm_name='sensor1' pci='0000:00:1f.2' start=True + salt '*' qcow2.modify_hardware_config vm_name='sensor1' pci='0000:c7:00.0' pci='0000:c4:00.0' start=True ``` This configures PCI passthrough and starts the VM 3. **Complete Hardware Configuration:** ```bash - salt '*' qcow2.modify_hardware_config vm_name='sensor1' cpu=8 memory=16384 pci='0000:00:1f.2' start=True + salt '*' qcow2.modify_hardware_config vm_name='sensor1' cpu=8 memory=16384 pci='0000:c7:00.0' start=True ``` This sets CPU, memory, PCI passthrough, and starts the VM @@ -210,7 +211,17 @@ def modify_hardware_config(vm_name, cpu=None, memory=None, pci=None, start=False else: raise ValueError('memory must be a positive integer.') if pci: - cmd.extend(['-p', pci]) + # Handle PCI IDs (can be a single device or comma-separated list) + if isinstance(pci, str): + devices = [dev.strip() for dev in pci.split(',') if dev.strip()] + elif isinstance(pci, list): + devices = pci + else: + devices = [pci] + + # Add each device with its own -p flag + for device in devices: + cmd.extend(['-p', str(device)]) if start: cmd.append('-s') diff --git a/salt/hypervisor/defaults.brainstorm.yaml b/salt/hypervisor/defaults.brainstorm.yaml deleted file mode 100644 index e69de29bb..000000000 diff --git a/salt/hypervisor/tools/sbin/so-kvm-modify-hardware b/salt/hypervisor/tools/sbin/so-kvm-modify-hardware index e2d64919a..a6becfb95 100644 --- a/salt/hypervisor/tools/sbin/so-kvm-modify-hardware +++ b/salt/hypervisor/tools/sbin/so-kvm-modify-hardware @@ -25,7 +25,8 @@ used during VM provisioning and hardware reconfiguration tasks. -v, --vm Name of the virtual machine to modify. -c, --cpu Number of virtual CPUs to assign. -m, --memory Amount of memory to assign in MiB. - -p, --pci PCI hardware ID(s) to passthrough to the VM (e.g., 0000:00:1f.2). Can be specified multiple times. + -p, --pci PCI hardware ID(s) to passthrough to the VM (e.g., 0000:c7:00.0). Can be specified multiple times. + Format: domain:bus:device.function -s, --start Start the VM after modification. **Examples:** @@ -33,7 +34,7 @@ used during VM provisioning and hardware reconfiguration tasks. 1. **Modify CPU and Memory with Multiple PCI Devices:** ```bash - so-kvm-modify-hardware -v vm1_sensor -c 4 -m 8192 -p 0000:00:1f.2 -p 0000:00:1f.3 -s + so-kvm-modify-hardware -v vm1_sensor -c 4 -m 8192 -p 0000:c7:00.0 -p 0000:c8:00.0 -s ``` This command modifies a VM with the following settings: @@ -41,18 +42,18 @@ used during VM provisioning and hardware reconfiguration tasks. - Hardware Configuration: - CPUs: `4` - Memory: `8192` MiB - - PCI Device Passthrough: `0000:00:1f.2`, `0000:00:1f.3` + - PCI Device Passthrough: `0000:c7:00.0`, `0000:c8:00.0` - The VM is started after modification due to the `-s` flag 2. **Add PCI Device Without Other Changes:** ```bash - so-kvm-modify-hardware -v vm2_master -p 0000:00:1f.4 + so-kvm-modify-hardware -v vm2_master -p 0000:c7:00.0 ``` This command adds a single PCI device passthrough to the VM: - VM Name: `vm2_master` - - PCI Device: `0000:00:1f.4` + - PCI Device: `0000:c7:00.0` - Existing CPU and memory settings are preserved 3. **Update Resource Allocation:** @@ -70,19 +71,19 @@ used during VM provisioning and hardware reconfiguration tasks. 4. **Add Multiple PCI Devices:** ```bash - so-kvm-modify-hardware -v vm4_node -p 0000:00:1f.2 -p 0000:00:1f.3 -p 0000:00:1f.4 -s + so-kvm-modify-hardware -v vm4_node -p 0000:c7:00.0 -p 0000:c4:00.0 -p 0000:c4:00.1 -s ``` This command adds multiple PCI devices and starts the VM: - VM Name: `vm4_node` - - PCI Devices: `0000:00:1f.2`, `0000:00:1f.3`, `0000:00:1f.4` + - PCI Devices: `0000:c7:00.0`, `0000:c4:00.0`, `0000:c4:00.1` - VM is started after modification **Notes:** - The script automatically stops the VM if it's running before making modifications. - At least one modification option (-c, -m, or -p) should be provided. -- The PCI hardware IDs must be in the format `domain:bus:slot.function` (e.g., `0000:00:1f.2`). +- The PCI hardware IDs must be in the format `domain:bus:device.function` (e.g., `0000:c7:00.0`). - Multiple PCI devices can be added by using the `-p` option multiple times. - Without the `-s` flag, the VM remains stopped after modification. - Existing hardware configurations are preserved if not explicitly modified. @@ -183,9 +184,19 @@ def modify_vm(dom, cpu_count, memory_amount, pci_ids, logger): 'managed': 'yes' }) source_elem = ET.SubElement(hostdev_elem, 'source') - domain_id, bus_slot_func = pci_id.split(':', 1) - bus_slot, function = bus_slot_func.split('.') - bus, slot = bus_slot[:2], bus_slot[2:] + # Split PCI ID into components (domain:bus:slot.function) + parts = pci_id.split(':') + if len(parts) != 3: + logger.error(f"Invalid PCI ID format: {pci_id}. Expected format: domain:bus:slot.function") + sys.exit(1) + domain_id = parts[0] + bus = parts[1] + slot_func = parts[2].split('.') + if len(slot_func) != 2: + logger.error(f"Invalid PCI ID format: {pci_id}. Expected format: domain:bus:slot.function") + sys.exit(1) + slot = slot_func[0] + function = slot_func[1] address_attrs = { 'domain': f'0x{domain_id}', 'bus': f'0x{bus}', diff --git a/salt/manager/tools/sbin/so-salt-cloud b/salt/manager/tools/sbin/so-salt-cloud index 3edc1c385..78473d96a 100644 --- a/salt/manager/tools/sbin/so-salt-cloud +++ b/salt/manager/tools/sbin/so-salt-cloud @@ -49,7 +49,8 @@ Options: --search4 DNS search domain for IPv4. -c, --cpu Number of virtual CPUs to assign. -m, --memory Amount of memory to assign in MiB. - -P, --pci PCI hardware ID(s) to passthrough to the VM (e.g., 0000:00:1f.2). Can be specified multiple times. + -P, --pci PCI hardware ID(s) to passthrough to the VM (e.g., 0000:c7:00.0). Can be specified multiple times. + Format: domain:bus:device.function Examples: @@ -57,7 +58,7 @@ Examples: Command: so-salt-cloud -p sool9-hyper1 vm1_sensor --static4 --ip4 192.168.1.10/24 --gw4 192.168.1.1 \ - --dns4 192.168.1.1,192.168.1.2 --search4 example.local -c 4 -m 8192 -P 0000:00:1f.2 -P 0000:00:1f.3 + --dns4 192.168.1.1,192.168.1.2 --search4 example.local -c 4 -m 8192 -P 0000:c7:00.0 -P 0000:c4:00.0 This command provisions a VM named vm1_sensor using the sool9-hyper1 profile with the following settings: @@ -69,7 +70,7 @@ Examples: - Hardware Configuration: - CPUs: 4 - Memory: 8192 MiB - - PCI Device Passthrough: 0000:00:1f.2, 0000:00:1f.3 + - PCI Device Passthrough: 0000:c7:00.0, 0000:c4:00.0 2. DHCP Configuration with Default Hardware Settings: @@ -88,13 +89,13 @@ Examples: 4. DHCP Configuration with Custom Hardware Specifications and Multiple PCI Devices: Command: - so-salt-cloud -p sool9-hyper1 vm4_node --dhcp4 -c 8 -m 16384 -P 0000:00:1f.4 -P 0000:00:1f.5 + so-salt-cloud -p sool9-hyper1 vm4_node --dhcp4 -c 8 -m 16384 -P 0000:c7:00.0 -P 0000:c4:00.0 -P 0000:c4:00.1 This command provisions a VM named vm4_node using DHCP for network configuration and custom hardware settings: - CPUs: 8 - Memory: 16384 MiB - - PCI Device Passthrough: 0000:00:1f.4, 0000:00:1f.5 + - PCI Device Passthrough: 0000:c7:00.0, 0000:c4:00.0, 0000:c4:00.1 5. Static IP Configuration with DNS and Search Domain: @@ -116,6 +117,7 @@ Notes: - Hardware parameters (-c, -m, -P) are optional. If not provided, default values from the profile will be used. - The -P or --pci option can be specified multiple times to pass through multiple PCI devices to the VM. - The vm_name should include the role of the VM after an underscore (e.g., hostname_role), as the script uses this to determine the VM's role for firewall configuration. +- PCI hardware IDs must be in the format domain:bus:device.function (e.g., 0000:c7:00.0). Description: @@ -283,9 +285,8 @@ def run_qcow2_modify_hardware_config(profile, vm_name, cpu=None, memory=None, pc # Add PCI devices if provided if pci_list: - # Join the list of PCI IDs into a comma-separated string - pci_devices = ','.join(pci_list) - args_list.append('pci=' + pci_devices) + # Pass all PCI devices as a comma-separated list + args_list.append('pci=' + ','.join(pci_list)) r = local.cmd(target, 'qcow2.modify_hardware_config', args_list) logger.info(f'qcow2.modify_hardware_config: {r}') @@ -327,7 +328,7 @@ def parse_arguments(): parser.add_argument("--search4", help="DNS search domain for IPv4.") parser.add_argument('-c', '--cpu', type=int, help='Number of virtual CPUs to assign.') parser.add_argument('-m', '--memory', type=int, help='Amount of memory to assign in MiB.') - parser.add_argument('-P', '--pci', action='append', help='PCI hardware ID(s) to passthrough to the VM (e.g., 0000:00:1f.2). Can be specified multiple times.') + parser.add_argument('-P', '--pci', action='append', help='PCI hardware ID(s) to passthrough to the VM (e.g., 0000:c7:00.0). Can be specified multiple times.') args = parser.parse_args()