On Wed, Jan 24, 2024 at 20:37:40 +0100, Andrea Bolognani wrote:
> In addition to the code in qemuDomainControllerDefPostParse(),
> which we have just factored into its own function, we also have
> some code in qemuDomainDefAddDefaultDevices() that deals with
> choosing the model for a USB controller, specifically for q35
> guests. Integrate it into the newly-created function.
>
> Since we want slightly different behaviors depending on whether
> the USB controller that we're working on is the one that we try
> to automatically add for certain new guests (addDefaultUSB),
> introduce a new parameter to the function and a new possible
> return value.
>
> Signed-off-by: Andrea Bolognani <[email protected]>
> ---
> src/qemu/qemu_domain.c | 74 ++++++++++++++++++++++++++++++++----------
> 1 file changed, 56 insertions(+), 18 deletions(-)
>
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 09f572b0b5..d992b51877 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -4151,9 +4151,35 @@ qemuDomainDefaultSCSIControllerModel(const
> virDomainDef *def,
> }
>
>
> +/**
> + * qemuDomainDefaultUSBControllerModel:
> + * @def: domain definition
> + * @cont: controller definition, or NULL
> + * @autoAdded: whether this controller is being automatically added
> + * @qemuCaps: QEMU capabilities, or NULL
> + * @parseFlags: parse flags
> + *
> + * Choose a reasonable model to use for a USB controller where a
> + * specific one hasn't been provided by the user.
> + *
> + * The choice is based on a number of factors, including the guest's
> + * architecture and machine type. @qemuCaps, if provided, might be
> + * taken into consideration too.
> + *
> + * @autoAdded should be true is this is a controller that libvirt is
> + * trying to automatically add on domain creation for the user's
> + * convenience: in that case, the function might decide to simply not
> + * add the controller instead of reporting a failure.
> + *
> + * Returns: >=0 (a virDomainControllerModelUSB value) on success,
> + * -1 on error, and
This is NOT an error and is misrepresenting the _DEFAULT case which has
-1, which is also a success case at least in some situations.
> + * -2 if no suitable model could be found but it's okay to
> + * just skip the controller altogether.
IMO this should be VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE and not a new
arbitrary value. I also don't think that this function needs to know
whether the controller was auto-added, or not
> + */
> static int
> qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
> const virDomainControllerDef *cont,
> + bool autoAdded,
> virQEMUCaps *qemuCaps,
> unsigned int parseFlags)
> {
> @@ -4169,7 +4195,7 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef
> *def,
> * See qemuBuildControllersCommandLine() */
>
> if (ARCH_IS_S390(def->os.arch)) {
> - if (cont->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
> + if (cont && cont->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
> /* set the default USB model to none for s390 unless an
> * address is found */
> return VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
> @@ -4198,6 +4224,22 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef
> *def,
> return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
> }
>
> + if (ARCH_IS_X86(def->os.arch)) {
> + if (qemuDomainIsQ35(def) && autoAdded) {
> + /* Prefer adding a USB3 controller if supported, fall back
> + * to USB2 if there is no USB3 available, and if that's
> + * unavailable don't add anything.
> + */
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
> + return VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
> + return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
> + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
> + return VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
> + return -2;
> + }
> + }
> +
> /* Default USB controller is piix3-uhci if available. */
> if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI))
> return VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
> @@ -4209,7 +4251,8 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef
> *def,
> static int
> qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
> virDomainDef *def,
> - virQEMUCaps *qemuCaps)
> + virQEMUCaps *qemuCaps,
> + unsigned int parseFlags)
> {
> bool addDefaultUSB = false;
> int usbModel = -1; /* "default for machinetype" */
> @@ -4243,20 +4286,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
> addPCIeRoot = true;
> addImplicitSATA = true;
> addITCOWatchdog = true;
> -
> - /* Prefer adding a USB3 controller if supported, fall back
> - * to USB2 if there is no USB3 available, and if that's
> - * unavailable don't add anything.
> - */
> - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
> - usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
> - else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
> - usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
> - else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
> - usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
> - else
> - addDefaultUSB = false;
> - break;
> }
> if (qemuDomainIsI440FX(def))
> addPCIRoot = true;
> @@ -4348,6 +4377,15 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
> break;
> }
>
> + if (addDefaultUSB) {
> + usbModel = qemuDomainDefaultUSBControllerModel(def, NULL, true,
> qemuCaps, parseFlags);
> + /* A return value of -2 indicates that no reasonable default
> + * could be figured out, and that we should handle that by
> + * not adding the USB controller */
> + if (usbModel == -2)
> + addDefaultUSB = false;
> + }
> +
> if (addDefaultUSB &&
> virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_USB, 0) < 0
> &&
> virDomainDefAddUSBController(def, 0, usbModel) < 0)
> @@ -5091,7 +5129,7 @@ qemuDomainDefPostParse(virDomainDef *def,
> if (qemuDomainDefBootPostParse(def, driver, parseFlags) < 0)
> return -1;
>
> - if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
> + if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps, parseFlags) <
> 0)
> return -1;
>
> if (qemuDomainDefSetDefaultCPU(def, driver->hostarch, qemuCaps) < 0)
> @@ -5695,7 +5733,7 @@ qemuDomainControllerDefPostParse(virDomainControllerDef
> *cont,
>
> case VIR_DOMAIN_CONTROLLER_TYPE_USB:
> if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT &&
> qemuCaps) {
> - cont->model = qemuDomainDefaultUSBControllerModel(def, cont,
> qemuCaps, parseFlags);
> + cont->model = qemuDomainDefaultUSBControllerModel(def, cont,
> false, qemuCaps, parseFlags);
The code can check here explicitly whether _NONE was returned and
report appropriate error.
> }
> /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */
> if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 ||
> --
> 2.43.0
> _______________________________________________
> Devel mailing list -- [email protected]
ws> To unsubscribe send an email to [email protected]
_______________________________________________
Devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]