[libvirt] [PATCH v3 1/1] qemu_command: tidy up qemuBuildHostdevCommandLine loop
Michal Prívozník
mprivozn at redhat.com
Wed Dec 18 15:09:40 UTC 2019
On 12/18/19 10:28 AM, Daniel Henrique Barboza wrote:
> The current 'for' loop with 5 consecutive 'ifs' inside
> qemuBuildHostdevCommandLine can be a bit smarter:
>
> - all 5 'ifs' fails if hostdev->mode is not equal to
> VIR_DOMAIN_HOSTDEV_MODE_SUBSYS. This check can be moved to the
> start of the loop, failing to the next element immediately
> in case it fails;
>
> - all 5 'ifs' checks for a specific subsys->type to build the proper
> command line argument (virHostdevIsSCSIDevice and virHostdevIsMdevDevice
> do that but within a helper). Problem is that the code will keep
> checking for matches even if one was already found, and there is
> no way a hostdev will fit more than one 'if' (i.e. a hostdev can't
> have 2+ different types). This means that a SUBSYS_TYPE_USB will
> create its command line argument in the first 'if', then all other
> conditionals will surely fail but will end up being checked anyway.
>
> All of this can be avoided by moving the hostdev->mode comparing
> to the start of the loop and using a switch statement with
> subsys->type to execute the proper code for a given hostdev
> type.
>
> Suggested-by: Ján Tomko <jtomko at redhat.com>
> Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
> ---
> src/qemu/qemu_command.c | 52 +++++++++++++++++++++++++----------------
> 1 file changed, 32 insertions(+), 20 deletions(-)
Sorry for letting this slip review.
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 836057a4ff..948ef688f2 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -5309,23 +5309,31 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
> for (i = 0; i < def->nhostdevs; i++) {
> virDomainHostdevDefPtr hostdev = def->hostdevs[i];
> virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
> + virDomainHostdevSubsysSCSIPtr scsisrc;
> + virDomainHostdevSubsysMediatedDevPtr mdevsrc;
I think we can initialize these variables upfront, just like we are
doing in virDomainAuditHostdev(), virDomainHostdevDefParseXMLSubsys(),
qemuDomainGetHostdevPath() and many other places.
> g_autofree char *devstr = NULL;
> + g_autofree char *drvstr = NULL;
> + g_autofree char *vhostfdName = NULL;
> + unsigned int bootIndex;
And also this one.
> + int vhostfd = -1;
>
> - /* USB */
> - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
> - subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
> + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
> + continue;
>
> + switch (subsys->type) {
> + /* USB */
> + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
> virCommandAddArg(cmd, "-device");
> if (!(devstr =
> qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
> return -1;
> virCommandAddArg(cmd, devstr);
> - }
> +
> + break;
>
> /* PCI */
> - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
> - subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
> - unsigned int bootIndex = hostdev->info->bootIndex;
> + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
> + bootIndex = hostdev->info->bootIndex;
>
> /* bootNet will be non-0 if boot order was set and no other
> * net devices were encountered
> @@ -5343,13 +5351,12 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
> if (!devstr)
> return -1;
> virCommandAddArg(cmd, devstr);
> - }
> +
> + break;
>
> /* SCSI */
> - if (virHostdevIsSCSIDevice(hostdev)) {
> - virDomainHostdevSubsysSCSIPtr scsisrc =
> - &hostdev->source.subsys.u.scsi;
> - g_autofree char *drvstr = NULL;
> + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
> + scsisrc = &hostdev->source.subsys.u.scsi;
>
> if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
> virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc =
> @@ -5372,15 +5379,13 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
> if (!(devstr = qemuBuildSCSIHostdevDevStr(def, hostdev)))
> return -1;
> virCommandAddArg(cmd, devstr);
> - }
> +
> + break;
>
> /* SCSI_host */
> - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
> - subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
> + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> if (hostdev->source.subsys.u.scsi_host.protocol ==
> VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST) {
> - g_autofree char *vhostfdName = NULL;
> - int vhostfd = -1;
>
> if (virSCSIVHostOpenVhostSCSI(&vhostfd) < 0)
> return -1;
> @@ -5399,11 +5404,12 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
>
> virCommandAddArg(cmd, devstr);
> }
> - }
> +
> + break;
>
> /* MDEV */
> - if (virHostdevIsMdevDevice(hostdev)) {
> - virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
> + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
> + mdevsrc = &subsys->u.mdev;
>
> switch ((virMediatedDeviceModelType) mdevsrc->model) {
> case VIR_MDEV_MODEL_TYPE_VFIO_PCI:
> @@ -5422,6 +5428,12 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
> qemuBuildHostdevMediatedDevStr(def, hostdev, qemuCaps)))
> return -1;
> virCommandAddArg(cmd, devstr);
> +
> + break;
> +
> + default:
> + virReportEnumRangeError(virDomainHostdevSubsysType, subsys->type);
> + return -1;
If we typecast the variable used in switch() properly, then this can be
turned into "case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:".
I'm doing the suggested changes, ACKing and pushing.
Once again, sorry.
Michal
More information about the libvir-list
mailing list