typedef enum {
QEMU_PROCESS_EVENT_WATCHDOG = 0,
QEMU_PROCESS_EVENT_GUESTPANIC,
+ QEMU_PROCESS_EVENT_DEVICE_DELETED,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;
virDomainObjPtr vm;
qemuProcessEventType eventType;
int action;
+ void *data;
};
const char *qemuDomainAsyncJobPhaseToString(enum qemuDomainAsyncJob job,
virObjectUnref(cfg);
}
+
+static void
+processDeviceDeletedEvent(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ char *devAlias)
+{
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainDeviceDef dev;
+
+ VIR_DEBUG("Removing device %s from domain %p %s",
+ devAlias, vm, vm->def->name);
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Domain is not running");
+ goto endjob;
+ }
+
+ if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0)
+ goto endjob;
+
+ qemuDomainRemoveDevice(driver, vm, &dev);
+
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
+ VIR_WARN("unable to save domain status after removing device %s",
+ devAlias);
+
+ endjob:
+ /* We had an extra reference to vm before starting a new job so ending the
+ * job is guaranteed not to remove the last reference.
+ */
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
+ cleanup:
+ VIR_FREE(devAlias);
+ virObjectUnref(cfg);
+}
+
+
static void qemuProcessEventHandler(void *data, void *opaque)
{
struct qemuProcessEvent *processEvent = data;
case QEMU_PROCESS_EVENT_GUESTPANIC:
processGuestPanicEvent(driver, vm, processEvent->action);
break;
- default:
- break;
+ case QEMU_PROCESS_EVENT_DEVICE_DELETED:
+ processDeviceDeletedEvent(driver, vm, processEvent->data);
+ break;
+ case QEMU_PROCESS_EVENT_LAST:
+ break;
}
if (virObjectUnref(vm))
void *opaque)
{
virQEMUDriverPtr driver = opaque;
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- virDomainDeviceDef dev;
+ struct qemuProcessEvent *processEvent = NULL;
+ char *data;
virObjectLock(vm);
if (qemuDomainSignalDeviceRemoval(vm, devAlias))
goto cleanup;
- if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0)
- goto cleanup;
+ if (VIR_ALLOC(processEvent) < 0)
+ goto error;
- qemuDomainRemoveDevice(driver, vm, &dev);
+ processEvent->eventType = QEMU_PROCESS_EVENT_DEVICE_DELETED;
+ if (VIR_STRDUP(data, devAlias) < 0)
+ goto error;
+ processEvent->data = data;
+ processEvent->vm = vm;
- if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- VIR_WARN("unable to save domain status with balloon change");
+ virObjectRef(vm);
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+ ignore_value(virObjectUnref(vm));
+ goto error;
+ }
cleanup:
virObjectUnlock(vm);
- virObjectUnref(cfg);
return 0;
+ error:
+ if (processEvent)
+ VIR_FREE(processEvent->data);
+ VIR_FREE(processEvent);
+ goto cleanup;
}