[Spice-commits] 8 commits - configure.ac server/agent-msg-filter.c server/agent-msg-filter.h server/red_dispatcher.c server/red_dispatcher.h server/reds.c server/spice.h server/tests spice-common

Alon Levy alon at kemper.freedesktop.org
Thu Sep 13 04:49:20 PDT 2012


 configure.ac                       |    6 ++--
 server/agent-msg-filter.c          |    8 +++++
 server/agent-msg-filter.h          |    1 
 server/red_dispatcher.c            |   51 +++++++++++++++++++++++++++++++++-
 server/red_dispatcher.h            |    4 ++
 server/reds.c                      |   55 +++++++++++++++++++++++++++++++++++--
 server/spice.h                     |   14 ++++++---
 server/tests/basic_event_loop.c    |    2 -
 server/tests/test_display_base.c   |   46 ++++++++++++++++++++++++++++++
 server/tests/test_display_base.h   |    1 
 server/tests/test_display_no_ssl.c |    1 
 spice-common                       |    2 -
 12 files changed, 179 insertions(+), 12 deletions(-)

New commits:
commit 56eef9eeaaeab11545982792094843c60bab0d1c
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 18:35:09 2012 +0300

    spice-server 0.11.5
    
    Added api:
     QXL interface (3.2)
      client_monitors_config

diff --git a/configure.ac b/configure.ac
index 1c57110..0545af6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,10 +12,10 @@ AC_PREREQ([2.57])
 
 m4_define([SPICE_MAJOR], 0)
 m4_define([SPICE_MINOR], 11)
-m4_define([SPICE_MICRO], 4)
-m4_define([SPICE_CURRENT], [5])
+m4_define([SPICE_MICRO], 5)
+m4_define([SPICE_CURRENT], [6])
 m4_define([SPICE_REVISION], [0])
-m4_define([SPICE_AGE], [4])
+m4_define([SPICE_AGE], [5])
 
 # Note on the library name on linux (SONAME) produced by libtool (for reference, gleaned
 # from looking at libtool 2.4.2)
diff --git a/server/spice.h b/server/spice.h
index 2b94906..fc10303 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -23,7 +23,7 @@
 #include <spice/qxl_dev.h>
 #include <spice/vd_agent.h>
 
-#define SPICE_SERVER_VERSION 0x000b04 /* release 0.11.4 */
+#define SPICE_SERVER_VERSION 0x000b05 /* release 0.11.5 */
 
 /* interface base type */
 
commit 9e1d165fc01d9125fb8d6a65ac231b737db98189
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 18:39:28 2012 +0300

    server/tests: agent mock, client_monitors_config

diff --git a/server/tests/basic_event_loop.c b/server/tests/basic_event_loop.c
index 34bb178..c6f6698 100644
--- a/server/tests/basic_event_loop.c
+++ b/server/tests/basic_event_loop.c
@@ -115,7 +115,7 @@ static void watch_remove(SpiceWatch *watch)
 
 static void channel_event(int event, SpiceChannelEventInfo *info)
 {
-    DPRINTF(0, "channel event con, type, id, event: %ld, %d, %d, %d\n",
+    DPRINTF(0, "channel event con, type, id, event: %ld, %d, %d, %d",
             info->connection_id, info->type, info->id, event);
 }
 
diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
index 710e3a8..8c7f512 100644
--- a/server/tests/test_display_base.c
+++ b/server/tests/test_display_base.c
@@ -10,6 +10,7 @@
 #include <sys/types.h>
 #include <getopt.h>
 
+#include "spice.h"
 #include <spice/qxl_dev.h>
 
 #include "test_display_base.h"
@@ -700,6 +701,11 @@ static int flush_resources(QXLInstance *qin)
     return TRUE;
 }
 
+static void client_monitors_config(QXLInstance *qin, VDAgentMonitorsConfig *monitors_config)
+{
+    printf("%s: %d\n", __func__, monitors_config->num_of_monitors);
+}
+
 QXLInterface display_sif = {
     .base = {
         .type = SPICE_INTERFACE_QXL,
@@ -720,6 +726,7 @@ QXLInterface display_sif = {
     .req_cursor_notification = req_cursor_notification,
     .notify_update = notify_update,
     .flush_resources = flush_resources,
+    .client_monitors_config = client_monitors_config,
 };
 
 /* interface for tests */
@@ -728,6 +735,45 @@ void test_add_display_interface(Test* test)
     spice_server_add_interface(test->server, &test->qxl_instance.base);
 }
 
+static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
+{
+    printf("%s: %d\n", __func__, len);
+    return len;
+}
+
+static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
+{
+    printf("%s: %d\n", __func__, len);
+    return 0;
+}
+
+static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
+{
+    printf("%s: %d\n", __func__, connected);
+}
+
+static SpiceCharDeviceInterface vdagent_sif = {
+    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
+    .base.description   = "test spice virtual channel char device",
+    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
+    .state              = vmc_state,
+    .write              = vmc_write,
+    .read               = vmc_read,
+};
+
+SpiceCharDeviceInstance vdagent_sin = {
+    .base = {
+        .sif = &vdagent_sif.base,
+    },
+    .subtype = "vdagent",
+};
+
+void test_add_agent_interface(SpiceServer *server)
+{
+    spice_server_add_interface(server, &vdagent_sin.base);
+}
+
 void test_set_simple_command_list(Test *test, int *simple_commands, int num_commands)
 {
     int i;
diff --git a/server/tests/test_display_base.h b/server/tests/test_display_base.h
index db97b8c..c3b9fea 100644
--- a/server/tests/test_display_base.h
+++ b/server/tests/test_display_base.h
@@ -105,6 +105,7 @@ struct Test {
 void test_set_simple_command_list(Test *test, int *command, int num_commands);
 void test_set_command_list(Test *test, Command *command, int num_commands);
 void test_add_display_interface(Test *test);
+void test_add_agent_interface(SpiceServer *server); // TODO - Test *test
 Test* test_new(SpiceCoreInterface* core);
 
 uint32_t test_get_width(void);
diff --git a/server/tests/test_display_no_ssl.c b/server/tests/test_display_no_ssl.c
index 67325cc..83ab3dc 100644
--- a/server/tests/test_display_no_ssl.c
+++ b/server/tests/test_display_no_ssl.c
@@ -43,6 +43,7 @@ int main(void)
     test = test_new(core);
     //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
     test_add_display_interface(test);
+    test_add_agent_interface(test->server);
     test_set_simple_command_list(test, simple_commands, COUNT(simple_commands));
 
     ping_timer = core->timer_add(pinger, NULL);
commit d694739b214853f19ab1a0df27e49b5417946b70
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 18:26:29 2012 +0300

    server: Filter VD_AGENT_MONITORS_CONFIG
    
    If the guest supports client monitors config we pass it the
    VDAgentMonitorsConfig message via the
    QXLInterface::client_monitors_config api instead of via the vdagent.

diff --git a/server/agent-msg-filter.c b/server/agent-msg-filter.c
index 7584b52..b48dd76 100644
--- a/server/agent-msg-filter.c
+++ b/server/agent-msg-filter.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include "red_common.h"
 #include "agent-msg-filter.h"
+#include "red_dispatcher.h"
 
 void agent_msg_filter_init(struct AgentMsgFilter *filter,
     int copy_paste, int discard_all)
@@ -80,6 +81,13 @@ data_to_read:
                 filter->result = AGENT_MSG_FILTER_DISCARD;
             }
             break;
+        case VD_AGENT_MONITORS_CONFIG:
+            if (red_dispatcher_use_client_monitors_config()) {
+                filter->result = AGENT_MSG_FILTER_MONITORS_CONFIG;
+            } else {
+                filter->result = AGENT_MSG_FILTER_OK;
+            }
+            break;
         default:
             filter->result = AGENT_MSG_FILTER_OK;
         }
diff --git a/server/agent-msg-filter.h b/server/agent-msg-filter.h
index ecccfc7..0132ad7 100644
--- a/server/agent-msg-filter.h
+++ b/server/agent-msg-filter.h
@@ -28,6 +28,7 @@ enum {
     AGENT_MSG_FILTER_OK,
     AGENT_MSG_FILTER_DISCARD,
     AGENT_MSG_FILTER_PROTO_ERROR,
+    AGENT_MSG_FILTER_MONITORS_CONFIG,
     AGENT_MSG_FILTER_END
 };
 
diff --git a/server/reds.c b/server/reds.c
index 57ce88b..5537c15 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -234,6 +234,15 @@ typedef struct SpiceCharDeviceStateItem {
     SpiceCharDeviceState *st;
 } SpiceCharDeviceStateItem;
 
+/* Intermediate state for on going monitors config message from a single
+ * client, being passed to the guest */
+typedef struct RedsClientMonitorsConfig {
+    MainChannelClient *mcc;
+    uint8_t *buffer;
+    int buffer_size;
+    int buffer_pos;
+} RedsClientMonitorsConfig;
+
 typedef struct RedsState {
     int listen_socket;
     int secure_listen_socket;
@@ -284,6 +293,8 @@ typedef struct RedsState {
 #endif
     int peer_minor_version;
     int allow_multiple_clients;
+
+    RedsClientMonitorsConfig client_monitors_config;
 } RedsState;
 
 static RedsState *reds = NULL;
@@ -1184,6 +1195,41 @@ void reds_release_agent_data_buffer(uint8_t *buf)
     dev_state->recv_from_client_buf_pushed = FALSE;
 }
 
+static void reds_client_monitors_config_cleanup(void)
+{
+    RedsClientMonitorsConfig *cmc = &reds->client_monitors_config;
+
+    cmc->buffer_size = cmc->buffer_pos = 0;
+    free(cmc->buffer);
+    cmc->buffer = NULL;
+    cmc->mcc = NULL;
+}
+
+static void reds_on_main_agent_monitors_config(
+        MainChannelClient *mcc, void *message, size_t size)
+{
+    VDAgentMessage *msg_header;
+    VDAgentMonitorsConfig *monitors_config;
+    RedsClientMonitorsConfig *cmc = &reds->client_monitors_config;
+
+    cmc->buffer_size += size;
+    cmc->buffer = realloc(cmc->buffer, cmc->buffer_size);
+    spice_assert(cmc->buffer);
+    cmc->mcc = mcc;
+    memcpy(cmc->buffer + cmc->buffer_pos, message, size);
+    cmc->buffer_pos += size;
+    msg_header = (VDAgentMessage *)cmc->buffer;
+    if (sizeof(VDAgentMessage) > cmc->buffer_size ||
+            msg_header->size > cmc->buffer_size - sizeof(VDAgentMessage)) {
+        spice_debug("not enough data yet. %d\n", cmc->buffer_size);
+        return;
+    }
+    monitors_config = (VDAgentMonitorsConfig *)(cmc->buffer + sizeof(*msg_header));
+    spice_debug("%s: %d\n", __func__, monitors_config->num_of_monitors);
+    red_dispatcher_client_monitors_config(monitors_config);
+    reds_client_monitors_config_cleanup();
+}
+
 void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
 {
     VDIPortState *dev_state = &reds->agent_state;
@@ -1199,11 +1245,13 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
         break;
     case AGENT_MSG_FILTER_DISCARD:
         return;
+    case AGENT_MSG_FILTER_MONITORS_CONFIG:
+        reds_on_main_agent_monitors_config(mcc, message, size);
+        return;
     case AGENT_MSG_FILTER_PROTO_ERROR:
         reds_disconnect();
         return;
     }
-
     // TODO - start tracking agent data per channel
     header =  (VDIChunkHeader *)dev_state->recv_from_client_buf->buf;
     header->port = VDP_CLIENT_PORT;
@@ -3980,6 +4028,9 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
     inputs_init();
 
     reds->mouse_mode = SPICE_MOUSE_MODE_SERVER;
+
+    reds_client_monitors_config_cleanup();
+
     reds->allow_multiple_clients = getenv(SPICE_DEBUG_ALLOW_MC_ENV) != NULL;
     if (reds->allow_multiple_clients) {
         spice_warning("spice: allowing multiple client connections (crashy)");
commit 4338968aad68a84b62d7946b50ecd3d391a66571
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Sep 12 18:59:34 2012 +0300

    server/reds: reuse already defined local

diff --git a/server/reds.c b/server/reds.c
index 98b316d..57ce88b 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1208,7 +1208,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
     header =  (VDIChunkHeader *)dev_state->recv_from_client_buf->buf;
     header->port = VDP_CLIENT_PORT;
     header->size = size;
-    reds->agent_state.recv_from_client_buf->buf_used = sizeof(VDIChunkHeader) + size;
+    dev_state->recv_from_client_buf->buf_used = sizeof(VDIChunkHeader) + size;
 
     dev_state->recv_from_client_buf_pushed = TRUE;
     spice_char_device_write_buffer_add(reds->agent_state.base, dev_state->recv_from_client_buf);
commit dc69ef49d08cf835bdb480ee68247232c69ad725
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 18:30:17 2012 +0300

    server/red_dispatcher: client_monitors_config support
    
    Adds two functions:
     - red_dispatcher_use_client_monitors_config:
       check that QXLInterface supports client_monitors_config and that it's
       functional.
     - red_dispatcher_client_monitors_config:
       send the client monitors configuration to the guest.

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 3a4229e..39d05ab 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -83,6 +83,22 @@ extern spice_wan_compression_t zlib_glz_state;
 
 static RedDispatcher *dispatchers = NULL;
 
+static int red_dispatcher_version_check(int major, int minor)
+{
+    if (num_active_workers > 0) {
+        RedDispatcher *now = dispatchers;
+        while (now) {
+            if (now->base.major_version != major ||
+                now->base.minor_version < minor) {
+                return FALSE;
+            }
+            now = now->next;
+        }
+        return TRUE;
+    }
+    return FALSE;
+}
+
 static void red_dispatcher_set_display_peer(RedChannel *channel, RedClient *client,
                                             RedsStream *stream, int migration,
                                             int num_common_caps, uint32_t *common_caps, int num_caps,
@@ -295,6 +311,39 @@ static void red_dispatcher_update_area(RedDispatcher *dispatcher, uint32_t surfa
                             &payload);
 }
 
+int red_dispatcher_use_client_monitors_config(void)
+{
+    RedDispatcher *now = dispatchers;
+
+    if (num_active_workers == 0) {
+        return FALSE;
+    }
+
+    for (; now ; now = now->next) {
+        if (!red_dispatcher_version_check(3, 3) ||
+            !now->qxl->st->qif->client_monitors_config ||
+            !now->qxl->st->qif->client_monitors_config(now->qxl, NULL)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig *monitors_config)
+{
+    RedDispatcher *now = dispatchers;
+
+    while (now) {
+        if (!now->qxl->st->qif->client_monitors_config ||
+            !now->qxl->st->qif->client_monitors_config(now->qxl,
+                                                       monitors_config)) {
+            spice_warning("spice bug: QXLInterface::client_monitors_config"
+                          " failed/missing unexpectedly\n");
+        }
+        now = now->next;
+    }
+}
+
 static AsyncCommand *async_command_alloc(RedDispatcher *dispatcher,
                                          RedWorkerMessage message,
                                          uint64_t cookie)
diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
index 7e9ffe6..17eeb29 100644
--- a/server/red_dispatcher.h
+++ b/server/red_dispatcher.h
@@ -18,6 +18,8 @@
 #ifndef _H_RED_DISPATCHER
 #define _H_RED_DISPATCHER
 
+#include "red_channel.h"
+
 struct RedChannelClient;
 typedef struct AsyncCommand AsyncCommand;
 
@@ -35,6 +37,8 @@ uint32_t red_dispatcher_qxl_ram_size(void);
 int red_dispatcher_qxl_count(void);
 void red_dispatcher_async_complete(struct RedDispatcher *, AsyncCommand *);
 struct Dispatcher *red_dispatcher_get_dispatcher(struct RedDispatcher *);
+int red_dispatcher_use_client_monitors_config(void);
+void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig *monitors_config);
 
 typedef struct RedWorkerMessageDisplayConnect {
     RedClient * client;
commit ce42c76aed852eb88086ec371acf899d666ca3c6
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 16:24:54 2012 +0300

    server: add QXLInterface::client_monitors_config
    
    Used to implement guest monitor configuration change similarly to real
    hardware in conjunction with the new qemu interrupt
    QXL_INTERRUPT_CLIENT_MONITORS_CONFIG. client_monitors_config is also
    used to probe the support by the interface. If it is not supported we
    send the message to the guest agent.
    This makes a linux qxl driver similar to existing kms drivers.
    
    The logic is:
    
    For every received VDAgentMonitorsConfig:
     if client_monitors_config(NULL):
      write client configuration to pci rom BAR.
      send interrupt to guest
      guest kernel reads configuration from rom BAR.
      guest kernel issues event to user space
      user space reads (libdrm) and reconfigures (libXRandr)
     else: (current implementation)
      write message to guest agent
      guest agent issues reconfiguration via XRandr / windows Escape ioctl to kernel

diff --git a/server/spice.h b/server/spice.h
index 2b2ed36..2b94906 100644
--- a/server/spice.h
+++ b/server/spice.h
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <sys/socket.h>
 #include <spice/qxl_dev.h>
+#include <spice/vd_agent.h>
 
 #define SPICE_SERVER_VERSION 0x000b04 /* release 0.11.4 */
 
@@ -96,7 +97,7 @@ struct SpiceCoreInterface {
 
 #define SPICE_INTERFACE_QXL "qxl"
 #define SPICE_INTERFACE_QXL_MAJOR 3
-#define SPICE_INTERFACE_QXL_MINOR 2
+#define SPICE_INTERFACE_QXL_MINOR 3
 typedef struct QXLInterface QXLInterface;
 typedef struct QXLInstance QXLInstance;
 typedef struct QXLState QXLState;
@@ -240,8 +241,13 @@ struct QXLInterface {
                                  struct QXLRect *updated_rects,
                                  uint32_t num_updated_rects);
     void (*set_client_capabilities)(QXLInstance *qin,
-				    uint8_t client_present,
-				    uint8_t caps[58]);
+                                    uint8_t client_present,
+                                    uint8_t caps[58]);
+    /* returns 1 if the interface is supported, 0 otherwise.
+     * if monitors_config is NULL nothing is done except reporting the
+     * return code. */
+    int (*client_monitors_config)(QXLInstance *qin,
+                                  VDAgentMonitorsConfig *monitors_config);
 };
 
 struct QXLInstance {
commit 9b2e52f2bc4dec8ca8f34c8d6b3d9b8c5fe69c56
Author: Alon Levy <alevy at redhat.com>
Date:   Tue Sep 11 21:29:03 2012 +0300

    update spice-common module
    
    For qxl client_monitors_config support.

diff --git a/spice-common b/spice-common
index f67bcd0..9b9592f 160000
--- a/spice-common
+++ b/spice-common
@@ -1 +1 @@
-Subproject commit f67bcd03e92c2d04f987135ad9b467c93fd47908
+Subproject commit 9b9592f80cb71b4dacf88400236a9138f227ae1d
commit c41616bb7f82db5588b0d34327076b9a3c626019
Author: Alon Levy <alevy at redhat.com>
Date:   Mon Sep 10 18:32:51 2012 +0300

    server/red_dispatcher: change a printerr to debug

diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
index 69d4f0a..3a4229e 100644
--- a/server/red_dispatcher.c
+++ b/server/red_dispatcher.c
@@ -91,7 +91,7 @@ static void red_dispatcher_set_display_peer(RedChannel *channel, RedClient *clie
     RedWorkerMessageDisplayConnect payload;
     RedDispatcher *dispatcher;
 
-    spice_printerr("");
+    spice_debug("%s", "");
     dispatcher = (RedDispatcher *)channel->data;
     payload.client = client;
     payload.stream = stream;


More information about the Spice-commits mailing list