rgmanager: dbus notifications (Merged)
PATCH 1/1 rgmanager: dbus notifications (Merged)
Includes aforementioned makefile fix
Everything in one patch for easy reading.
Resolves: rhbz#657756
Signed-off-by Lon Hohberger <[email protected]>
--- 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
rgmanager/include/rg_dbus.h new file +20 -0
@@ -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
rgmanager/man/rgmanager.8 +2 -0
@@ -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
rgmanager/src/daemons/Makefile +5 -2
@@ -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
rgmanager/src/daemons/main.c +16 -3
@@ -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\n" ); +if (rgm_dbus_notify &&rgm_dbus_init () !=0 ) { + rgm_dbus_notify =0 ; +logt_print (LOG_NOTICE ,"Failed to initialize DBus; " +"notifications disabled\n" ); + } +if (init_resource_groups (0 , do_init) !=0 ) {logt_print (LOG_CRIT ,"#8: Couldn't initialize services\n" ); 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\n" ); 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\n" );cman_finish (clu);
rgmanager/src/daemons/update-dbus.c new file +266 -0
266 lines not on this page · raw message
Signature · 1 line
1.7.2.3
PATCH 1/1 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
Quoted 451 lines · Lon Hohberger
Includes aforementioned makefile fix
Everything in one patch for easy reading.
Resolves: rhbz#657756
Signed-off-by Lon Hohberger <[email protected]>--- 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.crgmanager/include/rg_dbus.h new file +20
-0@@ -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 rgmanager/man/rgmanager.8 +2
-0@@ -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 \-Nrgmanager/src/daemons/Makefile +5
-2@@ -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 thatrgmanager/src/daemons/main.c +16
-3@@ -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\n" ); +if (rgm_dbus_notify &&rgm_dbus_init () !=0 ) { + rgm_dbus_notify =0 ; +logt_print (LOG_NOTICE ,"Failed to initialize DBus; " +"notifications disabled\n" ); + } +if (init_resource_groups (0 , do_init) !=0 ) {logt_print (LOG_CRIT ,"#8: Couldn't initialize services\n" ); 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\n" ); 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\n" );cman_finish (clu);rgmanager/src/daemons/update-dbus.c new file +266
-0@@ -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\n" , + 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\n" ); +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\n" ); +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\n" , key); +rgm_dbus_release (); + } + +out_free: +if (m) +free_member_list (m); +free (data); +return 0 ; +} +#endif