qemu: implement input device hotplug

For both virtio input devices and USB input devices.

https://bugzilla.redhat.com/show_bug.cgi?id=1379603
This commit is contained in:
Ján Tomko 2017-10-04 11:09:27 +02:00
parent c547a5f8d8
commit bc9ffafcc7
4 changed files with 88 additions and 1 deletions

View File

@ -157,6 +157,7 @@ virDomainAuditDisk;
virDomainAuditFS;
virDomainAuditHostdev;
virDomainAuditInit;
virDomainAuditInput;
virDomainAuditIOThread;
virDomainAuditMemory;
virDomainAuditNet;
@ -386,6 +387,7 @@ virDomainHubTypeFromString;
virDomainHubTypeToString;
virDomainHypervTypeFromString;
virDomainHypervTypeToString;
virDomainInputBusTypeToString;
virDomainInputDefFind;
virDomainInputDefFree;
virDomainIOMMUModelTypeFromString;

View File

@ -7664,9 +7664,16 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
}
break;
case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainAttachInputDevice(driver, vm, dev->data.input);
if (ret == 0) {
alias = dev->data.input->info.alias;
dev->data.input = NULL;
}
break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT:
case VIR_DOMAIN_DEVICE_SOUND:
case VIR_DOMAIN_DEVICE_VIDEO:
case VIR_DOMAIN_DEVICE_GRAPHICS:

View File

@ -2905,6 +2905,79 @@ qemuDomainAttachWatchdog(virQEMUDriverPtr driver,
}
int
qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainInputDefPtr input)
{
int ret = -1;
char *devstr = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_INPUT,
{ .input = input } };
bool releaseaddr = false;
if (input->bus != VIR_DOMAIN_INPUT_BUS_USB &&
input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) {
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, "input") < 0)
return -1;
} else if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
if (priv->usbaddrs) {
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 (VIR_REALLOC_N(vm->def->inputs, vm->def->ninputs + 1) < 0)
goto cleanup;
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
goto exit_monitor;
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
releaseaddr = false;
goto cleanup;
}
VIR_APPEND_ELEMENT_COPY_INPLACE(vm->def->inputs, vm->def->ninputs, input);
ret = 0;
releaseaddr = false;
audit:
virDomainAuditInput(vm, input, "attach", ret == 0);
cleanup:
if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, &input->info, NULL);
VIR_FREE(devstr);
return ret;
exit_monitor:
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
releaseaddr = false;
goto cleanup;
}
goto audit;
}
static int
qemuDomainChangeNetBridge(virDomainObjPtr vm,
virDomainNetDefPtr olddev,

View File

@ -125,6 +125,11 @@ int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
int qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainWatchdogDefPtr watchdog);
int qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainInputDefPtr input);
int qemuDomainAttachLease(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainLeaseDefPtr lease);