Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Handle DBus disconnects gracefully
Stop libdbus from calling _exit() when connection is lost.
Do orderly exit when Disconnect signal is received instead.

[dsme] Handle DBus disconnects gracefully
  • Loading branch information
spiiroin committed Nov 19, 2013
1 parent d29bc54 commit ae1b8ba
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 24 deletions.
11 changes: 8 additions & 3 deletions modules/Makefile.am
Expand Up @@ -84,6 +84,7 @@ heartbeat_la_SOURCES = heartbeat.c
heartbeat_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)

state_la_SOURCES = state.c
state_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)

if WANT_RUNLEVEL
runlevel_la_SOURCES = runlevel.c
Expand All @@ -108,13 +109,15 @@ dbusproxy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(DBUSGLIB_CFLAGS)
dbusproxy_la_LIBADD = $(DBUSGLIB_LIBS) -ldsme_dbus_if

alarmtracker_la_SOURCES = alarmtracker.c
alarmtracker_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
alarmtracker_la_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE

thermalmanager_la_SOURCES = thermalmanager.c
thermalmanager_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) -DDSME_THERMAL_TUNING
thermalmanager_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) -DDSME_THERMAL_TUNING
thermalmanager_la_LIBADD = -lthermalmanager_dbus_if

emergencycalltracker_la_SOURCES = emergencycalltracker.c
emergencycalltracker_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)

usbtracker_la_SOURCES = usbtracker.c
usbtracker_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
Expand Down Expand Up @@ -166,11 +169,13 @@ diskmonitor_la_SOURCES = diskmonitor.c \
diskmonitor.h \
diskmonitor_backend.h

diskmonitor_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)

tempreaper_la_SOURCES = tempreaper.c
tempreaper_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)

dbusautoconnector_la_SOURCES = dbusautoconnector.c
dbusautoconnector_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
dbusautoconnector_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS)
dbusautoconnector_la_LIBADD = $(GLIB_LIBS)

if WANT_PWRKEY_MONITOR
Expand All @@ -181,6 +186,6 @@ endif

if WANT_BATTERY_TRACKER
batterytracker_la_SOURCES = batterytracker.c
batterytracker_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) -D_GNU_SOURCE
batterytracker_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) -D_GNU_SOURCE
batterytracker_la_LIBADD = $(GLIB_LIBS)
endif
76 changes: 59 additions & 17 deletions modules/dsme_dbus.c
Expand Up @@ -82,11 +82,64 @@ static bool dsme_dbus_check_arg_type(DBusMessageIter* iter, int want_type)
return false;
}

bool dsme_dbus_is_available(void)

static DBusHandlerResult
dsme_dbus_filter(DBusConnection *con, DBusMessage *msg, void *aptr)
{
if( dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected") ) {
dsme_log(LOG_CRIT, "Disconnected from system bus; terminating");
dsme_exit(EXIT_FAILURE);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusConnection *dsme_dbus_try_to_connect(DBusError *err)
{
return dbus_bus_get(DBUS_BUS_SYSTEM, 0) != 0;
static DBusConnection *con = 0;

if( con )
goto EXIT;

if( !(con = dbus_bus_get(DBUS_BUS_SYSTEM, err)) )
goto EXIT;

dbus_connection_add_filter(con, dsme_dbus_filter, 0, 0);
dbus_connection_set_exit_on_disconnect(con, FALSE);

EXIT:
// NOTE: returns null or new reference
return con ? dbus_connection_ref(con) : 0;
}

DBusConnection *dsme_dbus_get_connection(DBusError *error)
{
DBusError err = DBUS_ERROR_INIT;
DBusConnection *con = dsme_dbus_try_to_connect(&err);

if( !con ) {
if( error )
dbus_move_error(&err, error);
else
dsme_log(LOG_DEBUG, "dbus_bus_get(): %s\n", err.message);
}
dbus_error_free(&err);

// NOTE: returns null or new reference
return con;
}

bool dsme_dbus_is_available(void)
{
bool res = false;
DBusConnection *con = 0;

if( (con = dsme_dbus_try_to_connect(0)) ) {
dbus_connection_unref(con);
res = true;
}

return res;
}

struct DsmeDbusMessage {
DBusConnection* connection;
Expand Down Expand Up @@ -194,18 +247,6 @@ static void message_send_and_delete(DsmeDbusMessage* msg)
}


static DBusConnection* system_bus(DBusError* error)
{
DBusConnection* connection;

if (!(connection = dbus_bus_get(DBUS_BUS_SYSTEM, error))) {
dsme_log(LOG_DEBUG, "dbus_bus_get(): %s\n", error->message);
dbus_error_free(error);
}

return connection;
}

DsmeDbusMessage* dsme_dbus_signal_new(const char* path,
const char* interface,
const char* name)
Expand All @@ -218,14 +259,15 @@ DsmeDbusMessage* dsme_dbus_signal_new(const char* path,
dbus_error_init(&error);

// TODO: we only use the system bus
if ((connection = system_bus(&error))) {
if ((connection = dsme_dbus_get_connection(&error))) {
s = g_new(DsmeDbusMessage, 1);

s->connection = connection;
s->msg = dbus_message_new_signal(path, interface, name);

dbus_message_iter_init_append(s->msg, &s->iter);
}
dbus_error_free(&error);
}

return s;
Expand Down Expand Up @@ -557,8 +599,8 @@ static Filter* filter_new(void* child, FilterMessageHandler* handler)
dbus_error_init(&error);

// TODO: we only use the system bus
if ((connection = system_bus(&error)) == 0) {
dsme_log(LOG_ERR, "system_bus() failed: %s", error.message);
if ((connection = dsme_dbus_get_connection(&error)) == 0) {
dsme_log(LOG_ERR, "system bus connect failed: %s", error.message);
dbus_error_free(&error);
} else {

Expand Down
2 changes: 2 additions & 0 deletions modules/dsme_dbus.h
Expand Up @@ -26,6 +26,7 @@
#define DSME_DBUS_H

#include <stdbool.h>
#include <dbus/dbus.h>

typedef struct DsmeDbusMessage DsmeDbusMessage;

Expand All @@ -47,6 +48,7 @@ typedef struct dsme_dbus_signal_binding_t {


bool dsme_dbus_is_available(void);
DBusConnection *dsme_dbus_get_connection(DBusError *err);

void dsme_dbus_bind_methods(bool* bound_already,
const dsme_dbus_binding_t* bindings,
Expand Down
2 changes: 1 addition & 1 deletion modules/iphb.c
Expand Up @@ -2420,7 +2420,7 @@ static void systembus_connect(void)
{
DBusError err = DBUS_ERROR_INIT;

if( !(systembus = dbus_bus_get(DBUS_BUS_SYSTEM, &err)) ) {
if( !(systembus = dsme_dbus_get_connection(&err)) ) {
dsme_log(LOG_WARNING, PFIX"can't connect to systembus: %s: %s",
err.name, err.message);
goto cleanup;
Expand Down
6 changes: 3 additions & 3 deletions modules/usbtracker.c
Expand Up @@ -181,10 +181,10 @@ DSME_HANDLER(DSM_MSGTYPE_DBUS_CONNECT, client, msg)
DBusConnection *conn = 0;
DBusMessage *req = NULL;

if( !(conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err)) )
if( !(conn = dsme_dbus_get_connection(&err)) )
{
dsme_log(LOG_ERR, "DBUS_BUS_SYSTEM: %s: %s",
err.name, err.message);
dsme_log(LOG_ERR, "system bus connect: %s: %s",
err.name, err.message);
goto cleanup;
}

Expand Down

0 comments on commit ae1b8ba

Please sign in to comment.