[Spice-commits] 4 commits - server/cursor-channel.c server/dcc.c server/display-channel.c server/image-encoders.c server/red-channel-client.c server/red-worker.c server/reds-stream.c server/reds.c server/sound.c server/tests

Christophe Fergau teuf at kemper.freedesktop.org
Wed Mar 1 17:03:06 UTC 2017


 server/cursor-channel.c          |    4 
 server/dcc.c                     |    6 -
 server/display-channel.c         |   22 ++--
 server/image-encoders.c          |   12 +-
 server/red-channel-client.c      |    4 
 server/red-worker.c              |   34 +++----
 server/reds-stream.c             |   40 ++++-----
 server/reds.c                    |  107 +++++++++++++-----------
 server/sound.c                   |    2 
 server/tests/Makefile.am         |   10 ++
 server/tests/test-display-base.c |    7 +
 server/tests/test-display-base.h |    1 
 server/tests/test-vdagent.c      |  173 +++++++++++++++++++++++++++++++++++----
 13 files changed, 295 insertions(+), 127 deletions(-)

New commits:
commit be4ceb4e24c42c42b5e02e93d37789a4fdf45a01
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Wed Feb 1 19:12:40 2017 +0100

    test-vdagent: Make test case more useful
    
    This switches the test to using the GTest API, and add several tests
    related to https://bugzilla.redhat.com/show_bug.cgi?id=1411194
    
    This uses some API not available in glib 2.28, so this checks we have a
    new enough glib before building this test, and disables warnings when
    using too new glib API when building it.
    
    The "multiple-vmc-devices" is based off code written by Frediano Ziglio.
    
    Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
    Acked-by: Frediano Ziglio <fziglio at redhat.com>

diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index 4867d58..dd04834 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -46,6 +46,7 @@ check_PROGRAMS =				\
 	test-qxl-parsing			\
 	test-stat-file				\
 	test-leaks				\
+	test-vdagent				\
 	$(NULL)
 
 noinst_PROGRAMS =				\
@@ -57,7 +58,6 @@ noinst_PROGRAMS =				\
 	test-playback				\
 	test-display-resolution-changes		\
 	test-two-servers			\
-	test-vdagent				\
 	test-display-width-stride		\
 	spice-server-replay			\
 	$(check_PROGRAMS)			\
@@ -113,6 +113,14 @@ libtest_stat4_a_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_COMPRESS_STAT=1 -DTEST_RED_WORK
 
 test_qxl_parsing_LDADD = ../libserver.la $(LDADD)
 
+# Fallback implementations are provided for older glibs for the recent glib
+# methods this test is using, so no need to warn about them
+test_vdagent_CPPFLAGS =			\
+	$(AM_CPPFLAGS)			\
+	-UGLIB_VERSION_MIN_REQUIRED	\
+	-UGLIB_VERSION_MAX_ALLOWED	\
+	$(NULL)
+
 if HAVE_GSTREAMER
 test_gst_SOURCES = test-gst.c \
 	$(NULL)
diff --git a/server/tests/test-vdagent.c b/server/tests/test-vdagent.c
index e06229e..a4d48ee 100644
--- a/server/tests/test-vdagent.c
+++ b/server/tests/test-vdagent.c
@@ -37,14 +37,98 @@ int ping_ms = 100;
 #define MIN(a, b) ((a) > (b) ? (b) : (a))
 #endif
 
-static void pinger(SPICE_GNUC_UNUSED void *opaque)
+#if !GLIB_CHECK_VERSION(2, 34, 0)
+
+/* The code in this #ifdef block is taken from glib and is licensed under the
+ * GNU Lesser General Public License version 2 or later.
+ *
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Modified by the GLib Team and others 1997-2000.  See GLib AUTHORS
+ * file for a list of people on the GLib Team.
+ */
+
+typedef struct {
+    gchar *log_domain;
+    GLogLevelFlags log_level;
+    gchar *pattern;
+} GTestExpectedMessage;
+
+static GSList *expected_messages = NULL;
+
+static gboolean fatal_log_filter(const gchar *log_domain,
+                                 GLogLevelFlags log_level,
+                                 const gchar *msg,
+                                 gpointer user_data)
+{
+    GTestExpectedMessage *expected = expected_messages->data;
+
+    if ((g_strcmp0(expected->log_domain, log_domain) == 0)
+            && ((log_level & expected->log_level) == expected->log_level)
+            && (g_pattern_match_simple(expected->pattern, msg))) {
+        expected_messages = g_slist_delete_link(expected_messages,
+                                                expected_messages);
+        g_free (expected->log_domain);
+        g_free (expected->pattern);
+        g_free (expected);
+
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static void
+g_test_assert_expected_messages_internal (const char     *domain,
+                                          const char     *file,
+                                          int             line,
+                                          const char     *func)
+{
+  if (expected_messages)
+    {
+      GTestExpectedMessage *expected;
+      gchar *message;
+
+      expected = expected_messages->data;
+
+      message = g_strdup_printf ("Did not see expected message %s: %s",
+                                 expected->log_domain ? expected->log_domain : "**",
+                                 expected->pattern);
+      g_error ("%s", message);
+      g_free (message);
+    }
+}
+
+#define g_test_assert_expected_messages() g_test_assert_expected_messages_internal (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC)
+
+static void
+g_test_expect_message (const gchar    *log_domain,
+                       GLogLevelFlags  log_level,
+                       const gchar    *pattern)
 {
-    // show_channels is not thread safe - fails if disconnections / connections occur
-    //show_channels(server);
+  GTestExpectedMessage *expected;
+
+  g_return_if_fail (log_level != 0);
+  g_return_if_fail (pattern != NULL);
+  g_return_if_fail (~log_level & G_LOG_LEVEL_ERROR);
+
+  if (expected_messages == NULL)
+    {
+      g_test_log_set_fatal_handler(fatal_log_filter, NULL);
+    }
+
+  expected = g_new (GTestExpectedMessage, 1);
+  expected->log_domain = g_strdup (log_domain);
+  expected->log_level = log_level;
+  expected->pattern = g_strdup (pattern);
 
-    core->timer_start(ping_timer, ping_ms);
+  if ((log_level & G_LOG_LEVEL_MASK) <= G_LOG_LEVEL_WARNING)
+    {
+      expected_messages = g_slist_append (expected_messages, expected);
+    }
 }
 
+#endif /* GLIB_CHECK_VERSION(2, 34, 0) */
+
+
 static int vmc_write(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
                      SPICE_GNUC_UNUSED const uint8_t *buf,
                      int len)
@@ -62,6 +146,13 @@ static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
     static unsigned message_size;
     int ret;
 
+    if (pos == sizeof(message)) {
+        g_message("sent whole message");
+        pos++; /* Only print message once */
+    }
+    if (pos > sizeof(message)) {
+        return 0;
+    }
     if (pos == 0) {
         VDIChunkHeader *hdr = (VDIChunkHeader *)message;
         VDAgentMessage *msg = (VDAgentMessage *)&hdr[1];
@@ -83,9 +174,6 @@ static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
     ret = MIN(message_size - pos, len);
     memcpy(buf, &message[pos], ret);
     pos += ret;
-    if (pos == message_size) {
-        pos = 0;
-    }
     //printf("vmc_read %d (ret %d)\n", len, ret);
     return ret;
 }
@@ -105,24 +193,77 @@ static SpiceCharDeviceInterface vmc_interface = {
     .read               = vmc_read,
 };
 
-SpiceCharDeviceInstance vmc_instance = {
+static SpiceCharDeviceInstance vmc_instance = {
     .subtype = "vdagent",
 };
 
-int main(void)
+static void test_multiple_vmc_devices(void)
+{
+    SpiceCharDeviceInstance vmc_instances[2] = {
+        { .subtype = "vdagent", },
+        { .subtype = "vdagent", }
+    };
+    int status;
+
+    SpiceCoreInterface *core = basic_event_loop_init();
+    Test *test = test_new(core);
+
+    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+                          "*spice_server_char_device_add_interface: vdagent already attached");
+    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                          "*spice_server_remove_interface: assertion ?char_device->st != NULL'*");
+    vmc_instances[0].base.sif = &vmc_interface.base;
+    spice_server_add_interface(test->server, &vmc_instances[0].base);
+    vmc_instances[1].base.sif = &vmc_interface.base;
+    spice_server_add_interface(test->server, &vmc_instances[1].base);
+    status = spice_server_remove_interface(&vmc_instances[1].base);
+    g_assert_cmpint(status, ==, -1);
+    status = spice_server_remove_interface(&vmc_instances[0].base);
+    g_assert_cmpint(status, ==, 0);
+    g_test_assert_expected_messages();
+    test_destroy(test);
+    basic_event_loop_destroy();
+}
+
+static void test_duplicate_removal(void)
 {
-    Test *test;
+    SpiceCoreInterface *core = basic_event_loop_init();
+    Test *test = test_new(core);
+    int status;
+
+    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                          "*spice_server_remove_interface: assertion ?char_device->st != NULL'*");
+    vmc_instance.base.sif = &vmc_interface.base;
+    spice_server_add_interface(test->server, &vmc_instance.base);
+    status = spice_server_remove_interface(&vmc_instance.base);
+    g_assert_cmpint(status, ==, 0);
+    status = spice_server_remove_interface(&vmc_instance.base);
+    g_assert_cmpint(status, ==, -1);
+    g_test_assert_expected_messages();
+    test_destroy(test);
+    basic_event_loop_destroy();
+}
 
-    core = basic_event_loop_init();
-    test = test_new(core);
+static void test_agent_to_server(void)
+{
+    SpiceCoreInterface *core = basic_event_loop_init();
+    Test *test = test_new(core);
 
+    g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "sent whole message");
     vmc_instance.base.sif = &vmc_interface.base;
     spice_server_add_interface(test->server, &vmc_instance.base);
+    g_test_assert_expected_messages();
+    test_destroy(test);
+    basic_event_loop_destroy();
+}
 
-    ping_timer = core->timer_add(pinger, NULL);
-    core->timer_start(ping_timer, ping_ms);
+int main(int argc, char *argv[])
+{
+    g_test_init(&argc, &argv, NULL);
 
-    basic_event_loop_mainloop();
+    g_test_add_func("/server/vdagent/agent-to-server", test_agent_to_server);
+    g_test_add_func("/server/vdagent/duplicate-removal", test_duplicate_removal);
+    g_test_add_func("/server/vdagent/multiple-vmc-devices", test_multiple_vmc_devices);
 
-    return 0;
+    return g_test_run();
 }
commit 4633ea6d87849840ff7dbc2dc8dae6070d3fce02
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Thu Feb 2 14:08:28 2017 +0100

    Use spice_debug rather than spice_info in library code
    
    Using spice_info() gets in the way of tests using
    g_test_expect_message() as all the messages emitted using
    a non-debug log level must be listed as expected, otherwise we get a
    critical about an expected message not having been logged.
    
    Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
    Acked-by: Frediano Ziglio <fziglio at redhat.com>

diff --git a/server/cursor-channel.c b/server/cursor-channel.c
index 4fe3f8d..fe56098 100644
--- a/server/cursor-channel.c
+++ b/server/cursor-channel.c
@@ -294,7 +294,7 @@ static void cursor_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_it
 CursorChannel* cursor_channel_new(RedsState *server, QXLInstance *qxl,
                                   const SpiceCoreInterfaceInternal *core)
 {
-    spice_info("create cursor channel");
+    spice_debug("create cursor channel");
     return g_object_new(TYPE_CURSOR_CHANNEL,
                         "spice-server", server,
                         "core-interface", core,
@@ -413,7 +413,7 @@ void cursor_channel_connect(CursorChannel *cursor, RedClient *client, RedsStream
 
     spice_return_if_fail(cursor != NULL);
 
-    spice_info("add cursor channel client");
+    spice_debug("add cursor channel client");
     ccc = cursor_channel_client_new(cursor, client, stream,
                                     migrate,
                                     common_caps, num_common_caps,
diff --git a/server/dcc.c b/server/dcc.c
index 373dad9..e32004d 100644
--- a/server/dcc.c
+++ b/server/dcc.c
@@ -514,7 +514,7 @@ DisplayChannelClient *dcc_new(DisplayChannel *display,
                          "jpeg-state", jpeg_state,
                          "zlib-glz-state", zlib_glz_state,
                          NULL);
-    spice_info("New display (client %p) dcc %p stream %p", client, dcc, stream);
+    spice_debug("New display (client %p) dcc %p stream %p", client, dcc, stream);
     common_graphics_channel_set_during_target_migrate(COMMON_GRAPHICS_CHANNEL(display), mig_target);
     dcc->priv->id = common_graphics_channel_get_qxl(COMMON_GRAPHICS_CHANNEL(display))->id;
 
@@ -550,7 +550,7 @@ static int display_channel_client_wait_for_init(DisplayChannelClient *dcc)
         if (dcc->priv->pixmap_cache && dcc->priv->encoders.glz_dict) {
             dcc->priv->pixmap_cache_generation = dcc->priv->pixmap_cache->generation;
             /* TODO: move common.id? if it's used for a per client structure.. */
-            spice_info("creating encoder with id == %d", dcc->priv->id);
+            spice_debug("creating encoder with id == %d", dcc->priv->id);
             if (!image_encoders_glz_create(&dcc->priv->encoders, dcc->priv->id)) {
                 spice_critical("create global lz failed");
             }
@@ -1052,7 +1052,7 @@ static int dcc_handle_stream_report(DisplayChannelClient *dcc,
 
     agent = &dcc->priv->stream_agents[report->stream_id];
     if (!agent->video_encoder) {
-        spice_info("stream_report: no encoder for stream id %u. "
+        spice_debug("stream_report: no encoder for stream id %u. "
                    "The stream has probably been destroyed",
                    report->stream_id);
         return TRUE;
diff --git a/server/display-channel.c b/server/display-channel.c
index 2e359f8..fa2b281 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -195,13 +195,13 @@ void display_channel_set_stream_video(DisplayChannel *display, int stream_video)
 
     switch (stream_video) {
     case SPICE_STREAM_VIDEO_ALL:
-        spice_info("sv all");
+        spice_debug("sv all");
         break;
     case SPICE_STREAM_VIDEO_FILTER:
-        spice_info("sv filter");
+        spice_debug("sv filter");
         break;
     case SPICE_STREAM_VIDEO_OFF:
-        spice_info("sv off");
+        spice_debug("sv off");
         break;
     default:
         spice_warn_if_reached();
@@ -242,7 +242,7 @@ static void stop_streams(DisplayChannel *display)
         if (!stream->current) {
             stream_stop(display, stream);
         } else {
-            spice_info("attached stream");
+            spice_debug("attached stream");
         }
     }
 
@@ -886,17 +886,17 @@ static bool drawable_can_stream(DisplayChannel *display, Drawable *drawable)
 static void display_channel_print_stats(DisplayChannel *display)
 {
     stat_time_t total = display->priv->add_stat.total;
-    spice_info("add with shadow count %u",
+    spice_debug("add with shadow count %u",
                display->priv->add_with_shadow_count);
     display->priv->add_with_shadow_count = 0;
-    spice_info("add[%u] %f exclude[%u] %f __exclude[%u] %f",
+    spice_debug("add[%u] %f exclude[%u] %f __exclude[%u] %f",
                display->priv->add_stat.count,
                stat_cpu_time_to_sec(total),
                display->priv->exclude_stat.count,
                stat_cpu_time_to_sec(display->priv->exclude_stat.total),
                display->priv->__exclude_stat.count,
                stat_cpu_time_to_sec(display->priv->__exclude_stat.total));
-    spice_info("add %f%% exclude %f%% exclude2 %f%% __exclude %f%%",
+    spice_debug("add %f%% exclude %f%% exclude2 %f%% __exclude %f%%",
                (double)(total - display->priv->exclude_stat.total) / total * 100,
                (double)(display->priv->exclude_stat.total) / total * 100,
                (double)(display->priv->exclude_stat.total -
@@ -1934,7 +1934,7 @@ static void on_disconnect(RedChannelClient *rcc)
     DisplayChannel *display;
     DisplayChannelClient *dcc;
 
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_return_if_fail(rcc != NULL);
 
     dcc = DISPLAY_CHANNEL_CLIENT(rcc);
@@ -1991,7 +1991,7 @@ DisplayChannel* display_channel_new(RedsState *reds,
     DisplayChannel *display;
 
     /* FIXME: migrate is not used...? */
-    spice_info("create display channel");
+    spice_debug("create display channel");
     display = g_object_new(TYPE_DISPLAY_CHANNEL,
                            "spice-server", reds,
                            "core-interface", core,
@@ -2129,8 +2129,8 @@ void display_channel_update_compression(DisplayChannel *display, DisplayChannelC
     } else {
         display->priv->enable_zlib_glz_wrap = (dcc_get_zlib_glz_state(dcc) == SPICE_WAN_COMPRESSION_ALWAYS);
     }
-    spice_info("jpeg %s", display->priv->enable_jpeg ? "enabled" : "disabled");
-    spice_info("zlib-over-glz %s", display->priv->enable_zlib_glz_wrap ? "enabled" : "disabled");
+    spice_debug("jpeg %s", display->priv->enable_jpeg ? "enabled" : "disabled");
+    spice_debug("zlib-over-glz %s", display->priv->enable_zlib_glz_wrap ? "enabled" : "disabled");
 }
 
 void display_channel_gl_scanout(DisplayChannel *display)
diff --git a/server/image-encoders.c b/server/image-encoders.c
index 0d57260..bfc93b2 100644
--- a/server/image-encoders.c
+++ b/server/image-encoders.c
@@ -723,7 +723,7 @@ static GlzSharedDictionary *create_glz_dictionary(ImageEncoders *enc,
                                                   RedClient *client,
                                                   uint8_t id, int window_size)
 {
-    spice_info("Lz Window %d Size=%d", id, window_size);
+    spice_debug("Lz Window %d Size=%d", id, window_size);
 
     GlzEncDictContext *glz_dict =
         glz_enc_dictionary_create(window_size, MAX_LZ_ENCODERS, &enc->glz_data.usr);
@@ -838,7 +838,7 @@ int image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest,
     stat_start_time_init(&start_time, &enc->shared_data->quic_stat);
 
 #ifdef COMPRESS_DEBUG
-    spice_info("QUIC compress");
+    spice_debug("QUIC compress");
 #endif
 
     switch (src->format) {
@@ -927,7 +927,7 @@ int image_encoders_compress_lz(ImageEncoders *enc,
     stat_start_time_init(&start_time, &enc->shared_data->lz_stat);
 
 #ifdef COMPRESS_DEBUG
-    spice_info("LZ LOCAL compress");
+    spice_debug("LZ LOCAL compress");
 #endif
 
     encoder_data_init(&lz_data->data);
@@ -998,7 +998,7 @@ int image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest,
     stat_start_time_init(&start_time, &enc->shared_data->jpeg_alpha_stat);
 
 #ifdef COMPRESS_DEBUG
-    spice_info("JPEG compress");
+    spice_debug("JPEG compress");
 #endif
 
     switch (src->format) {
@@ -1115,7 +1115,7 @@ int image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest,
     stat_start_time_init(&start_time, &enc->shared_data->lz4_stat);
 
 #ifdef COMPRESS_DEBUG
-    spice_info("LZ4 compress");
+    spice_debug("LZ4 compress");
 #endif
 
     encoder_data_init(&lz4_data->data);
@@ -1227,7 +1227,7 @@ int image_encoders_compress_glz(ImageEncoders *enc,
     int zlib_size;
 
 #ifdef COMPRESS_DEBUG
-    spice_info("LZ global compress fmt=%d", src->format);
+    spice_debug("LZ global compress fmt=%d", src->format);
 #endif
 
     if ((src->x * src->y) >= glz_enc_dictionary_get_size(enc->glz_dict->dict)) {
diff --git a/server/red-channel-client.c b/server/red-channel-client.c
index b583da2..cd4b64e 100644
--- a/server/red-channel-client.c
+++ b/server/red-channel-client.c
@@ -1837,7 +1837,7 @@ int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
     uint64_t end_time;
     gboolean item_in_pipe;
 
-    spice_info(NULL);
+    spice_debug(NULL);
 
     if (timeout != -1) {
         end_time = spice_get_monotonic_time_ns() + timeout;
@@ -1892,7 +1892,7 @@ int red_channel_client_wait_outgoing_item(RedChannelClient *rcc,
     } else {
         end_time = UINT64_MAX;
     }
-    spice_info("blocked");
+    spice_debug("blocked");
 
     do {
         usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
diff --git a/server/red-worker.c b/server/red-worker.c
index e5adbaa..8735cd1 100644
--- a/server/red-worker.c
+++ b/server/red-worker.c
@@ -613,7 +613,7 @@ static void handle_dev_stop(void *opaque, void *payload)
 {
     RedWorker *worker = opaque;
 
-    spice_info("stop");
+    spice_debug("stop");
     spice_assert(worker->running);
 
     worker->running = FALSE;
@@ -732,7 +732,7 @@ static void handle_dev_display_connect(void *opaque, void *payload)
     DisplayChannel *display = worker->display_channel;
     DisplayChannelClient *dcc;
 
-    spice_info("connect new client");
+    spice_debug("connect new client");
     spice_return_if_fail(display);
 
     dcc = dcc_new(display, msg->client, msg->stream, msg->migration,
@@ -755,7 +755,7 @@ static void handle_dev_display_disconnect(void *opaque, void *payload)
     RedChannelClient *rcc = msg->rcc;
     RedWorker *worker = opaque;
 
-    spice_info("disconnect display client");
+    spice_debug("disconnect display client");
     spice_assert(rcc);
 
     guest_set_client_capabilities(worker);
@@ -769,7 +769,7 @@ static void handle_dev_display_migrate(void *opaque, void *payload)
     RedWorker *worker = opaque;
 
     RedChannelClient *rcc = msg->rcc;
-    spice_info("migrate display client");
+    spice_debug("migrate display client");
     spice_assert(rcc);
     red_migrate_display(worker->display_channel, rcc);
 }
@@ -829,7 +829,7 @@ static void handle_dev_cursor_connect(void *opaque, void *payload)
     RedWorkerMessageCursorConnect *msg = payload;
     RedWorker *worker = opaque;
 
-    spice_info("cursor connect");
+    spice_debug("cursor connect");
     cursor_channel_connect(worker->cursor_channel,
                            msg->client, msg->stream, msg->migration,
                            msg->common_caps, msg->num_common_caps,
@@ -843,7 +843,7 @@ static void handle_dev_cursor_disconnect(void *opaque, void *payload)
     RedWorkerMessageCursorDisconnect *msg = payload;
     RedChannelClient *rcc = msg->rcc;
 
-    spice_info("disconnect cursor client");
+    spice_debug("disconnect cursor client");
     spice_return_if_fail(rcc);
     red_channel_client_disconnect(rcc);
 }
@@ -853,7 +853,7 @@ static void handle_dev_cursor_migrate(void *opaque, void *payload)
     RedWorkerMessageCursorMigrate *msg = payload;
     RedChannelClient *rcc = msg->rcc;
 
-    spice_info("migrate cursor client");
+    spice_debug("migrate cursor client");
     cursor_channel_client_migrate(rcc);
 }
 
@@ -865,27 +865,27 @@ static void handle_dev_set_compression(void *opaque, void *payload)
 
     switch (image_compression) {
     case SPICE_IMAGE_COMPRESSION_AUTO_LZ:
-        spice_info("ic auto_lz");
+        spice_debug("ic auto_lz");
         break;
     case SPICE_IMAGE_COMPRESSION_AUTO_GLZ:
-        spice_info("ic auto_glz");
+        spice_debug("ic auto_glz");
         break;
     case SPICE_IMAGE_COMPRESSION_QUIC:
-        spice_info("ic quic");
+        spice_debug("ic quic");
         break;
 #ifdef USE_LZ4
     case SPICE_IMAGE_COMPRESSION_LZ4:
-        spice_info("ic lz4");
+        spice_debug("ic lz4");
         break;
 #endif
     case SPICE_IMAGE_COMPRESSION_LZ:
-        spice_info("ic lz");
+        spice_debug("ic lz");
         break;
     case SPICE_IMAGE_COMPRESSION_GLZ:
-        spice_info("ic glz");
+        spice_debug("ic glz");
         break;
     case SPICE_IMAGE_COMPRESSION_OFF:
-        spice_info("ic off");
+        spice_debug("ic off");
         break;
     default:
         spice_warning("ic invalid");
@@ -919,7 +919,7 @@ static void handle_dev_set_mouse_mode(void *opaque, void *payload)
     RedWorkerMessageSetMouseMode *msg = payload;
     RedWorker *worker = opaque;
 
-    spice_info("mouse mode %u", msg->mode);
+    spice_debug("mouse mode %u", msg->mode);
     cursor_channel_set_mouse_mode(worker->cursor_channel, msg->mode);
 }
 
@@ -1010,7 +1010,7 @@ static void handle_dev_loadvm_commands(void *opaque, void *payload)
     uint32_t count = msg->count;
     QXLCommandExt *ext = msg->ext;
 
-    spice_info("loadvm_commands");
+    spice_debug("loadvm_commands");
     for (i = 0 ; i < count ; ++i) {
         if (!loadvm_command(worker, &ext[i])) {
             /* XXX allow failure in loadvm? */
@@ -1390,7 +1390,7 @@ static void *red_worker_main(void *arg)
 {
     RedWorker *worker = arg;
 
-    spice_info("begin");
+    spice_debug("begin");
     SPICE_VERIFY(MAX_PIPE_SIZE > WIDE_CLIENT_ACK_WINDOW &&
            MAX_PIPE_SIZE > NARROW_CLIENT_ACK_WINDOW); //ensure wakeup by ack message
 
diff --git a/server/reds-stream.c b/server/reds-stream.c
index cb88fc9..910385b 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -342,7 +342,7 @@ void reds_stream_free(RedsStream *s)
     }
 
     reds_stream_remove_watch(s);
-    spice_info("close socket fd %d", s->socket);
+    spice_debug("close socket fd %d", s->socket);
     close(s->socket);
 
     free(s);
@@ -694,7 +694,7 @@ static int auth_sasl_check_ssf(RedsSASL *sasl, int *runSSF)
     }
 
     ssf = *(const int *)val;
-    spice_info("negotiated an SSF of %d", ssf);
+    spice_debug("negotiated an SSF of %d", ssf);
     if (ssf < 56) {
         return 0; /* 56 is good for Kerberos */
     }
@@ -737,7 +737,7 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
         datalen--; /* Don't count NULL byte when passing to _start() */
     }
 
-    spice_info("Step using SASL Data %p (%d bytes)",
+    spice_debug("Step using SASL Data %p (%d bytes)",
                clientdata, datalen);
     err = sasl_server_step(sasl->conn,
                            clientdata,
@@ -757,7 +757,7 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
         return REDS_SASL_ERROR_INVALID_DATA;
     }
 
-    spice_info("SASL return data %d bytes, %p", serveroutlen, serverout);
+    spice_debug("SASL return data %d bytes, %p", serveroutlen, serverout);
 
     if (serveroutlen) {
         serveroutlen += 1;
@@ -771,7 +771,7 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
     reds_stream_write_u8(stream, err == SASL_CONTINUE ? 0 : 1);
 
     if (err == SASL_CONTINUE) {
-        spice_info("%s", "Authentication must continue (step)");
+        spice_debug("%s", "Authentication must continue (step)");
         /* Wait for step length */
         reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
                                read_cb, opaque);
@@ -784,7 +784,7 @@ RedsSaslError reds_sasl_handle_auth_step(RedsStream *stream, AsyncReadDone read_
             goto authreject;
         }
 
-        spice_info("Authentication successful");
+        spice_debug("Authentication successful");
         reds_stream_write_u32(stream, SPICE_LINK_ERR_OK); /* Accept auth */
 
         /*
@@ -808,7 +808,7 @@ RedsSaslError reds_sasl_handle_auth_steplen(RedsStream *stream, AsyncReadDone re
 {
     RedsSASL *sasl = &stream->priv->sasl;
 
-    spice_info("Got steplen %d", sasl->len);
+    spice_debug("Got steplen %d", sasl->len);
     if (sasl->len > SASL_DATA_MAX_LEN) {
         spice_warning("Too much SASL data %d", sasl->len);
         return REDS_SASL_ERROR_INVALID_DATA;
@@ -860,7 +860,7 @@ RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read
         datalen--; /* Don't count NULL byte when passing to _start() */
     }
 
-    spice_info("Start SASL auth with mechanism %s. Data %p (%d bytes)",
+    spice_debug("Start SASL auth with mechanism %s. Data %p (%d bytes)",
                sasl->mechlist, clientdata, datalen);
     err = sasl_server_start(sasl->conn,
                             sasl->mechlist,
@@ -881,7 +881,7 @@ RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read
         return REDS_SASL_ERROR_INVALID_DATA;
     }
 
-    spice_info("SASL return data %d bytes, %p", serveroutlen, serverout);
+    spice_debug("SASL return data %d bytes, %p", serveroutlen, serverout);
 
     if (serveroutlen) {
         serveroutlen += 1;
@@ -895,7 +895,7 @@ RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read
     reds_stream_write_u8(stream, err == SASL_CONTINUE ? 0 : 1);
 
     if (err == SASL_CONTINUE) {
-        spice_info("%s", "Authentication must continue (start)");
+        spice_debug("%s", "Authentication must continue (start)");
         /* Wait for step length */
         reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
                                read_cb, opaque);
@@ -908,7 +908,7 @@ RedsSaslError reds_sasl_handle_auth_start(RedsStream *stream, AsyncReadDone read
             goto authreject;
         }
 
-        spice_info("Authentication successful");
+        spice_debug("Authentication successful");
         reds_stream_write_u32(stream, SPICE_LINK_ERR_OK); /* Accept auth */
 
         /*
@@ -931,7 +931,7 @@ RedsSaslError reds_sasl_handle_auth_startlen(RedsStream *stream, AsyncReadDone r
 {
     RedsSASL *sasl = &stream->priv->sasl;
 
-    spice_info("Got client start len %d", sasl->len);
+    spice_debug("Got client start len %d", sasl->len);
     if (sasl->len > SASL_DATA_MAX_LEN) {
         spice_warning("Too much SASL data %d", sasl->len);
         return REDS_SASL_ERROR_INVALID_DATA;
@@ -953,22 +953,22 @@ bool reds_sasl_handle_auth_mechname(RedsStream *stream, AsyncReadDone read_cb, v
     RedsSASL *sasl = &stream->priv->sasl;
 
     sasl->mechname[sasl->len] = '\0';
-    spice_info("Got client mechname '%s' check against '%s'",
+    spice_debug("Got client mechname '%s' check against '%s'",
                sasl->mechname, sasl->mechlist);
 
     if (strncmp(sasl->mechlist, sasl->mechname, sasl->len) == 0) {
         if (sasl->mechlist[sasl->len] != '\0' &&
             sasl->mechlist[sasl->len] != ',') {
-            spice_info("One %d", sasl->mechlist[sasl->len]);
+            spice_debug("One %d", sasl->mechlist[sasl->len]);
             return FALSE;
         }
     } else {
         char *offset = strstr(sasl->mechlist, sasl->mechname);
-        spice_info("Two %p", offset);
+        spice_debug("Two %p", offset);
         if (!offset) {
             return FALSE;
         }
-        spice_info("Two '%s'", offset);
+        spice_debug("Two '%s'", offset);
         if (offset[-1] != ',' ||
             (offset[sasl->len] != '\0'&&
              offset[sasl->len] != ',')) {
@@ -979,7 +979,7 @@ bool reds_sasl_handle_auth_mechname(RedsStream *stream, AsyncReadDone read_cb, v
     free(sasl->mechlist);
     sasl->mechlist = spice_strdup(sasl->mechname);
 
-    spice_info("Validated mechname '%s'", sasl->mechname);
+    spice_debug("Validated mechname '%s'", sasl->mechname);
 
     reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
                            read_cb, opaque);
@@ -998,7 +998,7 @@ bool reds_sasl_handle_auth_mechlen(RedsStream *stream, AsyncReadDone read_cb, vo
 
     sasl->mechname = spice_malloc(sasl->len + 1);
 
-    spice_info("Wait for client mechname");
+    spice_debug("Wait for client mechname");
     reds_stream_async_read(stream, (uint8_t *)sasl->mechname, sasl->len,
                            read_cb, opaque);
 
@@ -1096,7 +1096,7 @@ bool reds_sasl_start_auth(RedsStream *stream, AsyncReadDone read_cb, void *opaqu
         goto error_dispose;
     }
 
-    spice_info("Available mechanisms for client: '%s'", mechlist);
+    spice_debug("Available mechanisms for client: '%s'", mechlist);
 
     sasl->mechlist = spice_strdup(mechlist);
 
@@ -1107,7 +1107,7 @@ bool reds_sasl_start_auth(RedsStream *stream, AsyncReadDone read_cb, void *opaqu
         goto error;
     }
 
-    spice_info("Wait for client mechname length");
+    spice_debug("Wait for client mechname length");
     reds_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
                            read_cb, opaque);
 
diff --git a/server/reds.c b/server/reds.c
index 0a64dfd..f99dfda 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -494,7 +494,7 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
 
     if (reds->config->exit_on_disconnect)
     {
-        spice_info("Exiting server because of client disconnect.\n");
+        spice_debug("Exiting server because of client disconnect.\n");
         exit(0);
     }
 
@@ -503,7 +503,7 @@ void reds_client_disconnect(RedsState *reds, RedClient *client)
         return;
     }
 
-    spice_info(NULL);
+    spice_debug(NULL);
     /* disconnecting is set to prevent recursion because of the following:
      * main_channel_client_on_disconnect->
      *  reds_client_disconnect->red_client_destroy->main_channel...
@@ -579,7 +579,7 @@ static void reds_disconnect(RedsState *reds)
     GListIter iter;
     RedClient *client;
 
-    spice_info(NULL);
+    spice_debug(NULL);
     GLIST_FOREACH(reds->clients, iter, RedClient, client) {
         reds_client_disconnect(reds, client);
     }
@@ -1161,7 +1161,7 @@ void reds_on_main_mouse_mode_request(RedsState *reds, void *message, size_t size
         if (reds->is_client_mouse_allowed) {
             reds_set_mouse_mode(reds, SPICE_MOUSE_MODE_CLIENT);
         } else {
-            spice_info("client mouse is disabled");
+            spice_debug("client mouse is disabled");
         }
         break;
     case SPICE_MOUSE_MODE_SERVER:
@@ -1575,10 +1575,10 @@ static bool reds_send_link_error(RedLinkInfo *link, uint32_t error)
 
 static void reds_info_new_channel(RedLinkInfo *link, int connection_id)
 {
-    spice_info("channel %d:%d, connected successfully, over %s link",
-               link->link_mess->channel_type,
-               link->link_mess->channel_id,
-               reds_stream_is_ssl(link->stream) ? "Secure" : "Non Secure");
+    spice_debug("channel %d:%d, connected successfully, over %s link",
+                link->link_mess->channel_type,
+                link->link_mess->channel_id,
+                reds_stream_is_ssl(link->stream) ? "Secure" : "Non Secure");
     /* add info + send event */
     reds_stream_set_channel(link->stream, connection_id,
                             link->link_mess->channel_type,
@@ -1597,7 +1597,7 @@ static void reds_mig_target_client_add(RedsState *reds, RedClient *client)
     RedsMigTargetClient *mig_client;
 
     g_return_if_fail(reds);
-    spice_info(NULL);
+    spice_debug(NULL);
     mig_client = spice_new0(RedsMigTargetClient, 1);
     mig_client->client = client;
     mig_client->reds = reds;
@@ -1687,7 +1687,7 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link)
     MainChannelClient *mcc;
     int mig_target = FALSE;
 
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_assert(reds->main_channel);
 
     link_mess = link->link_mess;
@@ -1725,7 +1725,7 @@ static void reds_handle_main_link(RedsState *reds, RedLinkInfo *link)
                             link_mess->num_common_caps,
                             link_mess->num_common_caps ? caps : NULL, link_mess->num_channel_caps,
                             link_mess->num_channel_caps ? caps + link_mess->num_common_caps : NULL);
-    spice_info("NEW Client %p mcc %p connect-id %d", client, mcc, connection_id);
+    spice_debug("NEW Client %p mcc %p connect-id %d", client, mcc, connection_id);
     free(link_mess);
     red_client_set_main(client, mcc);
 
@@ -1813,10 +1813,10 @@ static int reds_link_mig_target_channels(RedsState *reds, RedClient *client)
     RedsMigTargetClient *mig_client;
     GList *item;
 
-    spice_info("%p", client);
+    spice_debug("%p", client);
     mig_client = reds_mig_target_client_find(reds, client);
     if (!mig_client) {
-        spice_info("Error: mig target client was not found");
+        spice_debug("Error: mig target client was not found");
         return FALSE;
     }
 
@@ -1863,7 +1863,7 @@ void reds_on_client_seamless_migrate_complete(RedsState *reds, RedClient *client
 {
     spice_debug(NULL);
     if (!reds_find_client(reds, client)) {
-        spice_info("client no longer exists");
+        spice_debug("client no longer exists");
         return;
     }
     main_channel_client_migrate_dst_complete(red_client_get_main(client));
@@ -1873,7 +1873,7 @@ void reds_on_client_semi_seamless_migrate_complete(RedsState *reds, RedClient *c
 {
     MainChannelClient *mcc;
 
-    spice_info("%p", client);
+    spice_debug("%p", client);
     mcc = red_client_get_main(client);
 
     // TODO: not doing net test. consider doing it on client_migrate_info
@@ -2149,7 +2149,7 @@ static void reds_handle_auth_mechanism(void *opaque)
     RedLinkInfo *link = (RedLinkInfo *)opaque;
     RedsState *reds = link->reds;
 
-    spice_info("Auth method: %d", link->auth_mechanism.auth_mechanism);
+    spice_debug("Auth method: %d", link->auth_mechanism.auth_mechanism);
 
     link->auth_mechanism.auth_mechanism = GUINT32_FROM_LE(link->auth_mechanism.auth_mechanism);
     if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SPICE
@@ -2158,7 +2158,7 @@ static void reds_handle_auth_mechanism(void *opaque)
         reds_get_spice_ticket(link);
 #if HAVE_SASL
     } else if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SASL) {
-        spice_info("Starting SASL");
+        spice_debug("Starting SASL");
         reds_start_auth_sasl(link);
 #endif
     } else {
@@ -2581,9 +2581,9 @@ static int reds_init_socket(const char *addr, int portnr, int family)
                              uaddr,INET6_ADDRSTRLEN, uport,32,
                              NI_NUMERICHOST | NI_NUMERICSERV);
             if (rc == 0) {
-                spice_info("bound to %s:%s", uaddr, uport);
+                spice_debug("bound to %s:%s", uaddr, uport);
             } else {
-                spice_info("cannot resolve address spice-server is bound to");
+                spice_debug("cannot resolve address spice-server is bound to");
             }
             freeaddrinfo(res);
             goto listen;
@@ -2804,7 +2804,7 @@ static int reds_init_ssl(RedsState *reds)
     /* Load our keys and certificates*/
     return_code = SSL_CTX_use_certificate_chain_file(reds->ctx, reds->config->ssl_parameters.certs_file);
     if (return_code == 1) {
-        spice_info("Loaded certificates from %s", reds->config->ssl_parameters.certs_file);
+        spice_debug("Loaded certificates from %s", reds->config->ssl_parameters.certs_file);
     } else {
         spice_warning("Could not load certificates from %s", reds->config->ssl_parameters.certs_file);
         return -1;
@@ -2816,7 +2816,7 @@ static int reds_init_ssl(RedsState *reds)
     return_code = SSL_CTX_use_PrivateKey_file(reds->ctx, reds->config->ssl_parameters.private_key_file,
                                               SSL_FILETYPE_PEM);
     if (return_code == 1) {
-        spice_info("Using private key from %s", reds->config->ssl_parameters.private_key_file);
+        spice_debug("Using private key from %s", reds->config->ssl_parameters.private_key_file);
     } else {
         spice_warning("Could not use private key file");
         return -1;
@@ -2825,7 +2825,7 @@ static int reds_init_ssl(RedsState *reds)
     /* Load the CAs we trust*/
     return_code = SSL_CTX_load_verify_locations(reds->ctx, reds->config->ssl_parameters.ca_certificate_file, 0);
     if (return_code == 1) {
-        spice_info("Loaded CA certificates from %s", reds->config->ssl_parameters.ca_certificate_file);
+        spice_debug("Loaded CA certificates from %s", reds->config->ssl_parameters.ca_certificate_file);
     } else {
         spice_warning("Could not use CA file %s", reds->config->ssl_parameters.ca_certificate_file);
         return -1;
@@ -2921,7 +2921,7 @@ static void reds_mig_release(RedServerConfig *config)
 
 static void reds_mig_started(RedsState *reds)
 {
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_assert(reds->config->mig_spice);
 
     reds->mig_inprogress = TRUE;
@@ -2972,7 +2972,7 @@ static void reds_migrate_channels_seamless(RedsState *reds)
 
 static void reds_mig_finished(RedsState *reds, int completed)
 {
-    spice_info(NULL);
+    spice_debug(NULL);
 
     reds->mig_inprogress = TRUE;
 
@@ -3003,7 +3003,7 @@ static void reds_mig_switch(RedsState *reds)
 static void migrate_timeout(void *opaque)
 {
     RedsState *reds = opaque;
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_assert(reds->mig_wait_connect || reds->mig_wait_disconnect);
     if (reds->mig_wait_connect) {
         /* we will fall back to the switch host scheme when migration completes */
@@ -3150,7 +3150,7 @@ static int spice_server_char_device_add_interface(SpiceServer *reds,
             SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
     RedCharDevice *dev_state = NULL;
 
-    spice_info("CHAR_DEVICE %s", char_device->subtype);
+    spice_debug("CHAR_DEVICE %s", char_device->subtype);
     if (strcmp(char_device->subtype, SUBTYPE_VDAGENT) == 0) {
         if (reds->vdagent) {
             spice_warning("vdagent already attached");
@@ -3203,7 +3203,7 @@ static int spice_server_char_device_remove_interface(RedsState *reds, SpiceBaseI
     SpiceCharDeviceInstance* char_device =
             SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
 
-    spice_info("remove CHAR_DEVICE %s", char_device->subtype);
+    spice_debug("remove CHAR_DEVICE %s", char_device->subtype);
     if (strcmp(char_device->subtype, SUBTYPE_VDAGENT) == 0) {
         g_return_val_if_fail(char_device == reds->vdagent, -1);
         if (reds->vdagent) {
@@ -3233,7 +3233,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
     const SpiceBaseInterface *interface = sin->sif;
 
     if (strcmp(interface->type, SPICE_INTERFACE_KEYBOARD) == 0) {
-        spice_info("SPICE_INTERFACE_KEYBOARD");
+        spice_debug("SPICE_INTERFACE_KEYBOARD");
         if (interface->major_version != SPICE_INTERFACE_KEYBOARD_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_KEYBOARD_MINOR) {
             spice_warning("unsupported keyboard interface");
@@ -3243,7 +3243,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
             return -1;
         }
     } else if (strcmp(interface->type, SPICE_INTERFACE_MOUSE) == 0) {
-        spice_info("SPICE_INTERFACE_MOUSE");
+        spice_debug("SPICE_INTERFACE_MOUSE");
         if (interface->major_version != SPICE_INTERFACE_MOUSE_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_MOUSE_MINOR) {
             spice_warning("unsupported mouse interface");
@@ -3255,7 +3255,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
     } else if (strcmp(interface->type, SPICE_INTERFACE_QXL) == 0) {
         QXLInstance *qxl;
 
-        spice_info("SPICE_INTERFACE_QXL");
+        spice_debug("SPICE_INTERFACE_QXL");
         if (interface->major_version != SPICE_INTERFACE_QXL_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_QXL_MINOR) {
             spice_warning("unsupported qxl interface");
@@ -3275,7 +3275,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
         red_qxl_set_compression_level(qxl, calc_compression_level(reds));
     } else if (strcmp(interface->type, SPICE_INTERFACE_TABLET) == 0) {
         SpiceTabletInstance *tablet = SPICE_CONTAINEROF(sin, SpiceTabletInstance, base);
-        spice_info("SPICE_INTERFACE_TABLET");
+        spice_debug("SPICE_INTERFACE_TABLET");
         if (interface->major_version != SPICE_INTERFACE_TABLET_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_TABLET_MINOR) {
             spice_warning("unsupported tablet interface");
@@ -3290,7 +3290,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
         }
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
-        spice_info("SPICE_INTERFACE_PLAYBACK");
+        spice_debug("SPICE_INTERFACE_PLAYBACK");
         if (interface->major_version != SPICE_INTERFACE_PLAYBACK_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_PLAYBACK_MINOR) {
             spice_warning("unsupported playback interface");
@@ -3299,7 +3299,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
         snd_attach_playback(reds, SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
-        spice_info("SPICE_INTERFACE_RECORD");
+        spice_debug("SPICE_INTERFACE_RECORD");
         if (interface->major_version != SPICE_INTERFACE_RECORD_MAJOR ||
             interface->minor_version > SPICE_INTERFACE_RECORD_MINOR) {
             spice_warning("unsupported record interface");
@@ -3316,7 +3316,7 @@ SPICE_GNUC_VISIBLE int spice_server_add_interface(SpiceServer *reds,
         spice_server_char_device_add_interface(reds, sin);
 
     } else if (strcmp(interface->type, SPICE_INTERFACE_MIGRATION) == 0) {
-        spice_info("SPICE_INTERFACE_MIGRATION");
+        spice_debug("SPICE_INTERFACE_MIGRATION");
         if (reds->migration_interface) {
             spice_warning("already have migration");
             return -1;
@@ -3346,14 +3346,14 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
         SpiceTabletInstance *tablet = SPICE_CONTAINEROF(sin, SpiceTabletInstance, base);
         g_return_val_if_fail(tablet->st != NULL, -1);
         reds = spice_tablet_state_get_server(tablet->st);
-        spice_info("remove SPICE_INTERFACE_TABLET");
+        spice_debug("remove SPICE_INTERFACE_TABLET");
         inputs_channel_detach_tablet(reds->inputs_channel, tablet);
         reds_update_mouse_mode(reds);
     } else if (strcmp(interface->type, SPICE_INTERFACE_PLAYBACK) == 0) {
-        spice_info("remove SPICE_INTERFACE_PLAYBACK");
+        spice_debug("remove SPICE_INTERFACE_PLAYBACK");
         snd_detach_playback(SPICE_CONTAINEROF(sin, SpicePlaybackInstance, base));
     } else if (strcmp(interface->type, SPICE_INTERFACE_RECORD) == 0) {
-        spice_info("remove SPICE_INTERFACE_RECORD");
+        spice_debug("remove SPICE_INTERFACE_RECORD");
         snd_detach_record(SPICE_CONTAINEROF(sin, SpiceRecordInstance, base));
     } else if (strcmp(interface->type, SPICE_INTERFACE_CHAR_DEVICE) == 0) {
         SpiceCharDeviceInstance *char_device = SPICE_CONTAINEROF(sin, SpiceCharDeviceInstance, base);
@@ -3378,7 +3378,7 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
 
 static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
 {
-    spice_info("starting %s", VERSION);
+    spice_debug("starting %s", VERSION);
 
 #if !GLIB_CHECK_VERSION(2,36,0)
     g_type_init();
@@ -4071,11 +4071,11 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *reds, const cha
     SpiceMigrateInterface *sif;
     int try_seamless;
 
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_assert(reds->migration_interface);
 
     if (reds->expect_migrate) {
-        spice_info("consecutive calls without migration. Canceling previous call");
+        spice_debug("consecutive calls without migration. Canceling previous call");
         main_channel_migrate_src_complete(reds->main_channel, FALSE);
     }
 
@@ -4106,7 +4106,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *reds, const cha
     } else {
         if (reds->clients == NULL) {
             reds_mig_release(reds->config);
-            spice_info("no client connected");
+            spice_debug("no client connected");
         }
         sif->migrate_connect_complete(reds->migration_interface);
     }
@@ -4118,7 +4118,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_info(SpiceServer *reds, const char*
                                           int port, int secure_port,
                                           const char* cert_subject)
 {
-    spice_info(NULL);
+    spice_debug(NULL);
     spice_assert(!reds->migration_interface);
 
     if (!reds_set_migration_dest_info(reds, dest, port, secure_port, cert_subject)) {
@@ -4129,7 +4129,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_info(SpiceServer *reds, const char*
 
 SPICE_GNUC_VISIBLE int spice_server_migrate_start(SpiceServer *reds)
 {
-    spice_info(NULL);
+    spice_debug(NULL);
     if (!reds->config->mig_spice) {
         return -1;
     }
@@ -4141,7 +4141,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_end(SpiceServer *reds, int completed
     SpiceMigrateInterface *sif;
     int ret = 0;
 
-    spice_info(NULL);
+    spice_debug(NULL);
 
     spice_assert(reds->migration_interface);
 
@@ -4155,7 +4155,7 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_end(SpiceServer *reds, int completed
 
     reds->expect_migrate = FALSE;
     if (!reds_main_channel_connected(reds)) {
-        spice_info("no peer connected");
+        spice_debug("no peer connected");
         goto complete;
     }
     reds_mig_finished(reds, completed);
@@ -4170,7 +4170,7 @@ complete:
 /* interface for switch-host migration */
 SPICE_GNUC_VISIBLE int spice_server_migrate_switch(SpiceServer *reds)
 {
-    spice_info(NULL);
+    spice_debug(NULL);
     if (reds->clients == NULL) {
        return 0;
     }
diff --git a/server/sound.c b/server/sound.c
index faaeb29..770e223 100644
--- a/server/sound.c
+++ b/server/sound.c
@@ -942,7 +942,7 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
     playback_client = frame->client;
     if (!playback_client || sin->st->channel.connection != SND_CHANNEL_CLIENT(playback_client)) {
         /* lost last reference, client has been destroyed previously */
-        spice_info("audio samples belong to a disconnected client");
+        spice_debug("audio samples belong to a disconnected client");
         return;
     }
     spice_assert(SND_CHANNEL_CLIENT(playback_client)->active);
commit 2650867f3071568bf5063235bdce04e6240ae6a9
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Thu Feb 2 12:20:50 2017 +0100

    reds: Close sockets when using spice_server_destroy()
    
    Currently, the network sockets opened by reds_init_net() are not closed
    on destruction, in other words they are leaked.
    
    Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>

diff --git a/server/reds.c b/server/reds.c
index a28653c..0a64dfd 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -3389,8 +3389,6 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
     }
     reds->core = core_interface_adapter;
     reds->core.public_interface = core_interface;
-    reds->listen_socket = -1;
-    reds->secure_listen_socket = -1;
     reds->agent_dev = red_char_device_vdi_port_new(reds);
     reds_update_agent_properties(reds);
     reds->clients = NULL;
@@ -3483,6 +3481,9 @@ SPICE_GNUC_VISIBLE SpiceServer *spice_server_new(void)
 #ifdef RED_STATISTICS
     reds->stat_file = stat_file_new(REDS_MAX_STAT_NODES);
 #endif
+    reds->listen_socket = -1;
+    reds->secure_listen_socket = -1;
+
     return reds;
 }
 
@@ -3680,6 +3681,16 @@ SPICE_GNUC_VISIBLE void spice_server_destroy(SpiceServer *reds)
     if (reds->main_dispatcher) {
         g_object_unref(reds->main_dispatcher);
     }
+    if (reds->listen_socket != -1) {
+       reds_core_watch_remove(reds, reds->listen_watch);
+       if (reds->config->spice_listen_socket_fd != reds->listen_socket) {
+          close(reds->listen_socket);
+       }
+    }
+    if (reds->secure_listen_socket != -1) {
+       reds_core_watch_remove(reds, reds->secure_listen_watch);
+       close(reds->secure_listen_socket);
+    }
 
     reds_cleanup(reds);
 #ifdef RED_STATISTICS
commit c8f8ea2224fe991c9f7bb5fcd76fe31d35e71210
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Thu Feb 2 12:21:36 2017 +0100

    test: Add test_destroy()
    
    This allows to chain several test cases by using
    test_new()/test_destroy().
    
    Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>

diff --git a/server/tests/test-display-base.c b/server/tests/test-display-base.c
index 55e37a5..636c505 100644
--- a/server/tests/test-display-base.c
+++ b/server/tests/test-display-base.c
@@ -908,6 +908,13 @@ Test *test_new(SpiceCoreInterface *core)
     return test;
 }
 
+void test_destroy(Test *test)
+{
+    test->core->timer_remove(test->wakeup_timer);
+    spice_server_destroy(test->server);
+    free(test);
+}
+
 static void init_automated(void)
 {
     struct sigaction sa;
diff --git a/server/tests/test-display-base.h b/server/tests/test-display-base.h
index 7b5b509..bdf7a11 100644
--- a/server/tests/test-display-base.h
+++ b/server/tests/test-display-base.h
@@ -137,6 +137,7 @@ 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);
+void test_destroy(Test *test);
 
 uint32_t test_get_width(void);
 uint32_t test_get_height(void);


More information about the Spice-commits mailing list