qemuBuildInputCommandLine: Generate via JSON

For 'usb-mouse'/'usb-tablet'/'usb-kbd' we don't use any special
property.

For 'virtio-input-pci' we only use the 'evdev' argument which is a
string so this conversion doesn't impact anything.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-10-01 13:16:15 +02:00
parent 31e509ad39
commit 478725b7c3
3 changed files with 93 additions and 78 deletions

View File

@ -4281,21 +4281,19 @@ qemuBuildNVRAMCommandLine(virCommand *cmd,
}
static char *
qemuBuildVirtioInputDevStr(const virDomainDef *def,
virDomainInputDef *dev,
virQEMUCaps *qemuCaps)
virJSONValue *
qemuBuildInputVirtioDevProps(const virDomainDef *def,
virDomainInputDef *dev,
virQEMUCaps *qemuCaps)
{
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
g_autoptr(virJSONValue) props = NULL;
const char *evdev = NULL;
switch ((virDomainInputType)dev->type) {
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
case VIR_DOMAIN_INPUT_TYPE_TABLET:
case VIR_DOMAIN_INPUT_TYPE_KBD:
case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_INPUT, dev) < 0) {
return NULL;
}
break;
case VIR_DOMAIN_INPUT_TYPE_EVDEV:
case VIR_DOMAIN_INPUT_TYPE_LAST:
@ -4304,42 +4302,54 @@ qemuBuildVirtioInputDevStr(const virDomainDef *def,
return NULL;
}
virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
if (dev->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH)
evdev = dev->source.evdev;
if (dev->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH) {
virBufferAddLit(&buf, ",evdev=");
virQEMUBuildBufferEscapeComma(&buf, dev->source.evdev);
}
if (qemuBuildDeviceAddressStr(&buf, def, &dev->info) < 0)
if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_INPUT, dev, qemuCaps)))
return NULL;
return virBufferContentAndReset(&buf);
if (virJSONValueObjectAdd(props,
"s:id", dev->info.alias,
"S:evdev", evdev,
NULL) < 0)
return NULL;
if (qemuBuildDeviceAddressProps(props, def, &dev->info) < 0)
return NULL;
return g_steal_pointer(&props);
}
static char *
qemuBuildUSBInputDevStr(const virDomainDef *def,
virDomainInputDef *dev,
virQEMUCaps *qemuCaps G_GNUC_UNUSED)
virJSONValue *
qemuBuildInputUSBDevProps(const virDomainDef *def,
virDomainInputDef *dev)
{
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
g_autoptr(virJSONValue) props = NULL;
const char *driver = NULL;
switch (dev->type) {
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
virBufferAsprintf(&buf, "usb-mouse,id=%s", dev->info.alias);
driver = "usb-mouse";
break;
case VIR_DOMAIN_INPUT_TYPE_TABLET:
virBufferAsprintf(&buf, "usb-tablet,id=%s", dev->info.alias);
driver = "usb-tablet";
break;
case VIR_DOMAIN_INPUT_TYPE_KBD:
virBufferAsprintf(&buf, "usb-kbd,id=%s", dev->info.alias);
driver = "usb-kbd";
break;
}
if (qemuBuildDeviceAddressStr(&buf, def, &dev->info) < 0)
if (virJSONValueObjectCreate(&props,
"s:driver", driver,
"s:id", dev->info.alias,
NULL) < 0)
return NULL;
return virBufferContentAndReset(&buf);
if (qemuBuildDeviceAddressProps(props, def, &dev->info) < 0)
return NULL;
return g_steal_pointer(&props);
}
@ -4366,27 +4376,6 @@ qemuBuildInputEvdevProps(virDomainInputDef *dev)
}
int
qemuBuildInputDevStr(char **devstr,
const virDomainDef *def,
virDomainInputDef *input,
virQEMUCaps *qemuCaps)
{
switch (input->bus) {
case VIR_DOMAIN_INPUT_BUS_USB:
if (!(*devstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
return -1;
break;
case VIR_DOMAIN_INPUT_BUS_VIRTIO:
if (!(*devstr = qemuBuildVirtioInputDevStr(def, input, qemuCaps)))
return -1;
break;
}
return 0;
}
static int
qemuBuildInputCommandLine(virCommand *cmd,
const virDomainDef *def,
@ -4409,15 +4398,29 @@ qemuBuildInputCommandLine(virCommand *cmd,
if (qemuBuildObjectCommandlineFromJSON(cmd, props, qemuCaps) < 0)
return -1;
} else {
g_autofree char *devstr = NULL;
g_autoptr(virJSONValue) props = NULL;
if (qemuBuildInputDevStr(&devstr, def, input, qemuCaps) < 0)
return -1;
switch ((virDomainInputBus) input->bus) {
case VIR_DOMAIN_INPUT_BUS_USB:
if (!(props = qemuBuildInputUSBDevProps(def, input)))
return -1;
break;
if (devstr) {
virCommandAddArg(cmd, "-device");
virCommandAddArg(cmd, devstr);
case VIR_DOMAIN_INPUT_BUS_VIRTIO:
if (!(props = qemuBuildInputVirtioDevProps(def, input, qemuCaps)))
return -1;
case VIR_DOMAIN_INPUT_BUS_PS2:
case VIR_DOMAIN_INPUT_BUS_XEN:
case VIR_DOMAIN_INPUT_BUS_PARALLELS:
case VIR_DOMAIN_INPUT_BUS_NONE:
case VIR_DOMAIN_INPUT_BUS_LAST:
break;
}
if (props &&
qemuBuildDeviceCommandlineFromJSON(cmd, props, qemuCaps) < 0)
return -1;
}
}

View File

@ -237,12 +237,14 @@ virJSONValue *
qemuBuildWatchdogDevProps(const virDomainDef *def,
virDomainWatchdogDef *dev);
int qemuBuildInputDevStr(char **devstr,
const virDomainDef *def,
virDomainInputDef *input,
virQEMUCaps *qemuCaps)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
virJSONValue *
qemuBuildInputVirtioDevProps(const virDomainDef *def,
virDomainInputDef *dev,
virQEMUCaps *qemuCaps);
virJSONValue *
qemuBuildInputUSBDevProps(const virDomainDef *def,
virDomainInputDef *dev);
char *
qemuBuildVsockDevStr(virDomainDef *def,

View File

@ -3229,7 +3229,7 @@ qemuDomainAttachInputDevice(virQEMUDriver *driver,
virDomainInputDef *input)
{
int ret = -1;
g_autofree char *devstr = NULL;
g_autoptr(virJSONValue) devprops = NULL;
qemuDomainObjPrivate *priv = vm->privateData;
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_INPUT,
{ .input = input } };
@ -3239,29 +3239,39 @@ qemuDomainAttachInputDevice(virQEMUDriver *driver,
bool teardownlabel = false;
bool teardowncgroup = false;
if (input->bus != VIR_DOMAIN_INPUT_BUS_USB &&
input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) {
if (qemuAssignDeviceInputAlias(vm->def, input, -1) < 0)
return -1;
switch ((virDomainInputBus) input->bus) {
case VIR_DOMAIN_INPUT_BUS_USB:
if (virDomainUSBAddressEnsure(priv->usbaddrs, &input->info) < 0)
return -1;
releaseaddr = true;
if (!(devprops = qemuBuildInputUSBDevProps(vm->def, input)))
goto cleanup;
break;
case VIR_DOMAIN_INPUT_BUS_VIRTIO:
if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
goto cleanup;
if (!(devprops = qemuBuildInputVirtioDevProps(vm->def, input, priv->qemuCaps)))
goto cleanup;
break;
case VIR_DOMAIN_INPUT_BUS_PS2:
case VIR_DOMAIN_INPUT_BUS_XEN:
case VIR_DOMAIN_INPUT_BUS_PARALLELS:
case VIR_DOMAIN_INPUT_BUS_NONE:
case VIR_DOMAIN_INPUT_BUS_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("input device on bus '%s' cannot be hot plugged."),
virDomainInputBusTypeToString(input->bus));
return -1;
}
if (input->bus == VIR_DOMAIN_INPUT_BUS_VIRTIO) {
if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
return -1;
} else if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
if (virDomainUSBAddressEnsure(priv->usbaddrs, &input->info) < 0)
goto cleanup;
releaseaddr = true;
}
if (qemuAssignDeviceInputAlias(vm->def, input, -1) < 0)
goto cleanup;
if (qemuBuildInputDevStr(&devstr, vm->def, input, priv->qemuCaps) < 0)
goto cleanup;
if (qemuDomainNamespaceSetupInput(vm, input, &teardowndevice) < 0)
goto cleanup;
@ -3280,7 +3290,7 @@ qemuDomainAttachInputDevice(virQEMUDriver *driver,
if (qemuDomainAttachExtensionDevice(priv->mon, &input->info) < 0)
goto exit_monitor;
if (qemuMonitorAddDevice(priv->mon, devstr) < 0) {
if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0) {
ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &input->info));
goto exit_monitor;
}