]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Implement multiple screen support for virDomainScreenshot
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 17 May 2018 11:53:34 +0000 (13:53 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 17 May 2018 15:13:11 +0000 (17:13 +0200)
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@redhat.com>
src/qemu/qemu_driver.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
tests/qemumonitorjsontest.c

index b6978380708c68e54f34a266476a7098cf7da3e0..e61af23870d97643a08b6dc9847dce60a2ba766d 100644 (file)
@@ -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,15 +4022,37 @@ qemuDomainScreenshot(virDomainPtr dom,
     if (virDomainObjCheckActive(vm) < 0)
         goto endjob;
 
-    /* Well, even if qemu allows multiple graphic cards, heads, whatever,
-     * screenshot command does not */
-    if (screen) {
-        virReportError(VIR_ERR_INVALID_ARG,
-                       "%s", _("currently is supported only taking "
-                               "screenshots of screen ID 0"));
+    if (!vm->def->nvideos) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                      _("no screens to take screenshot from"));
         goto endjob;
     }
 
+    if (screen) {
+        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)
         goto endjob;
 
@@ -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;
     }
index 3d7ca3ccfc5bb4af662de16009d8fb445cf07dc2..f21bf7000d770802c3f0d215377acbd2ce24e9c0 100644 (file)
@@ -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);
 }
index 33dc521e83fee1479a057446f6c9cbe67f7763b5..6cba37c2816cc556f98e8b6f45754e6e99271213 100644 (file)
@@ -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,
index e2e0004e4dbd72134f30dab9fc30b0309760e7df..6dcded93691e617a3d7e309a123ffc3700a87944 100644 (file)
@@ -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)
index e86b58f7ea73fb221c52e125c1c5d9d7794b93f8..8461932cac52e17c002fd60168577a0225e1fcc8 100644 (file)
@@ -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,
index edd57067bd553a30ad5f819e1c9d80b261b12f03..add5ff0f19fe17860e32438daf4adb9e3a92770b 100644 (file)
@@ -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)