summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2015-06-19 11:56:05 +0100
committerChristophe Fergeau <cfergeau@redhat.com>2015-06-26 16:17:42 +0200
commit6d4e58f70ddf9c178e2cc20dd5a3ade8b95fd142 (patch)
tree5fe73a982bbfb6943687d3f40ab941917d836ef7
parent878d81dae494fab6b67ba34254d389e7f42d7d9d (diff)
downloadspice-6d4e58f70ddf9c178e2cc20dd5a3ade8b95fd142.tar.gz
spice-6d4e58f70ddf9c178e2cc20dd5a3ade8b95fd142.tar.xz
spice-6d4e58f70ddf9c178e2cc20dd5a3ade8b95fd142.zip
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>
-rw-r--r--server/red_dispatcher.c10
-rw-r--r--server/red_dispatcher.h1
-rw-r--r--server/red_worker.c12
-rw-r--r--server/spice-qxl.h3
-rw-r--r--server/spice-server.syms5
5 files changed, 26 insertions, 5 deletions
diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 74adaa2d..a2ef2263 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -66,6 +66,7 @@ struct RedDispatcher {
Ring async_commands;
pthread_mutex_t async_lock;
QXLDevSurfaceCreate surface_create;
+ unsigned int max_monitors;
};
extern uint32_t streaming_video;
@@ -693,6 +694,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);
}
@@ -987,6 +989,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);
@@ -1110,6 +1118,8 @@ void 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 907b7c7c..70b8a628 100644
--- a/server/red_dispatcher.h
+++ b/server/red_dispatcher.h
@@ -200,6 +200,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 515262d6..f3d8ad93 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -11217,11 +11217,13 @@ static inline void red_monitors_config_item_add(DisplayChannelClient *dcc)
}
static void worker_update_monitors_config(RedWorker *worker,
- QXLMonitorsConfig *dev_monitors_config)
+ QXLMonitorsConfig *dev_monitors_config,
+ unsigned int max_monitors)
{
int heads_size;
MonitorsConfig *monitors_config;
int i;
+ unsigned int count = MIN(dev_monitors_config->count, max_monitors);
monitors_config_decref(worker->monitors_config);
@@ -11235,13 +11237,13 @@ static void worker_update_monitors_config(RedWorker *worker,
dev_monitors_config->heads[i].width,
dev_monitors_config->heads[i].height);
}
- heads_size = dev_monitors_config->count * sizeof(QXLHead);
+ heads_size = count * sizeof(QXLHead);
worker->monitors_config = monitors_config =
spice_malloc(sizeof(*monitors_config) + heads_size);
monitors_config->refs = 1;
monitors_config->worker = worker;
- monitors_config->count = dev_monitors_config->count;
- monitors_config->max_allowed = dev_monitors_config->max_allowed;
+ monitors_config->count = count;
+ monitors_config->max_allowed = MIN(dev_monitors_config->max_allowed, max_monitors);
memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size);
}
@@ -11651,7 +11653,7 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
dev_monitors_config->max_allowed);
return;
}
- worker_update_monitors_config(worker, dev_monitors_config);
+ worker_update_monitors_config(worker, dev_monitors_config, msg->max_monitors);
red_worker_push_monitors_config(worker);
}
diff --git a/server/spice-qxl.h b/server/spice-qxl.h
index 31ff742f..dd49a860 100644
--- a/server/spice-qxl.h
+++ b/server/spice-qxl.h
@@ -97,6 +97,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;
diff --git a/server/spice-server.syms b/server/spice-server.syms
index 21938112..3c7d9456 100644
--- a/server/spice-server.syms
+++ b/server/spice-server.syms
@@ -153,3 +153,8 @@ global:
spice_server_get_best_record_rate;
spice_server_set_record_rate;
} SPICE_SERVER_0.12.4;
+
+SPICE_SERVER_0.12.6 {
+global:
+ spice_qxl_set_max_monitors;
+} SPICE_SERVER_0.12.5;