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);
 
_______________________________________________
NetworkManager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to