[patch] make NM survive D-BUS system bus restarts



Hi,

Currently NetworkManager does not recover once the D-BUS system bus is
restarted.  With the attached patch it will survive such a exceptional
conditions.

It does the following:

      * add function nm_dbus_reinit to src/NetworkManagerDbus.c.
      * fix: handle the signal "Disconnected" on DBUS_INTERFACE_LOCAL
        rather than DBUS_INTERFACE_DBUS
      * create thread nm_dbus_reinit once we receive this signal.  Retry
        every three seconds until we have a new connection to the system
        bus.
      * call dbus_connection_set_exit_on_disconnect (connection, FALSE)
        in order not to get shutdown by libdbus.

Using g_timeout_add rather than a GThread did not work out.

   Timo

Patch: nm-dbus-reconnect-thoenig-02.patch
ChangeLog                |   17 +++++++++++++++++
src/NetworkManagerDbus.c |   36 +++++++++++++++++++++++++++++++++---
2 files changed, 50 insertions(+), 3 deletions(-)
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/NetworkManager/ChangeLog,v
retrieving revision 1.827
diff -u -r1.827 ChangeLog
--- ChangeLog	16 Feb 2006 09:38:40 -0000	1.827
+++ ChangeLog	17 Feb 2006 16:42:20 -0000
@@ -1,3 +1,20 @@
+2006-02-17  Timo Hoenig  <thoenig suse de>
+	
+	Fix NetworkManager to recover if the D-BUS system gets restarted.
+	* src/NetworkManagerDbus.c:
+		- (nm_dbus_reinit): reconnect to D-BUS system bus once it is
+			back.  If HAL is already back on the bus: call
+			nm_hal_init.
+		- (nm_dbus_signal_filter): expect D-BUS signal for disconnect
+			on DBUS_INTERFACE_LOCAL, not DBUS_INTERFACE_DBUS.
+		- (nm_dbus_signal_filter): clean up broken D-BUS connection
+			and create thread nm_dbus_reinit if the signal
+			"Disconnected" is received on the interface
+			DBUS_INTERFACE_LOCAL.
+		- (nm_dbus_init): do not let libdbus quit NetworkManager if
+			the connection to the D-BUS system bus breaks away.
+
+
 2006-02-16  Kang Jeong-Hee  <keizie gmail com>
 
 	* configure.in (ALL_LINGUAS): ko added. (Korean)
Index: src/NetworkManagerDbus.c
===================================================================
RCS file: /cvs/gnome/NetworkManager/src/NetworkManagerDbus.c,v
retrieving revision 1.105
diff -u -r1.105 NetworkManagerDbus.c
--- src/NetworkManagerDbus.c	20 Jan 2006 17:03:13 -0000	1.105
+++ src/NetworkManagerDbus.c	17 Feb 2006 16:42:20 -0000
@@ -46,6 +46,8 @@
 
 static char *get_nmi_match_string (const char *owner);
 
+static gpointer nm_dbus_reinit (gpointer user_data);
+
 /*
  * nm_dbus_create_error_message
  *
@@ -494,10 +496,12 @@
 			handled = TRUE;
 		}
 	}
-	else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "Disconnected"))
+	else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
 	{
-		/* FIXME: try to recover from disconnection */
+		nm_hal_deinit (data);
+		dbus_connection_unref (data->dbus_connection);
 		data->dbus_connection = NULL;
+		g_thread_create ((GThreadFunc) nm_dbus_reinit, (gpointer) data, FALSE, NULL);
 		handled = TRUE;
 	}
 	else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
@@ -734,6 +738,32 @@
 	return g_strdup_printf ("type='signal',interface='" NMI_DBUS_INTERFACE "',sender='%s',path='" NMI_DBUS_PATH "'", owner);
 }
 
+/*
+ * nm_dbus_reinit
+ *
+ * Reconnect to the system message bus if the connection was dropped.
+ *
+ */
+
+static gpointer nm_dbus_reinit (gpointer user_data)
+{
+	NMData *data = (NMData *) user_data;
+	char *owner;
+
+	g_return_val_if_fail (data != NULL, NULL);
+
+	while ((data->dbus_connection = nm_dbus_init (data)) == NULL)
+		g_usleep (G_USEC_PER_SEC * 3);
+
+	/* if HAL was quick it is already back on the bus. Thus, we do not receive NameOwnerChanged */
+	if ((owner = get_name_owner (data->dbus_connection, "org.freedesktop.Hal")))
+		nm_hal_init (data);
+
+	nm_info ("Successfully reconnected to the system bus.");
+	
+	return NULL;
+}
+
 
 /*
  * nm_dbus_init
@@ -762,7 +792,7 @@
 		goto out;
 	}
 
-	//dbus_connection_set_exit_on_disconnect (connection, FALSE);
+	dbus_connection_set_exit_on_disconnect (connection, FALSE);
 	dbus_connection_setup_with_g_main (connection, data->main_context);
 
 	data->nm_methods = nm_dbus_nm_methods_setup ();


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