DBus reconnect support (initial attempt)



One of the things that NM has needed for a while is the ability to properly handle Dbus disconnects, and to reconnect sanely. With a bit of help from the patch for GVM to do this (see http://bugzilla.gnome.org/show_bug.cgi?id=153673) I've managed to hack in support to let NM do this as well! This is an initial attempt, and it doesn't appear to fully play nicely, but it should at least be a decent starting point for others, esp. once we fully stabilise on the new DBUS/HAL API stuff.

extract-init.patch: Not very interesting, pulls the Dbus/HAL setup stuff out of the main function and into a nm_services_init() function instead. Shouldn't change the behaviour on its own, but does allow the next patch.

reconnect.patch: Looks for DBus disconnect messages, and sets a g_timeout thing in motion to try and reconnect at 500ms intervals. This will set the hal_ctx/dbus_connection variables to NULL while we're attempting to reconnect, so we may need to do smarter things elsewhere to handle the possible "we haven't reconnected" yet case. Notably, this may eventually allow starting NetworkManager *before* Dbus and connecting to it as and when it appears.

Should be of some use with any luck :-)

Tom
Index: src/NetworkManager.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManager.c,v
retrieving revision 1.58
diff -u -r1.58 NetworkManager.c
--- src/NetworkManager.c	11 Mar 2005 20:12:57 -0000	1.58
+++ src/NetworkManager.c	13 Mar 2005 22:13:15 -0000
@@ -664,7 +664,6 @@
  */
 int main( int argc, char *argv[] )
 {
-	LibHalContext	*ctx = NULL;
 	guint		 link_source_id;
 	GSource		*link_source;
 	gboolean		 become_daemon = TRUE;
@@ -751,13 +750,57 @@
 		exit (EXIT_FAILURE);
 	}	
 
+	if (!nm_services_init(nm_data))
+	{
+		nm_data_free (nm_data);
+		exit (EXIT_FAILURE);
+	}
+
+	/* We run dhclient when we need to, and we don't want any stray ones
+	 * lying around upon launch.
+	 */
+	nm_system_kill_all_dhcp_daemons ();
+
+	/* Bring up the loopback interface. */
+	nm_system_enable_loopback ();
+
+	/* Create watch functions that monitor cards for link status. */
+	nm_monitor_wireless_link_state (nm_data);
+	nm_monitor_wired_link_state (nm_data);
+
+	if (!nm_named_manager_start (nm_data->named, &error))
+	{
+		syslog (LOG_CRIT, "Couldn't initialize nameserver: %s", error->message);
+		exit (EXIT_FAILURE);
+	}
+
+	/* Wheeee!!! */
+	g_main_loop_run (nm_data->main_loop);
+
+	/* Cleanup */
+	if (libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error) != 0) {
+		syslog (LOG_NOTICE, "Error: libhal shutdown failed - %s", dbus_error.message);
+
+		dbus_error_free (&dbus_error);
+	}
+
+	libhal_ctx_free (nm_data->hal_ctx);
+
+	nm_data_free (nm_data);
+
+	exit (0);
+}
+
+gboolean nm_services_init(NMData *nm_data)
+{
+	DBusError 	dbus_error;
+	LibHalContext	*ctx = NULL;
 	/* Create our dbus service */
 	nm_data->dbus_connection = nm_dbus_init (nm_data);
 	if (!nm_data->dbus_connection)
 	{
-		syslog (LOG_CRIT, "nm_dbus_init() failed, exiting.  Either dbus is not running, or the NetworkManager dbus security policy was not loaded.");
-		nm_data_free (nm_data);
-		exit (EXIT_FAILURE);
+		syslog (LOG_CRIT, "nm_dbus_init() failed.  Either dbus is not running, or the NetworkManager dbus security policy was not loaded.");
+		return FALSE;
 	}
 
 	/* If NMI is running, grab allowed wireless network lists from it ASAP */
@@ -773,8 +816,8 @@
 	/* Initialize libhal.  We get a connection to the hal daemon here. */
 	if ((ctx = libhal_ctx_new()) == NULL)
 	{
-		syslog (LOG_CRIT, "libhal_ctx_new() failed, exiting...");
-		exit (EXIT_FAILURE);
+		syslog (LOG_CRIT, "libhal_ctx_new() failed");
+		return FALSE;
 	}
 
 	nm_hal_mainloop_integration (ctx, nm_data->dbus_connection); 
@@ -783,10 +826,10 @@
 
 	dbus_error_init (&dbus_error);
 	if(!libhal_ctx_init (ctx, &dbus_error)) {
-		syslog (LOG_CRIT, "libhal_ctx_init() failed, exiting...  Make sure the hal daemon is running? - %s", dbus_error.message);
+		syslog (LOG_CRIT, "libhal_ctx_init() failed.  Make sure the hal daemon is running? - %s", dbus_error.message);
 
 		dbus_error_free (&dbus_error);
-		exit (EXIT_FAILURE);
+		return FALSE;
 	}
 
 	nm_data->hal_ctx = ctx;
@@ -807,43 +850,11 @@
 	{
 		syslog (LOG_CRIT, "libhal_device_property_watch_all(): %s", dbus_error.message);
 		dbus_error_free (&dbus_error);
-		exit (EXIT_FAILURE);
+		return FALSE;
 	}
 
 	/* Grab network devices that are already present and add them to our list */
 	nm_add_initial_devices (nm_data);
-
-	/* We run dhclient when we need to, and we don't want any stray ones
-	 * lying around upon launch.
-	 */
-	nm_system_kill_all_dhcp_daemons ();
-
-	/* Bring up the loopback interface. */
-	nm_system_enable_loopback ();
-
-	/* Create watch functions that monitor cards for link status. */
-	nm_monitor_wireless_link_state (nm_data);
-	nm_monitor_wired_link_state (nm_data);
-
-	if (!nm_named_manager_start (nm_data->named, &error))
-	{
-		syslog (LOG_CRIT, "Couldn't initialize nameserver: %s", error->message);
-		exit (EXIT_FAILURE);
-	}
-
-	/* Wheeee!!! */
-	g_main_loop_run (nm_data->main_loop);
-
-	/* Cleanup */
-	if (libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error) != 0) {
-		syslog (LOG_NOTICE, "Error: libhal shutdown failed - %s", dbus_error.message);
-
-		dbus_error_free (&dbus_error);
-	}
-
-	libhal_ctx_free (nm_data->hal_ctx);
-
-	nm_data_free (nm_data);
-
-	exit (0);
+	return TRUE;
 }
+
Index: src/NetworkManagerDbus.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerDbus.c,v
retrieving revision 1.69
diff -u -r1.69 NetworkManagerDbus.c
--- src/NetworkManagerDbus.c	11 Mar 2005 20:12:57 -0000	1.69
+++ src/NetworkManagerDbus.c	13 Mar 2005 22:09:19 -0000
@@ -28,6 +28,7 @@
 #include <netinet/ether.h>
 
 #include "NetworkManager.h"
+#include "NetworkManagerMain.h"
 #include "NetworkManagerUtils.h"
 #include "NetworkManagerDevice.h"
 #include "NetworkManagerDbus.h"
@@ -864,6 +865,19 @@
 }
 
 
+static gboolean nm_reconnect_to_hal (gpointer user_data)
+{
+	NMData		*data = (NMData *)user_data;
+	syslog(LOG_DEBUG, "Trying a reconnect to HAL");
+	gboolean setup = nm_services_init(data);
+	if (setup) {
+		syslog(LOG_INFO,"Reconnected OK.");
+		return FALSE;
+	}
+	else
+		return TRUE;
+}
+
 /*
  * nm_dbus_nmi_filter
  *
@@ -885,8 +899,24 @@
 	method = dbus_message_get_member (message);
 	if (!(object_path = dbus_message_get_path (message)))
 		return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+	 syslog (LOG_DEBUG, "nm_dbus_nmi_filter() got method %s for path %s", method, object_path); 
+	if (dbus_message_is_signal (message,
+	                            DBUS_INTERFACE_LOCAL,
+	                            "Disconnected")) {
+		g_timeout_add(500, nm_reconnect_to_hal, data);
+		if (libhal_ctx_shutdown (data->hal_ctx, &error) != 0) {
+			syslog (LOG_NOTICE, "Error: libhal shutdown failed - %s", error.message);
+
+			dbus_error_free (&error);
+		}
+		data->hal_ctx = NULL;
+		dbus_connection_unref (data->dbus_connection);
+		data->dbus_connection = NULL;
+		syslog (LOG_DEBUG, "NetworkManager got disconnected from DBUS");
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
 
-	/* syslog (LOG_DEBUG, "nm_dbus_nmi_filter() got method %s for path %s", method, object_path); */
 
 	dbus_error_init (&error);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]