]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
qemu: Implement 'oncrash' coredump events when guest panicked
authorChen Fan <chen.fan.fnst@cn.fujitsu.com>
Fri, 7 Jun 2013 10:23:35 +0000 (18:23 +0800)
committerEric Blake <eblake@redhat.com>
Tue, 2 Jul 2013 18:02:31 +0000 (12:02 -0600)
Add doDumpCoreToAutoPath to implement
'coredump-destroy' and 'coredump-restart' events of the 'on_crash'
in the XML when domain crashed.

src/qemu/qemu_driver.c

index 624b09d19a5f24164c279a842b11e1e984d2ccb3..148694585e9e2118cff325b152d43ea289e2f9d7 100644 (file)
@@ -3633,6 +3633,59 @@ cleanup:
     virObjectUnref(cfg);
 }
 
+static int
+doCoreDumpToAutoDumpPath(virQEMUDriverPtr driver,
+                         virDomainObjPtr vm,
+                         unsigned int flags)
+{
+    int ret = -1;
+    char *dumpfile = NULL;
+    time_t curtime = time(NULL);
+    char timestr[100];
+    struct tm time_info;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+
+    localtime_r(&curtime, &time_info);
+    strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
+
+    if (virAsprintf(&dumpfile, "%s/%s-%s",
+                    cfg->autoDumpPath,
+                    vm->def->name,
+                    timestr) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (qemuDomainObjBeginAsyncJob(driver, vm,
+                                   QEMU_ASYNC_JOB_DUMP) < 0) {
+        goto cleanup;
+    }
+
+    if (!virDomainObjIsActive(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID,
+                       "%s", _("domain is not running"));
+        goto endjob;
+    }
+
+    flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
+    ret = doCoreDump(driver, vm, dumpfile,
+                     getCompressionType(driver), flags);
+    if (ret < 0)
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       "%s", _("Dump failed"));
+
+endjob:
+    /* Safe to ignore value since ref count was incremented in
+     * qemuProcessHandleGuestPanic().
+     */
+    ignore_value(qemuDomainObjEndAsyncJob(driver, vm));
+
+cleanup:
+    VIR_FREE(dumpfile);
+    virObjectUnref(cfg);
+    return ret;
+}
+
 static void
 processGuestPanicEvent(virQEMUDriverPtr driver,
                        virDomainObjPtr vm,
@@ -3669,6 +3722,12 @@ processGuestPanicEvent(virQEMUDriverPtr driver,
      }
 
     switch (action) {
+    case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_DESTROY:
+        if (doCoreDumpToAutoDumpPath(driver, vm, VIR_DUMP_MEMORY_ONLY) < 0) {
+            goto cleanup;
+        }
+        /* fall through */
+
     case VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY:
         priv->beingDestroyed = true;
 
@@ -3700,6 +3759,12 @@ processGuestPanicEvent(virQEMUDriverPtr driver,
         }
         break;
 
+    case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_RESTART:
+        if (doCoreDumpToAutoDumpPath(driver, vm, VIR_DUMP_MEMORY_ONLY) < 0) {
+            goto cleanup;
+        }
+        /* fall through */
+
     case VIR_DOMAIN_LIFECYCLE_CRASH_RESTART:
         qemuDomainSetFakeReboot(driver, vm, true);
         qemuProcessShutdownOrReboot(driver, vm);