[libvirt] [PATCH 4/4] read saved vm status on libvirtd startup

Guido Günther agx at sigxcpu.org
Sun Jan 18 19:28:59 UTC 2009


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




More information about the libvir-list mailing list