qemu_hotplug: standardize the names/args/calling of qemuDomainDetach*()

Most of these functions will soon contain only some setup for
detaching the device, not the detach code proper (since that code is
identical for these devices). Their device specific functions are all
being renamed to qemuDomainDetachPrep*(), where * is the
name of that device's data member in the virDomainDeviceDef
object.

Since there will be other code in qemuDomainDetachDeviceLive() after
the calls to qemuDomainDetachPrep*() that could still fail, we no
longer directly set "ret" with the return code from
qemuDomainDetachPrep*() functions, but simply return -1 on
failure, and wait until the end of qemuDomainDetachDeviceLive() to set
ret = 0.

Along with the rename, qemuDomainDetachPrep*() functions are also
given similar arglists, including an arg called "match" that points to
the proto-object of the device we want to delete, and another arg
"detach" that is used to return a pointer to the actual object that
will be (for now *has been*) detached. To make sure these new args
aren't confused with existing local pointers that sometimes had the
same name (detach), the local pointer to the device is now named after
the device type ("controller", "disk", etc). These point to the same
place as (*detach)->data.blah, it's just easier on the eyes to have,
e.g., "disk->dst" rather than "(*detach)->data.disk-dst".

Signed-off-by: Laine Stump <laine@laine.org>
ACKed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Laine Stump 2019-03-20 14:32:53 -04:00
parent 2ec6faea79
commit b6a53bf907

View File

@ -5370,21 +5370,22 @@ qemuFindDisk(virDomainDefPtr def, const char *dst)
} }
static int static int
qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, qemuDomainDetachPrepDisk(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev, virDomainDiskDefPtr match,
virDomainDiskDefPtr *detach,
bool async) bool async)
{ {
virDomainDiskDefPtr disk; virDomainDiskDefPtr disk;
int idx; int idx;
int ret = -1; int ret = -1;
if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) { if ((idx = qemuFindDisk(vm->def, match->dst)) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("disk %s not found"), dev->data.disk->dst); _("disk %s not found"), match->dst);
return -1; return -1;
} }
disk = vm->def->disks[idx]; *detach = disk = vm->def->disks[idx];
switch ((virDomainDiskDevice) disk->device) { switch ((virDomainDiskDevice) disk->device) {
case VIR_DOMAIN_DISK_DEVICE_DISK: case VIR_DOMAIN_DISK_DEVICE_DISK:
@ -5521,57 +5522,55 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
} }
static int static int
qemuDomainDetachControllerDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepController(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev, virDomainControllerDefPtr match,
virDomainControllerDefPtr *detach,
bool async) bool async)
{ {
int idx, ret = -1; int idx, ret = -1;
virDomainControllerDefPtr detach = NULL; virDomainControllerDefPtr controller = NULL;
if (dev->data.controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("'%s' controller cannot be hot unplugged."), _("'%s' controller cannot be hot unplugged."),
virDomainControllerTypeToString(dev->data.controller->type)); virDomainControllerTypeToString(match->type));
return -1; return -1;
} }
if ((idx = virDomainControllerFind(vm->def, if ((idx = virDomainControllerFind(vm->def, match->type, match->idx)) < 0) {
dev->data.controller->type,
dev->data.controller->idx)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING, virReportError(VIR_ERR_DEVICE_MISSING,
_("controller %s:%d not found"), _("controller %s:%d not found"),
virDomainControllerTypeToString(dev->data.controller->type), virDomainControllerTypeToString(match->type),
dev->data.controller->idx); match->idx);
goto cleanup; goto cleanup;
} }
detach = vm->def->controllers[idx]; *detach = controller = vm->def->controllers[idx];
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { if (qemuIsMultiFunctionDevice(vm->def, &controller->info)) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("cannot hot unplug multifunction PCI device: %s"), "%s", _("cannot hot unplug multifunction PCI device"));
dev->data.disk->dst);
goto cleanup; goto cleanup;
} }
if (qemuDomainControllerIsBusy(vm, detach)) { if (qemuDomainControllerIsBusy(vm, controller)) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s", virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("device cannot be detached: device is busy")); _("device cannot be detached: device is busy"));
goto cleanup; goto cleanup;
} }
if (!async) if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainMarkDeviceForRemoval(vm, &controller->info);
if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) if (qemuDomainDeleteDevice(vm, controller->info.alias) < 0)
goto cleanup; goto cleanup;
if (async) { if (async) {
ret = 0; ret = 0;
} else { } else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveControllerDevice(driver, vm, detach); ret = qemuDomainRemoveControllerDevice(driver, vm, controller);
} }
cleanup: cleanup:
@ -5583,29 +5582,30 @@ qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
/* search for a hostdev matching dev and detach it */ /* search for a hostdev matching dev and detach it */
static int static int
qemuDomainDetachHostDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepHostdev(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev, virDomainHostdevDefPtr match,
virDomainHostdevDefPtr *detach,
bool async) bool async)
{ {
virDomainHostdevDefPtr hostdev = dev->data.hostdev; virDomainHostdevSubsysPtr subsys = &match->source.subsys;
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb; virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci; virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi; virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev; virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
virDomainHostdevDefPtr detach = NULL; virDomainHostdevDefPtr hostdev = NULL;
int idx; int idx;
int ret = -1; int ret = -1;
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (match->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("hot unplug is not supported for hostdev mode '%s'"), _("hot unplug is not supported for hostdev mode '%s'"),
virDomainHostdevModeTypeToString(hostdev->mode)); virDomainHostdevModeTypeToString(match->mode));
return -1; return -1;
} }
idx = virDomainHostdevFind(vm->def, hostdev, &detach); idx = virDomainHostdevFind(vm->def, match, &hostdev);
*detach = hostdev;
if (idx < 0) { if (idx < 0) {
switch (subsys->type) { switch (subsys->type) {
@ -5658,27 +5658,27 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
if (qemuIsMultiFunctionDevice(vm->def, detach->info)) { if (qemuIsMultiFunctionDevice(vm->def, hostdev->info)) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("cannot hot unplug multifunction PCI device with guest address: " _("cannot hot unplug multifunction PCI device with guest address: "
"%.4x:%.2x:%.2x.%.1x"), "%.4x:%.2x:%.2x.%.1x"),
detach->info->addr.pci.domain, detach->info->addr.pci.bus, hostdev->info->addr.pci.domain, hostdev->info->addr.pci.bus,
detach->info->addr.pci.slot, detach->info->addr.pci.function); hostdev->info->addr.pci.slot, hostdev->info->addr.pci.function);
return -1; return -1;
} }
if (!detach->info->alias) { if (!hostdev->info->alias) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("device cannot be detached without a device alias")); "%s", _("device cannot be detached without a device alias"));
return -1; return -1;
} }
if (!async) if (!async)
qemuDomainMarkDeviceForRemoval(vm, detach->info); qemuDomainMarkDeviceForRemoval(vm, hostdev->info);
if (qemuDomainDeleteDevice(vm, detach->info->alias) < 0) { if (qemuDomainDeleteDevice(vm, hostdev->info->alias) < 0) {
if (virDomainObjIsActive(vm)) if (virDomainObjIsActive(vm))
virDomainAuditHostdev(vm, detach, "detach", false); virDomainAuditHostdev(vm, hostdev, "detach", false);
goto cleanup; goto cleanup;
} }
@ -5686,7 +5686,7 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
ret = 0; ret = 0;
} else { } else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveHostDevice(driver, vm, detach); ret = qemuDomainRemoveHostDevice(driver, vm, hostdev);
} }
cleanup: cleanup:
@ -5699,24 +5699,25 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepShmem(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainShmemDefPtr dev, virDomainShmemDefPtr match,
virDomainShmemDefPtr *detach,
bool async) bool async)
{ {
int ret = -1; int ret = -1;
ssize_t idx = -1; ssize_t idx = -1;
virDomainShmemDefPtr shmem = NULL; virDomainShmemDefPtr shmem = NULL;
if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) { if ((idx = virDomainShmemDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING, virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' shmem device not present " _("model '%s' shmem device not present "
"in domain configuration"), "in domain configuration"),
virDomainShmemModelTypeToString(dev->model)); virDomainShmemModelTypeToString(match->model));
return -1; return -1;
} }
shmem = vm->def->shmems[idx]; *detach = shmem = vm->def->shmems[idx];
switch ((virDomainShmemModel)shmem->model) { switch ((virDomainShmemModel)shmem->model) {
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN: case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
@ -5753,13 +5754,16 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachWatchdog(virQEMUDriverPtr driver, qemuDomainDetachPrepWatchdog(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainWatchdogDefPtr dev, virDomainWatchdogDefPtr match,
virDomainWatchdogDefPtr *detach,
bool async) bool async)
{ {
int ret = -1; int ret = -1;
virDomainWatchdogDefPtr watchdog = vm->def->watchdog; virDomainWatchdogDefPtr watchdog;
*detach = watchdog = vm->def->watchdog;
if (!watchdog) { if (!watchdog) {
virReportError(VIR_ERR_DEVICE_MISSING, "%s", virReportError(VIR_ERR_DEVICE_MISSING, "%s",
@ -5770,9 +5774,9 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
/* While domains can have up to one watchdog, the one supplied by the user /* While domains can have up to one watchdog, the one supplied by the user
* doesn't necessarily match the one domain has. Refuse to detach in such * doesn't necessarily match the one domain has. Refuse to detach in such
* case. */ * case. */
if (!(watchdog->model == dev->model && if (!(watchdog->model == match->model &&
watchdog->action == dev->action && watchdog->action == match->action &&
virDomainDeviceInfoAddressIsEqual(&dev->info, &watchdog->info))) { virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
virReportError(VIR_ERR_DEVICE_MISSING, virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' watchdog device not present " _("model '%s' watchdog device not present "
"in domain configuration"), "in domain configuration"),
@ -5808,40 +5812,41 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepRedirdev(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRedirdevDefPtr dev, virDomainRedirdevDefPtr match,
virDomainRedirdevDefPtr *detach,
bool async) bool async)
{ {
int ret = -1; int ret = -1;
virDomainRedirdevDefPtr tmpRedirdevDef; virDomainRedirdevDefPtr redirdev;
ssize_t idx; ssize_t idx;
if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) { if ((idx = virDomainRedirdevDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s", virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("no matching redirdev was not found")); _("no matching redirdev was not found"));
return -1; return -1;
} }
tmpRedirdevDef = vm->def->redirdevs[idx]; *detach = redirdev = vm->def->redirdevs[idx];
if (!tmpRedirdevDef->info.alias) { if (!redirdev->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("alias not set for redirdev device")); _("alias not set for redirdev device"));
return -1; return -1;
} }
if (!async) if (!async)
qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info); qemuDomainMarkDeviceForRemoval(vm, &redirdev->info);
if (qemuDomainDeleteDevice(vm, tmpRedirdevDef->info.alias) < 0) if (qemuDomainDeleteDevice(vm, redirdev->info.alias) < 0)
goto cleanup; goto cleanup;
if (async) { if (async) {
ret = 0; ret = 0;
} else { } else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef); ret = qemuDomainRemoveRedirdevDevice(driver, vm, redirdev);
} }
cleanup: cleanup:
@ -5852,53 +5857,54 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachNetDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepNet(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainDeviceDefPtr dev, virDomainNetDefPtr match,
virDomainNetDefPtr *detach,
bool async) bool async)
{ {
int detachidx, ret = -1; int detachidx, ret = -1;
virDomainNetDefPtr detach = NULL; virDomainNetDefPtr net = NULL;
if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0) if ((detachidx = virDomainNetFindIdx(vm->def, match)) < 0)
goto cleanup; goto cleanup;
detach = vm->def->nets[detachidx]; *detach = net = vm->def->nets[detachidx];
if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { if (qemuIsMultiFunctionDevice(vm->def, &net->info)) {
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
_("cannot hot unplug multifunction PCI device: %s"), _("cannot hot unplug multifunction PCI device: %s"),
detach->ifname); net->ifname);
goto cleanup; goto cleanup;
} }
if (!detach->info.alias) { if (!net->info.alias) {
if (qemuAssignDeviceNetAlias(vm->def, detach, -1) < 0) if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
goto cleanup; goto cleanup;
} }
if (virDomainNetGetActualBandwidth(detach) && if (virDomainNetGetActualBandwidth(net) &&
virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) && virNetDevSupportBandwidth(virDomainNetGetActualType(net)) &&
virNetDevBandwidthClear(detach->ifname) < 0) virNetDevBandwidthClear(net->ifname) < 0)
VIR_WARN("cannot clear bandwidth setting for device : %s", VIR_WARN("cannot clear bandwidth setting for device : %s",
detach->ifname); net->ifname);
/* deactivate the tap/macvtap device on the host, which could also /* deactivate the tap/macvtap device on the host, which could also
* affect the parent device (e.g. macvtap passthrough mode sets * affect the parent device (e.g. macvtap passthrough mode sets
* the parent device offline) * the parent device offline)
*/ */
ignore_value(qemuInterfaceStopDevice(detach)); ignore_value(qemuInterfaceStopDevice(net));
if (!async) if (!async)
qemuDomainMarkDeviceForRemoval(vm, &detach->info); qemuDomainMarkDeviceForRemoval(vm, &net->info);
if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) { if (qemuDomainDeleteDevice(vm, net->info.alias) < 0) {
if (virDomainObjIsActive(vm)) { if (virDomainObjIsActive(vm)) {
/* the audit message has a different format for hostdev network devices */ /* the audit message has a different format for hostdev network devices */
if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(detach), "detach", false); virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(net), "detach", false);
else else
virDomainAuditNet(vm, detach, NULL, "detach", false); virDomainAuditNet(vm, net, NULL, "detach", false);
} }
goto cleanup; goto cleanup;
} }
@ -5907,7 +5913,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
ret = 0; ret = 0;
} else { } else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveNetDevice(driver, vm, detach); ret = qemuDomainRemoveNetDevice(driver, vm, net);
} }
cleanup: cleanup:
@ -5976,42 +5982,43 @@ qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepRNG(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainRNGDefPtr rng, virDomainRNGDefPtr match,
virDomainRNGDefPtr *detach,
bool async) bool async)
{ {
ssize_t idx; ssize_t idx;
virDomainRNGDefPtr tmpRNG; virDomainRNGDefPtr rng;
int ret = -1; int ret = -1;
if ((idx = virDomainRNGFind(vm->def, rng)) < 0) { if ((idx = virDomainRNGFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING, virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' RNG device not present " _("model '%s' RNG device not present "
"in domain configuration"), "in domain configuration"),
virDomainRNGBackendTypeToString(rng->model)); virDomainRNGBackendTypeToString(match->model));
return -1; return -1;
} }
tmpRNG = vm->def->rngs[idx]; *detach = rng = vm->def->rngs[idx];
if (!tmpRNG->info.alias) { if (!rng->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("alias not set for RNG device")); _("alias not set for RNG device"));
return -1; return -1;
} }
if (!async) if (!async)
qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); qemuDomainMarkDeviceForRemoval(vm, &rng->info);
if (qemuDomainDeleteDevice(vm, tmpRNG->info.alias) < 0) if (qemuDomainDeleteDevice(vm, rng->info.alias) < 0)
goto cleanup; goto cleanup;
if (async) { if (async) {
ret = 0; ret = 0;
} else { } else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); ret = qemuDomainRemoveRNGDevice(driver, vm, rng);
} }
cleanup: cleanup:
@ -6022,26 +6029,27 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver, qemuDomainDetachPrepMemory(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainMemoryDefPtr memdef, virDomainMemoryDefPtr match,
virDomainMemoryDefPtr *detach,
bool async) bool async)
{ {
virDomainMemoryDefPtr mem; virDomainMemoryDefPtr mem;
int idx; int idx;
int ret = -1; int ret = -1;
qemuDomainMemoryDeviceAlignSize(vm->def, memdef); qemuDomainMemoryDeviceAlignSize(vm->def, match);
if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) { if ((idx = virDomainMemoryFindByDef(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING, virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' memory device not present " _("model '%s' memory device not present "
"in the domain configuration"), "in the domain configuration"),
virDomainMemoryModelTypeToString(memdef->model)); virDomainMemoryModelTypeToString(match->model));
return -1; return -1;
} }
mem = vm->def->mems[idx]; *detach = mem = vm->def->mems[idx];
if (!mem->info.alias) { if (!mem->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -6070,20 +6078,21 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
static int static int
qemuDomainDetachInputDevice(virDomainObjPtr vm, qemuDomainDetachPrepInput(virDomainObjPtr vm,
virDomainInputDefPtr def, virDomainInputDefPtr match,
virDomainInputDefPtr *detach,
bool async) bool async)
{ {
virDomainInputDefPtr input; virDomainInputDefPtr input;
int ret = -1; int ret = -1;
int idx; int idx;
if ((idx = virDomainInputDefFind(vm->def, def)) < 0) { if ((idx = virDomainInputDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s", virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("matching input device not found")); _("matching input device not found"));
return -1; return -1;
} }
input = vm->def->inputs[idx]; *detach = input = vm->def->inputs[idx];
switch ((virDomainInputBus) input->bus) { switch ((virDomainInputBus) input->bus) {
case VIR_DOMAIN_INPUT_BUS_PS2: case VIR_DOMAIN_INPUT_BUS_PS2:
@ -6121,16 +6130,18 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
static int static int
qemuDomainDetachVsockDevice(virDomainObjPtr vm, qemuDomainDetachPrepVsock(virDomainObjPtr vm,
virDomainVsockDefPtr dev, virDomainVsockDefPtr match,
virDomainVsockDefPtr *detach,
bool async) bool async)
{ {
virDomainVsockDefPtr vsock = vm->def->vsock; virDomainVsockDefPtr vsock;
int ret = -1; int ret = -1;
*detach = vsock = vm->def->vsock;
if (!vsock || if (!vsock ||
!virDomainVsockDefEquals(dev, vsock)) { !virDomainVsockDefEquals(match, vsock)) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s", virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("matching vsock device not found")); _("matching vsock device not found"));
return -1; return -1;
@ -6186,6 +6197,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
virQEMUDriverPtr driver, virQEMUDriverPtr driver,
bool async) bool async)
{ {
virDomainDeviceDef detach = { .type = match->type };
int ret = -1; int ret = -1;
switch ((virDomainDeviceType)match->type) { switch ((virDomainDeviceType)match->type) {
@ -6208,38 +6220,70 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
* assure it is okay to detach the device. * assure it is okay to detach the device.
*/ */
case VIR_DOMAIN_DEVICE_DISK: case VIR_DOMAIN_DEVICE_DISK:
ret = qemuDomainDetachDeviceDiskLive(driver, vm, match, async); if (qemuDomainDetachPrepDisk(driver, vm, match->data.disk,
&detach.data.disk, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_CONTROLLER: case VIR_DOMAIN_DEVICE_CONTROLLER:
ret = qemuDomainDetachControllerDevice(driver, vm, match, async); if (qemuDomainDetachPrepController(driver, vm, match->data.controller,
&detach.data.controller, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_NET: case VIR_DOMAIN_DEVICE_NET:
ret = qemuDomainDetachNetDevice(driver, vm, match, async); if (qemuDomainDetachPrepNet(driver, vm, match->data.net,
&detach.data.net, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_HOSTDEV: case VIR_DOMAIN_DEVICE_HOSTDEV:
ret = qemuDomainDetachHostDevice(driver, vm, match, async); if (qemuDomainDetachPrepHostdev(driver, vm, match->data.hostdev,
&detach.data.hostdev, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_RNG:
ret = qemuDomainDetachRNGDevice(driver, vm, match->data.rng, async); if (qemuDomainDetachPrepRNG(driver, vm, match->data.rng,
&detach.data.rng, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_MEMORY:
ret = qemuDomainDetachMemoryDevice(driver, vm, match->data.memory, async); if (qemuDomainDetachPrepMemory(driver, vm, match->data.memory,
&detach.data.memory, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_SHMEM:
ret = qemuDomainDetachShmemDevice(driver, vm, match->data.shmem, async); if (qemuDomainDetachPrepShmem(driver, vm, match->data.shmem,
&detach.data.shmem, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_WATCHDOG:
ret = qemuDomainDetachWatchdog(driver, vm, match->data.watchdog, async); if (qemuDomainDetachPrepWatchdog(driver, vm, match->data.watchdog,
&detach.data.watchdog, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:
ret = qemuDomainDetachInputDevice(vm, match->data.input, async); if (qemuDomainDetachPrepInput(vm, match->data.input,
&detach.data.input, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_REDIRDEV:
ret = qemuDomainDetachRedirdevDevice(driver, vm, match->data.redirdev, async); if (qemuDomainDetachPrepRedirdev(driver, vm, match->data.redirdev,
&detach.data.redirdev, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_VSOCK: case VIR_DOMAIN_DEVICE_VSOCK:
ret = qemuDomainDetachVsockDevice(vm, match->data.vsock, async); if (qemuDomainDetachPrepVsock(vm, match->data.vsock,
&detach.data.vsock, async) < 0) {
return -1;
}
break; break;
case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_FS:
@ -6261,6 +6305,8 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
return -1; return -1;
} }
ret = 0;
return ret; return ret;
} }