Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.c | 31 ++++++++++++++++++--------- src/qemu/qemu_process.h | 1 + 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 97b194b057..fea1f24250 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16300,6 +16300,62 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr conn, } +static virDomainPtr qemuDomainQemuReconnect(virConnectPtr conn, + const char *name, + unsigned int flags) +{ + virQEMUDriverPtr driver = conn->privateData; + virDomainObjPtr vm = NULL; + virDomainPtr dom = NULL; + virCapsPtr caps = NULL; + virQEMUDriverConfigPtr cfg; + + virCheckFlags(0, NULL); + + cfg = virQEMUDriverGetConfig(driver); + + if (strchr(name, '/')) { + virReportError(VIR_ERR_XML_ERROR, + _("name %s cannot contain '/'"), name); + goto cleanup; + } + + vm = virDomainObjListFindByName(driver->domains, name); + if (vm) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Domain '%s' already exists"), name); + goto cleanup; + } + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto cleanup; + + if (!(vm = virDomainObjListLoadStatus(driver->domains, + cfg->stateDir, + name, + caps, + driver->xmlopt, + NULL, NULL))) { + goto cleanup; + } + + if (virDomainQemuReconnectEnsureACL(conn, vm->def) < 0) { + qemuDomainRemoveInactive(driver, vm); + goto cleanup; + } + + dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); + + qemuDomainObjEndJob(driver, vm); + + cleanup: + virDomainObjEndAPI(&vm); + virObjectUnref(caps); + virObjectUnref(cfg); + return dom; +} + + static int qemuDomainOpenConsole(virDomainPtr dom, const char *dev_name, @@ -21262,6 +21318,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainSnapshotDelete = qemuDomainSnapshotDelete, /* 0.8.0 */ .domainQemuMonitorCommand = qemuDomainQemuMonitorCommand, /* 0.8.3 */ .domainQemuAttach = qemuDomainQemuAttach, /* 0.9.4 */ + .domainQemuReconnect = qemuDomainQemuReconnect, /* 4.1.0 */ .domainQemuAgentCommand = qemuDomainQemuAgentCommand, /* 0.10.0 */ .connectDomainQemuMonitorEventRegister = qemuConnectDomainQemuMonitorEventRegister, /* 1.2.3 */ .connectDomainQemuMonitorEventDeregister = qemuConnectDomainQemuMonitorEventDeregister, /* 1.2.3 */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a0f430f89f..ea924cf9b6 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7088,14 +7088,10 @@ struct qemuProcessReconnectData { * We can't do normal MonitorEnter & MonitorExit because these two lock the * monitor lock, which does not exists in this early phase. */ -static void -qemuProcessReconnect(void *opaque) +int +qemuProcessReconnect(virQEMUDriverPtr driver, virDomainObjPtr obj, virConnectPtr conn) { - struct qemuProcessReconnectData *data = opaque; - virQEMUDriverPtr driver = data->driver; - virDomainObjPtr obj = data->obj; qemuDomainObjPrivatePtr priv; - virConnectPtr conn = data->conn; struct qemuDomainJobObj oldjob; int state; int reason; @@ -7104,8 +7100,7 @@ qemuProcessReconnect(void *opaque) unsigned int stopFlags = 0; bool jobStarted = false; virCapsPtr caps = NULL; - - VIR_FREE(data); + int ret = -1; qemuDomainObjRestoreJob(obj, &oldjob); if (oldjob.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) @@ -7297,6 +7292,7 @@ qemuProcessReconnect(void *opaque) if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback) driver->inhibitCallback(true, driver->inhibitOpaque); + ret = 0; cleanup: if (jobStarted) { if (!virDomainObjIsActive(obj)) @@ -7311,7 +7307,7 @@ qemuProcessReconnect(void *opaque) virObjectUnref(cfg); virObjectUnref(caps); virNWFilterUnlockFilterUpdates(); - return; + return ret; error: if (virDomainObjIsActive(obj)) { @@ -7338,6 +7334,21 @@ qemuProcessReconnect(void *opaque) goto cleanup; } + +static void +qemuProcessReconnectThread(void *opaque) +{ + struct qemuProcessReconnectData *data = opaque; + virQEMUDriverPtr driver = data->driver; + virDomainObjPtr obj = data->obj; + virConnectPtr conn = data->conn; + + qemuProcessReconnect(driver, obj, conn); + + VIR_FREE(data); +} + + static int qemuProcessReconnectHelper(virDomainObjPtr obj, void *opaque) @@ -7369,7 +7380,7 @@ qemuProcessReconnectHelper(virDomainObjPtr obj, */ virObjectRef(data->conn); - if (virThreadCreate(&thread, false, qemuProcessReconnect, data) < 0) { + if (virThreadCreate(&thread, false, qemuProcessReconnectThread, data) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create thread. QEMU initialization " "might be incomplete")); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index cd9a720313..846577d341 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -45,6 +45,7 @@ int qemuProcessBuildDestroyMemoryPaths(virQEMUDriverPtr driver, void qemuProcessAutostartAll(virQEMUDriverPtr driver); void qemuProcessReconnectAll(virConnectPtr conn, virQEMUDriverPtr driver); +int qemuProcessReconnect(virQEMUDriverPtr driver, virDomainObjPtr obj, virConnectPtr conn); typedef struct _qemuProcessIncomingDef qemuProcessIncomingDef; typedef qemuProcessIncomingDef *qemuProcessIncomingDefPtr; -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list