]> git.meshlink.io Git - catta/commitdiff
reconnect if the DBUS daemon kicks avahi-daemon. Since the DBUS system bus socket...
authorLennart Poettering <lennart@poettering.net>
Mon, 24 Apr 2006 01:48:56 +0000 (01:48 +0000)
committerLennart Poettering <lennart@poettering.net>
Mon, 24 Apr 2006 01:48:56 +0000 (01:48 +0000)
git-svn-id: file:///home/lennart/svn/public/avahi/trunk@1197 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-daemon/dbus-internal.h
avahi-daemon/dbus-protocol.c
avahi-daemon/dbus-protocol.h
avahi-daemon/main.c

index f91407e4fc2fe8edf7903de589ce66fc167ff3a4..11c1094abf65c1e7055ad4f4bf8cccb71457a10e 100644 (file)
@@ -168,10 +168,14 @@ struct Client {
 };
 
 struct Server {
+    const AvahiPoll *poll_api;
     DBusConnection *bus;
     AVAHI_LLIST_HEAD(Client, clients);
     int n_clients;
     unsigned current_id;
+
+    AvahiTimeout *reconnect_timeout;
+    int reconnect;
 };
 
 extern Server *server;
index 2e3fd2f2d594d8cf8a93fd1d7f6b5330912c36f9..5b9bc503a8ff32c2458c327945aaa99ce21e3ec1 100644 (file)
@@ -48,6 +48,7 @@
 #include <avahi-common/alternative.h>
 #include <avahi-common/error.h>
 #include <avahi-common/domain.h>
+#include <avahi-common/timeval.h>
 
 #include <avahi-core/log.h>
 #include <avahi-core/core.h>
 
 /* #define VALGRIND_WORKAROUND 1 */
 
+#define RECONNECT_MSEC 3000
+
 Server *server = NULL;
 
 static int disable_user_service_publishing = 0;
 
+static int dbus_connect(void);
+static void dbus_disconnect(void);
+
 static void client_free(Client *c) {
     
     assert(server);
@@ -156,6 +162,20 @@ static Client *client_get(const char *name, int create) {
     return client;
 }
 
+static void reconnect_callback(AvahiTimeout *t, AVAHI_GCC_UNUSED void *userdata) {
+    assert(!server->bus);
+
+    if (dbus_connect() < 0) {
+        struct timeval tv;
+        avahi_log_debug(__FILE__": Connection failed, retrying in %ims...", RECONNECT_MSEC);
+        avahi_elapse_time(&tv, RECONNECT_MSEC, 0);
+        server->poll_api->timeout_update(t, &tv);
+    } else {
+        avahi_log_debug(__FILE__": Successfully reconnected.");
+        server->poll_api->timeout_update(t, NULL);
+    }
+}
+
 static DBusHandlerResult msg_signal_filter_impl(AVAHI_GCC_UNUSED DBusConnection *c, DBusMessage *m, AVAHI_GCC_UNUSED void *userdata) {
     DBusError error;
 
@@ -167,12 +187,24 @@ static DBusHandlerResult msg_signal_filter_impl(AVAHI_GCC_UNUSED DBusConnection
 /*                     dbus_message_get_member(m)); */
 
     if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) {
-        /* No, we shouldn't quit, but until we get somewhere
-         * usefull such that we can restore our state, we will */
-        avahi_log_warn("Disconnnected from D-BUS, terminating...");
-        
-        raise(SIGQUIT); /* The signal handler will catch this and terminate the process cleanly*/
-        
+        struct timeval tv;
+
+        if (server->reconnect) {
+            avahi_log_warn("Disconnnected from D-BUS, trying to reconnect in %ims...", RECONNECT_MSEC);
+            
+            dbus_disconnect();
+            
+            avahi_elapse_time(&tv, RECONNECT_MSEC, 0);
+            
+            if (server->reconnect_timeout)
+                server->poll_api->timeout_update(server->reconnect_timeout, &tv);
+            else
+                server->reconnect_timeout = server->poll_api->timeout_new(server->poll_api, &tv, reconnect_callback, NULL);
+        } else {
+            avahi_log_warn("Disconnnected from D-BUS, exiting.");
+            raise(SIGQUIT);
+        }
+            
         return DBUS_HANDLER_RESULT_HANDLED;
         
     } else if (dbus_message_is_signal(m, DBUS_INTERFACE_DBUS, "NameAcquired")) {
@@ -986,7 +1018,7 @@ void dbus_protocol_server_state_changed(AvahiServerState state) {
     int32_t t;
     const char *e;
     
-    if (!server)
+    if (!server || !server->bus)
         return;
 
     m = dbus_message_new_signal(AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "StateChanged");
@@ -1004,7 +1036,7 @@ void dbus_protocol_server_state_changed(AvahiServerState state) {
     dbus_message_unref(m);
 }
 
-int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_publishing) {
+static int dbus_connect(void) {
     DBusError error;
 
     static const DBusObjectPathVTable server_vtable = {
@@ -1016,26 +1048,23 @@ int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_pub
         NULL
     };
 
-    dbus_error_init(&error);
-
-    disable_user_service_publishing = _disable_user_service_publishing;
-
-    server = avahi_new(Server, 1);
-    AVAHI_LLIST_HEAD_INIT(Clients, server->clients);
-    server->current_id = 0;
-    server->n_clients = 0;
+    assert(server);
+    assert(!server->bus);
 
+    dbus_error_init(&error);
+    
     if (!(server->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
         assert(dbus_error_is_set(&error));
         avahi_log_error("dbus_bus_get(): %s", error.message);
         goto fail;
     }
-
-    if (avahi_dbus_connection_glue(server->bus, poll_api) < 0) {
+    if (avahi_dbus_connection_glue(server->bus, server->poll_api) < 0) {
         avahi_log_error("avahi_dbus_connection_glue() failed");
         goto fail;
     }
 
+    dbus_connection_set_exit_on_disconnect(server->bus, FALSE);
+    
     if (dbus_bus_request_name(
             server->bus,
             AVAHI_DBUS_NAME,
@@ -1054,7 +1083,7 @@ int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_pub
         goto fail;
     }
 
-    if (!(dbus_connection_add_filter(server->bus, msg_signal_filter_impl, (void*) poll_api, NULL))) {
+    if (!(dbus_connection_add_filter(server->bus, msg_signal_filter_impl, (void*) server->poll_api, NULL))) {
         avahi_log_error("dbus_connection_add_filter() failed");
         goto fail;
     }
@@ -1072,16 +1101,68 @@ int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_pub
     }
 
     return 0;
-
 fail:
+
+    if (dbus_error_is_set(&error))
+        dbus_error_free(&error);
+
     if (server->bus) {
         dbus_connection_disconnect(server->bus);
         dbus_connection_unref(server->bus);
+        server->bus = NULL;
     }
 
-    if (dbus_error_is_set(&error))
-        dbus_error_free(&error);
+    return -1;
+}
+
+static void dbus_disconnect(void) {
+    assert(server);
+
+    while (server->clients)
+        client_free(server->clients);
+    
+    assert(server->n_clients == 0);
+
+    if (server->bus) {
+        dbus_connection_disconnect(server->bus);
+        dbus_connection_unref(server->bus);
+        server->bus = NULL;
+    }
+}
+
+int dbus_protocol_setup(const AvahiPoll *poll_api, int _disable_user_service_publishing, int force) {
+
+    disable_user_service_publishing = _disable_user_service_publishing;
+
+    server = avahi_new(Server, 1);
+    AVAHI_LLIST_HEAD_INIT(Clients, server->clients);
+    server->current_id = 0;
+    server->n_clients = 0;
+    server->bus = NULL;
+    server->poll_api = poll_api;
+    server->reconnect_timeout = NULL;
+    server->reconnect = force;
+
+    if (dbus_connect() < 0) {
+        struct timeval tv;
+
+        if (!force)
+            goto fail;
+
+        avahi_log_warn("WARNING: Failed to contact D-BUS daemon, retrying in %ims.", RECONNECT_MSEC);
+        
+        avahi_elapse_time(&tv, RECONNECT_MSEC, 0);
+        server->reconnect_timeout = server->poll_api->timeout_new(server->poll_api, &tv, reconnect_callback, NULL);
+    }
         
+    return 0;
+
+fail:
+    if (server->bus) {
+        dbus_connection_disconnect(server->bus);
+        dbus_connection_unref(server->bus);
+    }
+
     avahi_free(server);
     server = NULL;
     return -1;
@@ -1090,17 +1171,11 @@ fail:
 void dbus_protocol_shutdown(void) {
 
     if (server) {
-    
-        while (server->clients)
-            client_free(server->clients);
-
-        assert(server->n_clients == 0);
-
-        if (server->bus) {
-            dbus_connection_disconnect(server->bus);
-            dbus_connection_unref(server->bus);
-        }
+        dbus_disconnect();
 
+        if (server->reconnect_timeout)
+            server->poll_api->timeout_free(server->reconnect_timeout);
+        
         avahi_free(server);
         server = NULL;
     }
index d23b5248a47b5d8bab0aa7fc293b2bf308bbe455..d4404f2379eb0d4122290cee558c30f545510ad6 100644 (file)
@@ -22,7 +22,7 @@
   USA.
 ***/
 
-int dbus_protocol_setup(const AvahiPoll *poll_api, int disable_user_service_publishing);
+int dbus_protocol_setup(const AvahiPoll *poll_api, int disable_user_service_publishing, int force);
 void dbus_protocol_shutdown(void);
 void dbus_protocol_server_state_changed(AvahiServerState state);
 
index f32cbd6db855ac832a58d1ab583f941ebbae88d6..a9dfb42457838f3cf009b3522e1cb76eddb7ef02 100644 (file)
@@ -743,13 +743,12 @@ static int run_server(DaemonConfig *c) {
 
 #ifdef HAVE_DBUS
     if (c->enable_dbus) {
-        if (dbus_protocol_setup(poll_api, config.disable_user_service_publishing) < 0) {
+        if (dbus_protocol_setup(poll_api, config.disable_user_service_publishing, !c->fail_on_missing_dbus && !config.use_chroot) < 0) {
+
+            avahi_log_warn("WARNING: Failed to contact D-BUS daemon.");
 
             if (c->fail_on_missing_dbus)
                 goto finish;
-
-            avahi_log_warn("WARNING: Failed to contact D-BUS daemon, disabling D-BUS support.");
-            c->enable_dbus = 0;
         }
     }
 #endif