mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-08 15:25:47 +00:00
Implement qemu dump capabilities
* src/qemu_driver.c (qemudDomainCoreDump): New (qemuDriver): Add core dump function. The behaviour is similar as the current Xen dump
This commit is contained in:
parent
c4951f11b7
commit
e1abc44814
@ -2954,6 +2954,108 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int qemudDomainCoreDump(virDomainPtr dom,
|
||||||
|
const char *path,
|
||||||
|
int flags ATTRIBUTE_UNUSED) {
|
||||||
|
struct qemud_driver *driver = dom->conn->privateData;
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
char *command = NULL;
|
||||||
|
char *info = NULL;
|
||||||
|
char *safe_path = NULL;
|
||||||
|
int resume = 0, paused = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
qemuDriverLock(driver);
|
||||||
|
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
|
|
||||||
|
if (!vm) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(dom->uuid, uuidstr);
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_DOMAIN,
|
||||||
|
_("no domain with matching uuid '%s'"), uuidstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virDomainIsActive(vm)) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_INVALID,
|
||||||
|
"%s", _("domain is not running"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Migrate will always stop the VM, so once we support live dumping
|
||||||
|
the resume condition will stay the same, independent of whether
|
||||||
|
the stop command is issued. */
|
||||||
|
resume = (vm->state == VIR_DOMAIN_RUNNING);
|
||||||
|
|
||||||
|
/* Pause domain for non-live dump */
|
||||||
|
if (vm->state == VIR_DOMAIN_RUNNING) {
|
||||||
|
if (qemudMonitorCommand (vm, "stop", &info) < 0) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("suspending before dump failed"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
DEBUG ("%s: stop reply: %s", vm->def->name, info);
|
||||||
|
VIR_FREE(info);
|
||||||
|
paused = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Migrate to file */
|
||||||
|
safe_path = qemudEscapeShellArg(path);
|
||||||
|
if (!safe_path) {
|
||||||
|
virReportOOMError(dom->conn);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virAsprintf(&command, "migrate \"exec:"
|
||||||
|
"dd of='%s' 2>/dev/null"
|
||||||
|
"\"", safe_path) == -1) {
|
||||||
|
virReportOOMError(dom->conn);
|
||||||
|
command = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemudMonitorCommand(vm, command, &info) < 0) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("migrate operation failed"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ("%s: migrate reply: %s", vm->def->name, info);
|
||||||
|
|
||||||
|
/* If the command isn't supported then qemu prints:
|
||||||
|
* unknown command: migrate" */
|
||||||
|
if (strstr(info, "unknown command:")) {
|
||||||
|
qemudReportError (dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
|
||||||
|
"%s",
|
||||||
|
_("'migrate' not supported by this qemu"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
paused = 1;
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(safe_path);
|
||||||
|
VIR_FREE(command);
|
||||||
|
VIR_FREE(info);
|
||||||
|
|
||||||
|
/* Since the monitor is always attached to a pty for libvirt, it
|
||||||
|
will support synchronous operations so we always get here after
|
||||||
|
the migration is complete. */
|
||||||
|
if (resume && paused) {
|
||||||
|
if (qemudMonitorCommand(vm, "cont", &info) < 0) {
|
||||||
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("resuming after dump failed"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
DEBUG ("%s: cont reply: %s", vm->def->name, info);
|
||||||
|
VIR_FREE(info);
|
||||||
|
}
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
|
static int qemudDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus) {
|
||||||
struct qemud_driver *driver = dom->conn->privateData;
|
struct qemud_driver *driver = dom->conn->privateData;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
@ -5453,7 +5555,7 @@ static virDriver qemuDriver = {
|
|||||||
qemudDomainGetInfo, /* domainGetInfo */
|
qemudDomainGetInfo, /* domainGetInfo */
|
||||||
qemudDomainSave, /* domainSave */
|
qemudDomainSave, /* domainSave */
|
||||||
qemudDomainRestore, /* domainRestore */
|
qemudDomainRestore, /* domainRestore */
|
||||||
NULL, /* domainCoreDump */
|
qemudDomainCoreDump, /* domainCoreDump */
|
||||||
qemudDomainSetVcpus, /* domainSetVcpus */
|
qemudDomainSetVcpus, /* domainSetVcpus */
|
||||||
#if HAVE_SCHED_GETAFFINITY
|
#if HAVE_SCHED_GETAFFINITY
|
||||||
qemudDomainPinVcpu, /* domainPinVcpu */
|
qemudDomainPinVcpu, /* domainPinVcpu */
|
||||||
|
Loading…
Reference in New Issue
Block a user