9119d9
From 57bf3fecbd49af584a25b45611038f19e6fd3c9c Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <57bf3fecbd49af584a25b45611038f19e6fd3c9c@dist-git>
9119d9
From: Michal Privoznik <mprivozn@redhat.com>
9119d9
Date: Fri, 26 Aug 2011 16:41:17 +0800
9119d9
Subject: [PATCH] RHEL: screenshot: Implement multiple screen support
9119d9
9119d9
For https://bugzilla.redhat.com/show_bug.cgi?id=1026966
9119d9
    https://bugzilla.redhat.com/show_bug.cgi?id=710489
9119d9
RHEL only, requires __com.redhat_qxl_screendump
9119d9
9119d9
As RHEL qemu supports taking screenshot of other monitors than the
9119d9
first one, we can allow libvirt to support this feature too.
9119d9
9119d9
Although this command allows screen specification via ID, there is
9119d9
not a way to assign one to the primary monitor. Therefore, we must
9119d9
stick to upstream command in case of primary monitor, and use this
9119d9
new command in other cases.
9119d9
9119d9
(cherry picked from commit 800c9b2c1e0347585213ba6895db7cf064cda21c in
9119d9
rhel-6.5 branch)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
9119d9
Conflicts:
9119d9
	src/qemu/qemu_driver.c - context
9119d9
	src/qemu/qemu_monitor.c - don't return -1 without reporting an
9119d9
	    error
9119d9
---
9119d9
 src/qemu/qemu_driver.c       | 22 +++++++++++++++-------
9119d9
 src/qemu/qemu_monitor.c      | 23 +++++++++++++++++------
9119d9
 src/qemu/qemu_monitor.h      |  3 ++-
9119d9
 src/qemu/qemu_monitor_json.c | 24 ++++++++++++++++++++++++
9119d9
 src/qemu/qemu_monitor_json.h |  4 ++++
9119d9
 5 files changed, 62 insertions(+), 14 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
9119d9
index 239a300..aceddb1 100644
9119d9
--- a/src/qemu/qemu_driver.c
9119d9
+++ b/src/qemu/qemu_driver.c
9119d9
@@ -3735,6 +3735,8 @@ qemuDomainScreenshot(virDomainPtr dom,
9119d9
     char *ret = NULL;
9119d9
     bool unlink_tmp = false;
9119d9
     virQEMUDriverConfigPtr cfg = NULL;
9119d9
+    int video_index = 0;
9119d9
+    const char *video_id = NULL;
9119d9
 
9119d9
     virCheckFlags(0, NULL);
9119d9
 
9119d9
@@ -3756,12 +3758,15 @@ qemuDomainScreenshot(virDomainPtr dom,
9119d9
         goto endjob;
9119d9
     }
9119d9
 
9119d9
-    /* Well, even if qemu allows multiple graphic cards, heads, whatever,
9119d9
-     * screenshot command does not */
9119d9
-    if (screen) {
9119d9
-        virReportError(VIR_ERR_INVALID_ARG,
9119d9
-                       "%s", _("currently is supported only taking "
9119d9
-                               "screenshots of screen ID 0"));
9119d9
+    while (video_index < vm->def->nvideos) {
9119d9
+        if (screen < vm->def->videos[video_index]->heads)
9119d9
+            break;
9119d9
+        screen -= vm->def->videos[video_index]->heads;
9119d9
+        video_index++;
9119d9
+    }
9119d9
+
9119d9
+    if (video_index == vm->def->nvideos) {
9119d9
+        virReportError(VIR_ERR_INVALID_ARG, "%s", _("no such screen"));
9119d9
         goto endjob;
9119d9
     }
9119d9
 
9119d9
@@ -3776,8 +3781,11 @@ qemuDomainScreenshot(virDomainPtr dom,
9119d9
 
9119d9
     virSecurityManagerSetSavedStateLabel(qemu_driver->securityManager, vm->def, tmp);
9119d9
 
9119d9
+    if (video_index)
9119d9
+        video_id = vm->def->videos[video_index]->info.alias;
9119d9
+
9119d9
     qemuDomainObjEnterMonitor(driver, vm);
9119d9
-    if (qemuMonitorScreendump(priv->mon, tmp) < 0) {
9119d9
+    if (qemuMonitorScreendump(priv->mon, tmp, video_id) < 0) {
9119d9
         qemuDomainObjExitMonitor(driver, vm);
9119d9
         goto endjob;
9119d9
     }
9119d9
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
9119d9
index 5b2952a..2edc19b 100644
9119d9
--- a/src/qemu/qemu_monitor.c
9119d9
+++ b/src/qemu/qemu_monitor.c
9119d9
@@ -3340,11 +3340,12 @@ int qemuMonitorSendKey(qemuMonitorPtr mon,
9119d9
 }
9119d9
 
9119d9
 int qemuMonitorScreendump(qemuMonitorPtr mon,
9119d9
-                          const char *file)
9119d9
+                          const char *file,
9119d9
+                          const char *id)
9119d9
 {
9119d9
     int ret;
9119d9
 
9119d9
-    VIR_DEBUG("mon=%p, file=%s", mon, file);
9119d9
+    VIR_DEBUG("mon=%p, file=%s, id=%s", mon, file, id);
9119d9
 
9119d9
     if (!mon) {
9119d9
         virReportError(VIR_ERR_INVALID_ARG, "%s",
9119d9
@@ -3352,10 +3353,20 @@ int qemuMonitorScreendump(qemuMonitorPtr mon,
9119d9
         return -1;
9119d9
     }
9119d9
 
9119d9
-    if (mon->json)
9119d9
-        ret = qemuMonitorJSONScreendump(mon, file);
9119d9
-    else
9119d9
-        ret = qemuMonitorTextScreendump(mon, file);
9119d9
+    if (id) {
9119d9
+        if (mon->json) {
9119d9
+            ret = qemuMonitorJSONScreendumpRH(mon, file, id);
9119d9
+        } else {
9119d9
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
9119d9
+                           _("non-zero screen IDs require JSON monitor"));
9119d9
+            ret = -1;
9119d9
+        }
9119d9
+    } else {
9119d9
+        if (mon->json)
9119d9
+            ret = qemuMonitorJSONScreendump(mon, file);
9119d9
+        else
9119d9
+            ret = qemuMonitorTextScreendump(mon, file);
9119d9
+    }
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
9119d9
index 4fd6f01..ecba7e1 100644
9119d9
--- a/src/qemu/qemu_monitor.h
9119d9
+++ b/src/qemu/qemu_monitor.h
9119d9
@@ -676,7 +676,8 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
9119d9
 int qemuMonitorInjectNMI(qemuMonitorPtr mon);
9119d9
 
9119d9
 int qemuMonitorScreendump(qemuMonitorPtr mon,
9119d9
-                          const char *file);
9119d9
+                          const char *file,
9119d9
+                          const char *id);
9119d9
 
9119d9
 int qemuMonitorSendKey(qemuMonitorPtr mon,
9119d9
                        unsigned int holdtime,
9119d9
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
9119d9
index 62e7d5d..6e8834f 100644
9119d9
--- a/src/qemu/qemu_monitor_json.c
9119d9
+++ b/src/qemu/qemu_monitor_json.c
9119d9
@@ -3661,6 +3661,30 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
+int qemuMonitorJSONScreendumpRH(qemuMonitorPtr mon,
9119d9
+                                const char *file,
9119d9
+                                const char *id)
9119d9
+{
9119d9
+    int ret = -1;
9119d9
+    virJSONValuePtr cmd, reply = NULL;
9119d9
+
9119d9
+    cmd = qemuMonitorJSONMakeCommand("__com.redhat_qxl_screendump",
9119d9
+                                     "s:filename", file,
9119d9
+                                     "s:id", id,
9119d9
+                                     NULL);
9119d9
+    if (!cmd)
9119d9
+        return -1;
9119d9
+
9119d9
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
9119d9
+
9119d9
+    if (ret == 0)
9119d9
+        ret = qemuMonitorJSONCheckError(cmd, reply);
9119d9
+
9119d9
+    virJSONValueFree(cmd);
9119d9
+    virJSONValueFree(reply);
9119d9
+    return ret;
9119d9
+}
9119d9
+
9119d9
 int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
9119d9
                               const char *file)
9119d9
 {
9119d9
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
9119d9
index d8c9308..efa2330 100644
9119d9
--- a/src/qemu/qemu_monitor_json.h
9119d9
+++ b/src/qemu/qemu_monitor_json.h
9119d9
@@ -277,6 +277,10 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
9119d9
                            unsigned int *keycodes,
9119d9
                            unsigned int nkeycodes);
9119d9
 
9119d9
+int qemuMonitorJSONScreendumpRH(qemuMonitorPtr mon,
9119d9
+                                const char *file,
9119d9
+                                const char *id);
9119d9
+
9119d9
 int qemuMonitorJSONScreendump(qemuMonitorPtr mon,
9119d9
                               const char *file);
9119d9
 
9119d9
-- 
9119d9
2.1.0
9119d9