FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 02-02-2011, 11:37 PM
Lon Hohberger
 
Default rgmanager: dbus notifications (Merged)

Includes aforementioned makefile fix

Everything in one patch for easy reading.

Resolves: rhbz#657756

Signed-off-by: Lon Hohberger <lhh@redhat.com>
---
rgmanager/include/rg_dbus.h | 20 +++
rgmanager/man/rgmanager.8 | 2 +
rgmanager/src/daemons/Makefile | 7 +-
rgmanager/src/daemons/main.c | 19 ++-
rgmanager/src/daemons/update-dbus.c | 266 +++++++++++++++++++++++++++++++++++
5 files changed, 309 insertions(+), 5 deletions(-)
create mode 100644 rgmanager/include/rg_dbus.h
create mode 100644 rgmanager/src/daemons/update-dbus.c

diff --git a/rgmanager/include/rg_dbus.h b/rgmanager/include/rg_dbus.h
new file mode 100644
index 0000000..3ef5ae1
--- /dev/null
+++ b/rgmanager/include/rg_dbus.h
@@ -0,0 +1,20 @@
+#ifndef _RGM_DBUS_H
+#define _RGM_DBUS_H
+
+int rgm_dbus_init(void);
+int rgm_dbus_release(void);
+extern int rgm_dbus_notify;
+
+#ifdef DBUS
+
+#define RGM_DBUS_DEFAULT 1
+#define RGM_DBUS_UPDATE (rgm_dbus_notify?rgm_dbus_update:0)
+int32_t rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size);
+
+#else
+
+#define RGM_DBUS_DEFAULT 0
+#define RGM_DBUS_UPDATE NULL
+
+#endif /* DBUS */
+#endif
diff --git a/rgmanager/man/rgmanager.8 b/rgmanager/man/rgmanager.8
index 39b2195..2b018d2 100644
--- a/rgmanager/man/rgmanager.8
+++ b/rgmanager/man/rgmanager.8
@@ -371,6 +371,8 @@ will leave the virtual machine running.
Run in the foreground (do not fork).
.IP -d
Enable debug-level logging.
+.IP -q
+Disable DBus signals which are normally sent when services change state.
.IP -w
Disable internal process monitoring (for debugging).
.IP -N
diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
index 94e0dbb..4dbbe5a 100644
--- a/rgmanager/src/daemons/Makefile
+++ b/rgmanager/src/daemons/Makefile
@@ -29,6 +29,7 @@ OBJS1= fo_domain.o
service_op.o
slang_event.o
event_config.o
+ update-dbus.o
watchdog.o

OBJS2= test-noccs.o
@@ -40,12 +41,13 @@ OBJS2= test-noccs.o
rg_locks-noccs.o
event_config-noccs.o

-CFLAGS += -DSHAREDIR="${sharedir}" -D_GNU_SOURCE
+CFLAGS += -DDBUS -DSHAREDIR="${sharedir}" -D_GNU_SOURCE
CFLAGS += -fPIC
CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${dlmincdir} -I${logtincdir}
CFLAGS += `xml2-config --cflags` -I${slangincdir}
CFLAGS += -I$(S)/../../include
CFLAGS += -I${incdir}
+CFLAGS += `pkg-config --cflags dbus-1`

NOCCS_CFLAGS += -DNO_CCS

@@ -59,6 +61,7 @@ DLM_LDFLAGS += -L${dlmlibdir} -ldlm
XML2_LDFLAGS += `xml2-config --libs`
SLANG_LDFLAGS += -L${slanglibdir} -lslang
EXTRA_LDFLAGS += -lpthread
+DBUS_LDFLAGS += `pkg-config --libs dbus-1`

LDDEPS += ../clulib/libclulib.a

@@ -66,7 +69,7 @@ ${TARGET1}: ${OBJS1} ${LDDEPS}
$(CC) -o $@ $^ $(CCS_LDFLAGS) $(CMAN_LDFLAGS)
$(DLM_LDFLAGS) $(XML2_LDFLAGS)
$(SLANG_LDFLAGS) $(EXTRA_LDFLAGS)
- $(LOGSYS_LDFLAGS) $(LD_FLAGS)
+ $(LOGSYS_LDFLAGS) $(LD_FLAGS) $(DBUS_LDFLAGS)

#
# Our test program links against the local allocator so that
diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
index 4e34246..02cd2dc 100644
--- a/rgmanager/src/daemons/main.c
+++ b/rgmanager/src/daemons/main.c
@@ -23,6 +23,7 @@
#include <members.h>
#include <daemon_init.h>
#include <groups.h>
+#include <rg_dbus.h>

#ifdef WRAP_THREADS
void dump_thread_states(FILE *);
@@ -43,7 +44,6 @@ static uint8_t ALIGNED port = RG_PORT;
static char *rgmanager_lsname = (char *)"rgmanager"; /* XXX default */
static int status_poll_interval = DEFAULT_CHECK_INTERVAL;

-
static void
segfault(int __attribute__ ((unused)) sig)
{
@@ -684,6 +684,8 @@ event_loop(msgctx_t *localctx, msgctx_t *clusterctx)
dump_internal_state("/var/lib/cluster/rgmanager-dump");
}

+ rgm_dbus_init();
+
while (running && (tv.tv_sec || tv.tv_usec)) {
FD_ZERO(&rfds);
max = -1;
@@ -949,7 +951,7 @@ main(int argc, char **argv)
pthread_t th;
cman_handle_t clu = NULL;

- while ((rv = getopt(argc, argv, "wfdN")) != EOF) {
+ while ((rv = getopt(argc, argv, "wfdNq")) != EOF) {
switch (rv) {
case 'w':
wd = 0;
@@ -963,6 +965,9 @@ main(int argc, char **argv)
case 'f':
foreground = 1;
break;
+ case 'q':
+ rgm_dbus_notify = 0;
+ break;
default:
return 1;
break;
@@ -1032,6 +1037,12 @@ main(int argc, char **argv)
configure_rgmanager(-1, debug, &cluster_timeout);
logt_print(LOG_NOTICE, "Resource Group Manager Starting
");

+ if (rgm_dbus_notify && rgm_dbus_init() != 0) {
+ rgm_dbus_notify = 0;
+ logt_print(LOG_NOTICE, "Failed to initialize DBus; "
+ "notifications disabled
");
+ }
+
if (init_resource_groups(0, do_init) != 0) {
logt_print(LOG_CRIT, "#8: Couldn't initialize services
");
goto out_ls;
@@ -1074,7 +1085,8 @@ main(int argc, char **argv)

ds_key_init("rg_lockdown", 32, 10);
#else
- if (vf_init(me.cn_nodeid, port, NULL, NULL, cluster_timeout) != 0) {
+ if (vf_init(me.cn_nodeid, port, NULL, RGM_DBUS_UPDATE,
+ cluster_timeout) != 0) {
logt_print(LOG_CRIT, "#11: Couldn't set up VF listen socket
");
goto out_ls;
}
@@ -1106,6 +1118,7 @@ out_ls:
clu_lock_finished(rgmanager_lsname);

out:
+ rgm_dbus_release();
logt_print(LOG_NOTICE, "Shutdown complete, exiting
");
cman_finish(clu);

diff --git a/rgmanager/src/daemons/update-dbus.c b/rgmanager/src/daemons/update-dbus.c
new file mode 100644
index 0000000..f465d1d
--- /dev/null
+++ b/rgmanager/src/daemons/update-dbus.c
@@ -0,0 +1,266 @@
+/* DBus notifications */
+#include <stdint.h>
+#include <rg_dbus.h>
+#include <errno.h>
+
+#ifdef DBUS
+
+#include <stdio.h>
+#include <stdint.h>
+#include <resgroup.h>
+#include <poll.h>
+#include <dbus/dbus.h>
+#include <liblogthread.h>
+#include <members.h>
+
+
+#define DBUS_RGM_NAME "com.redhat.cluster.rgmanager"
+#define DBUS_RGM_IFACE "com.redhat.cluster.rgmanager"
+#define DBUS_RGM_PATH "/com/redhat/cluster/rgmanager"
+
+static DBusConnection *db = NULL;
+static pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t th = 0;
+#endif
+
+/* Set this to the desired value prior to calling rgm_dbus_init() */
+int rgm_dbus_notify = RGM_DBUS_DEFAULT;
+
+
+int
+rgm_dbus_init(void)
+#ifdef DBUS
+{
+ DBusConnection *dbc = NULL;
+ DBusError err;
+
+ if (!rgm_dbus_notify)
+ return 0;
+
+ pthread_mutex_lock(&mu);
+ if (db) {
+ pthread_mutex_unlock(&mu);
+ return 0;
+ }
+
+ dbus_error_init(&err);
+
+ dbc = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+ if (!dbc) {
+ logt_print(LOG_DEBUG,
+ "DBus Failed to initialize: dbus_bus_get: %s
",
+ err.message);
+ dbus_error_free(&err);
+ pthread_mutex_unlock(&mu);
+ return -1;
+ }
+
+ dbus_connection_set_exit_on_disconnect(dbc, FALSE);
+
+ db = dbc;
+ pthread_mutex_unlock(&mu);
+ logt_print(LOG_DEBUG, "DBus Notifications Initialized
");
+ return 0;
+}
+#else
+{
+ errno = ENOSYS;
+ return -1;
+}
+#endif
+
+
+#ifdef DBUS
+static int
+_rgm_dbus_release(void)
+{
+ pthread_t t;
+
+ if (!db)
+ return 0;
+
+ /* tell thread to exit - not sure how to tell dbus
+ * to wake up, so just have it poll XXX */
+
+ /* if the thread left because the dbus connection died,
+ this block is avoided */
+ if (th) {
+ t = th;
+ th = 0;
+ pthread_join(t, NULL);
+ }
+
+ dbus_connection_close(db);
+ dbus_connection_unref(db);
+ db = NULL;
+
+ logt_print(LOG_DEBUG, "DBus Released
");
+ return 0;
+}
+#endif
+
+
+/* Clean shutdown (e.g. when exiting */
+int
+rgm_dbus_release(void)
+#ifdef DBUS
+{
+ int ret;
+
+ pthread_mutex_lock(&mu);
+ ret = _rgm_dbus_release();
+ pthread_mutex_unlock(&mu);
+ return ret;
+}
+#else
+{
+ return 0;
+}
+#endif
+
+
+#ifdef DBUS
+/* Auto-flush thread. Since sending only guarantees queueing,
+ * we need this thread to push things out over dbus in the
+ * background */
+static void *
+_dbus_auto_flush(void *arg)
+{
+ /* DBus connection functions are thread safe */
+ dbus_connection_ref(db);
+ while (dbus_connection_read_write(db, 500)) {
+ if (!th)
+ break;
+ }
+
+ dbus_connection_unref(db);
+ th = 0;
+ return NULL;
+}
+
+
+static int
+_rgm_dbus_notify(const char *svcname,
+ const char *svcstatus,
+ const char *svcflags,
+ const char *svcowner,
+ const char *svclast)
+{
+ DBusMessage *msg = NULL;
+ int ret = -1;
+
+ if (!db) {
+ goto out_free;
+ }
+
+ pthread_mutex_lock(&mu);
+
+ /* Check to ensure the connection is still valid. If it
+ * isn't, clean up and shut down the dbus connection.
+ *
+ * The main rgmanager thread will periodically try to
+ * reinitialize the dbus notification subsystem unless
+ * the administrator ran rgmanager with the -D command
+ * line option.
+ */
+ if (dbus_connection_get_is_connected(db) != TRUE) {
+ goto out_unlock;
+ }
+
+ if (!th) {
+ /* start auto-flush thread if needed */
+ pthread_create(&th, NULL, _dbus_auto_flush, NULL);
+ }
+
+ if (!(msg = dbus_message_new_signal(DBUS_RGM_PATH,
+ DBUS_RGM_IFACE,
+ "ServiceStateChange"))) {
+ goto out_unlock;
+ }
+
+ if (!dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &svcname,
+ DBUS_TYPE_STRING, &svcstatus,
+ DBUS_TYPE_STRING, &svcflags,
+ DBUS_TYPE_STRING, &svcowner,
+ DBUS_TYPE_STRING, &svclast,
+ DBUS_TYPE_INVALID)) {
+ goto out_unlock;
+ }
+
+ dbus_connection_send(db, msg, NULL);
+ ret = 0;
+
+out_unlock:
+ pthread_mutex_unlock(&mu);
+ if (msg)
+ dbus_message_unref(msg);
+out_free:
+ return ret;
+}
+
+
+/*
+ * view-formation callback function
+ */
+int32_t
+rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size)
+{
+ char flags[64];
+ rg_state_t *st;
+ cluster_member_list_t *m = NULL;
+ const char *owner;
+ const char *last;
+ int ret = 0;
+
+ if (!rgm_dbus_notify)
+ goto out_free;
+ if (!db)
+ goto out_free;
+ if (view == 1)
+ goto out_free;
+ if (size != (sizeof(*st)))
+ goto out_free;
+
+ st = (rg_state_t *)data;
+ swab_rg_state_t(st);
+
+ /* Don't send transitional states */
+ if (st->rs_state == RG_STATE_STARTING ||
+ st->rs_state == RG_STATE_STOPPING)
+ goto out_free;
+
+ m = member_list();
+ if (!m)
+ goto out_free;
+
+ owner = memb_id_to_name(m, st->rs_owner);
+ last = memb_id_to_name(m, st->rs_last_owner);
+
+ if (!owner)
+ owner = "(none)";
+ if (!last)
+ last = "(none)";
+
+ flags[0] = 0;
+ rg_flags_str(flags, sizeof(flags), st->rs_flags, (char *)" ");
+ if (flags[0] == 0)
+ snprintf(flags, sizeof(flags), "(none)");
+
+ ret = _rgm_dbus_notify(st->rs_name,
+ rg_state_str(st->rs_state),
+ (char *)flags, owner, last);
+
+ if (ret < 0) {
+ logt_print(LOG_ERR, "Error sending update for %s; "
+ "DBus notifications disabled
", key);
+ rgm_dbus_release();
+ }
+
+out_free:
+ if (m)
+ free_member_list(m);
+ free(data);
+ return 0;
+}
+#endif
--
1.7.2.3
 
Old 02-03-2011, 05:18 AM
"Fabio M. Di Nitto"
 
Default rgmanager: dbus notifications (Merged)

You might as well cherry pick the build system patch to enable/disable
dbus in the same patch set.

That way we have no delta and we can avoid possible merge conflicts later.

Fabio

On 02/03/2011 01:37 AM, Lon Hohberger wrote:
> Includes aforementioned makefile fix
>
> Everything in one patch for easy reading.
>
> Resolves: rhbz#657756
>
> Signed-off-by: Lon Hohberger <lhh@redhat.com>
> ---
> rgmanager/include/rg_dbus.h | 20 +++
> rgmanager/man/rgmanager.8 | 2 +
> rgmanager/src/daemons/Makefile | 7 +-
> rgmanager/src/daemons/main.c | 19 ++-
> rgmanager/src/daemons/update-dbus.c | 266 +++++++++++++++++++++++++++++++++++
> 5 files changed, 309 insertions(+), 5 deletions(-)
> create mode 100644 rgmanager/include/rg_dbus.h
> create mode 100644 rgmanager/src/daemons/update-dbus.c
>
> diff --git a/rgmanager/include/rg_dbus.h b/rgmanager/include/rg_dbus.h
> new file mode 100644
> index 0000000..3ef5ae1
> --- /dev/null
> +++ b/rgmanager/include/rg_dbus.h
> @@ -0,0 +1,20 @@
> +#ifndef _RGM_DBUS_H
> +#define _RGM_DBUS_H
> +
> +int rgm_dbus_init(void);
> +int rgm_dbus_release(void);
> +extern int rgm_dbus_notify;
> +
> +#ifdef DBUS
> +
> +#define RGM_DBUS_DEFAULT 1
> +#define RGM_DBUS_UPDATE (rgm_dbus_notify?rgm_dbus_update:0)
> +int32_t rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size);
> +
> +#else
> +
> +#define RGM_DBUS_DEFAULT 0
> +#define RGM_DBUS_UPDATE NULL
> +
> +#endif /* DBUS */
> +#endif
> diff --git a/rgmanager/man/rgmanager.8 b/rgmanager/man/rgmanager.8
> index 39b2195..2b018d2 100644
> --- a/rgmanager/man/rgmanager.8
> +++ b/rgmanager/man/rgmanager.8
> @@ -371,6 +371,8 @@ will leave the virtual machine running.
> Run in the foreground (do not fork).
> .IP -d
> Enable debug-level logging.
> +.IP -q
> +Disable DBus signals which are normally sent when services change state.
> .IP -w
> Disable internal process monitoring (for debugging).
> .IP -N
> diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
> index 94e0dbb..4dbbe5a 100644
> --- a/rgmanager/src/daemons/Makefile
> +++ b/rgmanager/src/daemons/Makefile
> @@ -29,6 +29,7 @@ OBJS1= fo_domain.o
> service_op.o
> slang_event.o
> event_config.o
> + update-dbus.o
> watchdog.o
>
> OBJS2= test-noccs.o
> @@ -40,12 +41,13 @@ OBJS2= test-noccs.o
> rg_locks-noccs.o
> event_config-noccs.o
>
> -CFLAGS += -DSHAREDIR="${sharedir}" -D_GNU_SOURCE
> +CFLAGS += -DDBUS -DSHAREDIR="${sharedir}" -D_GNU_SOURCE
> CFLAGS += -fPIC
> CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${dlmincdir} -I${logtincdir}
> CFLAGS += `xml2-config --cflags` -I${slangincdir}
> CFLAGS += -I$(S)/../../include
> CFLAGS += -I${incdir}
> +CFLAGS += `pkg-config --cflags dbus-1`
>
> NOCCS_CFLAGS += -DNO_CCS
>
> @@ -59,6 +61,7 @@ DLM_LDFLAGS += -L${dlmlibdir} -ldlm
> XML2_LDFLAGS += `xml2-config --libs`
> SLANG_LDFLAGS += -L${slanglibdir} -lslang
> EXTRA_LDFLAGS += -lpthread
> +DBUS_LDFLAGS += `pkg-config --libs dbus-1`
>
> LDDEPS += ../clulib/libclulib.a
>
> @@ -66,7 +69,7 @@ ${TARGET1}: ${OBJS1} ${LDDEPS}
> $(CC) -o $@ $^ $(CCS_LDFLAGS) $(CMAN_LDFLAGS)
> $(DLM_LDFLAGS) $(XML2_LDFLAGS)
> $(SLANG_LDFLAGS) $(EXTRA_LDFLAGS)
> - $(LOGSYS_LDFLAGS) $(LD_FLAGS)
> + $(LOGSYS_LDFLAGS) $(LD_FLAGS) $(DBUS_LDFLAGS)
>
> #
> # Our test program links against the local allocator so that
> diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
> index 4e34246..02cd2dc 100644
> --- a/rgmanager/src/daemons/main.c
> +++ b/rgmanager/src/daemons/main.c
> @@ -23,6 +23,7 @@
> #include <members.h>
> #include <daemon_init.h>
> #include <groups.h>
> +#include <rg_dbus.h>
>
> #ifdef WRAP_THREADS
> void dump_thread_states(FILE *);
> @@ -43,7 +44,6 @@ static uint8_t ALIGNED port = RG_PORT;
> static char *rgmanager_lsname = (char *)"rgmanager"; /* XXX default */
> static int status_poll_interval = DEFAULT_CHECK_INTERVAL;
>
> -
> static void
> segfault(int __attribute__ ((unused)) sig)
> {
> @@ -684,6 +684,8 @@ event_loop(msgctx_t *localctx, msgctx_t *clusterctx)
> dump_internal_state("/var/lib/cluster/rgmanager-dump");
> }
>
> + rgm_dbus_init();
> +
> while (running && (tv.tv_sec || tv.tv_usec)) {
> FD_ZERO(&rfds);
> max = -1;
> @@ -949,7 +951,7 @@ main(int argc, char **argv)
> pthread_t th;
> cman_handle_t clu = NULL;
>
> - while ((rv = getopt(argc, argv, "wfdN")) != EOF) {
> + while ((rv = getopt(argc, argv, "wfdNq")) != EOF) {
> switch (rv) {
> case 'w':
> wd = 0;
> @@ -963,6 +965,9 @@ main(int argc, char **argv)
> case 'f':
> foreground = 1;
> break;
> + case 'q':
> + rgm_dbus_notify = 0;
> + break;
> default:
> return 1;
> break;
> @@ -1032,6 +1037,12 @@ main(int argc, char **argv)
> configure_rgmanager(-1, debug, &cluster_timeout);
> logt_print(LOG_NOTICE, "Resource Group Manager Starting
");
>
> + if (rgm_dbus_notify && rgm_dbus_init() != 0) {
> + rgm_dbus_notify = 0;
> + logt_print(LOG_NOTICE, "Failed to initialize DBus; "
> + "notifications disabled
");
> + }
> +
> if (init_resource_groups(0, do_init) != 0) {
> logt_print(LOG_CRIT, "#8: Couldn't initialize services
");
> goto out_ls;
> @@ -1074,7 +1085,8 @@ main(int argc, char **argv)
>
> ds_key_init("rg_lockdown", 32, 10);
> #else
> - if (vf_init(me.cn_nodeid, port, NULL, NULL, cluster_timeout) != 0) {
> + if (vf_init(me.cn_nodeid, port, NULL, RGM_DBUS_UPDATE,
> + cluster_timeout) != 0) {
> logt_print(LOG_CRIT, "#11: Couldn't set up VF listen socket
");
> goto out_ls;
> }
> @@ -1106,6 +1118,7 @@ out_ls:
> clu_lock_finished(rgmanager_lsname);
>
> out:
> + rgm_dbus_release();
> logt_print(LOG_NOTICE, "Shutdown complete, exiting
");
> cman_finish(clu);
>
> diff --git a/rgmanager/src/daemons/update-dbus.c b/rgmanager/src/daemons/update-dbus.c
> new file mode 100644
> index 0000000..f465d1d
> --- /dev/null
> +++ b/rgmanager/src/daemons/update-dbus.c
> @@ -0,0 +1,266 @@
> +/* DBus notifications */
> +#include <stdint.h>
> +#include <rg_dbus.h>
> +#include <errno.h>
> +
> +#ifdef DBUS
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <resgroup.h>
> +#include <poll.h>
> +#include <dbus/dbus.h>
> +#include <liblogthread.h>
> +#include <members.h>
> +
> +
> +#define DBUS_RGM_NAME "com.redhat.cluster.rgmanager"
> +#define DBUS_RGM_IFACE "com.redhat.cluster.rgmanager"
> +#define DBUS_RGM_PATH "/com/redhat/cluster/rgmanager"
> +
> +static DBusConnection *db = NULL;
> +static pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
> +static pthread_t th = 0;
> +#endif
> +
> +/* Set this to the desired value prior to calling rgm_dbus_init() */
> +int rgm_dbus_notify = RGM_DBUS_DEFAULT;
> +
> +
> +int
> +rgm_dbus_init(void)
> +#ifdef DBUS
> +{
> + DBusConnection *dbc = NULL;
> + DBusError err;
> +
> + if (!rgm_dbus_notify)
> + return 0;
> +
> + pthread_mutex_lock(&mu);
> + if (db) {
> + pthread_mutex_unlock(&mu);
> + return 0;
> + }
> +
> + dbus_error_init(&err);
> +
> + dbc = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
> + if (!dbc) {
> + logt_print(LOG_DEBUG,
> + "DBus Failed to initialize: dbus_bus_get: %s
",
> + err.message);
> + dbus_error_free(&err);
> + pthread_mutex_unlock(&mu);
> + return -1;
> + }
> +
> + dbus_connection_set_exit_on_disconnect(dbc, FALSE);
> +
> + db = dbc;
> + pthread_mutex_unlock(&mu);
> + logt_print(LOG_DEBUG, "DBus Notifications Initialized
");
> + return 0;
> +}
> +#else
> +{
> + errno = ENOSYS;
> + return -1;
> +}
> +#endif
> +
> +
> +#ifdef DBUS
> +static int
> +_rgm_dbus_release(void)
> +{
> + pthread_t t;
> +
> + if (!db)
> + return 0;
> +
> + /* tell thread to exit - not sure how to tell dbus
> + * to wake up, so just have it poll XXX */
> +
> + /* if the thread left because the dbus connection died,
> + this block is avoided */
> + if (th) {
> + t = th;
> + th = 0;
> + pthread_join(t, NULL);
> + }
> +
> + dbus_connection_close(db);
> + dbus_connection_unref(db);
> + db = NULL;
> +
> + logt_print(LOG_DEBUG, "DBus Released
");
> + return 0;
> +}
> +#endif
> +
> +
> +/* Clean shutdown (e.g. when exiting */
> +int
> +rgm_dbus_release(void)
> +#ifdef DBUS
> +{
> + int ret;
> +
> + pthread_mutex_lock(&mu);
> + ret = _rgm_dbus_release();
> + pthread_mutex_unlock(&mu);
> + return ret;
> +}
> +#else
> +{
> + return 0;
> +}
> +#endif
> +
> +
> +#ifdef DBUS
> +/* Auto-flush thread. Since sending only guarantees queueing,
> + * we need this thread to push things out over dbus in the
> + * background */
> +static void *
> +_dbus_auto_flush(void *arg)
> +{
> + /* DBus connection functions are thread safe */
> + dbus_connection_ref(db);
> + while (dbus_connection_read_write(db, 500)) {
> + if (!th)
> + break;
> + }
> +
> + dbus_connection_unref(db);
> + th = 0;
> + return NULL;
> +}
> +
> +
> +static int
> +_rgm_dbus_notify(const char *svcname,
> + const char *svcstatus,
> + const char *svcflags,
> + const char *svcowner,
> + const char *svclast)
> +{
> + DBusMessage *msg = NULL;
> + int ret = -1;
> +
> + if (!db) {
> + goto out_free;
> + }
> +
> + pthread_mutex_lock(&mu);
> +
> + /* Check to ensure the connection is still valid. If it
> + * isn't, clean up and shut down the dbus connection.
> + *
> + * The main rgmanager thread will periodically try to
> + * reinitialize the dbus notification subsystem unless
> + * the administrator ran rgmanager with the -D command
> + * line option.
> + */
> + if (dbus_connection_get_is_connected(db) != TRUE) {
> + goto out_unlock;
> + }
> +
> + if (!th) {
> + /* start auto-flush thread if needed */
> + pthread_create(&th, NULL, _dbus_auto_flush, NULL);
> + }
> +
> + if (!(msg = dbus_message_new_signal(DBUS_RGM_PATH,
> + DBUS_RGM_IFACE,
> + "ServiceStateChange"))) {
> + goto out_unlock;
> + }
> +
> + if (!dbus_message_append_args(msg,
> + DBUS_TYPE_STRING, &svcname,
> + DBUS_TYPE_STRING, &svcstatus,
> + DBUS_TYPE_STRING, &svcflags,
> + DBUS_TYPE_STRING, &svcowner,
> + DBUS_TYPE_STRING, &svclast,
> + DBUS_TYPE_INVALID)) {
> + goto out_unlock;
> + }
> +
> + dbus_connection_send(db, msg, NULL);
> + ret = 0;
> +
> +out_unlock:
> + pthread_mutex_unlock(&mu);
> + if (msg)
> + dbus_message_unref(msg);
> +out_free:
> + return ret;
> +}
> +
> +
> +/*
> + * view-formation callback function
> + */
> +int32_t
> +rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size)
> +{
> + char flags[64];
> + rg_state_t *st;
> + cluster_member_list_t *m = NULL;
> + const char *owner;
> + const char *last;
> + int ret = 0;
> +
> + if (!rgm_dbus_notify)
> + goto out_free;
> + if (!db)
> + goto out_free;
> + if (view == 1)
> + goto out_free;
> + if (size != (sizeof(*st)))
> + goto out_free;
> +
> + st = (rg_state_t *)data;
> + swab_rg_state_t(st);
> +
> + /* Don't send transitional states */
> + if (st->rs_state == RG_STATE_STARTING ||
> + st->rs_state == RG_STATE_STOPPING)
> + goto out_free;
> +
> + m = member_list();
> + if (!m)
> + goto out_free;
> +
> + owner = memb_id_to_name(m, st->rs_owner);
> + last = memb_id_to_name(m, st->rs_last_owner);
> +
> + if (!owner)
> + owner = "(none)";
> + if (!last)
> + last = "(none)";
> +
> + flags[0] = 0;
> + rg_flags_str(flags, sizeof(flags), st->rs_flags, (char *)" ");
> + if (flags[0] == 0)
> + snprintf(flags, sizeof(flags), "(none)");
> +
> + ret = _rgm_dbus_notify(st->rs_name,
> + rg_state_str(st->rs_state),
> + (char *)flags, owner, last);
> +
> + if (ret < 0) {
> + logt_print(LOG_ERR, "Error sending update for %s; "
> + "DBus notifications disabled
", key);
> + rgm_dbus_release();
> + }
> +
> +out_free:
> + if (m)
> + free_member_list(m);
> + free(data);
> + return 0;
> +}
> +#endif
 

Thread Tools




All times are GMT. The time now is 06:37 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org