<div dir="ltr">looks good to me, ACK<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 10, 2015 at 1:54 PM, Frediano Ziglio <span dir="ltr"><<a href="mailto:fziglio@redhat.com" target="_blank">fziglio@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">spice-server will attempt to limit number of monitors.<br>
Guest machine can send monitor list it accepts. Limiting the number sent<br>
by guest will limit the number of monitors client will try to enable.<br>
The guest usually see client monitors enabled and start using it so<br>
not seeing client monitor won't try to enable more monitor.<br>
In this case the additional monitor guest can support will always be<br>
seen as heads with no attached monitors.<br>
This allows limiting monitors number without changing guest drivers.<br>
<br>
Signed-off-by: Frediano Ziglio <<a href="mailto:fziglio@redhat.com">fziglio@redhat.com</a>><br>
---<br>
 server/red_dispatcher.c  | 11 +++++++++++<br>
 server/red_dispatcher.h  |  1 +<br>
 server/red_worker.c      | 12 +++++++-----<br>
 server/spice-qxl.h       |  3 +++<br>
 server/spice-server.syms |  5 +++++<br>
 5 files changed, 27 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c<br>
index f5f3e52..3838bbb 100644<br>
--- a/server/red_dispatcher.c<br>
+++ b/server/red_dispatcher.c<br>
@@ -66,6 +66,7 @@ struct RedDispatcher {<br>
     Ring async_commands;<br>
     pthread_mutex_t  async_lock;<br>
     QXLDevSurfaceCreate surface_create;<br>
+    unsigned max_monitors;<br>
 };<br>
<br>
 extern uint32_t streaming_video;<br>
@@ -693,6 +694,7 @@ static void red_dispatcher_monitors_config_async(RedDispatcher *dispatcher,<br>
     payload.base.cmd = async_command_alloc(dispatcher, message, cookie);<br>
     payload.monitors_config = monitors_config;<br>
     payload.group_id = group_id;<br>
+    payload.max_monitors = dispatcher->max_monitors;<br>
<br>
     dispatcher_send_message(&dispatcher->dispatcher, message, &payload);<br>
 }<br>
@@ -987,6 +989,13 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors<br>
 }<br>
<br>
 SPICE_GNUC_VISIBLE<br>
+void spice_qxl_set_monitors_config_limit(QXLInstance *instance,<br>
+                                         unsigned max_monitors)<br>
+{<br>
+    instance->st->dispatcher->max_monitors = MAX(1u, max_monitors);<br>
+}<br>
+<br>
+SPICE_GNUC_VISIBLE<br>
 void spice_qxl_driver_unload(QXLInstance *instance)<br>
 {<br>
     red_dispatcher_driver_unload(instance->st->dispatcher);<br>
@@ -1110,6 +1119,8 @@ void red_dispatcher_init(QXLInstance *qxl)<br>
     red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;<br>
     red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands;<br>
<br>
+    red_dispatcher->max_monitors = UINT16_MAX;<br>
+<br>
     qxl->st->qif->get_init_info(qxl, &init_info);<br>
<br>
     init_data.memslot_id_bits = init_info.memslot_id_bits;<br>
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h<br>
index 907b7c7..70b8a62 100644<br>
--- a/server/red_dispatcher.h<br>
+++ b/server/red_dispatcher.h<br>
@@ -200,6 +200,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync {<br>
     RedWorkerMessageAsync base;<br>
     QXLPHYSICAL monitors_config;<br>
     int group_id;<br>
+    unsigned int max_monitors;<br>
 } RedWorkerMessageMonitorsConfigAsync;<br>
<br>
 typedef struct RedWorkerMessageDriverUnload {<br>
diff --git a/server/red_worker.c b/server/red_worker.c<br>
index 5deb30b..564bfba 100644<br>
--- a/server/red_worker.c<br>
+++ b/server/red_worker.c<br>
@@ -11234,11 +11234,13 @@ static inline void red_monitors_config_item_add(DisplayChannelClient *dcc)<br>
 }<br>
<br>
 static void worker_update_monitors_config(RedWorker *worker,<br>
-                                          QXLMonitorsConfig *dev_monitors_config)<br>
+                                          QXLMonitorsConfig *dev_monitors_config,<br>
+                                          unsigned max_monitors)<br>
 {<br>
     int heads_size;<br>
     MonitorsConfig *monitors_config;<br>
     int i;<br>
+    unsigned count = MIN(dev_monitors_config->count, max_monitors);<br>
<br>
     monitors_config_decref(worker->monitors_config);<br>
<br>
@@ -11252,13 +11254,13 @@ static void worker_update_monitors_config(RedWorker *worker,<br>
                     dev_monitors_config->heads[i].width,<br>
                     dev_monitors_config->heads[i].height);<br>
     }<br>
-    heads_size = dev_monitors_config->count * sizeof(QXLHead);<br>
+    heads_size = count * sizeof(QXLHead);<br>
     worker->monitors_config = monitors_config =<br>
         spice_malloc(sizeof(*monitors_config) + heads_size);<br>
     monitors_config->refs = 1;<br>
     monitors_config->worker = worker;<br>
-    monitors_config->count = dev_monitors_config->count;<br>
-    monitors_config->max_allowed = dev_monitors_config->max_allowed;<br>
+    monitors_config->count = count;<br>
+    monitors_config->max_allowed = MIN(dev_monitors_config->max_allowed, max_monitors);<br>
     memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size);<br>
 }<br>
<br>
@@ -11668,7 +11670,7 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)<br>
                       dev_monitors_config->max_allowed);<br>
         return;<br>
     }<br>
-    worker_update_monitors_config(worker, dev_monitors_config);<br>
+    worker_update_monitors_config(worker, dev_monitors_config, msg->max_monitors);<br>
     red_worker_push_monitors_config(worker);<br>
 }<br>
<br>
diff --git a/server/spice-qxl.h b/server/spice-qxl.h<br>
index 31ff742..34d106c 100644<br>
--- a/server/spice-qxl.h<br>
+++ b/server/spice-qxl.h<br>
@@ -97,6 +97,9 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors<br>
                                      int group_id, uint64_t cookie);<br>
 /* since spice 0.12.3 */<br>
 void spice_qxl_driver_unload(QXLInstance *instance);<br>
+/* since spice 0.12.8 */<br>
+void spice_qxl_set_monitors_config_limit(QXLInstance *instance,<br>
+                                         unsigned max_monitors);<br>
<br>
 typedef struct QXLDrawArea {<br>
     uint8_t *buf;<br>
diff --git a/server/spice-server.syms b/server/spice-server.syms<br>
index 2193811..dfe526d 100644<br>
--- a/server/spice-server.syms<br>
+++ b/server/spice-server.syms<br>
@@ -153,3 +153,8 @@ global:<br>
     spice_server_get_best_record_rate;<br>
     spice_server_set_record_rate;<br>
 } SPICE_SERVER_0.12.4;<br>
+<br>
+SPICE_SERVER_0.12.8 {<br>
+global:<br>
+    spice_qxl_set_monitors_config_limit;<br>
+} SPICE_SERVER_0.12.5;<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.1.0<br>
<br>
_______________________________________________<br>
Spice-devel mailing list<br>
<a href="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/spice-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/spice-devel</a><br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">Marc-André Lureau</div>
</div>