
On Thu, May 12, 2011 at 06:29:14PM +0200, Michal Privoznik wrote:
* 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 | 90 +++++++++++++++++++++++++++++++++++++++++- 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 | 5 ++ src/qemu/qemu_monitor_text.c | 31 ++++++++++++++ src/qemu/qemu_monitor_text.h | 3 + 7 files changed, 174 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 482f177..c0cd407 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2486,6 +2486,94 @@ cleanup: return ret; }
+static char * +qemuDomainScreenshot(virDomainPtr dom, + virStreamPtr st, + unsigned int screen, + 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; + } + + /* Well, even if qemu allows multiple graphic cards, heads, whatever, + * screenshot command does not */ + if (screen) { + qemuReportError(VIR_ERR_INVALID_ARG, + "%s", _("currently is supported only taking " + "screenshots of screen ID 0")); + 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");
I don't think we need the '; charset=binary' bit - just use the mimetype on its own. ACK if that change is made Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|