* src/qemu/qemu_driver.c: new qemuDomainScreenshot() function * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Monitor command --- src/qemu/qemu_driver.c | 80 +++++++++++++++++++++++++++++++++++++++++- src/qemu/qemu_monitor.c | 20 ++++++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 23 ++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++ src/qemu/qemu_monitor_text.c | 31 ++++++++++++++++ src/qemu/qemu_monitor_text.h | 2 + 7 files changed, 162 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5abecef..a564382 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2435,6 +2435,84 @@ cleanup: return ret; } +static char * +qemuDomainScreenshot(virDomainPtr dom, + virStreamPtr st, + unsigned int flags ATTRIBUTE_UNUSED) +{ + struct qemud_driver *driver = dom->conn->privateData; + virDomainObjPtr vm; + qemuDomainObjPrivatePtr priv; + char *tmp = NULL; + int tmp_fd = -1; + char *ret = NULL; + + qemuDriverLock(driver); + vm = virDomainFindByUUID(&driver->domains, dom->uuid); + qemuDriverUnlock(driver); + + if (!vm) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(dom->uuid, uuidstr); + qemuReportError(VIR_ERR_NO_DOMAIN, + _("no domain matching uuid '%s'"), uuidstr); + goto cleanup; + } + + priv = vm->privateData; + + if (qemuDomainObjBeginJob(vm) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + qemuReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + if (virAsprintf(&tmp, "%s/qemu.screendump.XXXXXX", driver->cacheDir) < 0) { + virReportOOMError(); + goto endjob; + } + + if ((tmp_fd = mkstemp(tmp)) == -1) { + virReportSystemError(errno, _("mkstemp(\"%s\") failed"), tmp); + goto endjob; + } + + qemuDomainObjEnterMonitor(vm); + if (qemuMonitorScreendump(priv->mon, tmp) < 0) { + qemuDomainObjExitMonitor(vm); + goto endjob; + } + qemuDomainObjExitMonitor(vm); + + if (VIR_CLOSE(tmp_fd) < 0) { + virReportSystemError(errno, _("unable to close %s"), tmp); + goto endjob; + } + + if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY, true) < 0) { + qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("unable to open stream")); + goto endjob; + } + + ret = strdup("image/x-portable-pixmap; charset=binary"); + +endjob: + VIR_FORCE_CLOSE(tmp_fd); + VIR_FREE(tmp); + + if (qemuDomainObjEndJob(vm) == 0) + vm = NULL; + +cleanup: + if (vm) + virDomainObjUnlock(vm); + return ret; +} + static void processWatchdogEvent(void *data, void *opaque) { int ret; @@ -7120,7 +7198,7 @@ static virDriver qemuDriver = { qemudDomainSave, /* domainSave */ qemuDomainRestore, /* domainRestore */ qemudDomainCoreDump, /* domainCoreDump */ - NULL, /* domainScreenshot */ + qemuDomainScreenshot, /* domainScreenshot */ qemudDomainSetVcpus, /* domainSetVcpus */ qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index f89038e..3c0a808 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2228,3 +2228,23 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply); return ret; } + +int qemuMonitorScreendump(qemuMonitorPtr mon, + const char *file) +{ + int ret; + + VIR_DEBUG("mon=%p, file=%s", mon, file); + + if (!mon) { + qemuReportError(VIR_ERR_INVALID_ARG,"%s", + _("monitor must not be NULL")); + return -1; + } + + if (mon->json) + ret = qemuMonitorJSONScreendump(mon, file); + else + ret = qemuMonitorTextScreendump(mon, file); + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c90219b..5c96f12 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -423,6 +423,9 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, char **reply, bool hmp); +int qemuMonitorScreendump(qemuMonitorPtr mon, + const char *file); + /** * When running two dd process and using <> redirection, we need a * shell that will not truncate files. These two strings serve that diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 20a78e1..df45e4b 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2513,3 +2513,26 @@ cleanup: return ret; } + +int qemuMonitorJSONScreendump(qemuMonitorPtr mon, + const char *file) +{ + int ret; + virJSONValuePtr cmd, reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("screendump", + "s:filename", file, + NULL); + + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 086f0e1..bcfdd24 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -204,4 +204,8 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, char **reply_str, bool hmp); +int qemuMonitorJSONScreendump(qemuMonitorPtr mon, + const char *file); + + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 53781c8..f71cf2d 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -2628,3 +2628,34 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd, return ret; } + +/* Returns -1 on error, -2 if not supported */ +int qemuMonitorTextScreendump(qemuMonitorPtr mon, const char *file) +{ + char *cmd = NULL; + char *reply = NULL; + int ret = -1; + + if (virAsprintf(&cmd, "screendump %s", file) < 0){ + virReportOOMError(); + goto cleanup; + } + + if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("taking screenshot failed")); + goto cleanup; + } + + if (strstr(reply, "unknown command:")) { + ret = -2; + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(reply); + VIR_FREE(cmd); + return ret; +} diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 0838a2b..773d33c 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -198,4 +198,6 @@ int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name); int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply); +int qemuMonitorTextScreendump(qemuMonitorPtr mon, const char *file); + #endif /* QEMU_MONITOR_TEXT_H */ -- 1.7.5.rc3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list