Blob Blame History Raw
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 19 Jun 2015 11:56:05 +0100
Subject: [PATCH] server: allows to set maximum monitors

spice-server will attempt to limit number of monitors.
Guest machine can send monitor list it accepts. Limiting the number sent
by guest will limit the number of monitors client will try to enable.
The guest usually see client monitors enabled and start using it so
not seeing client monitor won't try to enable more monitor.
In this case the additional monitor guest can support will always be
seen as heads with no attached monitors.
This allows limiting monitors number without changing guest drivers.

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
 server/red_dispatcher.c  | 10 ++++++++++
 server/red_dispatcher.h  |  1 +
 server/red_worker.c      |  4 +++-
 server/spice-server.syms |  5 +++++
 server/spice.h           |  3 +++
 5 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 6ecd3d4..6b395f4 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -64,6 +64,7 @@ struct RedDispatcher {
     Ring async_commands;
     pthread_mutex_t  async_lock;
     QXLDevSurfaceCreate surface_create;
+    unsigned int max_monitors;
 };
 
 typedef struct RedWorkeState {
@@ -701,6 +702,7 @@ static void red_dispatcher_monitors_config_async(RedDispatcher *dispatcher,
     payload.base.cmd = async_command_alloc(dispatcher, message, cookie);
     payload.monitors_config = monitors_config;
     payload.group_id = group_id;
+    payload.max_monitors = dispatcher->max_monitors;
 
     dispatcher_send_message(&dispatcher->dispatcher, message, &payload);
 }
@@ -995,6 +997,12 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
 }
 
 SPICE_GNUC_VISIBLE
+void spice_qxl_set_max_monitors(QXLInstance *instance, unsigned int max_monitors)
+{
+    instance->st->dispatcher->max_monitors = MAX(1u, max_monitors);
+}
+
+SPICE_GNUC_VISIBLE
 void spice_qxl_driver_unload(QXLInstance *instance)
 {
     red_dispatcher_driver_unload(instance->st->dispatcher);
@@ -1116,6 +1124,8 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
     red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;
     red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands;
 
+    red_dispatcher->max_monitors = UINT_MAX;
+
     qxl->st->qif->get_init_info(qxl, &init_info);
 
     init_data.memslot_id_bits = init_info.memslot_id_bits;
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
index 7d23b11..bc4d620 100644
--- a/server/red_dispatcher.h
+++ b/server/red_dispatcher.h
@@ -199,6 +199,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync {
     RedWorkerMessageAsync base;
     QXLPHYSICAL monitors_config;
     int group_id;
+    unsigned int max_monitors;
 } RedWorkerMessageMonitorsConfigAsync;
 
 typedef struct RedWorkerMessageDriverUnload {
diff --git a/server/red_worker.c b/server/red_worker.c
index dfa5274..64a7758 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -11749,7 +11749,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
         /* TODO: raise guest bug (requires added QXL interface) */
         return;
     }
-    worker_update_monitors_config(worker, dev_monitors_config, count, max_allowed);
+    worker_update_monitors_config(worker, dev_monitors_config,
+                                  MIN(count, msg->max_monitors),
+                                  MIN(max_allowed, msg->max_monitors));
     red_worker_push_monitors_config(worker);
 }
 
diff --git a/server/spice-server.syms b/server/spice-server.syms
index 4f2dc37..59da512 100644
--- a/server/spice-server.syms
+++ b/server/spice-server.syms
@@ -145,3 +145,8 @@ SPICE_SERVER_0.12.4 {
 global:
     spice_server_set_agent_file_xfer;
 } SPICE_SERVER_0.12.3;
+
+SPICE_SERVER_0.12.6 {
+global:
+    spice_qxl_set_max_monitors;
+} SPICE_SERVER_0.12.4;
diff --git a/server/spice.h b/server/spice.h
index 9c8e18a..3645775 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -170,6 +170,9 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
                                      int group_id, uint64_t cookie);
 /* since spice 0.12.3 */
 void spice_qxl_driver_unload(QXLInstance *instance);
+/* since spice 0.12.6 */
+void spice_qxl_set_max_monitors(QXLInstance *instance,
+                                unsigned int max_monitors);
 
 typedef struct QXLDrawArea {
     uint8_t *buf;