diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-03-14 09:41:19 +0100 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2012-03-14 15:01:59 +0100 |
commit | 434adeb05b0d8aef0d983b346bd820287db22eae (patch) | |
tree | 646d36c151c38501f9b0071988983ebf64fe11a3 | |
parent | a8a11db952a8c47f61656fa562052a6af89c3642 (diff) |
usbredir: Check for existing usb channels after libusb init
Currently trying to view a usbredir enabled vm from virt-manager causes
virt-manager to crash. This crash is caused by the following happening:
-virt-manager sets up the session, including connecting all the channels
-a spice-gtk internal code path calls spice_usb_device_manager_get()
-spice_usb_device_manager_get calls channel_new on all already connected
usb channels
-channel_new does:
spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel),
self->priv->context);
-But self->priv->context has not been set yet (so is NULL) -> segfault!
This patch fixes this by moving the iterating over already connected
usb channels to after the setting of self->priv->context. Note this means
that the channels will no longer get checked when there is no USB_REDIR
support. That is not a problem since spice_usb_device_manager_initable_init
will return FALSE in that case anyways.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r-- | gtk/usb-device-manager.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c index 29e9b4c..14b60c9 100644 --- a/gtk/usb-device-manager.c +++ b/gtk/usb-device-manager.c @@ -64,9 +64,2 @@ /* ------------------------------------------------------------------ */ -/* Prototypes for private functions */ -static void channel_new(SpiceSession *session, SpiceChannel *channel, - gpointer user_data); -static void channel_destroy(SpiceSession *session, SpiceChannel *channel, - gpointer user_data); - -/* ------------------------------------------------------------------ */ /* gobject glue */ @@ -111,2 +104,6 @@ struct _SpiceUsbDeviceManagerPrivate { #ifdef USE_USBREDIR +static void channel_new(SpiceSession *session, SpiceChannel *channel, + gpointer user_data); +static void channel_destroy(SpiceSession *session, SpiceChannel *channel, + gpointer user_data); static void spice_usb_device_manager_uevent_cb(GUdevClient *client, @@ -150,4 +147,2 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, { - GList *list; - GList *it; SpiceUsbDeviceManager *self; @@ -155,2 +150,4 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, #ifdef USE_USBREDIR + GList *list; + GList *it; int rc; @@ -177,13 +174,4 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, - g_signal_connect(priv->session, "channel-new", - G_CALLBACK(channel_new), self); - g_signal_connect(priv->session, "channel-destroy", - G_CALLBACK(channel_destroy), self); - list = spice_session_get_channels(priv->session); - for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { - channel_new(priv->session, it->data, (gpointer*)self); - } - g_list_free(list); - #ifdef USE_USBREDIR + /* Initialize libusb */ rc = libusb_init(&priv->context); @@ -197,2 +185,14 @@ static gboolean spice_usb_device_manager_initable_init(GInitable *initable, + /* Start listening for usb channels connect/disconnect */ + g_signal_connect(priv->session, "channel-new", + G_CALLBACK(channel_new), self); + g_signal_connect(priv->session, "channel-destroy", + G_CALLBACK(channel_destroy), self); + list = spice_session_get_channels(priv->session); + for (it = g_list_first(list); it != NULL; it = g_list_next(it)) { + channel_new(priv->session, it->data, (gpointer*)self); + } + g_list_free(list); + + /* Start listening for usb devices plug / unplug */ priv->udev = g_udev_client_new(subsystems); @@ -462,2 +462,4 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas +#ifdef USE_USBREDIR + /* ------------------------------------------------------------------ */ @@ -465,3 +467,2 @@ static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klas -#ifdef USE_USBREDIR static gboolean spice_usb_device_manager_get_udev_bus_n_address( @@ -482,3 +483,2 @@ static gboolean spice_usb_device_manager_get_udev_bus_n_address( } -#endif @@ -493,3 +493,2 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel, if (SPICE_IS_USBREDIR_CHANNEL(channel)) { -#ifdef USE_USBREDIR spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel), @@ -497,3 +496,2 @@ static void channel_new(SpiceSession *session, SpiceChannel *channel, spice_channel_connect(channel); -#endif g_ptr_array_add(self->priv->channels, channel); @@ -511,3 +509,2 @@ static void channel_destroy(SpiceSession *session, SpiceChannel *channel, -#ifdef USE_USBREDIR static void spice_usb_device_manager_auto_connect_cb(GObject *gobject, |