Blame SOURCES/0083-server-allows-to-set-maximum-monitors.patch

e2c81d
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
e2c81d
From: Frediano Ziglio <fziglio@redhat.com>
e2c81d
Date: Fri, 19 Jun 2015 11:56:05 +0100
e2c81d
Subject: [PATCH] server: allows to set maximum monitors
e2c81d
e2c81d
spice-server will attempt to limit number of monitors.
e2c81d
Guest machine can send monitor list it accepts. Limiting the number sent
e2c81d
by guest will limit the number of monitors client will try to enable.
e2c81d
The guest usually see client monitors enabled and start using it so
e2c81d
not seeing client monitor won't try to enable more monitor.
e2c81d
In this case the additional monitor guest can support will always be
e2c81d
seen as heads with no attached monitors.
e2c81d
This allows limiting monitors number without changing guest drivers.
e2c81d
e2c81d
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
e2c81d
---
e2c81d
 server/red_dispatcher.c  | 10 ++++++++++
e2c81d
 server/red_dispatcher.h  |  1 +
e2c81d
 server/red_worker.c      |  4 +++-
e2c81d
 server/spice-server.syms |  5 +++++
e2c81d
 server/spice.h           |  3 +++
e2c81d
 5 files changed, 22 insertions(+), 1 deletion(-)
e2c81d
e2c81d
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
e2c81d
index 6ecd3d4..6b395f4 100644
e2c81d
--- a/server/red_dispatcher.c
e2c81d
+++ b/server/red_dispatcher.c
e2c81d
@@ -64,6 +64,7 @@ struct RedDispatcher {
e2c81d
     Ring async_commands;
e2c81d
     pthread_mutex_t  async_lock;
e2c81d
     QXLDevSurfaceCreate surface_create;
e2c81d
+    unsigned int max_monitors;
e2c81d
 };
e2c81d
 
e2c81d
 typedef struct RedWorkeState {
e2c81d
@@ -701,6 +702,7 @@ static void red_dispatcher_monitors_config_async(RedDispatcher *dispatcher,
e2c81d
     payload.base.cmd = async_command_alloc(dispatcher, message, cookie);
e2c81d
     payload.monitors_config = monitors_config;
e2c81d
     payload.group_id = group_id;
e2c81d
+    payload.max_monitors = dispatcher->max_monitors;
e2c81d
 
e2c81d
     dispatcher_send_message(&dispatcher->dispatcher, message, &payload);
e2c81d
 }
e2c81d
@@ -995,6 +997,12 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
e2c81d
 }
e2c81d
 
e2c81d
 SPICE_GNUC_VISIBLE
e2c81d
+void spice_qxl_set_max_monitors(QXLInstance *instance, unsigned int max_monitors)
e2c81d
+{
e2c81d
+    instance->st->dispatcher->max_monitors = MAX(1u, max_monitors);
e2c81d
+}
e2c81d
+
e2c81d
+SPICE_GNUC_VISIBLE
e2c81d
 void spice_qxl_driver_unload(QXLInstance *instance)
e2c81d
 {
e2c81d
     red_dispatcher_driver_unload(instance->st->dispatcher);
e2c81d
@@ -1116,6 +1124,8 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
e2c81d
     red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;
e2c81d
     red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands;
e2c81d
 
e2c81d
+    red_dispatcher->max_monitors = UINT_MAX;
e2c81d
+
e2c81d
     qxl->st->qif->get_init_info(qxl, &init_info);
e2c81d
 
e2c81d
     init_data.memslot_id_bits = init_info.memslot_id_bits;
e2c81d
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
e2c81d
index 7d23b11..bc4d620 100644
e2c81d
--- a/server/red_dispatcher.h
e2c81d
+++ b/server/red_dispatcher.h
e2c81d
@@ -199,6 +199,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync {
e2c81d
     RedWorkerMessageAsync base;
e2c81d
     QXLPHYSICAL monitors_config;
e2c81d
     int group_id;
e2c81d
+    unsigned int max_monitors;
e2c81d
 } RedWorkerMessageMonitorsConfigAsync;
e2c81d
 
e2c81d
 typedef struct RedWorkerMessageDriverUnload {
e2c81d
diff --git a/server/red_worker.c b/server/red_worker.c
e2c81d
index dfa5274..64a7758 100644
e2c81d
--- a/server/red_worker.c
e2c81d
+++ b/server/red_worker.c
e2c81d
@@ -11749,7 +11749,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
e2c81d
         /* TODO: raise guest bug (requires added QXL interface) */
e2c81d
         return;
e2c81d
     }
e2c81d
-    worker_update_monitors_config(worker, dev_monitors_config, count, max_allowed);
e2c81d
+    worker_update_monitors_config(worker, dev_monitors_config,
e2c81d
+                                  MIN(count, msg->max_monitors),
e2c81d
+                                  MIN(max_allowed, msg->max_monitors));
e2c81d
     red_worker_push_monitors_config(worker);
e2c81d
 }
e2c81d
 
e2c81d
diff --git a/server/spice-server.syms b/server/spice-server.syms
e2c81d
index 4f2dc37..59da512 100644
e2c81d
--- a/server/spice-server.syms
e2c81d
+++ b/server/spice-server.syms
e2c81d
@@ -145,3 +145,8 @@ SPICE_SERVER_0.12.4 {
e2c81d
 global:
e2c81d
     spice_server_set_agent_file_xfer;
e2c81d
 } SPICE_SERVER_0.12.3;
e2c81d
+
e2c81d
+SPICE_SERVER_0.12.6 {
e2c81d
+global:
e2c81d
+    spice_qxl_set_max_monitors;
e2c81d
+} SPICE_SERVER_0.12.4;
e2c81d
diff --git a/server/spice.h b/server/spice.h
e2c81d
index 9c8e18a..3645775 100644
e2c81d
--- a/server/spice.h
e2c81d
+++ b/server/spice.h
e2c81d
@@ -170,6 +170,9 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
e2c81d
                                      int group_id, uint64_t cookie);
e2c81d
 /* since spice 0.12.3 */
e2c81d
 void spice_qxl_driver_unload(QXLInstance *instance);
e2c81d
+/* since spice 0.12.6 */
e2c81d
+void spice_qxl_set_max_monitors(QXLInstance *instance,
e2c81d
+                                unsigned int max_monitors);
e2c81d
 
e2c81d
 typedef struct QXLDrawArea {
e2c81d
     uint8_t *buf;