mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
qemu: Remove devices only after DEVICE_DELETED event
This commit is contained in:
parent
ab47cc9bf9
commit
3fbf78bdf3
@ -220,6 +220,9 @@ qemuDomainObjPrivateAlloc(void)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virCondInit(&priv->unplugFinished) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!(priv->devs = virChrdevAlloc()))
|
if (!(priv->devs = virChrdevAlloc()))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -248,6 +251,7 @@ qemuDomainObjPrivateFree(void *data)
|
|||||||
VIR_FREE(priv->lockState);
|
VIR_FREE(priv->lockState);
|
||||||
VIR_FREE(priv->origname);
|
VIR_FREE(priv->origname);
|
||||||
|
|
||||||
|
virCondDestroy(&priv->unplugFinished);
|
||||||
virChrdevFree(priv->devs);
|
virChrdevFree(priv->devs);
|
||||||
|
|
||||||
/* This should never be non-NULL if we get here, but just in case... */
|
/* This should never be non-NULL if we get here, but just in case... */
|
||||||
|
@ -168,6 +168,9 @@ struct _qemuDomainObjPrivate {
|
|||||||
size_t ncleanupCallbacks_max;
|
size_t ncleanupCallbacks_max;
|
||||||
|
|
||||||
virCgroupPtr cgroup;
|
virCgroupPtr cgroup;
|
||||||
|
|
||||||
|
virCond unplugFinished; /* signals that unpluggingDevice was unplugged */
|
||||||
|
const char *unpluggingDevice; /* alias of the device that is being unplugged */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "device_conf.h"
|
#include "device_conf.h"
|
||||||
#include "virstoragefile.h"
|
#include "virstoragefile.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "virtime.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
#define CHANGE_MEDIA_RETRIES 10
|
#define CHANGE_MEDIA_RETRIES 10
|
||||||
@ -2488,6 +2489,122 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDeviceDefPtr dev)
|
||||||
|
{
|
||||||
|
switch ((virDomainDeviceType) dev->type) {
|
||||||
|
case VIR_DOMAIN_DEVICE_DISK:
|
||||||
|
qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
|
qemuDomainRemoveControllerDevice(driver, vm, dev->data.controller);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_NET:
|
||||||
|
qemuDomainRemoveNetDevice(driver, vm, dev->data.net);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_HOSTDEV:
|
||||||
|
qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_CHR:
|
||||||
|
qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
|
case VIR_DOMAIN_DEVICE_INPUT:
|
||||||
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
|
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
||||||
|
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
||||||
|
case VIR_DOMAIN_DEVICE_HUB:
|
||||||
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
|
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||||
|
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||||
|
case VIR_DOMAIN_DEVICE_NVRAM:
|
||||||
|
case VIR_DOMAIN_DEVICE_RNG:
|
||||||
|
case VIR_DOMAIN_DEVICE_LAST:
|
||||||
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
||||||
|
_("don't know how to remove a %s device"),
|
||||||
|
virDomainDeviceTypeToString(dev->type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wait up to 5 seconds for device removal to finish. */
|
||||||
|
#define QEMU_REMOVAL_WAIT_TIME (1000ull * 5)
|
||||||
|
|
||||||
|
static void
|
||||||
|
qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm,
|
||||||
|
virDomainDeviceInfoPtr info)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
|
||||||
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
|
||||||
|
priv->unpluggingDevice = info->alias;
|
||||||
|
else
|
||||||
|
priv->unpluggingDevice = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
qemuDomainResetDeviceRemoval(virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
priv->unpluggingDevice = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns:
|
||||||
|
* -1 on error
|
||||||
|
* 0 when DEVICE_DELETED event is unsupported
|
||||||
|
* 1 when device removal finished
|
||||||
|
* 2 device removal did not finish in QEMU_REMOVAL_WAIT_TIME
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
unsigned long long until;
|
||||||
|
|
||||||
|
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (virTimeMillisNow(&until) < 0)
|
||||||
|
return -1;
|
||||||
|
until += QEMU_REMOVAL_WAIT_TIME;
|
||||||
|
|
||||||
|
while (priv->unpluggingDevice) {
|
||||||
|
if (virCondWaitUntil(&priv->unplugFinished,
|
||||||
|
&vm->parent.lock, until) < 0) {
|
||||||
|
if (errno == ETIMEDOUT) {
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to wait on unplug condition"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
|
||||||
|
const char *devAlias)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
|
||||||
|
if (STREQ_NULLABLE(priv->unpluggingDevice, devAlias)) {
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
|
virCondSignal(&priv->unplugFinished);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
|
int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDiskDefPtr detach)
|
virDomainDiskDefPtr detach)
|
||||||
@ -2526,6 +2643,8 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
|
|||||||
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
||||||
@ -2547,10 +2666,12 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
|
|
||||||
qemuDomainRemoveDiskDevice(driver, vm, detach);
|
if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
|
qemuDomainRemoveDiskDevice(driver, vm, detach);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2583,6 +2704,8 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
|
|||||||
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
@ -2595,10 +2718,12 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
|
|
||||||
qemuDomainRemoveDiskDevice(driver, vm, detach);
|
if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
|
qemuDomainRemoveDiskDevice(driver, vm, detach);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2698,6 +2823,8 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
|
||||||
@ -2713,11 +2840,13 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
|
|
||||||
qemuDomainRemoveControllerDevice(driver, vm, detach);
|
if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
|
qemuDomainRemoveControllerDevice(driver, vm, detach);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2745,6 +2874,8 @@ qemuDomainDetachHostPciDevice(virQEMUDriverPtr driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
||||||
@ -2776,6 +2907,8 @@ qemuDomainDetachHostUsbDevice(virQEMUDriverPtr driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
@ -2811,6 +2944,8 @@ qemuDomainDetachHostScsiDevice(virQEMUDriverPtr driver,
|
|||||||
if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
|
if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
|
if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
|
||||||
if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
|
if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
|
||||||
@ -2859,9 +2994,11 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
virDomainAuditHostdev(vm, detach, "detach", false);
|
virDomainAuditHostdev(vm, detach, "detach", false);
|
||||||
else
|
else if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
qemuDomainRemoveHostDevice(driver, vm, detach);
|
qemuDomainRemoveHostDevice(driver, vm, detach);
|
||||||
|
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2992,6 +3129,8 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
|||||||
if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0)
|
if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, &detach->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
|
||||||
@ -3024,9 +3163,13 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
|
|
||||||
qemuDomainRemoveNetDevice(driver, vm, detach);
|
if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
|
qemuDomainRemoveNetDevice(driver, vm, detach);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
VIR_FREE(hostnet_name);
|
VIR_FREE(hostnet_name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -3171,6 +3314,8 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|||||||
if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0)
|
if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
|
||||||
|
|
||||||
qemuDomainObjEnterMonitor(driver, vm);
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
|
if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
@ -3183,10 +3328,12 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
qemuDomainObjExitMonitor(driver, vm);
|
qemuDomainObjExitMonitor(driver, vm);
|
||||||
|
|
||||||
qemuDomainRemoveChrDevice(driver, vm, tmpChr);
|
if (!qemuDomainWaitForDeviceRemoval(vm))
|
||||||
|
qemuDomainRemoveChrDevice(driver, vm, tmpChr);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
qemuDomainResetDeviceRemoval(vm);
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(charAlias);
|
VIR_FREE(charAlias);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -119,4 +119,11 @@ virDomainChrDefPtr
|
|||||||
qemuDomainChrRemove(virDomainDefPtr vmdef,
|
qemuDomainChrRemove(virDomainDefPtr vmdef,
|
||||||
virDomainChrDefPtr chr);
|
virDomainChrDefPtr chr);
|
||||||
|
|
||||||
|
void qemuDomainRemoveDevice(virQEMUDriverPtr driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainDeviceDefPtr dev);
|
||||||
|
|
||||||
|
void qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
|
||||||
|
const char *devAlias);
|
||||||
|
|
||||||
#endif /* __QEMU_HOTPLUG_H__ */
|
#endif /* __QEMU_HOTPLUG_H__ */
|
||||||
|
@ -1313,6 +1313,37 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
const char *devAlias)
|
||||||
|
{
|
||||||
|
virQEMUDriverPtr driver = qemu_driver;
|
||||||
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
virDomainDeviceDef dev;
|
||||||
|
|
||||||
|
virObjectLock(vm);
|
||||||
|
|
||||||
|
VIR_DEBUG("Device %s removed from domain %p %s",
|
||||||
|
devAlias, vm, vm->def->name);
|
||||||
|
|
||||||
|
qemuDomainSignalDeviceRemoval(vm, devAlias);
|
||||||
|
|
||||||
|
if (virDomainDefFindDevice(vm->def, devAlias, &dev) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
qemuDomainRemoveDevice(driver, vm, &dev);
|
||||||
|
|
||||||
|
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
|
||||||
|
VIR_WARN("unable to save domain status with balloon change");
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(vm);
|
||||||
|
virObjectUnref(cfg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static qemuMonitorCallbacks monitorCallbacks = {
|
static qemuMonitorCallbacks monitorCallbacks = {
|
||||||
.destroy = qemuProcessHandleMonitorDestroy,
|
.destroy = qemuProcessHandleMonitorDestroy,
|
||||||
.eofNotify = qemuProcessHandleMonitorEOF,
|
.eofNotify = qemuProcessHandleMonitorEOF,
|
||||||
@ -1333,6 +1364,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
|
|||||||
.domainBalloonChange = qemuProcessHandleBalloonChange,
|
.domainBalloonChange = qemuProcessHandleBalloonChange,
|
||||||
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
|
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
|
||||||
.domainGuestPanic = qemuProcessHandleGuestPanic,
|
.domainGuestPanic = qemuProcessHandleGuestPanic,
|
||||||
|
.domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user