}
static int
-qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
- bool async)
+qemuDomainDetachPrepDisk(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr match,
+ virDomainDiskDefPtr *detach,
+ bool async)
{
virDomainDiskDefPtr disk;
int idx;
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,
- _("disk %s not found"), dev->data.disk->dst);
+ _("disk %s not found"), match->dst);
return -1;
}
- disk = vm->def->disks[idx];
+ *detach = disk = vm->def->disks[idx];
switch ((virDomainDiskDevice) disk->device) {
case VIR_DOMAIN_DISK_DEVICE_DISK:
}
static int
-qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
- bool async)
+qemuDomainDetachPrepController(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainControllerDefPtr match,
+ virDomainControllerDefPtr *detach,
+ bool async)
{
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,
_("'%s' controller cannot be hot unplugged."),
- virDomainControllerTypeToString(dev->data.controller->type));
+ virDomainControllerTypeToString(match->type));
return -1;
}
- if ((idx = virDomainControllerFind(vm->def,
- dev->data.controller->type,
- dev->data.controller->idx)) < 0) {
+ if ((idx = virDomainControllerFind(vm->def, match->type, match->idx)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING,
_("controller %s:%d not found"),
- virDomainControllerTypeToString(dev->data.controller->type),
- dev->data.controller->idx);
+ virDomainControllerTypeToString(match->type),
+ match->idx);
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,
- _("cannot hot unplug multifunction PCI device: %s"),
- dev->data.disk->dst);
+ "%s", _("cannot hot unplug multifunction PCI device"));
goto cleanup;
}
- if (qemuDomainControllerIsBusy(vm, detach)) {
+ if (qemuDomainControllerIsBusy(vm, controller)) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("device cannot be detached: device is busy"));
goto cleanup;
}
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;
if (async) {
ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
- ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
+ ret = qemuDomainRemoveControllerDevice(driver, vm, controller);
}
cleanup:
/* search for a hostdev matching dev and detach it */
static int
-qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
- bool async)
+qemuDomainDetachPrepHostdev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr match,
+ virDomainHostdevDefPtr *detach,
+ bool async)
{
- virDomainHostdevDefPtr hostdev = dev->data.hostdev;
- virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
+ virDomainHostdevSubsysPtr subsys = &match->source.subsys;
virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
- virDomainHostdevDefPtr detach = NULL;
+ virDomainHostdevDefPtr hostdev = NULL;
int idx;
int ret = -1;
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+ if (match->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("hot unplug is not supported for hostdev mode '%s'"),
- virDomainHostdevModeTypeToString(hostdev->mode));
+ virDomainHostdevModeTypeToString(match->mode));
return -1;
}
- idx = virDomainHostdevFind(vm->def, hostdev, &detach);
+ idx = virDomainHostdevFind(vm->def, match, &hostdev);
+ *detach = hostdev;
if (idx < 0) {
switch (subsys->type) {
return -1;
}
- if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
+ if (qemuIsMultiFunctionDevice(vm->def, hostdev->info)) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("cannot hot unplug multifunction PCI device with guest address: "
"%.4x:%.2x:%.2x.%.1x"),
- detach->info->addr.pci.domain, detach->info->addr.pci.bus,
- detach->info->addr.pci.slot, detach->info->addr.pci.function);
+ hostdev->info->addr.pci.domain, hostdev->info->addr.pci.bus,
+ hostdev->info->addr.pci.slot, hostdev->info->addr.pci.function);
return -1;
}
- if (!detach->info->alias) {
+ if (!hostdev->info->alias) {
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("device cannot be detached without a device alias"));
return -1;
}
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))
- virDomainAuditHostdev(vm, detach, "detach", false);
+ virDomainAuditHostdev(vm, hostdev, "detach", false);
goto cleanup;
}
ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
- ret = qemuDomainRemoveHostDevice(driver, vm, detach);
+ ret = qemuDomainRemoveHostDevice(driver, vm, hostdev);
}
cleanup:
static int
-qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainShmemDefPtr dev,
- bool async)
+qemuDomainDetachPrepShmem(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainShmemDefPtr match,
+ virDomainShmemDefPtr *detach,
+ bool async)
{
int ret = -1;
ssize_t idx = -1;
virDomainShmemDefPtr shmem = NULL;
- if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) {
+ if ((idx = virDomainShmemDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' shmem device not present "
"in domain configuration"),
- virDomainShmemModelTypeToString(dev->model));
+ virDomainShmemModelTypeToString(match->model));
return -1;
}
- shmem = vm->def->shmems[idx];
+ *detach = shmem = vm->def->shmems[idx];
switch ((virDomainShmemModel)shmem->model) {
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
static int
-qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainWatchdogDefPtr dev,
- bool async)
+qemuDomainDetachPrepWatchdog(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainWatchdogDefPtr match,
+ virDomainWatchdogDefPtr *detach,
+ bool async)
{
int ret = -1;
- virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
+ virDomainWatchdogDefPtr watchdog;
+
+ *detach = watchdog = vm->def->watchdog;
if (!watchdog) {
virReportError(VIR_ERR_DEVICE_MISSING, "%s",
/* 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
* case. */
- if (!(watchdog->model == dev->model &&
- watchdog->action == dev->action &&
- virDomainDeviceInfoAddressIsEqual(&dev->info, &watchdog->info))) {
+ if (!(watchdog->model == match->model &&
+ watchdog->action == match->action &&
+ virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' watchdog device not present "
"in domain configuration"),
static int
-qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainRedirdevDefPtr dev,
- bool async)
+qemuDomainDetachPrepRedirdev(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRedirdevDefPtr match,
+ virDomainRedirdevDefPtr *detach,
+ bool async)
{
int ret = -1;
- virDomainRedirdevDefPtr tmpRedirdevDef;
+ virDomainRedirdevDefPtr redirdev;
ssize_t idx;
- if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
+ if ((idx = virDomainRedirdevDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("no matching redirdev was not found"));
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",
_("alias not set for redirdev device"));
return -1;
}
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;
if (async) {
ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
- ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
+ ret = qemuDomainRemoveRedirdevDevice(driver, vm, redirdev);
}
cleanup:
static int
-qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev,
- bool async)
+qemuDomainDetachPrepNet(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainNetDefPtr match,
+ virDomainNetDefPtr *detach,
+ bool async)
{
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;
- 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,
_("cannot hot unplug multifunction PCI device: %s"),
- detach->ifname);
+ net->ifname);
goto cleanup;
}
- if (!detach->info.alias) {
- if (qemuAssignDeviceNetAlias(vm->def, detach, -1) < 0)
+ if (!net->info.alias) {
+ if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
goto cleanup;
}
- if (virDomainNetGetActualBandwidth(detach) &&
- virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) &&
- virNetDevBandwidthClear(detach->ifname) < 0)
+ if (virDomainNetGetActualBandwidth(net) &&
+ virNetDevSupportBandwidth(virDomainNetGetActualType(net)) &&
+ virNetDevBandwidthClear(net->ifname) < 0)
VIR_WARN("cannot clear bandwidth setting for device : %s",
- detach->ifname);
+ net->ifname);
/* deactivate the tap/macvtap device on the host, which could also
* affect the parent device (e.g. macvtap passthrough mode sets
* the parent device offline)
*/
- ignore_value(qemuInterfaceStopDevice(detach));
+ ignore_value(qemuInterfaceStopDevice(net));
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)) {
/* the audit message has a different format for hostdev network devices */
- if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
- virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(detach), "detach", false);
+ if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+ virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(net), "detach", false);
else
- virDomainAuditNet(vm, detach, NULL, "detach", false);
+ virDomainAuditNet(vm, net, NULL, "detach", false);
}
goto cleanup;
}
ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
- ret = qemuDomainRemoveNetDevice(driver, vm, detach);
+ ret = qemuDomainRemoveNetDevice(driver, vm, net);
}
cleanup:
static int
-qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainRNGDefPtr rng,
- bool async)
+qemuDomainDetachPrepRNG(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainRNGDefPtr match,
+ virDomainRNGDefPtr *detach,
+ bool async)
{
ssize_t idx;
- virDomainRNGDefPtr tmpRNG;
+ virDomainRNGDefPtr rng;
int ret = -1;
- if ((idx = virDomainRNGFind(vm->def, rng)) < 0) {
+ if ((idx = virDomainRNGFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING,
_("model '%s' RNG device not present "
"in domain configuration"),
- virDomainRNGBackendTypeToString(rng->model));
+ virDomainRNGBackendTypeToString(match->model));
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",
_("alias not set for RNG device"));
return -1;
}
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;
if (async) {
ret = 0;
} else {
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
- ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
+ ret = qemuDomainRemoveRNGDevice(driver, vm, rng);
}
cleanup:
static int
-qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainMemoryDefPtr memdef,
- bool async)
+qemuDomainDetachPrepMemory(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainMemoryDefPtr match,
+ virDomainMemoryDefPtr *detach,
+ bool async)
{
virDomainMemoryDefPtr mem;
int idx;
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,
_("model '%s' memory device not present "
"in the domain configuration"),
- virDomainMemoryModelTypeToString(memdef->model));
+ virDomainMemoryModelTypeToString(match->model));
return -1;
}
- mem = vm->def->mems[idx];
+ *detach = mem = vm->def->mems[idx];
if (!mem->info.alias) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
static int
-qemuDomainDetachInputDevice(virDomainObjPtr vm,
- virDomainInputDefPtr def,
- bool async)
+qemuDomainDetachPrepInput(virDomainObjPtr vm,
+ virDomainInputDefPtr match,
+ virDomainInputDefPtr *detach,
+ bool async)
{
virDomainInputDefPtr input;
int ret = -1;
int idx;
- if ((idx = virDomainInputDefFind(vm->def, def)) < 0) {
+ if ((idx = virDomainInputDefFind(vm->def, match)) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("matching input device not found"));
return -1;
}
- input = vm->def->inputs[idx];
+ *detach = input = vm->def->inputs[idx];
switch ((virDomainInputBus) input->bus) {
case VIR_DOMAIN_INPUT_BUS_PS2:
static int
-qemuDomainDetachVsockDevice(virDomainObjPtr vm,
- virDomainVsockDefPtr dev,
- bool async)
+qemuDomainDetachPrepVsock(virDomainObjPtr vm,
+ virDomainVsockDefPtr match,
+ virDomainVsockDefPtr *detach,
+ bool async)
{
- virDomainVsockDefPtr vsock = vm->def->vsock;
+ virDomainVsockDefPtr vsock;
int ret = -1;
+ *detach = vsock = vm->def->vsock;
if (!vsock ||
- !virDomainVsockDefEquals(dev, vsock)) {
+ !virDomainVsockDefEquals(match, vsock)) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("matching vsock device not found"));
return -1;
virQEMUDriverPtr driver,
bool async)
{
+ virDomainDeviceDef detach = { .type = match->type };
int ret = -1;
switch ((virDomainDeviceType)match->type) {
* assure it is okay to detach the device.
*/
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
-
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;
case VIR_DOMAIN_DEVICE_FS:
return -1;
}
+ ret = 0;
+
return ret;
}