According to virDomainScreenshot() documentation, screens are
numbered sequentially. e.g. having two graphics cards, both with
four heads, screen ID 5 addresses the second head on the second
card.
But apart from that, there's nothing special happening here.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 38 +++++++++++++++++++++++++++++++-------
src/qemu/qemu_monitor.c | 4 +++-
src/qemu/qemu_monitor.h | 2 ++
src/qemu/qemu_monitor_json.c | 4 ++++
src/qemu/qemu_monitor_json.h | 2 ++
tests/qemumonitorjsontest.c | 2 +-
6 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b697838070..e61af23870 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3999,6 +3999,8 @@ qemuDomainScreenshot(virDomainPtr dom,
qemuDomainObjPrivatePtr priv;
char *tmp = NULL;
int tmp_fd = -1;
+ size_t i;
+ const char *videoAlias = NULL;
char *ret = NULL;
bool unlink_tmp = false;
virQEMUDriverConfigPtr cfg = NULL;
@@ -4020,13 +4022,35 @@ qemuDomainScreenshot(virDomainPtr dom,
if (virDomainObjCheckActive(vm) < 0)
goto endjob;
- /* Well, even if qemu allows multiple graphic cards, heads, whatever,
- * screenshot command does not */
+ if (!vm->def->nvideos) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no screens to take screenshot from"));
+ goto endjob;
+ }
+
if (screen) {
- virReportError(VIR_ERR_INVALID_ARG,
- "%s", _("currently is supported only taking "
- "screenshots of screen ID 0"));
- goto endjob;
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SCREENDUMP_DEVICE)) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("qemu does not allow specifying screen ID"));
+ goto endjob;
+ }
+
+ for (i = 0; i < vm->def->nvideos; i++) {
+ const virDomainVideoDef *video = vm->def->videos[i];
+
+ if (screen < video->heads) {
+ videoAlias = video->info.alias;
+ break;
+ }
+
+ screen -= video->heads;
+ }
+
+ if (i == vm->def->nvideos) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("no such screen ID"));
+ goto endjob;
+ }
}
if (virAsprintf(&tmp, "%s/qemu.screendump.XXXXXX", cfg->cacheDir)
< 0)
@@ -4041,7 +4065,7 @@ qemuDomainScreenshot(virDomainPtr dom,
qemuSecuritySetSavedStateLabel(driver->securityManager, vm->def, tmp);
qemuDomainObjEnterMonitor(driver, vm);
- if (qemuMonitorScreendump(priv->mon, tmp) < 0) {
+ if (qemuMonitorScreendump(priv->mon, videoAlias, screen, tmp) < 0) {
ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto endjob;
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 3d7ca3ccfc..f21bf7000d 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3477,6 +3477,8 @@ qemuMonitorSendKey(qemuMonitorPtr mon,
int
qemuMonitorScreendump(qemuMonitorPtr mon,
+ const char *device,
+ unsigned int head,
const char *file)
{
VIR_DEBUG("file=%s", file);
@@ -3484,7 +3486,7 @@ qemuMonitorScreendump(qemuMonitorPtr mon,
QEMU_CHECK_MONITOR(mon);
if (mon->json)
- return qemuMonitorJSONScreendump(mon, file);
+ return qemuMonitorJSONScreendump(mon, device, head, file);
else
return qemuMonitorTextScreendump(mon, file);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 33dc521e83..6cba37c281 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -886,6 +886,8 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
int qemuMonitorInjectNMI(qemuMonitorPtr mon);
int qemuMonitorScreendump(qemuMonitorPtr mon,
+ const char *device,
+ unsigned int head,
const char *file);
int qemuMonitorSendKey(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e2e0004e4d..6dcded9369 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4483,6 +4483,8 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
}
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
+ const char *device,
+ unsigned int head,
const char *file)
{
int ret = -1;
@@ -4490,6 +4492,8 @@ int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
cmd = qemuMonitorJSONMakeCommand("screendump",
"s:filename", file,
+ "S:device", device,
+ "p:head", head,
NULL);
if (!cmd)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index e86b58f7ea..8461932cac 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -296,6 +296,8 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
unsigned int nkeycodes);
int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
+ const char *device,
+ unsigned int head,
const char *file);
int qemuMonitorJSONBlockStream(qemuMonitorPtr mon,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index edd57067bd..add5ff0f19 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1348,7 +1348,7 @@ GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb",
"/foo/bar", NULL, 1024, 0, 0,
VIR_DOMAIN_BLOCK_REBASE_SHALLOW | VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1",
"/foo/bar2", NULL, 1024)
GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb")
-GEN_TEST_FUNC(qemuMonitorJSONScreendump, "/foo/bar")
+GEN_TEST_FUNC(qemuMonitorJSONScreendump, NULL, 0, "/foo/bar")
GEN_TEST_FUNC(qemuMonitorJSONOpenGraphics, "spice", "spicefd",
false)
GEN_TEST_FUNC(qemuMonitorJSONNBDServerStart, "localhost", 12345,
"test-alias")
GEN_TEST_FUNC(qemuMonitorJSONNBDServerAdd, "vda", true)
--
2.16.1