add --crash support to "virsh dump"

This patch adds the --crash option (already present in "xm dump-core")
to "virsh dump".  virDomainCoreDump already has a flags argument, so
the API/ABI is untouched.

* include/libvirt/libvirt.h.in (virDomainCoreDumpFlags): New flag for
  CoreDump
* src/test/test_driver.c (testDomainCoreDump): Do not crash
  after dump unless VIR_DUMP_CRASH is given.
* src/qemu/qemu_driver.c (qemudDomainCoreDump): Shutdown the domain
  instead of restarting it if --crash is passed.
* src/xen/xend_internal.c (xenDaemonDomainCoreDump): Support --crash.
* tools/virsh.c (opts_dump): Add --crash.
  (cmdDump): Map it to flags for virDomainCoreDump and pass them.
This commit is contained in:
Paolo Bonzini 2009-12-14 11:59:27 +01:00 committed by Daniel Veillard
parent f509e16241
commit b927aed8a3
5 changed files with 41 additions and 13 deletions

View File

@ -334,6 +334,11 @@ struct _virDomainInterfaceStats {
typedef virDomainInterfaceStatsStruct *virDomainInterfaceStatsPtr; typedef virDomainInterfaceStatsStruct *virDomainInterfaceStatsPtr;
/* Domain core dump flags. */
typedef enum {
VIR_DUMP_CRASH = (1 << 0), /* crash after dump */
} virDomainCoreDumpFlags;
/* Domain migration flags. */ /* Domain migration flags. */
typedef enum { typedef enum {
VIR_MIGRATE_LIVE = (1 << 0), /* live migration */ VIR_MIGRATE_LIVE = (1 << 0), /* live migration */

View File

@ -3802,6 +3802,7 @@ static int qemudDomainCoreDump(virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
int resume = 0, paused = 0; int resume = 0, paused = 0;
int ret = -1, fd = -1; int ret = -1, fd = -1;
virDomainEventPtr event = NULL;
const char *args[] = { const char *args[] = {
"cat", "cat",
NULL, NULL,
@ -3892,10 +3893,17 @@ static int qemudDomainCoreDump(virDomainPtr dom,
goto endjob; goto endjob;
endjob: endjob:
if ((ret == 0) && (flags & VIR_DUMP_CRASH)) {
qemudShutdownVMDaemon(dom->conn, driver, vm);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
}
/* Since the monitor is always attached to a pty for libvirt, it /* Since the monitor is always attached to a pty for libvirt, it
will support synchronous operations so we always get here after will support synchronous operations so we always get here after
the migration is complete. */ the migration is complete. */
if (resume && paused) { else if (resume && paused) {
qemuDomainObjEnterMonitor(vm); qemuDomainObjEnterMonitor(vm);
if (qemuMonitorStartCPUs(priv->mon, dom->conn) < 0) { if (qemuMonitorStartCPUs(priv->mon, dom->conn) < 0) {
if (virGetLastError() == NULL) if (virGetLastError() == NULL)
@ -3907,12 +3915,19 @@ endjob:
if (qemuDomainObjEndJob(vm) == 0) if (qemuDomainObjEndJob(vm) == 0)
vm = NULL; vm = NULL;
if ((ret == 0) && (flags & VIR_DUMP_CRASH) && !vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
vm = NULL;
}
cleanup: cleanup:
if (ret != 0) if (ret != 0)
unlink(path); unlink(path);
if (vm) if (vm)
virDomainObjUnlock(vm); virDomainObjUnlock(vm);
if (event)
qemuDomainEventQueue(driver, event);
return ret; return ret;
} }

View File

@ -1911,15 +1911,16 @@ static int testDomainCoreDump(virDomainPtr domain,
goto cleanup; goto cleanup;
} }
testDomainShutdownState(domain, privdom); if (flags & VIR_DUMP_CRASH) {
event = virDomainEventNewFromObj(privdom, testDomainShutdownState(domain, privdom);
VIR_DOMAIN_EVENT_STOPPED, event = virDomainEventNewFromObj(privdom,
VIR_DOMAIN_EVENT_STOPPED_CRASHED); VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
if (!privdom->persistent) { if (!privdom->persistent) {
virDomainRemoveInactive(&privconn->domains, virDomainRemoveInactive(&privconn->domains,
privdom); privdom);
privdom = NULL; privdom = NULL;
}
} }
ret = 0; ret = 0;

View File

@ -3253,8 +3253,10 @@ xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
return(-1); return(-1);
} }
return xend_op(domain->conn, domain->name, "op", "dump", "file", filename, return xend_op(domain->conn, domain->name,
"live", "0", "crash", "0", NULL); "op", "dump", "file", filename, "live", "0",
"crash", (flags & VIR_DUMP_CRASH ? "1" : "0"),
NULL);
} }
/** /**

View File

@ -1431,6 +1431,7 @@ static const vshCmdInfo info_dump[] = {
}; };
static const vshCmdOptDef opts_dump[] = { static const vshCmdOptDef opts_dump[] = {
{"crash", VSH_OT_BOOL, 0, gettext_noop("crash the domain after core dump")},
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("where to dump the core")}, {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("where to dump the core")},
{NULL, 0, 0, NULL} {NULL, 0, 0, NULL}
@ -1443,6 +1444,7 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
char *name; char *name;
char *to; char *to;
int ret = TRUE; int ret = TRUE;
int flags = 0;
if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
return FALSE; return FALSE;
@ -1453,7 +1455,10 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
if (!(dom = vshCommandOptDomain(ctl, cmd, &name))) if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return FALSE; return FALSE;
if (virDomainCoreDump(dom, to, 0) == 0) { if (vshCommandOptBool (cmd, "crash"))
flags |= VIR_DUMP_CRASH;
if (virDomainCoreDump(dom, to, flags) == 0) {
vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to); vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to);
} else { } else {
vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); vshError(ctl, _("Failed to core dump domain %s to %s"), name, to);