[Debian-ha-commits] [cluster-glue] 16/73: Imported Upstream version 1.0.7

Richard Winters devrik-guest at moszumanska.debian.org
Sat Apr 18 20:24:31 UTC 2015


This is an automated email from the git hooks/post-receive script.

devrik-guest pushed a commit to branch master
in repository cluster-glue.

commit 3a090d99b0b8e0f406e46626fa5918224e255455
Author: Richard B Winters <rik at mmogp.com>
Date:   Sat Apr 18 07:48:42 2015 -0400

    Imported Upstream version 1.0.7
---
 .hg_archival.txt                           |   2 +-
 .hgtags                                    |   1 +
 ChangeLog                                  |  26 ++
 cluster-glue-fedora.spec                   |   5 +-
 cluster-glue-suse.spec                     |   2 +-
 configure.ac                               |  14 +-
 doc/stonith/README.riloe                   |  14 ++
 include/clplumbing/cl_log.h                |  43 +---
 include/clplumbing/cl_random.h             |  30 ++-
 lib/clplumbing/cl_log.c                    | 391 +++++++++++++----------------
 lib/clplumbing/cl_random.c                 | 112 ++-------
 lib/plugins/stonith/apcmastersnmp.c        |   2 +-
 lib/plugins/stonith/external.c             |  15 +-
 lib/plugins/stonith/external/ibmrsa-telnet |   7 +-
 lib/plugins/stonith/external/rackpdu       |   1 -
 lib/plugins/stonith/rcd_serial.c           |   2 +-
 lib/stonith/Makefile.am                    |   4 +-
 lib/stonith/ha_log.sh                      |   2 +-
 lib/stonith/main.c                         |  93 ++++++-
 logd/ha_logd.c                             | 111 +++++---
 logd/logd.cf                               |  24 +-
 logd/logtest.c                             |   5 +-
 lrm/lrmd/lrmd.c                            |   7 +-
 23 files changed, 512 insertions(+), 401 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index 35b3691..76b6b91 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,2 +1,2 @@
 repo: e3ffdd7ae81c596b2be7e1e110d2c1255161340e
-node: e876b4cf30be589652d620b887077a9bd38f0540
+node: 5e06b2ddd24b37ad6c1c25d958d7a9dda7d02f93
diff --git a/.hgtags b/.hgtags
index 160b05e..baccb9f 100644
--- a/.hgtags
+++ b/.hgtags
@@ -57,3 +57,4 @@ f6c2cd2593f365f984ce051db61466738ac05dcd Beta-0.4.9f
 3229873980e1028bf05de81f5bafccb3a92b9aa4 glue-1.0.4
 3af80b93d9e5d5e441f3f4c3aad16775ea27d2d9 glue-1.0.5
 1c87a0c58c59fc384b93ec11476cefdbb6ddc1e1 glue-1.0.6
+61200fbe18358e420cdc2037d87e803e150c1eac glue-1.0.7-rc1
diff --git a/ChangeLog b/ChangeLog
index 9cb84c4..f6688c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+* Tue Nov 30 2010 Dejan Muhamedagic <dejan at suse.de>, Lars Ellenberg <lars.ellenberg at linbit.com>, and many others
+- stable release 1.0.7
+- clplumbing: ipc: adjust socket buffers size when adjusting ipc queue length
+- logd: add a SIGHUP signal handler to timely close/open log files
+- logd: use buffered io with fflush and fsync
+- logd: reopen logfiles on inode change (logrotate)
+- clplumbing: cl_log: keep logfiles open, but default to non-buffered io (lf#2470)
+- clplumbing: cl_log: add new optional common syslog message prefix
+- stonith: use ST_DEVICEID for the short description in meta-data
+- stonith: external: interpret properly exit codes from external stonith
+  plugins (bnc#630357)
+- stonith: external: avoid false out of memory error if a parameter isn't set (bnc#646205)
+- stonith: external: check if PATH already contains GLUE_SHARED_DIR
+  (memory leak, lf#2484)
+- stonith(8): reduce the number of stonith plugin invocations (bnc#630357)
+- stonith(8): use cl_log for logging if invoked by stonithd (pcmk 1.1)
+- stonith: external/sbd: make sbd use realtime priority for IO (works only with CFQ)
+- stonith: cyclades: add the serial_port parameter to the meta-data
+- stonith: external/riloe: add support for http proxies
+- stonith: external/ipmi: provide opt param "passwd_method" to hide
+  the ipmi password from config and logs
+- stonith: external/nut: support for the Network UPS Tools
+- stonith: external/rackpdu: remove displaced local command
+- stonith: rcd_serial: rename dtr|rts parameter to dtr_rts
+- configure: test for POSIX signals (fixes rcd_serial)
+
 * Fri Jul  9 2010 Dejan Muhamedagic <dejan at suse.de>
 - stable release 1.0.6
 - clplumbing: Add identity info of the user on the other side of socket
diff --git a/cluster-glue-fedora.spec b/cluster-glue-fedora.spec
index 1f16ce1..4ad2b71 100644
--- a/cluster-glue-fedora.spec
+++ b/cluster-glue-fedora.spec
@@ -15,13 +15,14 @@
 
 Name:		cluster-glue
 Summary:	Reusable cluster components
-Version:	1.0.6
+Version:	1.0.7
 Release:	1%{?dist}
 License:	GPLv2+ and LGPLv2+
 Url:		http://www.linux-ha.org/wiki/Cluster_Glue
 Group:		System Environment/Base
 Source0:	cluster-glue.tar.bz2
 Requires:	perl-TimeDate
+Requires:	cluster-glue-libs = %{version}-%{release}
 
 # Directives to allow upgrade from combined heartbeat packages in Fedora11
 Provides:       heartbeat-stonith = 3.0.0-1
@@ -159,7 +160,6 @@ standards, and an interface to common STONITH devices.
 %package -n cluster-glue-libs
 Summary:	Reusable cluster libraries
 Group:		Development/Libraries
-Requires:	%{name} = %{version}-%{release}
 Obsoletes:	libheartbeat2
 
 %description -n cluster-glue-libs
@@ -188,7 +188,6 @@ exit 0
 %package -n cluster-glue-libs-devel 
 Summary:	Headers and libraries for writing cluster managers
 Group:		Development/Libraries
-Requires:	%{name} = %{version}-%{release}
 Requires:	cluster-glue-libs = %{version}-%{release}
 Obsoletes:	libheartbeat-devel
 
diff --git a/cluster-glue-suse.spec b/cluster-glue-suse.spec
index 140494e..3aafd14 100644
--- a/cluster-glue-suse.spec
+++ b/cluster-glue-suse.spec
@@ -29,7 +29,7 @@
 
 Name:           cluster-glue
 Summary:        Reusable cluster components
-Version:        1.0.6
+Version:        1.0.7
 Release:        1%{?dist}
 License:        GPL v2 or later; LGPL v2.1 or later
 Url:            http://www.linux-ha.org/wiki/Cluster_Glue
diff --git a/configure.ac b/configure.ac
index 70bbecf..8ef20dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ dnl     checks for compiler characteristics
 dnl     checks for library functions
 dnl     checks for system services
 
-AC_INIT(cluster-glue, 1.0.6, linux-ha-dev at lists.linux-ha.org)
+AC_INIT(cluster-glue, 1.0.7, linux-ha-dev at lists.linux-ha.org)
 
 FEATURES=""
 HB_PKG=heartbeat
@@ -717,6 +717,18 @@ if test x"$ac_cv_HAVE_SYSLOG_FACILITYNAMES" = x"yes"; then
     AC_DEFINE(HAVE_SYSLOG_FACILITYNAMES,1,[ ])
 fi
 
+dnl Check for POSIX signals
+dnl
+AC_CACHE_CHECK([have POSIX signals],ac_cv_HAVE_POSIX_SIGNALS,[
+AC_TRY_COMPILE([
+#include <signal.h>
+],
+[ struct sigaction act, oact; sigaction(0, &act, &oact); return 0;],
+ac_cv_HAVE_POSIX_SIGNALS=yes,ac_cv_HAVE_POSIX_SIGNALS=no,ac_cv_HAVE_POSIX_SIGNALS=cross)])
+if test x"$ac_cv_HAVE_POSIX_SIGNALS" = x"yes"; then
+    AC_DEFINE(HAVE_POSIX_SIGNALS,1,[ ])
+fi
+
 dnl 'reboot()' system call: one argument (e.g. Linux) or two (e.g. Solaris)?
 dnl
 AC_CACHE_CHECK([number of arguments in reboot system call],
diff --git a/doc/stonith/README.riloe b/doc/stonith/README.riloe
index ccd365a..4befe95 100644
--- a/doc/stonith/README.riloe
+++ b/doc/stonith/README.riloe
@@ -1,3 +1,8 @@
+Note for iLO 3 users
+
+This plugin doesn't support the iLO version 3. Please use ipmilan
+or external/ipmi, iLO3 should support IPMI.
+
 Alain St-Denis wrote the riloe plugin. Here is short usage:
 
 primitive st0 stonith:external/riloe \
@@ -20,3 +25,12 @@ ilo_powerdown_method:
 	"power". The "button" method is easier on the host, but
 	requires ACPI.  "power" should be more reliable, but not to
 	be used excessively for testing.
+
+ilo_proxyhost (string): Proxy hostname
+	proxy hostname if required to access ILO board
+
+ilo_proxyport (string, [3128]): Proxy port
+	proxy port if required to access ILO board
+	parameter will be ignored if proxy hostname is not set
+
+
diff --git a/include/clplumbing/cl_log.h b/include/clplumbing/cl_log.h
index 39c1292..edaae93 100644
--- a/include/clplumbing/cl_log.h
+++ b/include/clplumbing/cl_log.h
@@ -39,16 +39,16 @@ void            cl_log(int priority, const char * fmt, ...) G_GNUC_PRINTF(2,3);
 void            cl_perror(const char * fmt, ...) G_GNUC_PRINTF(1,2);
 void		cl_log_enable_stderr(int truefalse);
 void		cl_log_enable_stdout(int truefalse);
-int		cl_set_logging_wqueue_maxlen(int);
 gboolean	cl_log_test_logd(void);
 void		cl_log_set_uselogd(int truefalse);
 void		cl_log_enable_syslog_filefmt(int truefalse);
+void		cl_log_use_buffered_io(int truefalse);
 gboolean	cl_log_get_uselogd(void);
 void		cl_log_set_facility(int facility);
 void		cl_log_set_entity(const char *	entity);
+void		cl_log_set_syslogprefix(const char *prefix);
 void		cl_log_set_logfile(const char *	path);
 void		cl_log_set_debugfile(const char * path);
-void		inherit_compress(void);
 void		cl_inherit_logging_environment(int maxqlen);
 int		cl_log_set_logd_channel_source( void (*create_callback)(struct IPC_CHANNEL* chan),
 						GDestroyNotify destroy_callback);
@@ -61,34 +61,17 @@ void		cl_glib_msg_handler(const gchar *log_domain
 ,		gpointer user_data);
 
 void		cl_flush_logs(void);
-void cl_log_args(int argc, char **argv);
-int cl_log_is_logd_fd(int fd);
+void		cl_log_args(int argc, char **argv);
+int		cl_log_is_logd_fd(int fd);
+const char *	prio2str(int priority);
 
-
-typedef struct CircularBuffer_s 
-{
-	const char*	name;
-	size_t		size;
-	gboolean	empty_after_dump;
-	GQueue*		queue;
-	
-} CircularBuffer_t;
-
-typedef struct CircularBufferEntry_s 
-{
-	int level;
-	char *buf;
-	
-} CircularBufferEntry_t;
-
-CircularBuffer_t *NewCircularBuffer(
-	const char *name, unsigned int size, gboolean empty_after_dump);
-void LogToCircularBuffer(
-	CircularBuffer_t *buffer, int level, const char *fmt, ...) G_GNUC_PRINTF(3,4);
-
-void EmptyCircularBuffer(CircularBuffer_t *buffer);
-
-/* the prototype is designed to be easy to give to G_main_add_SignalHandler() */
-gboolean DumpCircularBuffer(int nsig, gpointer buffer);
+/* cl_log_use_buffered_io and cl_log_do_fflush as optimization for logd,
+ * so it may buffer a few message lines, then fflush them out in one write.
+ * Set do_fsync != 0, if you even want it to fsync. */
+void            cl_log_do_fflush(int do_fsync);
+void            cl_log_use_buffered_io(int truefalse);
+/* We now keep the file handles open for a potentially very long time.
+ * Sometimes we may need to close them explicitly. */
+void            cl_log_close_log_files(void);
 
 #endif
diff --git a/include/clplumbing/cl_random.h b/include/clplumbing/cl_random.h
index a17f808..d1e37ce 100644
--- a/include/clplumbing/cl_random.h
+++ b/include/clplumbing/cl_random.h
@@ -19,10 +19,34 @@
  */
 
 #include <stdlib.h>
+
+/* Intended usage is srand(cl_randseed()).
+ * This returns on "as good as it gets" random number usually taken from
+ * /dev/urandom to have a nice seed for future random numbers generated by
+ * rand(). */
 unsigned int	cl_randseed(void);
-/* Is currently rand() based.
- * Does srand(cl_randseed()) once internally.
- * Assumes mainloop is setup. */
+
+/* get_next_random() currently rand() based.
+ *
+ * You probably want to use cl_rand_from_interval instead.
+ *
+ * You don't need to srand(), it will seed once with cl_randseed internally.
+ *
+ * It is called that way, because it was exposed in the header file for a long
+ * time, and used to be coded in an attempt to pregenerate a queue of random
+ * numbers from the mainloop, and it would shift the next random number from
+ * that queue and trigger generation of new random numbers "at idle time" to
+ * refill that queue.
+ * Only that functionality never actually worked, is not interessting anymore
+ * anyways (rand() is cheap enough), and is now ripped out.
+ *
+ * So it now does srand(cl_randseed()) once internally,
+ * and from there on is equivalent to calling rand() directly,
+ * and could be called cl_rand().
+ *
+ * If you want your own specific rand seed to re-generate a particular
+ * sequence, call it once, throw away the return code, then call
+ * srand(yourseed).  Or don't use it anywhere in your code. */
 int		get_next_random(void);
 
 /* generate some random number in the range [a;b];
diff --git a/lib/clplumbing/cl_log.c b/lib/clplumbing/cl_log.c
index 47e9080..a179e40 100644
--- a/lib/clplumbing/cl_log.c
+++ b/lib/clplumbing/cl_log.c
@@ -56,6 +56,7 @@
 #endif
 
 #define	DFLT_ENTITY	"cluster"
+#define	DFLT_PREFIX	""
 #define NULLTIME 	0
 #define QUEUE_SATURATION_FUZZ 10
 
@@ -69,17 +70,19 @@ static gboolean		syslogformatfile = TRUE;
 int LogToDaemon(int priority, const char * buf, int bstrlen, gboolean use_pri_str);
 
 static int LogToLoggingDaemon(int priority, const char * buf, int bstrlen, gboolean use_pri_str);
-IPC_Message* ChildLogIPCMessage(int priority, const char *buf, int bstrlen, 
+static IPC_Message* ChildLogIPCMessage(int priority, const char *buf, int bstrlen, 
 				gboolean use_priority_str, IPC_Channel* ch);
-void	FreeChildLogIPCMessage(IPC_Message* msg);
-gboolean send_dropped_message(gboolean use_pri_str, IPC_Channel *chan);
+static void	FreeChildLogIPCMessage(IPC_Message* msg);
+static gboolean send_dropped_message(gboolean use_pri_str, IPC_Channel *chan);
+static int cl_set_logging_wqueue_maxlen(int qlen);
 
-const char * prio2str(int priority);
 static int		use_logging_daemon =  FALSE;
 static int		conn_logd_time = 0;
 static char		cl_log_entity[MAXENTITY]= DFLT_ENTITY;
+static char		cl_log_syslogprefix[MAXENTITY] = DFLT_PREFIX;
 static char		common_log_entity[MAXENTITY]= DFLT_ENTITY;
 static int		cl_log_facility = LOG_USER;
+static int		use_buffered_io = 0;
 
 static void		cl_opensyslog(void);
 static int		syslog_enabled = 0;
@@ -155,11 +158,17 @@ cl_log_get_logdtime(void)
 
 void
 cl_log_set_logdtime(int logdtime)
-{	
-	conn_logd_time = logdtime;	
+{
+	conn_logd_time = logdtime;
 	return;
 }
 
+void
+cl_log_use_buffered_io(int truefalse)
+{
+	use_buffered_io = truefalse;
+	cl_log_close_log_files();
+}
 
 #define ENVPRE		"HA_"
 
@@ -173,7 +182,7 @@ cl_log_set_logdtime(int logdtime)
 #define TRADITIONAL_COMPRESSION "HA_traditional_compression"
 #define COMPRESSION	 "HA_compression"
 
-void
+static void
 inherit_compress(void)
 {
 	char* inherit_env = NULL;
@@ -270,7 +279,7 @@ add_logging_channel_mainloop(IPC_Channel* chan)
 	
 	if (chp == NULL){
 		cl_log(LOG_INFO, "adding logging channel to mainloop failed");
-	}	
+	}
 
 	logging_chan_in_main_loop = TRUE;
 	
@@ -292,14 +301,14 @@ create_logging_channel(void)
 {
 	GHashTable*	attrs;
 	char		path[] = IPC_PATH_ATTR;
-	char		sockpath[] = HA_LOGDAEMON_IPC;	
+	char		sockpath[] = HA_LOGDAEMON_IPC;
 	IPC_Channel*	chan;
 	static gboolean	complained_yet = FALSE;
 	
 	attrs = g_hash_table_new(g_str_hash, g_str_equal);
-	g_hash_table_insert(attrs, path, sockpath);	
+	g_hash_table_insert(attrs, path, sockpath);
 
-	chan =ipc_channel_constructor(IPC_ANYTYPE, attrs);       	
+	chan =ipc_channel_constructor(IPC_ANYTYPE, attrs);
 	
 	g_hash_table_destroy(attrs);	
 	
@@ -326,7 +335,7 @@ create_logging_channel(void)
 
 	if (create_logging_channel_callback){
 		create_logging_channel_callback(chan);
-	}		
+	}
 	
 	
 	return chan;
@@ -348,7 +357,7 @@ cl_log_test_logd(void)
 		logging_daemon_chan = chan = NULL;
 	}
 	
-	logging_daemon_chan = chan = create_logging_channel();			
+	logging_daemon_chan = chan = create_logging_channel();
 	
 	if (chan == NULL){
 		return FALSE;
@@ -358,7 +367,7 @@ cl_log_test_logd(void)
 		if (!logging_chan_in_main_loop){
 			chan->ops->destroy(chan);
 		}
-		logging_daemon_chan = chan = NULL;	
+		logging_daemon_chan = chan = NULL;
 		return FALSE;
 	}
 	
@@ -397,20 +406,36 @@ cl_log_set_entity(const char *	entity)
 }
 
 void
+cl_log_set_syslogprefix(const char *prefix)
+{
+	if (prefix == NULL) {
+		prefix = DFLT_PREFIX;
+	}
+	strncpy(cl_log_syslogprefix, prefix, MAXENTITY);
+	cl_log_syslogprefix[MAXENTITY-1] = '\0';
+	if (syslog_enabled) {
+		syslog_enabled = 0;
+		cl_opensyslog();
+	}
+}
+
+void
 cl_log_set_logfile(const char *	path)
 {
-    if(path != NULL && strcasecmp("/dev/null", path) == 0) {
-	path = NULL;
-    }
+	if(path != NULL && strcasecmp("/dev/null", path) == 0) {
+		path = NULL;
+	}
 	logfile_name = path;
+	cl_log_close_log_files();
 }
 void
 cl_log_set_debugfile(const char * path)
 {
-    if(path != NULL && strcasecmp("/dev/null", path) == 0) {
-	path = NULL;
-    }
-    debugfile_name = path;
+	if(path != NULL && strcasecmp("/dev/null", path) == 0) {
+		path = NULL;
+	}
+	debugfile_name = path;
+	cl_log_close_log_files();
 }
 
 
@@ -502,18 +527,98 @@ append_log(FILE * fp, const char * entity, int entity_pid
 	,	msg);
 }
 
-/*
- * Just open the given file name
+/* As performance optimization we try to keep the file descriptor
+ * open all the time, but as logrotation needs to work, the calling
+ * program actually needs a signal handler.
+ *
+ * To be able to keep files open even without signal handler,
+ * we remember the stat info, and close/reopen if the inode changed.
+ * We keep the number of stat() calls to one per file per minute.
+ * logrotate should be configured for delayed compression, if any.
  */
-static FILE * 
-open_log_file(const char * fname)
+
+struct log_file_context {
+	FILE *fp;
+	struct stat stat_buf;
+};
+
+static struct log_file_context log_file, debug_file;
+
+static void close_log_file(struct log_file_context *lfc)
 {
-	FILE * fp = fopen(fname ,"a");
-	if (!fp) {
-		syslog(LOG_ERR, "Failed to open log file %s: %s\n" , 
-		       fname, strerror(errno)); 
+	/* ignore errors, we cannot do anything about them anyways */
+	fflush(lfc->fp);
+	fsync(fileno(lfc->fp));
+	fclose(lfc->fp);
+	lfc->fp = NULL;
+}
+
+void cl_log_close_log_files(void)
+{
+	if (log_file.fp)
+		close_log_file(&log_file);
+	if (debug_file.fp)
+		close_log_file(&debug_file);
+}
+
+static void maybe_close_log_file(const char *fname, struct log_file_context *lfc)
+{
+	struct stat buf;
+	if (!lfc->fp)
+		return;
+	if (stat(fname, &buf) || buf.st_ino != lfc->stat_buf.st_ino) {
+		close_log_file(lfc);
+		cl_log(LOG_INFO, "log-rotate detected on logfile %s", fname);
 	}
-	return fp;
+}
+
+/* Default to unbuffered IO.  logd or others can use cl_log_use_buffered_io(1)
+ * to enable fully buffered mode, and then use fflush appropriately.
+ */
+static void open_log_file(const char *fname, struct log_file_context *lfc)
+{
+	lfc->fp = fopen(fname ,"a");
+	if (!lfc->fp) {
+		syslog(LOG_ERR, "Failed to open log file %s: %s\n" ,
+		       fname, strerror(errno));
+	} else {
+		setvbuf(lfc->fp, NULL,
+				use_buffered_io ? _IOFBF : _IONBF,
+				BUFSIZ);
+		fstat(fileno(lfc->fp), &lfc->stat_buf);
+	}
+}
+
+static void maybe_reopen_log_files(const char *log_fname, const char *debug_fname)
+{
+	static TIME_T last_stat_time;
+
+	if (log_file.fp || debug_file.fp) {
+		TIME_T now = time(NULL);
+		if (now - last_stat_time > 59) {
+			/* Don't use an exact minute, have it jitter around a
+			 * bit against cron or others.  Note that, if there
+			 * is no new log message, it can take much longer
+			 * than this to notice logrotation and actually close
+			 * our file handle on the possibly already rotated,
+			 * or even deleted.
+			 *
+			 * As long as at least one minute pases between
+			 * renaming the log file, and further processing,
+			 * no message will be lost, so this should do fine:
+			 * (mv ha-log ha-log.1; sleep 60; gzip ha-log.1)
+			 */
+			maybe_close_log_file(log_fname, &log_file);
+			maybe_close_log_file(debug_fname, &debug_file);
+			last_stat_time = now;
+		}
+	}
+
+	if (log_fname && !log_file.fp)
+		open_log_file(log_fname, &log_file);
+
+	if (debug_fname && !debug_file.fp)
+		open_log_file(debug_fname, &debug_file);
 }
 
 /*
@@ -530,65 +635,58 @@ cl_direct_log(int priority, const char* buf, gboolean use_priority_str,
 	const char *	pristr;
 	int	needprivs = !cl_have_full_privs();
 
-	if (entity == NULL){
-		entity =cl_log_entity;
-	}
-	
 	pristr = use_priority_str ? prio2str(priority) : NULL;
+	
+	if (!entity)
+		entity = *cl_log_entity	? cl_log_entity : DFLT_ENTITY;
 
 	if (needprivs) {
 		return_to_orig_privs();
 	}
 	
 	if (syslog_enabled) {
-		if (entity) {
-			strncpy(common_log_entity, entity, MAXENTITY);
-		} else {
-			strncpy(common_log_entity, DFLT_ENTITY,MAXENTITY);
-		}
+		snprintf(common_log_entity, MAXENTITY, "%s",
+			*cl_log_syslogprefix ? cl_log_syslogprefix : entity);
 
-		common_log_entity[MAXENTITY-1] = '\0';
-
-		if (pristr) {
-			syslog(priority, "[%d]: %s: %s%c",
-			       entity_pid, pristr,  buf, 0);
-		}else {
-			syslog(priority, "[%d]: %s%c", entity_pid, buf, 0);
-		}
+		/* The extra trailing '\0' is supposed to work around some
+		 * "known syslog bug that ends up concatinating entries".
+		 * Knowledge about which syslog package, version, platform and
+		 * what exactly the bug was has been lost, but leaving it in
+		 * won't do any harm either. */
+		syslog(priority, "%s[%d]: %s%s%s%c",
+			*cl_log_syslogprefix ? entity : "",
+			entity_pid,
+			pristr ?: "",  pristr ? ": " : "",
+			buf, 0);
 	}
 
-	if (debugfile_name != NULL) {
-		static FILE * debug_fp = NULL;
-		if (!debug_fp) {
-			/* As performance optimization we keep the file-handle
-			 * open all the time */
-			debug_fp = open_log_file(debugfile_name);
-		}
-		if (debug_fp)
-			append_log(debug_fp ,entity, entity_pid, ts, pristr, 
-				   buf);
-	}
+	maybe_reopen_log_files(logfile_name, debugfile_name);
 
-	if (priority != LOG_DEBUG && logfile_name != NULL) {
-		static FILE * log_fp = NULL;
-		if (!log_fp) {
-			/* As performance optimization we keep the file-handle
-			 * open all the time */
-			log_fp = open_log_file(logfile_name);
-		}
-		if (log_fp)
-			append_log(log_fp ,entity, entity_pid, ts, pristr, 
-				   buf);
-	}
+	if (debug_file.fp)
+		append_log(debug_file.fp, entity, entity_pid, ts, pristr, buf);
+
+	if (priority != LOG_DEBUG && log_file.fp)
+		append_log(log_file.fp, entity, entity_pid, ts, pristr, buf);
 
 	if (needprivs) {
 		return_to_dropped_privs();
 	}
-	
 	return;
 }
 
-
+void cl_log_do_fflush(int do_fsync)
+{
+	if (log_file.fp) {
+		fflush(log_file.fp);
+		if (do_fsync)
+			fsync(fileno(log_file.fp));
+	}
+	if (debug_file.fp) {
+		fflush(debug_file.fp);
+		if (do_fsync)
+			fsync(fileno(debug_file.fp));
+	}
+}
 
 /*
  * This function can cost us realtime unless use_logging_daemon
@@ -734,7 +832,7 @@ ha_timestamp(TIME_T t)
 }
 
 
-int
+static int
 cl_set_logging_wqueue_maxlen(int qlen)
 {
 	int sendrc;
@@ -805,6 +903,10 @@ LogToLoggingDaemon(int priority, const char * buf,
 	int			sendrc = IPC_FAIL;
 	int			intval = conn_logd_time;
 	
+	/* make sure we don't hold file descriptors open
+	 * we don't intend to use again */
+	cl_log_close_log_files();
+
 	if (chan == NULL) {
 		longclock_t	lnow = time_longclock();
 		
@@ -897,7 +999,7 @@ LogToLoggingDaemon(int priority, const char * buf,
 }
 
 
-gboolean
+static gboolean
 send_dropped_message(gboolean use_pri_str, IPC_Channel *chan)
 {
 	int sendrc;
@@ -925,26 +1027,7 @@ send_dropped_message(gboolean use_pri_str, IPC_Channel *chan)
 }
 
 
-
-
-static int childlog_ipcmsg_allocated = 0;
-static int childlog_ipcmsg_freed = 0;
-void	childlog_dump_ipcmsg_stats(void);
-void
-childlog_dump_ipcmsg_stats(void)
-{
-	
-	cl_log(LOG_INFO, "childlog ipcmsg allocated:%d, freed=%d, diff =%d",
-	       childlog_ipcmsg_allocated,
-	       childlog_ipcmsg_freed,
-	       childlog_ipcmsg_allocated - childlog_ipcmsg_freed);
-	
-	return;
-	
-	
-}
-
-IPC_Message*
+static IPC_Message*
 ChildLogIPCMessage(int priority, const char *buf, int bufstrlen, 
 		   gboolean use_prio_str, IPC_Channel* ch)
 {
@@ -1003,13 +1086,11 @@ ChildLogIPCMessage(int priority, const char *buf, int bufstrlen,
 	ret->msg_done = FreeChildLogIPCMessage;
 	ret->msg_ch = ch;
 
-	childlog_ipcmsg_allocated++;
-
 	return ret;
 }
 
 
-void
+static void
 FreeChildLogIPCMessage(IPC_Message* msg)
 {
 	if (msg == NULL) {
@@ -1020,9 +1101,7 @@ FreeChildLogIPCMessage(IPC_Message* msg)
 	
 	memset(msg, 0, sizeof (*msg));
 	free(msg);
-	
-	childlog_ipcmsg_freed ++;
-	
+		
 	return;
 
 }
@@ -1040,120 +1119,6 @@ cl_opensyslog(void)
 	openlog(common_log_entity, LOG_CONS, cl_log_facility);
 }
 
-/* What a horrible substitute for a low-overhead event log!! - FIXME!! */
-
-CircularBuffer_t *
-NewCircularBuffer(const char *name, uint size, gboolean empty_after_dump)
-{
-	CircularBuffer_t *buffer = malloc(sizeof(CircularBuffer_t));
-	if (!buffer) {
-		return buffer;
-	}
-	buffer->name = name;
-	buffer->size = size;
-	buffer->empty_after_dump = empty_after_dump;
-	buffer->queue = g_queue_new();
-
-#if 1
-	if(empty_after_dump == FALSE) {
-		cl_log(LOG_ERR, "This requires glib 2.4");
-		empty_after_dump = TRUE;
-	}
-#endif
-
-	return buffer;
-}
-
-void
-LogToCircularBuffer(CircularBuffer_t *buffer, int level, const char *fmt, ...)
-{
-	va_list ap;
-	char buf[MAXLINE];
-	int	nbytes;
-	CircularBufferEntry_t *entry = malloc(sizeof(CircularBufferEntry_t));
-	
-	if (!entry) {
-		return;
-	}
-	va_start(ap, fmt);
-	nbytes=vsnprintf(buf, MAXLINE, fmt, ap);
-	/*	nbytes=vasprintf(&buf, fmt, ap); */
-	va_end(ap);
-
-	entry->buf = buf;
-	entry->level = level;
-
-	g_queue_push_tail(buffer->queue, entry);
-
-	while(buffer->queue->length > buffer->size) {
-		entry = g_queue_pop_head(buffer->queue);
-		free(entry->buf);
-		free(entry);
-	}
-}
-
-void
-EmptyCircularBuffer(CircularBuffer_t *buffer) 
-{
-	CircularBufferEntry_t *entry = NULL;
-	while(buffer->queue->length > 0) {
-		entry = g_queue_pop_head(buffer->queue);
-		free(entry->buf);
-		free(entry);
-	}
-}
-
-gboolean
-DumpCircularBuffer(int nsig, gpointer user_data) 
-{
-	CircularBuffer_t *buffer = user_data;
-	CircularBufferEntry_t *entry = NULL;
-	
-	if(buffer == NULL) {
-		/* error */
-		cl_log(LOG_ERR, "No buffer supplied to dump.");
-		return FALSE;
-	}
-
-	if(logging_daemon_chan != NULL
-	   && logging_daemon_chan->send_queue->max_qlen < buffer->size) {
-		/* We have no hope of getting the whole buffer out via the
-		 *  logging daemon.  Use direct log instead so the messages
-		 *  come out in the right order.
-		 */ 
-		cl_log_depth++;
-	}
-	
-	cl_log(LOG_INFO, "Mark: Begin dump of buffer %s", buffer->name);
-	if(buffer->empty_after_dump) {
-		while(buffer->queue->length > 0) {
-			entry = g_queue_pop_head(buffer->queue);
-			cl_log(entry->level, "%s", entry->buf);
-			free(entry->buf);
-			free(entry);
-		}
-
-	} else {
-#if 1
-		cl_log(LOG_ERR, "This requires g_queue_peek_nth() from glib 2.4");
-#else
-		uint lpc = 0;
-		uint queue_len = buffer->queue->length;
-		for(lpc = 0; lpc < queue_len; lpc++) {
-			entry = g_queue_peek_nth(buffer->queue, lpc);
-			cl_log(entry->level, "%s", entry->buf);
-		}
-#endif
-	}
-	if(logging_daemon_chan != NULL
-	   && logging_daemon_chan->send_queue->max_qlen < buffer->size) {
-		/* Return is back to normal */
-		cl_log_depth--;
-	}
-	cl_log(LOG_INFO, "Mark: End dump of buffer %s", buffer->name);
-	return TRUE;
-}
-
 
 void
 cl_log_args(int argc, char **argv)
diff --git a/lib/clplumbing/cl_random.c b/lib/clplumbing/cl_random.c
index 0956575..4bafcfe 100644
--- a/lib/clplumbing/cl_random.c
+++ b/lib/clplumbing/cl_random.c
@@ -38,97 +38,6 @@
 #include <sys/time.h>
 #include <sys/times.h>
 
-#define	MAXRAND 100	/* How many do we try and keep around? */
-
-typedef int	rand_t;
-
-static int	first = 0;
-static int	last = 0;
-static rand_t	randomness[MAXRAND];
-
-/* How many random numbers do we currently have ? */
-#define NUMRNUMS	((first <= last) ? (last-first)	\
-			:	((MAXRAND-first)+(last+1)))
-
-#define IS_QUEUEFULL	(NUMRNUMS == MAXRAND)
-#define IS_QUEUEEMPTY	(first == last)
-
-
-
-static gboolean	randgen_scheduled = FALSE;
-static gboolean	inityet = FALSE;
-
-static void		cl_init_random(void);
-
-
-static rand_t
-gen_a_random(void)
-{
-	if (!inityet) {
-		cl_init_random();
-	}
-	return	rand();
-}
-
-
-static gboolean
-add_a_random(gpointer notused)
-{
-	if (IS_QUEUEFULL) {
-		return FALSE;
-	}
-	++last;
-	if (last >= MAXRAND) {
-		last = 0;
-	}
-	randomness[last] = gen_a_random();
-	return !IS_QUEUEFULL;
-}
-
-
-static void
-get_more_random(void)
-{
-	if (randgen_scheduled || IS_QUEUEFULL) {
-		return;
-	}
-	if (g_main_loop_is_running(NULL)) {
-		randgen_scheduled = TRUE;
-		Gmain_timeout_add_full(G_PRIORITY_LOW+1, 10, add_a_random, NULL, NULL);
-	}
-}
-
-int
-get_next_random(void)
-{
-	rand_t	ret;
-	if (IS_QUEUEEMPTY) {
-		ret = gen_a_random();
-	}else{
-		ret = randomness[first];
-		++first;
-		if (first >= MAXRAND) {
-			first = 0;
-		}
-	}
-	get_more_random();
-	return ret;
-}
-
-static void
-cl_init_random(void)
-{
-	if (inityet) {
-		return;
-	}
-	inityet=TRUE;
-	srand(cl_randseed());
-	first = 0;
-	last = 0;
-	get_more_random();
-}
-
-
 /* Used to provide seed to the random number generator */
 unsigned int
 cl_randseed(void)
@@ -232,3 +141,24 @@ cl_randseed(void)
 	return (unsigned int) horrid; /* pointer to local variable exposed */
 #endif
 }
+
+static gboolean        inityet = FALSE;
+
+static void
+cl_init_random(void)
+{
+	if (inityet)
+		return;
+
+	inityet=TRUE;
+	srand(cl_randseed());
+}
+
+int
+get_next_random(void)
+{
+	if (!inityet)
+		cl_init_random();
+
+	return	rand();
+}
diff --git a/lib/plugins/stonith/apcmastersnmp.c b/lib/plugins/stonith/apcmastersnmp.c
index 00d89c5..0ad473e 100644
--- a/lib/plugins/stonith/apcmastersnmp.c
+++ b/lib/plugins/stonith/apcmastersnmp.c
@@ -171,7 +171,7 @@ struct pluginDevice {
 };
 
 /* for checking hardware (issue a warning if mismatch) */
-static const char* APC_tested_ident[] = {"AP9606","AP7920","AP7921","AP_other_well_tested"};
+static const char* APC_tested_ident[] = {"AP9606","AP7920","AP7921","AP7900","AP_other_well_tested"};
 
 /* constant strings */
 static const char *pluginid = "APCMS-SNMP-Stonith";
diff --git a/lib/plugins/stonith/external.c b/lib/plugins/stonith/external.c
index 13557c2..683dd84 100644
--- a/lib/plugins/stonith/external.c
+++ b/lib/plugins/stonith/external.c
@@ -338,6 +338,9 @@ external_parse_config_info(struct pluginDevice* sd, StonithNVpair * info)
 	 * whitespace can be passed to the plugins... */
 	for (nv = info; nv->s_name; nv++) {
 		key = STRDUP(nv->s_name);
+		if (!nv->s_name || !nv->s_value) {
+			continue;
+		}
 		if (!key) {
 			goto err_mem;
 		}
@@ -750,11 +753,13 @@ external_run_cmd(struct pluginDevice *sd, const char *op, char **output)
 
 	/* external plugins need path to ha_log.sh */
 	path = getenv("PATH");
-	new_path_len = strlen(path)+strlen(GLUE_SHARED_DIR)+2;
-	new_path = (char *)g_malloc(new_path_len);
-	snprintf(new_path, new_path_len, "%s:%s", path, GLUE_SHARED_DIR);
-	setenv("PATH", new_path, 1);
-	g_free(new_path);
+	if (strncmp(GLUE_SHARED_DIR,path,strlen(GLUE_SHARED_DIR))) {
+		new_path_len = strlen(path)+strlen(GLUE_SHARED_DIR)+2;
+		new_path = (char *)g_malloc(new_path_len);
+		snprintf(new_path, new_path_len, "%s:%s", GLUE_SHARED_DIR, path);
+		setenv("PATH", new_path, 1);
+		g_free(new_path);
+	}
 
 	/* set the logtag appropriately */
 	logtag_len = strlen(PIL_PLUGIN_S)+strlen(sd->subplugin)+2;
diff --git a/lib/plugins/stonith/external/ibmrsa-telnet b/lib/plugins/stonith/external/ibmrsa-telnet
index e140da6..4d75d9a 100644
--- a/lib/plugins/stonith/external/ibmrsa-telnet
+++ b/lib/plugins/stonith/external/ibmrsa-telnet
@@ -76,8 +76,9 @@ class RSABoard(telnetlib.Telnet):
         return "%s,%03d" % (time.strftime("%Y-%m-%d %H:%M:%S",
                             time.localtime(ct)), msecs)
 
-    def write(self, buffer):
-        self._history.append(self._get_timestamp() + ': WRITE: ' + repr(buffer))
+    def write(self, buffer, nolog = False):
+        self._history.append(self._get_timestamp() + ': WRITE: ' +
+            (nolog and '******' or repr(buffer)))
         telnetlib.Telnet.write(self, buffer)
 
     def expect(self, what, timeout=20):
@@ -93,7 +94,7 @@ class RSABoard(telnetlib.Telnet):
         self.write(user)
         self.write('\r')
         line = self.expect(['\nPassword: ', '\npassword: '], self._timeout)
-        self.write(passwd)
+        self.write(passwd, nolog = True)
         self.write('\r')
         line = self.expect(['\nsystem>', '> '], self._timeout)
 
diff --git a/lib/plugins/stonith/external/rackpdu b/lib/plugins/stonith/external/rackpdu
index 03188b8..b53fd03 100644
--- a/lib/plugins/stonith/external/rackpdu
+++ b/lib/plugins/stonith/external/rackpdu
@@ -122,7 +122,6 @@ innode=$2
 case $incommand in
 gethosts)
 	if [ "$hostlist" = "AUTO" ]; then
-	    local snmp_result
 	    snmp_result=`snmpwalk -v1 -c $community $pduip $names_oid 2>&1`
         if [ $? -ne 0 ]; then
             ha_log.sh err "snmpwalk $community $pduip $names_oid failed. Result: $snmp_result"
diff --git a/lib/plugins/stonith/rcd_serial.c b/lib/plugins/stonith/rcd_serial.c
index 095bbe8..43426ce 100644
--- a/lib/plugins/stonith/rcd_serial.c
+++ b/lib/plugins/stonith/rcd_serial.c
@@ -43,7 +43,7 @@
 #define PIL_PLUGINLICENSE 	LICENSE_LGPL
 #define PIL_PLUGINLICENSEURL 	URL_LGPL
 
-#define	ST_DTRRTS		"dtr|rts"
+#define	ST_DTRRTS		"dtr_rts"
 #define	ST_MSDURATION		"msduration"
 #define MAX_RCD_SERIALLINE	512
 
diff --git a/lib/stonith/Makefile.am b/lib/stonith/Makefile.am
index 057086e..614ed16 100644
--- a/lib/stonith/Makefile.am
+++ b/lib/stonith/Makefile.am
@@ -33,7 +33,9 @@ endif
 
 stonith_SOURCES		= main.c
 
-stonith_LDADD		= libstonith.la $(top_builddir)/lib/pils/libpils.la $(GLIBLIB)
+stonith_LDADD		= libstonith.la $(top_builddir)/lib/pils/libpils.la $(GLIBLIB) \
+			$(top_builddir)/lib/clplumbing/libplumb.la	\
+			$(top_builddir)/lib/clplumbing/libplumbgpl.la
 stonith_LDFLAGS		=  @LIBADD_DL@ @LIBLTDL@ -export-dynamic @DLOPEN_FORCE_FLAGS@ @LIBADD_INTL@ 
 
 meatclient_SOURCES	= meatclient.c 
diff --git a/lib/stonith/ha_log.sh b/lib/stonith/ha_log.sh
index 0651712..3f52c2c 100755
--- a/lib/stonith/ha_log.sh
+++ b/lib/stonith/ha_log.sh
@@ -83,7 +83,7 @@ ha_log() {
 $msg
 EOF
 
-	if [ -n "$HA_LOGFACILITY" ]; then
+	if [ -n "$HA_LOGFACILITY" -a "$HA_LOGFACILITY" != none ]; then
 		logger -t "$HA_LOGTAG" -p $HA_LOGFACILITY.$loglevel "$msg"
 	fi	
 	dest=${HA_LOGFILE:-$HA_DEBUGLOG}
diff --git a/lib/stonith/main.c b/lib/stonith/main.c
index ec10039..0365009 100644
--- a/lib/stonith/main.c
+++ b/lib/stonith/main.c
@@ -28,6 +28,7 @@
 #include <syslog.h>
 #include <stonith/stonith.h>
 #include <pils/plugin.h>
+#include <clplumbing/cl_log.h>
 #include <glib.h>
 #include <libxml/entities.h>
 
@@ -39,6 +40,10 @@ extern int	optind, opterr, optopt;
 
 static int	debug = 0;
 
+#define LOG_TERMINAL 0
+#define LOG_CLLOG 1
+static int	log_destination = LOG_TERMINAL;
+
 static const char META_TEMPLATE[] =
 "<?xml version=\"1.0\"?>\n"
 "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
@@ -68,11 +73,26 @@ void print_stonith_meta(Stonith * stonith_obj, const char *rsc_type);
 void print_types(void);
 void print_confignames(Stonith *s);
 
+void log_buf(int severity, char *buf);
+void log_msg(int severity, const char * fmt, ...)G_GNUC_PRINTF(2,3);
+void trans_log(int priority, const char * fmt, ...)G_GNUC_PRINTF(2,3);
+
+static int pil_loglevel_to_syslog_severity[] = {
+	/* Indices: <none>=0, PIL_FATAL=1, PIL_CRIT=2, PIL_WARN=3,
+	   PIL_INFO=4, PIL_DEBUG=5 
+	*/
+	LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING, LOG_INFO, LOG_DEBUG
+	};
+
 /*
  * Note that we don't use the cl_log logging code because the STONITH
  * command is intended to be shipped without the clplumbing libraries.
  *
  *	:-(
+ *
+ * The stonith command has so far always been shipped along with
+ * the clplumbing library, so we'll use cl_log
+ * If that ever changes, we'll use something else
  */
 
 void
@@ -256,7 +276,7 @@ print_stonith_meta(Stonith * stonith_obj, const char *rsc_type)
 	}
 	xml_meta_longdesc = (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc);
 
-	meta_shortdesc = stonith_get_info(stonith_obj, ST_DEVICENAME);
+	meta_shortdesc = stonith_get_info(stonith_obj, ST_DEVICEID);
 	if (meta_shortdesc == NULL) {
 	    fprintf(stderr, "stonithRA plugin: no short description");
 	    meta_shortdesc = no_parameter_info;
@@ -285,7 +305,7 @@ print_types()
 
 	typelist = stonith_types();
 	if (typelist == NULL) {
-		syslog(LOG_ERR, "Could not list Stonith types.");
+		log_msg(LOG_ERR, "Could not list Stonith types.");
 	}else{
 		char **	this;
 
@@ -311,6 +331,45 @@ print_confignames(Stonith *s)
 	printf("\n");
 }
 
+void
+log_buf(int severity, char *buf)
+{
+	if (log_destination == LOG_TERMINAL) {
+		if (severity != LOG_DEBUG || debug) {
+			fprintf(stderr, "%s: %s\n", prio2str(severity),buf);
+		}
+	} else {
+		cl_log(severity, "%s", buf);
+	}
+}
+
+void
+log_msg(int severity, const char * fmt, ...)
+{
+	va_list         ap;
+	char            buf[MAXLINE];
+
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf)-1, fmt, ap);
+	va_end(ap);
+	log_buf(severity, buf);
+}
+
+void
+trans_log(int priority, const char * fmt, ...)
+{
+	int				severity;
+	va_list         ap;
+	char            buf[MAXLINE];
+
+	severity = pil_loglevel_to_syslog_severity[ priority % sizeof
+		(pil_loglevel_to_syslog_severity) ];
+	va_start(ap, fmt);
+	vsnprintf(buf, sizeof(buf)-1, fmt, ap);
+	va_end(ap);
+	log_buf(severity, buf);
+}
+
 int
 main(int argc, char** argv)
 {
@@ -429,6 +488,17 @@ main(int argc, char** argv)
 		}
 	}
 
+	/* if we're invoked by stonithd, log through cl_log */
+	if (!isatty(fileno(stdin))) {
+		log_destination = LOG_CLLOG;
+		cl_log_set_entity("stonith");
+		cl_log_enable_stderr(debug?TRUE:FALSE);
+		cl_log_set_facility(HA_LOG_FACILITY);
+
+		/* Use logd if it's enabled by heartbeat */
+		cl_inherit_logging_environment(0);
+	}
+
 	if (help && !errors) {
 		usage(cmdname, 0, SwitchType);
 	}
@@ -486,22 +556,19 @@ main(int argc, char** argv)
 		exit(0);
 	}
 
-#ifndef LOG_PERROR
-#	define LOG_PERROR	0
-#endif
-	openlog(cmdname, (LOG_CONS|(silent ? 0 : LOG_PERROR)), LOG_USER);
 	if (SwitchType == NULL) {
-		fprintf(stderr,	"Must specify device type (-t option)\n");
+		log_msg(LOG_ERR,"Must specify device type (-t option)");
 		usage(cmdname, 1, NULL);
 	}
 	s = stonith_new(SwitchType);
 	if (s == NULL) {
-		syslog(LOG_ERR, "Invalid device type: '%s'", SwitchType);
+		log_msg(LOG_ERR,"Invalid device type: '%s'", SwitchType);
 		exit(S_OOPS);
 	}
 	if (debug) {
 		stonith_set_debug(s, debug);
 	}
+	stonith_set_log(s, (PILLogFun)trans_log);
 
 	if (!listparanames && !metadata && optfile == NULL &&
 			parameters == NULL && !params_from_env && nvcount == 0) {
@@ -541,11 +608,11 @@ main(int argc, char** argv)
 	if (optfile) {
 		/* Configure the Stonith object from a file */
 		if ((rc=stonith_set_config_file(s, optfile)) != S_OK) {
-			syslog(LOG_ERR
+			log_msg(LOG_ERR
 			,	"Invalid config file for %s device."
 			,	SwitchType);
 #if 0
-			syslog(LOG_INFO, "Config file syntax: %s"
+			log_msg(LOG_INFO, "Config file syntax: %s"
 			,	s->s_ops->getinfo(s, ST_CONF_FILE_SYNTAX));
 #endif
 			stonith_delete(s); s=NULL;
@@ -618,10 +685,10 @@ main(int argc, char** argv)
 
 			if (!silent) {
 				if (rc == S_OK) {
-					syslog(LOG_ERR, "%s device OK.", SwitchType);
+					log_msg(LOG_INFO, "%s device OK.", SwitchType);
 				}else{
 					/* Uh-Oh */
-					syslog(LOG_ERR, "%s device not accessible."
+					log_msg(LOG_ERR, "%s device not accessible."
 					,	SwitchType);
 				}
 			}
@@ -632,7 +699,7 @@ main(int argc, char** argv)
 
 			hostlist = stonith_get_hostlist(s);
 			if (hostlist == NULL) {
-				syslog(LOG_ERR, "Could not list hosts for %s."
+				log_msg(LOG_ERR, "Could not list hosts for %s."
 				,	SwitchType);
 				rc = -1;
 			}else{
diff --git a/logd/ha_logd.c b/logd/ha_logd.c
index fb40c81..6ff3d64 100644
--- a/logd/ha_logd.c
+++ b/logd/ha_logd.c
@@ -87,18 +87,20 @@ static gboolean needs_shutdown = FALSE;
 static struct {
 	char		debugfile[MAXLINE];
 	char		logfile[MAXLINE];
-	char		entity[MAXLINE];
+	char		entity[MAXENTITY];
+	char		syslogprefix[MAXENTITY];
 	int		log_facility;
 	mode_t		logmode;
 	gboolean	syslogfmtmsgs;
 } logd_config =
 	{
-		"",
-		"",
-		"logd",
-		HA_LOG_FACILITY,
-		0644,
-		FALSE
+		.debugfile = "",
+		.logfile   = "",
+		.entity    = "logd",
+		.syslogprefix = "",
+		.log_facility = HA_LOG_FACILITY,
+		.logmode  = 0644,
+		.syslogfmtmsgs = FALSE
 	};
 
 static void	logd_log(const char * fmt, ...) G_GNUC_PRINTF(1,2);
@@ -106,6 +108,7 @@ static int	set_debugfile(const char* option);
 static int	set_logfile(const char* option);
 static int	set_facility(const char * value);
 static int	set_entity(const char * option);
+static int	set_syslogprefix(const char * option);
 static int	set_sendqlen(const char * option);
 static int	set_recvqlen(const char * option);
 static int	set_logmode(const char * option);
@@ -123,17 +126,13 @@ static struct directive {
 	{"logfile",	set_logfile},
 	{"logfacility",	set_facility},
 	{"entity",	set_entity},
+	{"syslogprefix",set_syslogprefix},
 	{"sendqlen",	set_sendqlen},
 	{"recvqlen",	set_recvqlen},
 	{"logmode",	set_logmode},
 	{"syslogmsgfmt",set_syslogfmtmsgs}
 };
 
-struct _syslog_code {
-        const char    *c_name;
-        int     c_val;
-};
-
 static void
 logd_log( const char * fmt, ...)
 {
@@ -199,8 +198,34 @@ set_entity(const char * option)
 		logd_config.entity[0] = EOS;
 		return FALSE;
 	}
-	cl_log(LOG_INFO, "setting entity to %s", option);
-	strncpy(logd_config.entity, option, MAXLINE);
+	strncpy(logd_config.entity, option, MAXENTITY);
+	logd_config.entity[MAXENTITY-1] = '\0';
+	if (strlen(option) >= MAXENTITY)
+		cl_log(LOG_WARNING, "setting entity to %s (truncated from %s)",
+			logd_config.entity, option);
+	else
+		cl_log(LOG_INFO, "setting entity to %s", logd_config.entity);
+	return TRUE;
+
+}
+
+static int
+set_syslogprefix(const char * option)
+{
+	if (!option){
+		logd_config.syslogprefix[0] = EOS;
+		return FALSE;
+	}
+	strncpy(logd_config.syslogprefix, option, MAXENTITY);
+	logd_config.syslogprefix[MAXENTITY-1] = '\0';
+	if (strlen(option) >= MAXENTITY)
+		cl_log(LOG_WARNING,
+			"setting syslogprefix to %s (truncated from %s)",
+			logd_config.syslogprefix, option);
+	else
+		cl_log(LOG_INFO,
+			"setting syslogprefix to %s",
+			logd_config.syslogprefix);
 	return TRUE;
 
 }
@@ -510,8 +535,12 @@ logd_make_daemon(gboolean daemonize)
 	
 	if (cl_lock_pidfile(LOGD_PIDFILE) < 0 ){
 		pid = cl_read_pidfile(LOGD_PIDFILE);
-		fprintf(stderr, "%s: already running [pid %ld].\n",
-			cmdname, pid);
+		if (pid > 0)
+			fprintf(stderr, "%s: already running [pid %ld].\n",
+				cmdname, pid);
+		else
+			fprintf(stderr, "%s: problem creating pid file %s\n",
+				cmdname, LOGD_PIDFILE);
 		exit(LSB_EXIT_OK);
 	}
 	
@@ -703,6 +732,21 @@ logd_term_action(int sig, gpointer userdata)
         return TRUE;
 }
 
+/*
+ * Handle SIGHUP to re-open log files
+ */
+static gboolean
+logd_hup_action(int sig, gpointer userdata)
+{
+	cl_log_close_log_files();
+	if (write_process_pid)
+		/* do we want to propagate the HUP,
+		 * or do we assume that it was a killall anyways? */
+		CL_KILL(write_process_pid, SIGHUP);
+	else
+		cl_log(LOG_INFO, "SIGHUP received, re-opened log files");
+	return TRUE;
+}
 
 static void
 read_msg_process(IPC_Channel* chan)
@@ -742,6 +786,8 @@ read_msg_process(IPC_Channel* chan)
 
 	G_main_add_IPC_Channel(G_PRIORITY_DEFAULT, chan, FALSE,NULL,NULL,NULL);
 	
+	G_main_add_SignalHandler(G_PRIORITY_DEFAULT, SIGHUP, 
+				 logd_hup_action, mainloop, NULL);
 	g_main_run(mainloop);
 	
 	return;
@@ -750,16 +796,13 @@ read_msg_process(IPC_Channel* chan)
 static gboolean
 direct_log(IPC_Channel* ch, gpointer user_data)
 {
-	
 	IPC_Message*		ipcmsg;
 	GMainLoop*		loop;
-	
+	int			pri = LOG_DEBUG + 1;
 
 	loop =(GMainLoop*)user_data;
 	
-
 	while(ch->ops->is_message_pending(ch)){
-		
 		if (ch->ch_status == IPC_DISCONNECT){
 			cl_log(LOG_ERR, "read channel is disconnected:"
 			       "something very wrong happened");
@@ -778,6 +821,8 @@ direct_log(IPC_Channel* ch, gpointer user_data)
 			char *msgtext;
 			
 			logmsghdr = (LogDaemonMsgHdr*) ipcmsg->msg_body;
+			/* this copy nonsense is here because apparently ia64
+			 * complained about "unaligned memory access. */
 #define	COPYFIELD(copy, msg, field) memcpy(((u_char*)&copy.field), ((u_char*)&msg->field), sizeof(copy.field))
 			COPYFIELD(copy, logmsghdr, use_pri_str);
 			COPYFIELD(copy, logmsghdr, entity);
@@ -791,7 +836,9 @@ direct_log(IPC_Channel* ch, gpointer user_data)
 			,	copy.use_pri_str
 			,	copy.entity, copy.entity_pid
 			,	copy.timestamp);
-		
+
+			if (copy.priority < pri)
+				pri = copy.priority;
 
 			(void)logd_log;
 /*
@@ -808,14 +855,17 @@ direct_log(IPC_Channel* ch, gpointer user_data)
 				ipcmsg->msg_done(ipcmsg);
 			}
 		}
-		
 	}
+	/* current message backlog processed,
+	 * about to return to mainloop,
+	 * fflush and potentially fsync stuff */
+	cl_log_do_fflush(pri <= LOG_ERR);
+
 	if(needs_shutdown) {
 		cl_log(LOG_INFO, "Exiting write process");
 		g_main_quit(loop);
 		return FALSE;
 	}
-	
 	return TRUE;
 }
 
@@ -851,6 +901,9 @@ write_msg_process(IPC_Channel* readchan)
 
 	G_main_add_SignalHandler(G_PRIORITY_HIGH, SIGTERM, 
 				 logd_term_write_action, mainloop, NULL);
+				 
+	G_main_add_SignalHandler(G_PRIORITY_DEFAULT, SIGHUP, 
+				 logd_hup_action, mainloop, NULL);
 	
 	g_main_run(mainloop);
 	
@@ -975,10 +1028,10 @@ main(int argc, char** argv, char** envp)
 	if (strlen(logd_config.logfile) > 0) {
 		cl_log_set_logfile(logd_config.logfile);
 	}
+	cl_log_set_syslogprefix(logd_config.syslogprefix);
 	cl_log_set_entity(logd_config.entity);
 	cl_log_set_facility(logd_config.log_facility);
 	
-	
 	cl_log(LOG_INFO, "logd started with %s.",
 	       cfgfile ? cfgfile : "default configuration");
 
@@ -1002,25 +1055,25 @@ main(int argc, char** argv, char** envp)
         }
 
 	switch(pid = fork()){
-		
 	case -1:	
 		cl_perror("Can't fork child process!");
 		return -1;
 	case 0:
 		/*child*/
+		cl_log_use_buffered_io(1);
 		set_proc_title("ha_logd: write process");
 		write_msg_process(chanspair[WRITE_PROC_CHAN]);		
 		break;
 	default:
-		/*parent*/		
+		/*parent*/
 		set_proc_title("ha_logd: read process");
 		write_process_pid = pid;
-		
+		/* we don't expect to log anything in the parent. */
+		cl_log_close_log_files();
+
 		read_msg_process(chanspair[READ_PROC_CHAN]);
 		break;
 	}
-	
-	
 	return 0;
 }
 
diff --git a/logd/logd.cf b/logd/logd.cf
index 34ab807..cd8ccc3 100644
--- a/logd/logd.cf
+++ b/logd/logd.cf
@@ -10,17 +10,39 @@
 
 #
 #
+#	Octal file permission to create the log files with
+#	Default: 0644
+#logmode	0640
+
+
+#
+#
 #	Facility to use for syslog()/logger 
+#   (set to 'none' to disable syslog logging)
 #	Default: daemon
 #logfacility	daemon
 
 
 #	Entity to be shown at beginning of a message
-# 	for logging daemon
+#	generated by the logging daemon itself
 # 	Default: "logd"
 #entity logd
 
 
+#	Entity to be shown at beginning of _every_ message
+#	passed to syslog (not to log files).
+#
+#	Intended for easier filtering, or safe blacklisting.
+#	You can filter on logfacility and this prefix.
+#
+#	Message format changes like this:
+#	-Nov 18 11:30:31 soda logtest: [21366]: info: total message dropped: 0
+#	+Nov 18 11:30:31 soda common-prefix: logtest[21366]: info: total message dropped: 0
+#
+#	Default: none (disabled)
+#syslogprefix linux-ha
+
+
 #	Do we register to apphbd
 #	Default: no
 #useapphbd no
diff --git a/logd/logtest.c b/logd/logtest.c
index 93af0b8..11e4014 100644
--- a/logd/logtest.c
+++ b/logd/logtest.c
@@ -41,6 +41,7 @@
 int LogToDaemon(int priority, const char * buf, int bstrlen, gboolean use_pri_str);
 extern IPC_Channel * get_log_chan(void);
 
+static GMainLoop* loop;
 
 static gboolean
 send_log_msg(gpointer data)
@@ -55,11 +56,13 @@ send_log_msg(gpointer data)
 	
 	if (chan == NULL){
 		cl_log(LOG_ERR, "logging channel is NULL");
+		g_main_quit(loop);
 		return FALSE;
 
 	}
 	if (count >= maxcount){
 		cl_log(LOG_INFO, "total message dropped: %d", dropmsg);
+		g_main_quit(loop);
 		return FALSE;
 	}
 	
@@ -97,7 +100,6 @@ main(int argc, char** argv)
 {
 
 	long maxcount;
-	GMainLoop* loop;
 	
 	if (argc < 2){
 		usage(argv[0]);
@@ -106,6 +108,7 @@ main(int argc, char** argv)
 	
 	maxcount = atoi(argv[1]);
 	
+	cl_log_set_entity("logtest");
 	cl_log_set_facility(HA_LOG_FACILITY);
 	cl_log_set_uselogd(TRUE);
 	
diff --git a/lrm/lrmd/lrmd.c b/lrm/lrmd/lrmd.c
index fa819af..4c7295c 100644
--- a/lrm/lrmd/lrmd.c
+++ b/lrm/lrmd/lrmd.c
@@ -1407,6 +1407,7 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 	struct msg_map *msgmap_p, in_type;
 	lrmd_client_t* client = NULL;
 	struct ha_msg* msg = NULL;
+	char *msg_s;
 
 	client = (lrmd_client_t*)user_data;
 
@@ -1445,7 +1446,11 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 		LOG_FAILED_TO_GET_FIELD(F_LRM_TYPE);
 		return TRUE;
 	}
-	lrmd_debug2(LOG_DEBUG,"dumping request: %s",msg2string(msg));
+	msg_s = msg2string(msg);
+	if( msg_s ) {
+		lrmd_debug2(LOG_DEBUG,"dumping request: %s",msg_s);
+		free(msg_s);
+	}
 
 	if (!(msgmap_p = bsearch(&in_type, msg_maps,
 			MSG_NR, sizeof(struct msg_map), msg_type_cmp)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/cluster-glue.git



More information about the Debian-HA-Commits mailing list