|
|
0a7476 |
From 14c62fbf0a1ed27ab12ba439afd0d2e7c55996f2 Mon Sep 17 00:00:00 2001
|
|
|
0a7476 |
Message-Id: <14c62fbf0a1ed27ab12ba439afd0d2e7c55996f2@dist-git>
|
|
|
0a7476 |
From: Laine Stump <laine@laine.org>
|
|
|
0a7476 |
Date: Thu, 11 Apr 2019 15:14:47 -0400
|
|
|
0a7476 |
Subject: [PATCH] qemu_hotplug: standardize the names/args/calling of
|
|
|
0a7476 |
qemuDomainDetach*()
|
|
|
0a7476 |
|
|
|
0a7476 |
Most of these functions will soon contain only some setup for
|
|
|
0a7476 |
detaching the device, not the detach code proper (since that code is
|
|
|
0a7476 |
identical for these devices). Their device specific functions are all
|
|
|
0a7476 |
being renamed to qemuDomainDetachPrep*(), where * is the
|
|
|
0a7476 |
name of that device's data member in the virDomainDeviceDef
|
|
|
0a7476 |
object.
|
|
|
0a7476 |
|
|
|
0a7476 |
Since there will be other code in qemuDomainDetachDeviceLive() after
|
|
|
0a7476 |
the calls to qemuDomainDetachPrep*() that could still fail, we no
|
|
|
0a7476 |
longer directly set "ret" with the return code from
|
|
|
0a7476 |
qemuDomainDetachPrep*() functions, but simply return -1 on
|
|
|
0a7476 |
failure, and wait until the end of qemuDomainDetachDeviceLive() to set
|
|
|
0a7476 |
ret = 0.
|
|
|
0a7476 |
|
|
|
0a7476 |
Along with the rename, qemuDomainDetachPrep*() functions are also
|
|
|
0a7476 |
given similar arglists, including an arg called "match" that points to
|
|
|
0a7476 |
the proto-object of the device we want to delete, and another arg
|
|
|
0a7476 |
"detach" that is used to return a pointer to the actual object that
|
|
|
0a7476 |
will be (for now *has been*) detached. To make sure these new args
|
|
|
0a7476 |
aren't confused with existing local pointers that sometimes had the
|
|
|
0a7476 |
same name (detach), the local pointer to the device is now named after
|
|
|
0a7476 |
the device type ("controller", "disk", etc). These point to the same
|
|
|
0a7476 |
place as (*detach)->data.blah, it's just easier on the eyes to have,
|
|
|
0a7476 |
e.g., "disk->dst" rather than "(*detach)->data.disk-dst".
|
|
|
0a7476 |
|
|
|
0a7476 |
Signed-off-by: Laine Stump <laine@laine.org>
|
|
|
0a7476 |
ACKed-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
0a7476 |
(cherry picked from commit b6a53bf9079bc9ef2dc3f8b85ff5c84da14b9a0a)
|
|
|
0a7476 |
|
|
|
0a7476 |
Partially-Resolves: https://bugzilla.redhat.com/1658198
|
|
|
0a7476 |
Signed-off-by: Laine Stump <laine@redhat.com>
|
|
|
0a7476 |
Signed-off-by: Laine Stump <laine@laine.org>
|
|
|
0a7476 |
Message-Id: <20190411191453.24055-36-laine@redhat.com>
|
|
|
0a7476 |
Acked-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
0a7476 |
---
|
|
|
0a7476 |
src/qemu/qemu_hotplug.c | 316 +++++++++++++++++++++++-----------------
|
|
|
0a7476 |
1 file changed, 181 insertions(+), 135 deletions(-)
|
|
|
0a7476 |
|
|
|
0a7476 |
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|
|
0a7476 |
index 9c0ee1c6a5..693b8878b5 100644
|
|
|
0a7476 |
--- a/src/qemu/qemu_hotplug.c
|
|
|
0a7476 |
+++ b/src/qemu/qemu_hotplug.c
|
|
|
0a7476 |
@@ -4838,21 +4838,22 @@ qemuFindDisk(virDomainDefPtr def, const char *dst)
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainDeviceDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepDisk(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainDiskDefPtr match,
|
|
|
0a7476 |
+ virDomainDiskDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
virDomainDiskDefPtr disk;
|
|
|
0a7476 |
int idx;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) {
|
|
|
0a7476 |
+ if ((idx = qemuFindDisk(vm->def, match->dst)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
0a7476 |
- _("disk %s not found"), dev->data.disk->dst);
|
|
|
0a7476 |
+ _("disk %s not found"), match->dst);
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
- disk = vm->def->disks[idx];
|
|
|
0a7476 |
+ *detach = disk = vm->def->disks[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
switch ((virDomainDiskDevice) disk->device) {
|
|
|
0a7476 |
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
|
|
0a7476 |
@@ -4989,57 +4990,55 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainDeviceDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepController(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainControllerDefPtr match,
|
|
|
0a7476 |
+ virDomainControllerDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
int idx, ret = -1;
|
|
|
0a7476 |
- virDomainControllerDefPtr detach = NULL;
|
|
|
0a7476 |
+ virDomainControllerDefPtr controller = NULL;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (dev->data.controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
|
|
|
0a7476 |
+ if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
0a7476 |
_("'%s' controller cannot be hot unplugged."),
|
|
|
0a7476 |
- virDomainControllerTypeToString(dev->data.controller->type));
|
|
|
0a7476 |
+ virDomainControllerTypeToString(match->type));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainControllerFind(vm->def,
|
|
|
0a7476 |
- dev->data.controller->type,
|
|
|
0a7476 |
- dev->data.controller->idx)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainControllerFind(vm->def, match->type, match->idx)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING,
|
|
|
0a7476 |
_("controller %s:%d not found"),
|
|
|
0a7476 |
- virDomainControllerTypeToString(dev->data.controller->type),
|
|
|
0a7476 |
- dev->data.controller->idx);
|
|
|
0a7476 |
+ virDomainControllerTypeToString(match->type),
|
|
|
0a7476 |
+ match->idx);
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- detach = vm->def->controllers[idx];
|
|
|
0a7476 |
+ *detach = controller = vm->def->controllers[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
|
|
|
0a7476 |
+ if (qemuIsMultiFunctionDevice(vm->def, &controller->info)) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
0a7476 |
- _("cannot hot unplug multifunction PCI device: %s"),
|
|
|
0a7476 |
- dev->data.disk->dst);
|
|
|
0a7476 |
+ "%s", _("cannot hot unplug multifunction PCI device"));
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainControllerIsBusy(vm, detach)) {
|
|
|
0a7476 |
+ if (qemuDomainControllerIsBusy(vm, controller)) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
0a7476 |
_("device cannot be detached: device is busy"));
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!async)
|
|
|
0a7476 |
- qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
|
|
0a7476 |
+ qemuDomainMarkDeviceForRemoval(vm, &controller->info);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0)
|
|
|
0a7476 |
+ if (qemuDomainDeleteDevice(vm, controller->info.alias) < 0)
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
|
|
|
0a7476 |
if (async) {
|
|
|
0a7476 |
ret = 0;
|
|
|
0a7476 |
} else {
|
|
|
0a7476 |
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
|
|
|
0a7476 |
- ret = qemuDomainRemoveControllerDevice(driver, vm, detach);
|
|
|
0a7476 |
+ ret = qemuDomainRemoveControllerDevice(driver, vm, controller);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
cleanup:
|
|
|
0a7476 |
@@ -5051,29 +5050,30 @@ qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
/* search for a hostdev matching dev and detach it */
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainDeviceDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepHostdev(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainHostdevDefPtr match,
|
|
|
0a7476 |
+ virDomainHostdevDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
- virDomainHostdevDefPtr hostdev = dev->data.hostdev;
|
|
|
0a7476 |
- virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
|
|
|
0a7476 |
+ virDomainHostdevSubsysPtr subsys = &match->source.subsys;
|
|
|
0a7476 |
virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
|
|
|
0a7476 |
virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci;
|
|
|
0a7476 |
virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi;
|
|
|
0a7476 |
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
|
|
|
0a7476 |
- virDomainHostdevDefPtr detach = NULL;
|
|
|
0a7476 |
+ virDomainHostdevDefPtr hostdev = NULL;
|
|
|
0a7476 |
int idx;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
|
|
0a7476 |
+ if (match->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
|
|
0a7476 |
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
0a7476 |
_("hot unplug is not supported for hostdev mode '%s'"),
|
|
|
0a7476 |
- virDomainHostdevModeTypeToString(hostdev->mode));
|
|
|
0a7476 |
+ virDomainHostdevModeTypeToString(match->mode));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- idx = virDomainHostdevFind(vm->def, hostdev, &detach);
|
|
|
0a7476 |
+ idx = virDomainHostdevFind(vm->def, match, &hostdev);
|
|
|
0a7476 |
+ *detach = hostdev;
|
|
|
0a7476 |
|
|
|
0a7476 |
if (idx < 0) {
|
|
|
0a7476 |
switch (subsys->type) {
|
|
|
0a7476 |
@@ -5126,27 +5126,27 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
|
|
|
0a7476 |
+ if (qemuIsMultiFunctionDevice(vm->def, hostdev->info)) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
0a7476 |
_("cannot hot unplug multifunction PCI device with guest address: "
|
|
|
0a7476 |
"%.4x:%.2x:%.2x.%.1x"),
|
|
|
0a7476 |
- detach->info->addr.pci.domain, detach->info->addr.pci.bus,
|
|
|
0a7476 |
- detach->info->addr.pci.slot, detach->info->addr.pci.function);
|
|
|
0a7476 |
+ hostdev->info->addr.pci.domain, hostdev->info->addr.pci.bus,
|
|
|
0a7476 |
+ hostdev->info->addr.pci.slot, hostdev->info->addr.pci.function);
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (!detach->info->alias) {
|
|
|
0a7476 |
+ if (!hostdev->info->alias) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
0a7476 |
"%s", _("device cannot be detached without a device alias"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!async)
|
|
|
0a7476 |
- qemuDomainMarkDeviceForRemoval(vm, detach->info);
|
|
|
0a7476 |
+ qemuDomainMarkDeviceForRemoval(vm, hostdev->info);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainDeleteDevice(vm, detach->info->alias) < 0) {
|
|
|
0a7476 |
+ if (qemuDomainDeleteDevice(vm, hostdev->info->alias) < 0) {
|
|
|
0a7476 |
if (virDomainObjIsActive(vm))
|
|
|
0a7476 |
- virDomainAuditHostdev(vm, detach, "detach", false);
|
|
|
0a7476 |
+ virDomainAuditHostdev(vm, hostdev, "detach", false);
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
@@ -5154,7 +5154,7 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
ret = 0;
|
|
|
0a7476 |
} else {
|
|
|
0a7476 |
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
|
|
|
0a7476 |
- ret = qemuDomainRemoveHostDevice(driver, vm, detach);
|
|
|
0a7476 |
+ ret = qemuDomainRemoveHostDevice(driver, vm, hostdev);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
cleanup:
|
|
|
0a7476 |
@@ -5167,24 +5167,25 @@ qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainShmemDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepShmem(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainShmemDefPtr match,
|
|
|
0a7476 |
+ virDomainShmemDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
ssize_t idx = -1;
|
|
|
0a7476 |
virDomainShmemDefPtr shmem = NULL;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainShmemDefFind(vm->def, match)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING,
|
|
|
0a7476 |
_("model '%s' shmem device not present "
|
|
|
0a7476 |
"in domain configuration"),
|
|
|
0a7476 |
- virDomainShmemModelTypeToString(dev->model));
|
|
|
0a7476 |
+ virDomainShmemModelTypeToString(match->model));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- shmem = vm->def->shmems[idx];
|
|
|
0a7476 |
+ *detach = shmem = vm->def->shmems[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
switch ((virDomainShmemModel)shmem->model) {
|
|
|
0a7476 |
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
|
|
|
0a7476 |
@@ -5221,13 +5222,16 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainWatchdogDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepWatchdog(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainWatchdogDefPtr match,
|
|
|
0a7476 |
+ virDomainWatchdogDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
- virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
|
|
|
0a7476 |
+ virDomainWatchdogDefPtr watchdog;
|
|
|
0a7476 |
+
|
|
|
0a7476 |
+ *detach = watchdog = vm->def->watchdog;
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!watchdog) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING, "%s",
|
|
|
0a7476 |
@@ -5238,9 +5242,9 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
|
|
|
0a7476 |
/* While domains can have up to one watchdog, the one supplied by the user
|
|
|
0a7476 |
* doesn't necessarily match the one domain has. Refuse to detach in such
|
|
|
0a7476 |
* case. */
|
|
|
0a7476 |
- if (!(watchdog->model == dev->model &&
|
|
|
0a7476 |
- watchdog->action == dev->action &&
|
|
|
0a7476 |
- virDomainDeviceInfoAddressIsEqual(&dev->info, &watchdog->info))) {
|
|
|
0a7476 |
+ if (!(watchdog->model == match->model &&
|
|
|
0a7476 |
+ watchdog->action == match->action &&
|
|
|
0a7476 |
+ virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING,
|
|
|
0a7476 |
_("model '%s' watchdog device not present "
|
|
|
0a7476 |
"in domain configuration"),
|
|
|
0a7476 |
@@ -5276,40 +5280,41 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainRedirdevDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepRedirdev(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainRedirdevDefPtr match,
|
|
|
0a7476 |
+ virDomainRedirdevDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
- virDomainRedirdevDefPtr tmpRedirdevDef;
|
|
|
0a7476 |
+ virDomainRedirdevDefPtr redirdev;
|
|
|
0a7476 |
ssize_t idx;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainRedirdevDefFind(vm->def, match)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
0a7476 |
_("no matching redirdev was not found"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- tmpRedirdevDef = vm->def->redirdevs[idx];
|
|
|
0a7476 |
+ *detach = redirdev = vm->def->redirdevs[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (!tmpRedirdevDef->info.alias) {
|
|
|
0a7476 |
+ if (!redirdev->info.alias) {
|
|
|
0a7476 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
0a7476 |
_("alias not set for redirdev device"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!async)
|
|
|
0a7476 |
- qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
|
|
|
0a7476 |
+ qemuDomainMarkDeviceForRemoval(vm, &redirdev->info);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainDeleteDevice(vm, tmpRedirdevDef->info.alias) < 0)
|
|
|
0a7476 |
+ if (qemuDomainDeleteDevice(vm, redirdev->info.alias) < 0)
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
|
|
|
0a7476 |
if (async) {
|
|
|
0a7476 |
ret = 0;
|
|
|
0a7476 |
} else {
|
|
|
0a7476 |
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
|
|
|
0a7476 |
- ret = qemuDomainRemoveRedirdevDevice(driver, vm, tmpRedirdevDef);
|
|
|
0a7476 |
+ ret = qemuDomainRemoveRedirdevDevice(driver, vm, redirdev);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
cleanup:
|
|
|
0a7476 |
@@ -5320,53 +5325,54 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainDeviceDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepNet(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainNetDefPtr match,
|
|
|
0a7476 |
+ virDomainNetDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
int detachidx, ret = -1;
|
|
|
0a7476 |
- virDomainNetDefPtr detach = NULL;
|
|
|
0a7476 |
+ virDomainNetDefPtr net = NULL;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
|
|
|
0a7476 |
+ if ((detachidx = virDomainNetFindIdx(vm->def, match)) < 0)
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
|
|
|
0a7476 |
- detach = vm->def->nets[detachidx];
|
|
|
0a7476 |
+ *detach = net = vm->def->nets[detachidx];
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
|
|
|
0a7476 |
+ if (qemuIsMultiFunctionDevice(vm->def, &net->info)) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
0a7476 |
_("cannot hot unplug multifunction PCI device: %s"),
|
|
|
0a7476 |
- detach->ifname);
|
|
|
0a7476 |
+ net->ifname);
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (!detach->info.alias) {
|
|
|
0a7476 |
- if (qemuAssignDeviceNetAlias(vm->def, detach, -1) < 0)
|
|
|
0a7476 |
+ if (!net->info.alias) {
|
|
|
0a7476 |
+ if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (virDomainNetGetActualBandwidth(detach) &&
|
|
|
0a7476 |
- virNetDevSupportBandwidth(virDomainNetGetActualType(detach)) &&
|
|
|
0a7476 |
- virNetDevBandwidthClear(detach->ifname) < 0)
|
|
|
0a7476 |
+ if (virDomainNetGetActualBandwidth(net) &&
|
|
|
0a7476 |
+ virNetDevSupportBandwidth(virDomainNetGetActualType(net)) &&
|
|
|
0a7476 |
+ virNetDevBandwidthClear(net->ifname) < 0)
|
|
|
0a7476 |
VIR_WARN("cannot clear bandwidth setting for device : %s",
|
|
|
0a7476 |
- detach->ifname);
|
|
|
0a7476 |
+ net->ifname);
|
|
|
0a7476 |
|
|
|
0a7476 |
/* deactivate the tap/macvtap device on the host, which could also
|
|
|
0a7476 |
* affect the parent device (e.g. macvtap passthrough mode sets
|
|
|
0a7476 |
* the parent device offline)
|
|
|
0a7476 |
*/
|
|
|
0a7476 |
- ignore_value(qemuInterfaceStopDevice(detach));
|
|
|
0a7476 |
+ ignore_value(qemuInterfaceStopDevice(net));
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!async)
|
|
|
0a7476 |
- qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
|
|
0a7476 |
+ qemuDomainMarkDeviceForRemoval(vm, &net->info);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainDeleteDevice(vm, detach->info.alias) < 0) {
|
|
|
0a7476 |
+ if (qemuDomainDeleteDevice(vm, net->info.alias) < 0) {
|
|
|
0a7476 |
if (virDomainObjIsActive(vm)) {
|
|
|
0a7476 |
/* the audit message has a different format for hostdev network devices */
|
|
|
0a7476 |
- if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
|
|
|
0a7476 |
- virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(detach), "detach", false);
|
|
|
0a7476 |
+ if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV)
|
|
|
0a7476 |
+ virDomainAuditHostdev(vm, virDomainNetGetActualHostdev(net), "detach", false);
|
|
|
0a7476 |
else
|
|
|
0a7476 |
- virDomainAuditNet(vm, detach, NULL, "detach", false);
|
|
|
0a7476 |
+ virDomainAuditNet(vm, net, NULL, "detach", false);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
@@ -5375,7 +5381,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
ret = 0;
|
|
|
0a7476 |
} else {
|
|
|
0a7476 |
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
|
|
|
0a7476 |
- ret = qemuDomainRemoveNetDevice(driver, vm, detach);
|
|
|
0a7476 |
+ ret = qemuDomainRemoveNetDevice(driver, vm, net);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
cleanup:
|
|
|
0a7476 |
@@ -5444,42 +5450,43 @@ qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainRNGDefPtr rng,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepRNG(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainRNGDefPtr match,
|
|
|
0a7476 |
+ virDomainRNGDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
ssize_t idx;
|
|
|
0a7476 |
- virDomainRNGDefPtr tmpRNG;
|
|
|
0a7476 |
+ virDomainRNGDefPtr rng;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainRNGFind(vm->def, rng)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainRNGFind(vm->def, match)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING,
|
|
|
0a7476 |
_("model '%s' RNG device not present "
|
|
|
0a7476 |
"in domain configuration"),
|
|
|
0a7476 |
- virDomainRNGBackendTypeToString(rng->model));
|
|
|
0a7476 |
+ virDomainRNGBackendTypeToString(match->model));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- tmpRNG = vm->def->rngs[idx];
|
|
|
0a7476 |
+ *detach = rng = vm->def->rngs[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (!tmpRNG->info.alias) {
|
|
|
0a7476 |
+ if (!rng->info.alias) {
|
|
|
0a7476 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
0a7476 |
_("alias not set for RNG device"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!async)
|
|
|
0a7476 |
- qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
|
|
|
0a7476 |
+ qemuDomainMarkDeviceForRemoval(vm, &rng->info);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if (qemuDomainDeleteDevice(vm, tmpRNG->info.alias) < 0)
|
|
|
0a7476 |
+ if (qemuDomainDeleteDevice(vm, rng->info.alias) < 0)
|
|
|
0a7476 |
goto cleanup;
|
|
|
0a7476 |
|
|
|
0a7476 |
if (async) {
|
|
|
0a7476 |
ret = 0;
|
|
|
0a7476 |
} else {
|
|
|
0a7476 |
if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
|
|
|
0a7476 |
- ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG);
|
|
|
0a7476 |
+ ret = qemuDomainRemoveRNGDevice(driver, vm, rng);
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
cleanup:
|
|
|
0a7476 |
@@ -5490,26 +5497,27 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
- virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainMemoryDefPtr memdef,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepMemory(virQEMUDriverPtr driver,
|
|
|
0a7476 |
+ virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainMemoryDefPtr match,
|
|
|
0a7476 |
+ virDomainMemoryDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
virDomainMemoryDefPtr mem;
|
|
|
0a7476 |
int idx;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
- qemuDomainMemoryDeviceAlignSize(vm->def, memdef);
|
|
|
0a7476 |
+ qemuDomainMemoryDeviceAlignSize(vm->def, match);
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainMemoryFindByDef(vm->def, match)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_DEVICE_MISSING,
|
|
|
0a7476 |
_("model '%s' memory device not present "
|
|
|
0a7476 |
"in the domain configuration"),
|
|
|
0a7476 |
- virDomainMemoryModelTypeToString(memdef->model));
|
|
|
0a7476 |
+ virDomainMemoryModelTypeToString(match->model));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
- mem = vm->def->mems[idx];
|
|
|
0a7476 |
+ *detach = mem = vm->def->mems[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
if (!mem->info.alias) {
|
|
|
0a7476 |
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
0a7476 |
@@ -5538,20 +5546,21 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachInputDevice(virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainInputDefPtr def,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepInput(virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainInputDefPtr match,
|
|
|
0a7476 |
+ virDomainInputDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
virDomainInputDefPtr input;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
int idx;
|
|
|
0a7476 |
|
|
|
0a7476 |
- if ((idx = virDomainInputDefFind(vm->def, def)) < 0) {
|
|
|
0a7476 |
+ if ((idx = virDomainInputDefFind(vm->def, match)) < 0) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
0a7476 |
_("matching input device not found"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
- input = vm->def->inputs[idx];
|
|
|
0a7476 |
+ *detach = input = vm->def->inputs[idx];
|
|
|
0a7476 |
|
|
|
0a7476 |
switch ((virDomainInputBus) input->bus) {
|
|
|
0a7476 |
case VIR_DOMAIN_INPUT_BUS_PS2:
|
|
|
0a7476 |
@@ -5589,16 +5598,18 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
static int
|
|
|
0a7476 |
-qemuDomainDetachVsockDevice(virDomainObjPtr vm,
|
|
|
0a7476 |
- virDomainVsockDefPtr dev,
|
|
|
0a7476 |
- bool async)
|
|
|
0a7476 |
+qemuDomainDetachPrepVsock(virDomainObjPtr vm,
|
|
|
0a7476 |
+ virDomainVsockDefPtr match,
|
|
|
0a7476 |
+ virDomainVsockDefPtr *detach,
|
|
|
0a7476 |
+ bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
- virDomainVsockDefPtr vsock = vm->def->vsock;
|
|
|
0a7476 |
+ virDomainVsockDefPtr vsock;
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
|
|
|
0a7476 |
+ *detach = vsock = vm->def->vsock;
|
|
|
0a7476 |
if (!vsock ||
|
|
|
0a7476 |
- !virDomainVsockDefEquals(dev, vsock)) {
|
|
|
0a7476 |
+ !virDomainVsockDefEquals(match, vsock)) {
|
|
|
0a7476 |
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
0a7476 |
_("matching vsock device not found"));
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
@@ -5654,6 +5665,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|
|
0a7476 |
virQEMUDriverPtr driver,
|
|
|
0a7476 |
bool async)
|
|
|
0a7476 |
{
|
|
|
0a7476 |
+ virDomainDeviceDef detach = { .type = match->type };
|
|
|
0a7476 |
int ret = -1;
|
|
|
0a7476 |
|
|
|
0a7476 |
switch ((virDomainDeviceType)match->type) {
|
|
|
0a7476 |
@@ -5676,38 +5688,70 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|
|
0a7476 |
* assure it is okay to detach the device.
|
|
|
0a7476 |
*/
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_DISK:
|
|
|
0a7476 |
- ret = qemuDomainDetachDeviceDiskLive(driver, vm, match, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepDisk(driver, vm, match->data.disk,
|
|
|
0a7476 |
+ &detach.data.disk, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
|
|
0a7476 |
- ret = qemuDomainDetachControllerDevice(driver, vm, match, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepController(driver, vm, match->data.controller,
|
|
|
0a7476 |
+ &detach.data.controller, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_NET:
|
|
|
0a7476 |
- ret = qemuDomainDetachNetDevice(driver, vm, match, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepNet(driver, vm, match->data.net,
|
|
|
0a7476 |
+ &detach.data.net, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
|
|
0a7476 |
- ret = qemuDomainDetachHostDevice(driver, vm, match, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepHostdev(driver, vm, match->data.hostdev,
|
|
|
0a7476 |
+ &detach.data.hostdev, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_RNG:
|
|
|
0a7476 |
- ret = qemuDomainDetachRNGDevice(driver, vm, match->data.rng, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepRNG(driver, vm, match->data.rng,
|
|
|
0a7476 |
+ &detach.data.rng, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_MEMORY:
|
|
|
0a7476 |
- ret = qemuDomainDetachMemoryDevice(driver, vm, match->data.memory, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepMemory(driver, vm, match->data.memory,
|
|
|
0a7476 |
+ &detach.data.memory, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_SHMEM:
|
|
|
0a7476 |
- ret = qemuDomainDetachShmemDevice(driver, vm, match->data.shmem, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepShmem(driver, vm, match->data.shmem,
|
|
|
0a7476 |
+ &detach.data.shmem, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
|
|
0a7476 |
- ret = qemuDomainDetachWatchdog(driver, vm, match->data.watchdog, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepWatchdog(driver, vm, match->data.watchdog,
|
|
|
0a7476 |
+ &detach.data.watchdog, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_INPUT:
|
|
|
0a7476 |
- ret = qemuDomainDetachInputDevice(vm, match->data.input, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepInput(vm, match->data.input,
|
|
|
0a7476 |
+ &detach.data.input, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
|
|
0a7476 |
- ret = qemuDomainDetachRedirdevDevice(driver, vm, match->data.redirdev, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepRedirdev(driver, vm, match->data.redirdev,
|
|
|
0a7476 |
+ &detach.data.redirdev, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
-
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_VSOCK:
|
|
|
0a7476 |
- ret = qemuDomainDetachVsockDevice(vm, match->data.vsock, async);
|
|
|
0a7476 |
+ if (qemuDomainDetachPrepVsock(vm, match->data.vsock,
|
|
|
0a7476 |
+ &detach.data.vsock, async) < 0) {
|
|
|
0a7476 |
+ return -1;
|
|
|
0a7476 |
+ }
|
|
|
0a7476 |
break;
|
|
|
0a7476 |
|
|
|
0a7476 |
case VIR_DOMAIN_DEVICE_FS:
|
|
|
0a7476 |
@@ -5729,6 +5773,8 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|
|
0a7476 |
return -1;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
+ ret = 0;
|
|
|
0a7476 |
+
|
|
|
0a7476 |
return ret;
|
|
|
0a7476 |
}
|
|
|
0a7476 |
|
|
|
0a7476 |
--
|
|
|
0a7476 |
2.21.0
|
|
|
0a7476 |
|