From 3e9e1817ba1e225d6d7f0412011844e1d029e197 Mon Sep 17 00:00:00 2001 From: Simo Piiroinen Date: Mon, 7 Nov 2016 09:49:12 +0200 Subject: [PATCH] [dbus] Improve SystemBus connection management. MER#1694 D-Bus SystemBus connection is made from several places. Explicitly from the main() and implicitly from various modules that do ipc with other components. This makes it hard to tell when connection actually gets made, process wide dbus initialization happens in the wrong place and setting up signal matches is delayed by the synchronous initialization activity during startup. Move dbus_threads_init_default() to more appropriate place so that it actually is the first libdbus call that gets made. Handle connecting to SystemBus and installing signal listeners as early as possible and claim usb-moded service name separately when usb-moded is ready to process requests made over D-Bus. Add usb_moded_dbus_get_connection() function that other modules can use to get reference to the SystemBus connection when/if one has been made from the main logic. Signed-off-by: Simo Piiroinen --- src/usb_moded-dbus-private.h | 16 +++++++-- src/usb_moded-dbus.c | 69 +++++++++++++++++++++++++----------- src/usb_moded.c | 21 +++++++++-- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/usb_moded-dbus-private.h b/src/usb_moded-dbus-private.h index d0b3729..176a840 100644 --- a/src/usb_moded-dbus-private.h +++ b/src/usb_moded-dbus-private.h @@ -1,7 +1,12 @@ /* Copyright (C) 2010 Nokia Corporation. All rights reserved. + Copyright (C) 2013-2016 Jolla Ltd. Author: Philippe De Swert + Author: Philippe De Swert + Author: Vesa Halttunen + Author: Martin Jones + Author: Simo Piiroinen This program is free software; you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License @@ -18,8 +23,14 @@ 02110-1301 USA */ -/* initialize dbus communication channels */ -gboolean usb_moded_dbus_init(void); +/* Connect to D-Bus System Bus */ +gboolean usb_moded_dbus_init_connection(void); + +/* Claim D-Bus Service Name */ +gboolean usb_moded_dbus_init_service(void); + +/* Get current SystemBus connection */ +DBusConnection *usb_moded_dbus_get_connection(void); /* cleanup usb on exit */ void usb_moded_dbus_cleanup(void); @@ -35,3 +46,4 @@ int usb_moded_send_supported_modes_signal(const char *supported_modes); /* send hidden modes signal system bus */ int usb_moded_send_hidden_modes_signal(const char *hidden_modes); + diff --git a/src/usb_moded-dbus.c b/src/usb_moded-dbus.c index e1e16bf..537893f 100644 --- a/src/usb_moded-dbus.c +++ b/src/usb_moded-dbus.c @@ -2,10 +2,11 @@ @file usb_moded-dbus.c Copyright (C) 2010 Nokia Corporation. All rights reserved. - Copyright (C) 2012-2015 Jolla. All rights reserved. + Copyright (C) 2012-2016 Jolla. All rights reserved. @author: Philippe De Swert @author: Philippe De Swert + @author: Simo Piiroinen This program is free software; you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License @@ -467,18 +468,25 @@ static DBusHandlerResult msg_handler(DBusConnection *const connection, DBusMessa return status; } +DBusConnection *usb_moded_dbus_get_connection(void) +{ + DBusConnection *connection = 0; + if( dbus_connection_sys ) + connection = dbus_connection_ref(dbus_connection_sys); + else + log_err("something asked for connection ref while unconnected"); + return connection; +} + /** - * Init dbus for usb_moded + * Establish D-Bus SystemBus connection * * @return TRUE when everything went ok */ -gboolean usb_moded_dbus_init(void) +gboolean usb_moded_dbus_init_connection(void) { gboolean status = FALSE; - DBusError error; - int ret; - - dbus_error_init(&error); + DBusError error = DBUS_ERROR_INIT; /* connect to system bus */ if ((dbus_connection_sys = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) == NULL) @@ -491,6 +499,35 @@ gboolean usb_moded_dbus_init(void) if (!dbus_connection_add_filter(dbus_connection_sys, msg_handler, NULL, NULL)) goto EXIT; + /* Listen to init-done signals */ + dbus_bus_add_match(dbus_connection_sys, INIT_DONE_MATCH, 0); + + /* Connect D-Bus to the mainloop */ + dbus_connection_setup_with_g_main(dbus_connection_sys, NULL); + + /* everything went fine */ + status = TRUE; + +EXIT: + dbus_error_free(&error); + return status; +} + +/** + * Reserve "com.meego.usb_moded" D-Bus Service Name + * + * @return TRUE when everything went ok + */ +gboolean usb_moded_dbus_init_service(void) +{ + gboolean status = FALSE; + DBusError error = DBUS_ERROR_INIT; + int ret; + + if( !dbus_connection_sys ) { + goto EXIT; + } + /* Acquire D-Bus service */ ret = dbus_bus_request_name(dbus_connection_sys, USB_MODE_SERVICE, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) @@ -500,19 +537,6 @@ gboolean usb_moded_dbus_init(void) log_debug("DBUS ERROR: %s, %s \n", error.name, error.message); goto EXIT; } - - /* only match on signals/methods we support (if needed) - dbus_bus_add_match(dbus_connection_sys, USB_MODE_INTERFACE, &error); - */ - - /* Listen to init-done signals */ - dbus_bus_add_match(dbus_connection_sys, INIT_DONE_MATCH, 0); - - dbus_threads_init_default(); - - /* Connect D-Bus to the mainloop */ - dbus_connection_setup_with_g_main(dbus_connection_sys, NULL); - /* everything went fine */ status = TRUE; @@ -530,7 +554,10 @@ void usb_moded_dbus_cleanup(void) /* clean up system bus connection */ if (dbus_connection_sys != NULL) { - dbus_bus_release_name(dbus_connection_sys, USB_MODE_SERVICE, NULL); + if( dbus_connection_get_is_connected(dbus_connection_sys) ) { + // FIXME: do we want to do this? It is pretty useless on exit path. + dbus_bus_release_name(dbus_connection_sys, USB_MODE_SERVICE, NULL); + } dbus_connection_remove_filter(dbus_connection_sys, msg_handler, NULL); dbus_connection_unref(dbus_connection_sys); dbus_connection_sys = NULL; diff --git a/src/usb_moded.c b/src/usb_moded.c index 7188fe0..5c568a5 100644 --- a/src/usb_moded.c +++ b/src/usb_moded.c @@ -2,10 +2,11 @@ @file usb_moded.c Copyright (C) 2010 Nokia Corporation. All rights reserved. - Copyright (C) 2012 Jolla. All rights reserved. + Copyright (C) 2012-2016 Jolla. All rights reserved. @author: Philippe De Swert @author: Philippe De Swert + @author: Simo Piiroinen This program is free software; you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License @@ -1156,6 +1157,10 @@ int main(int argc, char* argv[]) #if !GLIB_CHECK_VERSION(2, 31, 0) g_thread_init(NULL); #endif + + /* Must be the 1st libdbus call that is made */ + dbus_threads_init_default(); + mainloop = g_main_loop_new(NULL, FALSE); if (rescue_mode && init_done_p()) @@ -1164,13 +1169,23 @@ int main(int argc, char* argv[]) log_warning("init done passed; rescue mode ignored"); } + /* Connect to SystemBus */ + if( !usb_moded_dbus_init_connection() ) + { + log_crit("dbus systembus connection failed\n"); + goto EXIT; + } + /* init daemon into a clean state first, then dbus and hw_abstraction last */ usb_moded_init(); - if( !usb_moded_dbus_init() ) + + /* Set up D-Bus Service */ + if( !usb_moded_dbus_init_service() ) { - log_crit("dbus ipc init failed\n"); + log_crit("usb-moded dbus service init failed\n"); goto EXIT; } + if( !hwal_init() ) { /* if hw_fallback is active we can live with a failed hwal_init */