connect back to running vms.
changes:
* don't use proc
* don't bother about stdin
* don't use global qemu_driver directly
Cheer,
-- Guido
---
src/qemu_driver.c | 112 +++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 96 insertions(+), 16 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 2dedca2..3b01fd4 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -297,6 +297,86 @@ cleanup:
}
+static int qemudOpenMonitor(virConnectPtr conn,
+ struct qemud_driver* driver,
+ virDomainObjPtr vm,
+ const char *monitor,
+ int reconnect);
+
+/**
+ * qemudReconnectVMs
+ *
+ * Reconnect running vms to the daemon process
+ */
+static int
+qemudReconnectVMs(struct qemud_driver *driver)
+{
+ int i;
+
+ for (i = 0 ; i < driver->domains.count ; i++) {
+ virDomainObjPtr vm = driver->domains.objs[i];
+ qemudDomainStatusPtr status = NULL;
+ char *config = NULL;
+ int rc;
+
+ virDomainObjLock(vm);
+ if ((rc = virFileReadPid(driver->stateDir, vm->def->name,
&vm->pid)) == 0)
+ DEBUG("Found pid %d for '%s'", vm->pid,
vm->def->name);
+ else
+ goto next;
+
+ if ((config = virDomainConfigFile(NULL,
+ driver->stateDir,
+ vm->def->name)) == NULL) {
+ qemudLog(QEMUD_ERR, _("Failed to read domain status for %s\n"),
+ vm->def->name);
+ goto next_error;
+ }
+
+ status = qemudDomainStatusParseFile(NULL, driver->caps, config, 0);
+ if (status) {
+ vm->newDef = vm->def;
+ vm->def = status->def;
+ } else {
+ qemudLog(QEMUD_ERR, _("Failed to parse domain status for %s\n"),
+ vm->def->name);
+ goto next_error;
+ }
+
+ if ((rc = qemudOpenMonitor(NULL, driver, vm, status->monitorpath, 1)) != 0) {
+ qemudLog(QEMUD_ERR, _("Failed to reconnect monitor for %s: %d\n"),
+ vm->def->name, rc);
+ goto next_error;
+ } else
+ vm->monitorpath = status->monitorpath;
+
+ if((vm->logfile = qemudLogFD(NULL, driver->logDir, vm->def->name))
< 0)
+ return -1;
+
+ vm->stdout_fd = vm->stderr_fd = vm->logfile;
+
+ if (vm->def->id >= driver->nextvmid)
+ driver->nextvmid = vm->def->id + 1;
+
+ vm->state = status->state;
+ goto next;
+
+next_error:
+ /* we failed to reconnect the vm so remove it's traces */
+ vm->def->id = -1;
+ qemudRemoveDomainStatus(NULL, driver, vm);
+ virDomainDefFree(vm->def);
+ vm->def = vm->newDef;
+ vm->newDef = NULL;
+next:
+ virDomainObjUnlock(vm);
+ VIR_FREE(status);
+ VIR_FREE(config);
+ }
+ return 0;
+}
+
+
/**
* qemudStartup:
*
@@ -396,6 +476,7 @@ qemudStartup(void) {
qemu_driver->autostartDir,
NULL, NULL) < 0)
goto error;
+ qemudReconnectVMs(qemu_driver);
qemudAutostartConfigs(qemu_driver);
qemuDriverUnlock(qemu_driver);
@@ -488,7 +569,6 @@ qemudActive(void) {
*/
static int
qemudShutdown(void) {
- unsigned int i;
if (!qemu_driver)
return -1;
@@ -496,15 +576,6 @@ qemudShutdown(void) {
qemuDriverLock(qemu_driver);
virCapabilitiesFree(qemu_driver->caps);
- /* shutdown active VMs */
- for (i = 0 ; i < qemu_driver->domains.count ; i++) {
- virDomainObjPtr dom = qemu_driver->domains.objs[i];
- virDomainObjLock(dom);
- if (virDomainIsActive(dom))
- qemudShutdownVMDaemon(NULL, qemu_driver, dom);
- virDomainObjUnlock(dom);
- }
-
virDomainObjListFree(&qemu_driver->domains);
VIR_FREE(qemu_driver->logDir);
@@ -621,7 +692,8 @@ qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
static int qemudOpenMonitor(virConnectPtr conn,
struct qemud_driver* driver,
virDomainObjPtr vm,
- const char *monitor) {
+ const char *monitor,
+ int reconnect) {
int monfd;
char buf[1024];
int ret = -1;
@@ -642,11 +714,19 @@ static int qemudOpenMonitor(virConnectPtr conn,
goto error;
}
- ret = qemudReadMonitorOutput(conn,
- vm, monfd,
- buf, sizeof(buf),
- qemudCheckMonitorPrompt,
- "monitor", 10000);
+ if (!reconnect) {
+ ret = qemudReadMonitorOutput(conn,
+ vm, monfd,
+ buf, sizeof(buf),
+ qemudCheckMonitorPrompt,
+ "monitor", 10000);
+ } else {
+ vm->monitor = monfd;
+ ret = 0;
+ }
+
+ if (ret != 0)
+ goto error;
if (!(vm->monitorpath = strdup(monitor))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
--
1.6.0.6