[Debian-ha-commits] [cluster-glue] 09/13: Imported Upstream version 1.0.9+hg2665

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


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

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

commit dbdcbb1ce5cdd250767abf1576bce35826fa1f49
Author: Richard B Winters <rik at mmogp.com>
Date:   Sat Apr 18 16:07:36 2015 -0400

    Imported Upstream version 1.0.9+hg2665
---
 .hg_archival.txt                     |   2 +-
 .hgtags                              |   1 +
 ChangeLog                            |   7 +
 cluster-glue-fedora.spec             |   2 +-
 cluster-glue-suse.spec               |   2 +-
 configure.ac                         |   2 +-
 doc/hb_report.8.txt                  |  36 ++---
 hb_report/hb_report.in               | 262 ++++++++++++++---------------------
 hb_report/utillib.sh                 |  13 +-
 include/clplumbing/loggingdaemon.h   |   2 +-
 lib/plugins/lrm/raexecupstart.c      |   2 +-
 lib/plugins/lrm/upstart-dbus.c       |  11 +-
 lib/plugins/lrm/upstart-dbus.h       |   2 +-
 lib/plugins/stonith/external/hetzner |  11 +-
 lib/plugins/stonith/external/ipmi    |  27 +++-
 lib/plugins/stonith/external/libvirt |   2 +-
 lib/plugins/stonith/external/ssh.in  |   2 +-
 lib/plugins/stonith/external/xen0    |   2 +-
 lib/plugins/stonith/ssh.c            |   2 +-
 lib/stonith/main.c                   |   6 +-
 lib/stonith/stonith.c                |   4 +-
 logd/logd.in                         |   2 +-
 lrm/lrmd/lrmd.c                      | 107 +++++++-------
 lrm/lrmd/lrmd.h                      |   9 ++
 lrm/test/README.regression           |   3 +
 lrm/test/evaltest.sh                 |   4 +
 lrm/test/regression.sh.in            |   2 +-
 lrm/test/testcases/BSC               |   1 +
 lrm/test/testcases/Makefile.am       |   3 +-
 lrm/test/testcases/basicset          |   1 +
 lrm/test/testcases/metadata          |  12 +-
 lrm/test/testcases/metadata.exp      |   7 -
 lrm/test/testcases/rscexec           |   1 +
 lrm/test/testcases/rscexec.exp       |  54 --------
 lrm/test/testcases/rscmgmt.exp       |   8 +-
 lrm/test/testcases/stonith           |   2 +
 lrm/test/testcases/stonith.exp       |   2 +
 37 files changed, 292 insertions(+), 326 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index 73caea4..0ed25bf 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,2 +1,2 @@
 repo: e3ffdd7ae81c596b2be7e1e110d2c1255161340e
-node: 5ea7e344a63312105ee78e54624d6a024ff82633
+node: bce0f5e5e6abee3655eec494e63d679f24203c51
diff --git a/.hgtags b/.hgtags
index fedd4ac..11b8031 100644
--- a/.hgtags
+++ b/.hgtags
@@ -61,3 +61,4 @@ f6c2cd2593f365f984ce051db61466738ac05dcd Beta-0.4.9f
 5e06b2ddd24b37ad6c1c25d958d7a9dda7d02f93 glue-1.0.7
 5740338816e1ff07d0e37f36214f442e183984d7 glue-1.0.8-rc1
 c69dc6ace936f501776df92dab3d611c2405f69e glue-1.0.8
+0a08a469fdc8a0db1875369497bc83c0523ceb21 glue-1.0.9
diff --git a/ChangeLog b/ChangeLog
index 855adc7..f7b60b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+* Mon Nov 28 2011 Dejan Muhamedagic <dejan at suse.de>, Lars Ellenberg <lars.ellenberg at linbit.com>, and many others
+- stable release 1.0.9
+- stonith: external/ipmi: add missing double quote
+- stonith: external/ipmi: add the priv parameter (ipmitool -L)
+- LRM: lrmd: set op status to cancelled for running monitor operations
+- ha_log: increase MAXENTITY size to accommodate long stonith strings
+- hb_report: improve destination directory handling (bnc#727295)
 * Tue Oct 18 2011 Dejan Muhamedagic <dejan at suse.de>, Lars Ellenberg <lars.ellenberg at linbit.com>, and many others
 - stable release 1.0.8
 - cl_log: log spamming control
diff --git a/cluster-glue-fedora.spec b/cluster-glue-fedora.spec
index 2c53cfc..42a25a5 100644
--- a/cluster-glue-fedora.spec
+++ b/cluster-glue-fedora.spec
@@ -15,7 +15,7 @@
 
 Name:		cluster-glue
 Summary:	Reusable cluster components
-Version:	1.0.8
+Version:	1.0.9
 Release:	1%{?dist}
 License:	GPLv2+ and LGPLv2+
 Url:		http://www.linux-ha.org/wiki/Cluster_Glue
diff --git a/cluster-glue-suse.spec b/cluster-glue-suse.spec
index 1a9b25d..bb81acd 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.8
+Version:        1.0.9
 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 2d143d4..6cf7a58 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.8, linux-ha-dev at lists.linux-ha.org)
+AC_INIT(cluster-glue, 1.0.9, linux-ha-dev at lists.linux-ha.org)
 
 FEATURES=""
 HB_PKG=heartbeat
diff --git a/doc/hb_report.8.txt b/doc/hb_report.8.txt
index 232851a..eff037b 100644
--- a/doc/hb_report.8.txt
+++ b/doc/hb_report.8.txt
@@ -27,12 +27,10 @@ Pacemaker (CRM) over the given period of time.
 OPTIONS
 -------
 dest::
-	The destination directory. Must be an absolute path. The
-	resulting tarball is placed in the parent directory and
-	contains the last directory element of this path. Typically
-	something like /tmp/standby-failed. If left out, the tarball
-	is created in your home directory named "hb_report-current_date",
-	for instance hb_report-Wed-03-Mar-2010.
+	The report name. It can also contain a path where to put the
+	report tarball. If left out, the tarball is created in the
+	current directory named "hb_report-current_date", for instance
+	hb_report-Wed-03-Mar-2010.
 
 *-d*::
 	Don't create the compressed tar, but leave the result in a
@@ -96,8 +94,8 @@ dest::
 	needed. Use if ssh(1) does not work to other nodes.
 
 *-Z*::
-	If destination directories exist, remove them instead of exiting
-	(this is default for CTS).
+	If the destination directory exist, remove it instead of
+	exiting (this is default for CTS).
 
 *-V*::
 	Print the version including the last repository changeset.
@@ -125,10 +123,10 @@ EXAMPLES
 Last night during the backup there were several warnings
 encountered (logserver is the log host):
 
-	logserver# hb_report -f 3:00 -t 4:00 -n "node1 node2" /tmp/report
+	logserver# hb_report -f 3:00 -t 4:00 -n "node1 node2" report
 
 collects everything from all nodes from 3am to 4am last night.
-The files are compressed to a tarball /tmp/report.tar.bz2.
+The files are compressed to a tarball report.tar.bz2.
 
 Just found a problem during testing:
 
@@ -138,15 +136,15 @@ Just found a problem during testing:
 	node1# /etc/init.d/heartbeat start
 	node1# nasty-command-that-breaks-things
 	node1# sleep 120 #wait for the cluster to settle
-	node1# hb_report -f 18:51 /tmp/hb1
+	node1# hb_report -f 18:51 hb1
 
-	# if hb_report can't figure out that this is openais
-	node1# hb_report -f 18:51 -A /tmp/hb1
+	# if hb_report can't figure out that this is corosync
+	node1# hb_report -f 18:51 -A hb1
 
 	# if hb_report can't figure out the cluster members
-	node1# hb_report -f 18:51 -n "node1 node2" /tmp/hb1
+	node1# hb_report -f 18:51 -n "node1 node2" hb1
 
-The files are compressed to a tarball /tmp/hb1.tar.bz2.
+The files are compressed to a tarball hb1.tar.bz2.
 
 INTERPRETING RESULTS
 --------------------
@@ -186,8 +184,10 @@ on all nodes will also be at the top, with per-node links created
 
 The cluster log files are named ha-log.txt regardless of the
 actual log file name on the system. If it is found on the
-loghost, then it is placed in the top directory. Files named
-messages are excerpts of /var/log/messages from nodes.
+loghost, then it is placed in the top directory. If not, the top
+directory ha-log.txt contains all nodes logs merged and sorted by
+time. Files named messages are excerpts of /var/log/messages from
+nodes.
 
 Most files are copied verbatim or they contain output of a
 command. For instance, cib.xml is a copy of the CIB found in
@@ -385,7 +385,7 @@ The second phase is the most involved. During this phase all
 local information is collected, which includes:
 
 - logs (both current and archived if the start time is far in the past)
-- various configuration files (openais, heartbeat, logd)
+- various configuration files (corosync, heartbeat, logd)
 - the CIB (both as xml and as represented by the crm shell)
 - pengine inputs (if this node was the DC at any point in
   time over the given period)
diff --git a/hb_report/hb_report.in b/hb_report/hb_report.in
index 7cdb28c..32947d6 100755
--- a/hb_report/hb_report.in
+++ b/hb_report/hb_report.in
@@ -36,7 +36,7 @@ export DEFAULT_HA_LOGFACILITY
 LOGD_CF=`findlogdcf @sysconfdir@ $HA_DIR`
 export LOGD_CF
 
-: ${SSH_OPTS="-T"}
+: ${SSH_OPTS="-T -o StrictHostKeyChecking=no"}
 LOG_PATTERNS="CRIT: ERROR:"
 # PEINPUTS_PATT="peng.*PEngine Input stored"
 
@@ -65,7 +65,7 @@ fi
 usage() {
 	cat<<EOF
 usage: hb_report -f {time|"cts:"testnum} [-t time] [-u user] [-l file]
-       [-n nodes] [-E files] [-p patt] [-L patt] [-e prog] [-MSDCZAVsvhd] [dest]
+       [-n nodes] [-E files] [-p patt] [-L patt] [-e prog] [-MSDZAVsvhd] [dest]
 
 	-f time: time to start from or a CTS test number
 	-t time: time to finish at (dflt: now)
@@ -86,7 +86,6 @@ usage: hb_report -f {time|"cts:"testnum} [-t time] [-u user] [-l file]
 	-e prog: your favourite editor
 	-M     : don't collect extra logs (/var/log/messages)
 	-D     : don't invoke editor to write description
-	-C     : remove the destination directory
 	-Z     : if destination directories exist, remove them instead of exiting
 	         (this is default for CTS)
 	-A     : this is an OpenAIS cluster
@@ -94,31 +93,30 @@ usage: hb_report -f {time|"cts:"testnum} [-t time] [-u user] [-l file]
 	         collectors on other nodes
 	-v     : increase verbosity
 	-V     : print version
-	dest   : destination directory
+	dest   : report name (may include path where to store the report)
 EOF
 
 [ "$1" != short ] &&
 	cat<<EOF
 
-	. the multifile output is first stored in a directory {dest}
-	  of which a tarball {dest}.tar.bz2 (or .gz) is created
+	. the multifile output is stored in a tarball {dest}.tar.bz2
 	. the time specification is as in either Date::Parse or
 	  Date::Manip, whatever you have installed; Date::Parse is
 	  preferred
 	. we try to figure where is the logfile; if we can't, please
-	  clue us in
+	  clue us in ('-l')
 	. we collect only one logfile and /var/log/messages; if you
 	  have more than one logfile, then use '-E' option to supply
 	  as many as you want ('-M' empties the list)
 
 	Examples
 
-	  hb_report -f 2pm /tmp/report_1
-	  hb_report -f "2007/9/5 12:30" -t "2007/9/5 14:00" /tmp/report_2
-	  hb_report -f 1:00 -t 3:00 -l /var/log/cluster/ha-debug /tmp/report_3
-	  hb_report -f "09sep07 2:00" -u hbadmin /tmp/report_4
-	  hb_report -f 18:00 -p "usern.*" -p "admin.*" /tmp/report_5
-	  hb_report -f cts:133 /tmp/ctstest_133
+	  hb_report -f 2pm report_1
+	  hb_report -f "2007/9/5 12:30" -t "2007/9/5 14:00" report_2
+	  hb_report -f 1:00 -t 3:00 -l /var/log/cluster/ha-debug report_3
+	  hb_report -f "09sep07 2:00" -u hbadmin report_4
+	  hb_report -f 18:00 -p "usern.*" -p "admin.*" report_5
+	  hb_report -f cts:133 ctstest_133
 
 	. WARNING . WARNING . WARNING . WARNING . WARNING . WARNING .
 
@@ -147,7 +145,7 @@ version() {
 setvarsanddefaults() {
 	local now=`perl -e 'print time()'`
 	# used by all
-	DESTDIR=""
+	DEST=""
 	FROM_TIME=""
 	CTS=""
 	TO_TIME=0
@@ -155,7 +153,7 @@ setvarsanddefaults() {
 	UNIQUE_MSG="Mark:HB_REPORT:$now"
 	SANITIZE="passw.*"
 	DO_SANITIZE=""
-	REMOVE_DEST="1"
+	FORCE_REMOVE_DEST=""
 	COMPRESS="1"
 	# logs to collect in addition
 	# NB: they all have to be in syslog format
@@ -169,30 +167,32 @@ setvarsanddefaults() {
 	NO_DESCRIPTION="1"
 	VERBOSITY=0
 }
-chkdirname() {
+chkname() {
 	[ "$1" ] || usage short
-	[ $# -ne 1 ] && fatal "bad directory name: $1"
-	echo $1 | grep -qs '^/' ||
-		fatal "destination directory must be an absolute path"
-	echo $1 | egrep -qs '/[.][.]*(/|$)' &&
-		fatal "sorry, no . or .. references in the destination"
-	[ "$1" = / ] &&
-		fatal "no root directory here, thank you"
+	echo $1 | grep -qs '[^a-zA-Z0-9 at _+=:-]' &&
+		fatal "$1 contains illegal characters"
 }
-destdir_inode_test() {
-	local root_inode=`ls -id / 2>/dev/null | awk '{print $1}'`
-	local dest_inode=`ls -id $1 2>/dev/null | awk '{print $1}'`
-	[ "$root_inode" = "$dest_inode" ] &&
-		fatal "no root directory here, thank you"
+set_dest() {
+	# default DEST has already been set earlier (if the
+	# argument is missing)
+	if [ $# -eq 1 ]; then
+		DEST=`basename $1`
+		DESTDIR=`dirname $1`
+	fi
+	chkname $DEST
+	if [ -z "$COMPRESS" -a -e "$DESTDIR/$DEST" ]; then
+		if [ "$FORCE_REMOVE_DEST" -o "$CTS" ]; then
+			rm -rf $DESTDIR/$DEST
+		else
+			fatal "destination directory $DESTDIR/$DEST exists, please cleanup or use -Z" 
+		fi
+	fi
 }
 chktime() {
 	[ "$1" ] || fatal "bad time specification: $2 (try 'YYYY-M-D H:M:S') "
 }
-msgcleanup() {
-	fatal "destination directory $DESTDIR exists on $1, please cleanup"
-}
-nodistdirectory() {
-	fatal "could not create the destination directory $DESTDIR"
+no_dir() {
+	fatal "could not create the working directory $WORKDIR"
 }
 time2str() {
 	perl -e "use POSIX; print strftime('%x %X',localtime($1));"
@@ -206,21 +206,6 @@ logmark() {
 	debug "run: logger -p $*"
 }
 #
-# a special stamp is logged through syslog on _all_ nodes
-#
-logmarks() {
-	local msg=$1
-	local c="hb_report __slave $DESTDIR logmark $msg"
-
-	for n in $NODES; do
-		if [ "$n" = "`uname -n`" ]; then
-			is_node && logmark $HA_LOGFACILITY.$HA_LOGLEVEL $msg
-		else
-			ssh $SSH_OPTS_AUTH $n "$c"
-		fi
-	done
-}
-#
 # first try syslog files, if none found then use the
 # logfile/debugfile settings
 #
@@ -260,8 +245,8 @@ is_our_log() {
 	local to_time=$3
 
 	local cat=`find_decompressor $logf`
-	local first_time=$(str2time "`$cat $logf | head -1 | $getstampproc`")
-	local last_time=$(str2time "`$cat $logf | tail -1 | $getstampproc`")
+	local first_time="`$cat $logf | head -10 | find_first_ts`"
+	local last_time="`$cat $logf | tail -10 | tac | find_first_ts`"
 	if [ x = "x$first_time" -o x = "x$last_time" ]; then
 		return 0 # skip (empty log?)
 	fi
@@ -439,6 +424,7 @@ cts_findlogseg() {
 #
 dumpenv() {
 	cat<<EOF
+DEST=$DEST
 FROM_TIME=$FROM_TIME
 TO_TIME=$TO_TIME
 USER_NODES="$USER_NODES"
@@ -446,12 +432,10 @@ NODES="$NODES"
 MASTER_NODE="$MASTER_NODE"
 HA_LOG=$HA_LOG
 MASTER_IS_HOSTLOG=$MASTER_IS_HOSTLOG
-DESTDIR=$DESTDIR
 UNIQUE_MSG=$UNIQUE_MSG
 SANITIZE="$SANITIZE"
 DO_SANITIZE="$DO_SANITIZE"
 EXTRA_LOGS="$EXTRA_LOGS"
-REMOVE_DEST="$REMOVE_DEST"
 USER_CLUSTER_TYPE="$USER_CLUSTER_TYPE"
 CONF="$CONF"
 B_CONF="$B_CONF"
@@ -474,13 +458,11 @@ start_slave_collector() {
 
 	dumpenv |
 	if [ "$node" = "$WE" ]; then
-		cat > $DESTDIR/.env
-		hb_report __slave $DESTDIR
+		$SUDO hb_report __slave
 	else
 		ssh $SSH_OPTS_AUTH $node \
-			"cat > $DESTDIR/.env; $SUDO hb_report __slave $DESTDIR" |
-			(cd $DESTDIR && tar xf -)
-	fi &
+			"$SUDO hb_report __slave"
+	fi | (cd $WORKDIR && tar xf -) &
 
 	SLAVEPIDS="$SLAVEPIDS $!"
 }
@@ -490,7 +472,7 @@ start_slave_collector() {
 # and how
 #
 testsshconn() {
-	ssh -T -o Batchmode=yes $1 true 2>/dev/null
+	ssh $SSH_OPTS -o Batchmode=yes $1 true 2>/dev/null
 }
 findsshuser() {
 	local n u rc
@@ -520,6 +502,8 @@ findsshuser() {
 	done
 	[ -n "$failed_nodes" ] &&
 		warning "ssh to node(s)$failed_nodes does not work"
+	# drop nodes we cannot reach
+	NODES=`for n in $failed_nodes $NODES; do echo $n; done | sort | uniq -u`
 	if [ "$ssh_user" != "__undef" ]; then
 		if [ "$ssh_user" != '""' ]; then
 			SSH_OPTS_AUTH="$SSH_OPTS -l $ssh_user"
@@ -529,8 +513,6 @@ findsshuser() {
 	else
 		return 1
 	fi
-	# drop nodes we cannot reach
-	NODES=`for n in $failed_nodes $NODES; do echo $n; done | sort | uniq -u`
 }
 
 #
@@ -888,14 +870,14 @@ Detailed description:
 
 EOF
 
-	if [ -f $DESTDIR/$SYSINFO_F ]; then
+	if [ -f $WORKDIR/$SYSINFO_F ]; then
 		echo "Common system info found:"
-		cat $DESTDIR/$SYSINFO_F
+		cat $WORKDIR/$SYSINFO_F
 	else
 		for n in $NODES; do
-			if [ -f $DESTDIR/$n/$SYSINFO_F ]; then
+			if [ -f $WORKDIR/$n/$SYSINFO_F ]; then
 				echo "System info $n:"
-				sed 's/^/	/' $DESTDIR/$n/$SYSINFO_F
+				sed 's/^/	/' $WORKDIR/$n/$SYSINFO_F
 			fi
 		done
 	fi
@@ -941,11 +923,7 @@ getlog() {
 		info "found the central log!"
 	fi
 
-	if is_node; then
-		outf=$DESTDIR/$WE/$HALOG_F
-	else
-		outf=$DESTDIR/$HALOG_F # we are log server, probably
-	fi
+	outf=$WORKDIR/$HALOG_F
 	if [ -f "$HA_LOG" ]; then
 		if [ "$NO_str2time" ]; then
 			warning "a log found; but we cannot slice it"
@@ -973,30 +951,30 @@ getlog() {
 # get all other info (config, stats, etc)
 #
 collect_info() {
-	getconfig $DESTDIR/$WE
-	getpeinputs $FROM_TIME $TO_TIME $DESTDIR/$WE
-	getbacktraces $FROM_TIME $TO_TIME $DESTDIR/$WE/$BT_F
-	getconfigurations $DESTDIR/$WE
-	touch_DC_if_dc $DESTDIR/$WE
-	sanitize $DESTDIR/$WE
-	crmconfig $DESTDIR/$WE
-	check_perms > $DESTDIR/$WE/$PERMISSIONS_F 2>&1
-	sys_info > $DESTDIR/$WE/$SYSINFO_F 2>&1
-	dlm_dump > $DESTDIR/$WE/$DLM_DUMP_F 2>&1
-	sys_stats > $DESTDIR/$WE/$SYSSTATS_F 2>&1
+	getconfig $WORKDIR
+	getpeinputs $FROM_TIME $TO_TIME $WORKDIR
+	getbacktraces $FROM_TIME $TO_TIME $WORKDIR/$BT_F
+	getconfigurations $WORKDIR
+	touch_DC_if_dc $WORKDIR
+	sanitize $WORKDIR
+	crmconfig $WORKDIR
+	check_perms > $WORKDIR/$PERMISSIONS_F 2>&1
+	sys_info > $WORKDIR/$SYSINFO_F 2>&1
+	dlm_dump > $WORKDIR/$DLM_DUMP_F 2>&1
+	sys_stats > $WORKDIR/$SYSSTATS_F 2>&1
 
 	for l in $EXTRA_LOGS; do
 		[ "$NO_str2time" ] && break
 		[ ! -f "$l" ] && continue
 		if [ "$l" = "$HA_LOG" -a "$l" != "$HALOG_F" ]; then
-			ln -s $HALOG_F $DESTDIR/$WE/`basename $l`
+			ln -s $HALOG_F $WORKDIR/`basename $l`
 			continue
 		fi
 		getstampproc=`find_getstampproc < $l`
 		if [ "$getstampproc" ]; then
 			export getstampproc # used by linetime
-			dumplogset $l $FROM_TIME $TO_TIME > $DESTDIR/$WE/`basename $l`
-			loginfo $l > $DESTDIR/$WE/`basename $l`.info
+			dumplogset $l $FROM_TIME $TO_TIME > $WORKDIR/`basename $l`
+			loginfo $l > $WORKDIR/`basename $l`.info
 		else
 			warning "could not figure out the log format of $l"
 		fi
@@ -1004,9 +982,9 @@ collect_info() {
 }
 finalword() {
 	if [ "$COMPRESS" = "1" ]; then
-		echo "The report is saved in $DESTDIR.tar$COMPRESS_EXT"
+		echo "The report is saved in $DESTDIR/$DEST.tar$COMPRESS_EXT"
 	else
-		echo "The report is saved in $DESTDIR"
+		echo "The report is saved in $DESTDIR/$DEST"
 	fi
 	echo " "
 	echo "Thank you for taking time to create this report."
@@ -1025,13 +1003,19 @@ if [ "$t" = "" ]; then
 		fatal "please install the perl Date::Parse module"
 fi
 
+WE=`uname -n`  # who am i?
+tmpdir=`mktemp -t -d .hb_report.workdir.XXXXXX`
+trap "rm -r $tmpdir" EXIT
+WORKDIR=$tmpdir
+
 #
 # part 1: get and check options; and the destination
 #
 if ! is_collector; then
 	setvarsanddefaults
 	userargs="$@"
-	DESTDIR="$HOME/hb_report-"`date +"%a-%d-%b-%Y"`
+	DESTDIR=.
+	DEST="hb_report-"`date +"%a-%d-%b-%Y"`
 	while getopts f:t:l:u:p:L:e:E:n:MSDCZAVsvhd o; do
 		case "$o" in
 			h) usage;;
@@ -1040,7 +1024,7 @@ if ! is_collector; then
 				if echo "$OPTARG" | grep -qs '^cts:'; then
 					FROM_TIME=0 # to be calculated later
 					CTS=`echo "$OPTARG" | sed 's/cts://'`
-					DESTDIR="$HOME/cts-$CTS-"`date +"%a-%d-%b-%Y"`
+					DEST="cts-$CTS-"`date +"%a-%d-%b-%Y"`
 				else
 					FROM_TIME=`str2time "$OPTARG"`
 					chktime "$FROM_TIME" "$OPTARG"
@@ -1060,29 +1044,31 @@ if ! is_collector; then
 			L) LOG_PATTERNS="$LOG_PATTERNS $OPTARG";;
 			S) NO_SSH=1;;
 			D) NO_DESCRIPTION=1;;
-			C) REMOVE_DEST=1;;
+			C) : ;;
 			Z) FORCE_REMOVE_DEST=1;;
 			M) EXTRA_LOGS="";;
 			E) EXTRA_LOGS="$EXTRA_LOGS $OPTARG";;
 			A) USER_CLUSTER_TYPE="openais";;
 			v) VERBOSITY=$((VERBOSITY + 1));;
-			d) COMPRESS="0"; REMOVE_DEST="0";;
+			d) COMPRESS="";;
 			[?]) usage short;;
 		esac
 	done
 	shift $(($OPTIND-1))
 	[ $# -gt 1 ] && usage short
-	if [ $# -eq 1 ]; then
-		DESTDIR=`echo $1 | sed 's,/*$,,'`
-	fi
-	chkdirname $DESTDIR
-	destdir_inode_test $DESTDIR
+	set_dest $*
 	[ "$FROM_TIME" ] || usage short
+	WORKDIR=$tmpdir/$DEST
 else
-	# slave gets the environment from .env
-	DESTDIR=$2
-	[ -d $DESTDIR ] || nodistdirectory
-	. $DESTDIR/.env
+	WORKDIR=$tmpdir/$DEST/$WE
+fi
+
+mkdir -p $WORKDIR
+[ -d $WORKDIR ] || no_dir
+
+if is_collector; then
+	cat > $WORKDIR/.env
+	. $WORKDIR/.env
 fi
 
 [ $VERBOSITY -gt 1 ] && set -x
@@ -1151,13 +1137,6 @@ elif ! is_collector; then
 	NODES_SOURCE=user
 fi
 
-if is_collector && [ "$3" = logmark ]; then
-	msg="$4"
-	logmark $HA_LOGFACILITY.$HA_LOGLEVEL $msg
-	exit
-fi
-
-WE=`uname -n`  # who am i?
 THIS_IS_NODE=""
 if ! is_collector; then
 	MASTER_NODE=$WE
@@ -1208,47 +1187,18 @@ if ! is_collector; then
 	if [ -z "$NO_SSH" ]; then
 		findsshuser
 	fi
-# final check: don't run if the destination directory exists
-	[ -d $DESTDIR ] && {
-		if [ "$FORCE_REMOVE_DEST" ]; then
-			rm -r $DESTDIR
-		else
-			msgcleanup "local node"
-		fi
-	}
-	mkdir -p $DESTDIR
-	[ -d $DESTDIR ] || nodistdirectory
-	for node in $NODES; do
-		[ "$node" = "$WE" ] && continue
-		ssh $SSH_OPTS_AUTH $node "test -d $DESTDIR" && {
-			if [ "$FORCE_REMOVE_DEST" -o "$CTS" ]; then # relax a bit for CTS
-				ssh $SSH_OPTS_AUTH $node "rm -r $DESTDIR"
-			else
-				test -d $DESTDIR && rmdir $DESTDIR
-				msgcleanup $node
-			fi
-		}
-		dumpenv |
-		ssh $SSH_OPTS_AUTH $node "mkdir -p $DESTDIR && cat > $DESTDIR/.env"
-	done
 fi
 
-# only cluster nodes need their own directories
-is_node && mkdir -p $DESTDIR/$WE
-
-if is_collector && [ $VERBOSITY -gt 1 ]; then
-	echo the debug information for node $WE is in $DESTDIR/$WE/debug.out
-	exec 2>>$DESTDIR/$WE/debug.out
+if is_collector && [ "$HA_LOGFACILITY" ]; then
+	logmark $HA_LOGFACILITY.$HA_LOGLEVEL $UNIQUE_MSG
+	# allow for the log message to get (hopefully) written to the
+	# log file
+	sleep 1
 fi
 
-if ! is_collector; then
-#
-# part 3: log marks to be searched for later
-#         important to do this now on _all_ nodes
-# 
-	if [ "$HA_LOGFACILITY" ]; then
-		logmarks $UNIQUE_MSG
-	fi
+if is_collector && [ $VERBOSITY -gt 1 ]; then
+	info "the debug information for node $WE is in $WE/debug.out"
+	exec 2>>debug.out
 fi
 
 #
@@ -1263,7 +1213,7 @@ fi
 if ! is_collector; then
 	# assume that only root can collect data
 	SUDO=""
-	if [ -z "$SSH_USER" -a `id -u` != 0 ] || [ "$SSH_USER" != root ]; then
+	if [ -z "$SSH_USER" -a `id -u` != 0 ] || [ -n "$SSH_USER" -a "$SSH_USER" != root ]; then
 		SUDO="sudo -u root -E"
 	fi
 	for node in $NODES; do
@@ -1279,30 +1229,24 @@ fi
 #
 if is_collector; then
 	collect_info
-	[ "$WE" != "$MASTER_NODE" ] &&
-		(cd $DESTDIR && tar cf - $WE)
+	(cd $WORKDIR/.. && tar cf - $WE)
 else
 	wait $SLAVEPIDS
-	analyze $DESTDIR > $DESTDIR/$ANALYSIS_F
-	events $DESTDIR
-	mktemplate > $DESTDIR/$DESCRIPTION_F
+	analyze $WORKDIR > $WORKDIR/$ANALYSIS_F
+	events $WORKDIR
+	mktemplate > $WORKDIR/$DESCRIPTION_F
 	[ "$NO_DESCRIPTION" ] || {
 		echo press enter to edit the problem description...
 		read junk
-		edittemplate $DESTDIR/$DESCRIPTION_F
+		edittemplate $WORKDIR/$DESCRIPTION_F
 	}
-	test -f $DESTDIR/$HALOG_F ||
-		combine_logs $DESTDIR
-	cd $DESTDIR/..
+	test -f $WORKDIR/$HALOG_F ||
+		combine_logs $WORKDIR
 	if [ "$COMPRESS" = "1" ]; then
 		pickcompress
-		tar cf - `basename $DESTDIR` | $COMPRESS_PROG > $DESTDIR.tar$COMPRESS_EXT
+		(cd $WORKDIR/.. && tar cf - $DEST) | $COMPRESS_PROG > $DESTDIR/$DEST.tar$COMPRESS_EXT
+	else
+		mv $WORKDIR $DESTDIR
 	fi
 	finalword
 fi
-
-if [ "$REMOVE_DEST" = "1" ]; then
-	if is_master || [ "$WE" != "$MASTER_NODE" ]; then
-		rm -r $DESTDIR
-	fi
-fi
diff --git a/hb_report/utillib.sh b/hb_report/utillib.sh
index 6dd99eb..2ac569d 100644
--- a/hb_report/utillib.sh
+++ b/hb_report/utillib.sh
@@ -108,7 +108,9 @@ syslogmsg() {
 #
 findmsg() {
 	# this is tricky, we try a few directories
-	syslogdirs="/var/log /var/logs /var/syslog /var/adm /var/log/ha /var/log/cluster"
+	syslogdirs="/var/log /var/logs /var/syslog /var/adm
+	/var/log/ha /var/log/cluster /var/log/pacemaker
+	/var/log/heartbeat /var/log/crm /var/log/corosync /var/log/openais"
 	favourites="ha-*"
 	mark=$1
 	log=""
@@ -172,6 +174,15 @@ find_getstampproc() {
 	done
 	echo $func
 }
+find_first_ts() {
+	local l ts
+	while read l; do
+		ts=$(str2time "`echo $l | $getstampproc`")
+		[ "$ts" ] && break
+		warning "cannot extract time: |$l|; will try the next one"
+	done
+	echo $ts
+}
 findln_by_time() {
 	local logf=$1
 	local tm=$2
diff --git a/include/clplumbing/loggingdaemon.h b/include/clplumbing/loggingdaemon.h
index 69698ff..ba986f5 100644
--- a/include/clplumbing/loggingdaemon.h
+++ b/include/clplumbing/loggingdaemon.h
@@ -16,7 +16,7 @@
 
 /* Messages sent to the logging daemon */
 #define	LD_LOGIT	2
-#define MAXENTITY	32
+#define MAXENTITY	64
 
 /* Message contains following header, followed by the text (char[]) itself */
 struct LogDaemonMsgHdr_s {
diff --git a/lib/plugins/lrm/raexecupstart.c b/lib/plugins/lrm/raexecupstart.c
index 36f97c7..baa0278 100644
--- a/lib/plugins/lrm/raexecupstart.c
+++ b/lib/plugins/lrm/raexecupstart.c
@@ -169,7 +169,7 @@ execra( const char * rsc_id, const char * rsc_type, const char * provider,
 	/* It'd be better if it returned GError, so we can distinguish
 	 * between failure modes (can't contact upstart, no such job,
 	 * or failure to do action. */
-	if (upstart_job_do(rsc_type, cmd)) {
+	if (upstart_job_do(rsc_type, cmd, timeout)) {
 		exit(EXECRA_OK);
 	} else {
 		exit(EXECRA_NO_RA);
diff --git a/lib/plugins/lrm/upstart-dbus.c b/lib/plugins/lrm/upstart-dbus.c
index d308c0e..b994d87 100644
--- a/lib/plugins/lrm/upstart-dbus.c
+++ b/lib/plugins/lrm/upstart-dbus.c
@@ -319,7 +319,7 @@ upstart_job_is_running(const gchar *name)
 }
 
 gboolean
-upstart_job_do(const gchar *name, UpstartJobCommand cmd)
+upstart_job_do(const gchar *name, UpstartJobCommand cmd, const int timeout)
 {
 	DBusGConnection *conn;
 	DBusGProxy *manager;
@@ -342,7 +342,8 @@ upstart_job_do(const gchar *name, UpstartJobCommand cmd)
 		switch (cmd) {
 		case UPSTART_JOB_START:
 			cmd_name = "Start";
-			dbus_g_proxy_call (job, cmd_name, &error,
+			dbus_g_proxy_call_with_timeout (job, cmd_name,
+				timeout, &error,
 				G_TYPE_STRV, no_args,
 				G_TYPE_BOOLEAN, TRUE,
 				G_TYPE_INVALID,
@@ -352,7 +353,8 @@ upstart_job_do(const gchar *name, UpstartJobCommand cmd)
 			break;
 		case UPSTART_JOB_STOP:
 			cmd_name = "Stop";
-			dbus_g_proxy_call(job, cmd_name, &error,
+			dbus_g_proxy_call_with_timeout(job, cmd_name,
+				timeout, &error,
 				G_TYPE_STRV, no_args,
 				G_TYPE_BOOLEAN, TRUE,
 				G_TYPE_INVALID,
@@ -360,7 +362,8 @@ upstart_job_do(const gchar *name, UpstartJobCommand cmd)
 			break;
 		case UPSTART_JOB_RESTART:
 			cmd_name = "Restart";
-			dbus_g_proxy_call (job, cmd_name, &error,
+			dbus_g_proxy_call_with_timeout (job, cmd_name,
+				timeout, &error,
 				G_TYPE_STRV, no_args,
 				G_TYPE_BOOLEAN, TRUE,
 				G_TYPE_INVALID,
diff --git a/lib/plugins/lrm/upstart-dbus.h b/lib/plugins/lrm/upstart-dbus.h
index d9932ec..bc72c95 100644
--- a/lib/plugins/lrm/upstart-dbus.h
+++ b/lib/plugins/lrm/upstart-dbus.h
@@ -29,7 +29,7 @@ typedef enum {
 } UpstartJobCommand;
 
 G_GNUC_INTERNAL gchar **upstart_get_all_jobs(void);
-G_GNUC_INTERNAL gboolean upstart_job_do(const gchar *name, UpstartJobCommand cmd);
+G_GNUC_INTERNAL gboolean upstart_job_do(const gchar *name, UpstartJobCommand cmd, const int timeout);
 G_GNUC_INTERNAL gboolean upstart_job_is_running (const gchar *name);
 
 #endif /* _UPSTART_DBUS_H_ */
diff --git a/lib/plugins/stonith/external/hetzner b/lib/plugins/stonith/external/hetzner
index 8846270..2b3e675 100755
--- a/lib/plugins/stonith/external/hetzner
+++ b/lib/plugins/stonith/external/hetzner
@@ -27,8 +27,15 @@
 # Read parameters from config file, format is based upon the hetzner OCF resource agent
 # developed by Kumina: http://blog.kumina.nl/2011/02/hetzner-failover-ip-ocf-script/
 conf_file="/etc/hetzner.cfg"
-user=`sed -n 's/^user.*=\ *//p' /etc/hetzner.cfg`
-pass=`sed -n 's/^pass.*=\ *//p' /etc/hetzner.cfg`
+
+case $1 in
+	get*) ;; # don't print errors if conf_file not present
+	*)
+		user=`sed -n 's/^user.*=\ *//p' $conf_file`
+		pass=`sed -n 's/^pass.*=\ *//p' $conf_file`
+	;;
+esac
+
 hetzner_server="https://robot-ws.your-server.de"
 
 check_http_response() {
diff --git a/lib/plugins/stonith/external/ipmi b/lib/plugins/stonith/external/ipmi
index 9dc5b3b..abadd5a 100644
--- a/lib/plugins/stonith/external/ipmi
+++ b/lib/plugins/stonith/external/ipmi
@@ -36,7 +36,7 @@ RESET="power reset"
 POWEROFF="power off"
 POWERON="power on"
 STATUS="power status"
-IPMITOOL=${ipmitool:-"`which ipmitool 2>/dev/null`}
+IPMITOOL=${ipmitool:-"`which ipmitool 2>/dev/null`"}
 
 have_ipmi() {
 	test -x "${IPMITOOL}"
@@ -46,6 +46,7 @@ have_ipmi() {
 # username, and password, and invokes ipmitool with any arguments
 # passed in
 run_ipmitool() {
+	local ipmitool_opts privlvl=""
 	have_ipmi || {
 		ha_log.sh err "ipmitool not installed"
 		return 1
@@ -59,6 +60,12 @@ run_ipmitool() {
 		# default to "lan" interface
 		interface="lan"
 	fi
+	if [ -n "${priv}" ]; then
+		# default to "lan" interface
+		privlvl="-L $priv"
+	fi
+
+	ipmitool_opts="-I ${interface} -H ${ipaddr} $privlvl"
 
         case "${passwd_method}" in
             param|'')
@@ -80,10 +87,10 @@ run_ipmitool() {
 
         if [ $passwd_method = env ]
         then
-            IPMI_PASSWORD="${passwd}" ${IPMITOOL} -I ${interface} -H ${ipaddr} -U "${userid}" -E ${action} 2>&1
+            IPMI_PASSWORD="${passwd}" ${IPMITOOL} $ipmitool_opts -U "${userid}" -E ${action}
         else
-            ${IPMITOOL} -I ${interface} -H ${ipaddr} -U "${userid}" $M "${passwd}" ${action} 2>&1
-        fi
+            ${IPMITOOL} $ipmitool_opts -U "${userid}" $M "${passwd}" ${action}
+        fi 2>&1
 }
 
 # Yet another convenience wrapper that invokes run_ipmitool, captures
@@ -237,6 +244,18 @@ IPMI interface to use, such as "lan" or "lanplus".
 </longdesc>
 </parameter>
 
+<parameter name="priv" unique="0">
+<content type="string" default=""/>
+<shortdesc lang="en">
+The privilege level of the user.
+</shortdesc>
+<longdesc lang="en">
+The privilege level of the user, for instance OPERATOR. If
+unspecified the privilege level is ADMINISTRATOR. See
+ipmitool(1) -L option for more information.
+</longdesc>
+</parameter>
+
 <parameter name="ipmitool" unique="0">
 <content type="string" default=""/>
 <shortdesc lang="en">
diff --git a/lib/plugins/stonith/external/libvirt b/lib/plugins/stonith/external/libvirt
index 8923565..1fb09a3 100644
--- a/lib/plugins/stonith/external/libvirt
+++ b/lib/plugins/stonith/external/libvirt
@@ -238,7 +238,7 @@ case $1 in
     ;;
 
     getinfo-devdescr)
-    echo "libvirt-based Linux host reset for Xen/KVM guest domain through hypervisor"
+    echo "libvirt-based host reset for Xen/KVM guest domain through hypervisor"
     exit 0
     ;;
 
diff --git a/lib/plugins/stonith/external/ssh.in b/lib/plugins/stonith/external/ssh.in
index dd786be..2a8eb73 100644
--- a/lib/plugins/stonith/external/ssh.in
+++ b/lib/plugins/stonith/external/ssh.in
@@ -130,7 +130,7 @@ getinfo-devname)
 	exit 0
 	;;
 getinfo-devdescr)
-	echo "ssh-based Linux host reset"
+	echo "ssh-based host reset"
 	echo "Fine for testing, but not suitable for production!"
 	echo "Only reboot action supported, no poweroff, and, surprisingly enough, no poweron."
 	exit 0
diff --git a/lib/plugins/stonith/external/xen0 b/lib/plugins/stonith/external/xen0
index 19e6867..ef1ee40 100644
--- a/lib/plugins/stonith/external/xen0
+++ b/lib/plugins/stonith/external/xen0
@@ -191,7 +191,7 @@ getinfo-devname)
     exit 0
     ;;
 getinfo-devdescr)
-    echo "ssh-based Linux host reset for Xen DomU trough Dom0"
+    echo "ssh-based host reset for Xen DomU trough Dom0"
     echo "Fine for testing, but not really suitable for production!"
     exit 0
     ;;
diff --git a/lib/plugins/stonith/ssh.c b/lib/plugins/stonith/ssh.c
index a42d2c8..1887584 100644
--- a/lib/plugins/stonith/ssh.c
+++ b/lib/plugins/stonith/ssh.c
@@ -290,7 +290,7 @@ ssh_get_info(StonithPlugin * s, int reqtype)
 
 
 	case ST_DEVICEDESCR:	/* Description of device type */
-		ret = "SSH-based Linux host reset\n"
+		ret = "SSH-based host reset\n"
 		"Fine for testing, but not suitable for production!";
 		break;
 
diff --git a/lib/stonith/main.c b/lib/stonith/main.c
index e76c061..ad4ddb9 100644
--- a/lib/stonith/main.c
+++ b/lib/stonith/main.c
@@ -55,10 +55,10 @@ static const char META_TEMPLATE[] =
 "<shortdesc lang=\"en\">%s</shortdesc>\n"
 "%s\n"
 "<actions>\n"
-"<action name=\"start\"   timeout=\"60\" />\n"
+"<action name=\"start\"   timeout=\"20\" />\n"
 "<action name=\"stop\"    timeout=\"15\" />\n"
-"<action name=\"status\"  timeout=\"60\" />\n"
-"<action name=\"monitor\" timeout=\"60\" interval=\"3600\" />\n"
+"<action name=\"status\"  timeout=\"20\" />\n"
+"<action name=\"monitor\" timeout=\"20\" interval=\"3600\" />\n"
 "<action name=\"meta-data\"  timeout=\"15\" />\n"
 "</actions>\n"
 "<special tag=\"heartbeat\">\n"
diff --git a/lib/stonith/stonith.c b/lib/stonith/stonith.c
index bd158a2..5d5ef29 100644
--- a/lib/stonith/stonith.c
+++ b/lib/stonith/stonith.c
@@ -178,7 +178,9 @@ get_plugin_list(const char *pltype)
 		return NULL;
 	}
 	if ((extPI = stonith_get_confignames(ext)) == NULL) {
-		LOG(PIL_INFO, "Cannot get %s plugin subplugins", pltype);
+		/* don't complain if rhcs plugins are not installed */
+		if (strcmp(pltype, "rhcs"))
+			LOG(PIL_INFO, "Cannot get %s plugin subplugins", pltype);
 		stonith_delete(ext);
 		return NULL;
 	}
diff --git a/logd/logd.in b/logd/logd.in
index e1f9f0a..cfb28b4 100755
--- a/logd/logd.in
+++ b/logd/logd.in
@@ -28,7 +28,7 @@
 # Required-Start: $network $syslog $remote_fs
 # Required-Stop: $network $syslog $remote_fs
 # X-Start-Before: heartbeat openais corosync
-# Default-Start: 2 3 4 5
+# Default-Start: 2 3 5
 # Default-Stop: 0 1 6
 ### END INIT INFO
 
diff --git a/lrm/lrmd/lrmd.c b/lrm/lrmd/lrmd.c
index 3df0cf4..88be04c 100644
--- a/lrm/lrmd/lrmd.c
+++ b/lrm/lrmd/lrmd.c
@@ -76,6 +76,7 @@ struct msg_map
 	const char 	*msg_type;
 	int	reply_time;
 	msg_handler	handler;
+	int min_priv; /* minimum privileges required */
 };
 
 /*
@@ -89,23 +90,23 @@ struct msg_map
 	(p->reply_time==REPLY_NOW)
 
 struct msg_map msg_maps[] = {
-	{REGISTER,	REPLY_NOW,	on_msg_register},
-	{GETRSCCLASSES,	NO_MSG,	on_msg_get_rsc_classes},
-	{GETRSCTYPES,	NO_MSG,	on_msg_get_rsc_types},
-	{GETPROVIDERS,	NO_MSG,	on_msg_get_rsc_providers},
-	{ADDRSC,	REPLY_NOW,	on_msg_add_rsc},
-	{GETRSC,	NO_MSG,	on_msg_get_rsc},
-	{GETLASTOP,	NO_MSG,	on_msg_get_last_op},
-	{GETALLRCSES,	NO_MSG,	on_msg_get_all},
-	{DELRSC,	REPLY_NOW,	on_msg_del_rsc},
-	{FAILRSC,	REPLY_NOW,	on_msg_fail_rsc},
-	{PERFORMOP,	REPLY_NOW,	on_msg_perform_op},
-	{FLUSHOPS,	REPLY_NOW,	on_msg_flush_all},
-	{CANCELOP,	REPLY_NOW,	on_msg_cancel_op},
-	{GETRSCSTATE,	NO_MSG,	on_msg_get_state},
-	{GETRSCMETA,	NO_MSG, 	on_msg_get_metadata},
-	{SETLRMDPARAM,	REPLY_NOW, 	on_msg_set_lrmd_param},
-	{GETLRMDPARAM,	NO_MSG, 	on_msg_get_lrmd_param},
+	{REGISTER,	REPLY_NOW,	on_msg_register, 0},
+	{GETRSCCLASSES,	NO_MSG,	on_msg_get_rsc_classes, 0},
+	{GETRSCTYPES,	NO_MSG,	on_msg_get_rsc_types, 0},
+	{GETPROVIDERS,	NO_MSG,	on_msg_get_rsc_providers, 0},
+	{ADDRSC,	REPLY_NOW,	on_msg_add_rsc, PRIV_ADMIN},
+	{GETRSC,	NO_MSG,	on_msg_get_rsc, PRIV_ADMIN},
+	{GETLASTOP,	NO_MSG,	on_msg_get_last_op, PRIV_ADMIN},
+	{GETALLRCSES,	NO_MSG,	on_msg_get_all, PRIV_ADMIN},
+	{DELRSC,	REPLY_NOW,	on_msg_del_rsc, PRIV_ADMIN},
+	{FAILRSC,	REPLY_NOW,	on_msg_fail_rsc, PRIV_ADMIN},
+	{PERFORMOP,	REPLY_NOW,	on_msg_perform_op, PRIV_ADMIN},
+	{FLUSHOPS,	REPLY_NOW,	on_msg_flush_all, PRIV_ADMIN},
+	{CANCELOP,	REPLY_NOW,	on_msg_cancel_op, PRIV_ADMIN},
+	{GETRSCSTATE,	NO_MSG,	on_msg_get_state, PRIV_ADMIN},
+	{GETRSCMETA,	NO_MSG, 	on_msg_get_metadata, 0},
+	{SETLRMDPARAM,	REPLY_NOW, 	on_msg_set_lrmd_param, PRIV_ADMIN},
+	{GETLRMDPARAM,	NO_MSG, 	on_msg_get_lrmd_param, 0},
 };
 #define MSG_NR sizeof(msg_maps)/sizeof(struct msg_map)
 
@@ -123,6 +124,7 @@ static gboolean reg_to_apphbd		= FALSE;
 static int max_child_count		= 4;
 static int retry_interval		= 1000; /* Millisecond */
 static int child_count			= 0;
+static IPC_Auth	* auth = NULL;
 
 static struct {
 	int	opcount;
@@ -1084,13 +1086,9 @@ init_start ()
 	DIR* dir = NULL;
 	PILPluginUniv * PluginLoadingSystem = NULL;
 	struct dirent* subdir;
-	struct passwd*	pw_entry;
 	char* dot = NULL;
 	char* ra_name = NULL;
         int len;
-	IPC_Auth	* auth = NULL;
-	int		one = 1;
-	GHashTable*	uidlist;
 	IPC_WaitConnection* conn_cmd = NULL;
 	IPC_WaitConnection* conn_cbk = NULL;
 
@@ -1105,6 +1103,10 @@ init_start ()
 		{"RAExec", &RAExecFuncs, NULL, NULL, NULL},
 		{ NULL, NULL, NULL, NULL, NULL} };
 
+	if( getenv("LRMD_MAX_CHILDREN") ) {
+		set_lrmd_param("max-children", getenv("LRMD_MAX_CHILDREN"));
+	}
+
 	qsort(msg_maps, MSG_NR, sizeof(struct msg_map), msg_type_cmp);
 
 	if (cl_lock_pidfile(PID_FILE) < 0) {
@@ -1163,25 +1165,6 @@ init_start ()
 	 *the other is for create the callback channel
 	 */
 
-	uidlist = g_hash_table_new(g_direct_hash, g_direct_equal);
-	/* Add root's uid */
-	g_hash_table_insert(uidlist, GUINT_TO_POINTER(0), &one); 
-
-	pw_entry = getpwnam(HA_CCMUSER);
-	if (pw_entry == NULL) {
-		lrmd_log(LOG_ERR, "Cannot get the uid of HACCMUSER");
-	} else {
-		g_hash_table_insert(uidlist, GUINT_TO_POINTER(pw_entry->pw_uid)
-				    , &one); 
-	}
-
-	if ( NULL == (auth = MALLOCT(struct IPC_AUTH)) ) {
-		lrmd_log(LOG_ERR, "init_start: MALLOCT (IPC_AUTH) failed.");
-	} else {
-		auth->uid = uidlist;
-		auth->gid = NULL;
-	}
-
 	/*Create a waiting connection to accept command connect from client*/
 	conn_cmd_attrs = g_hash_table_new(g_str_hash, g_str_equal);
 	g_hash_table_insert(conn_cmd_attrs, path, cmd_path);
@@ -1196,9 +1179,12 @@ init_start ()
 	}
 
 	/*Create a source to handle new connect rquests for command*/
-	G_main_add_IPC_WaitConnection( G_PRIORITY_HIGH, conn_cmd, auth, FALSE,
+	G_main_add_IPC_WaitConnection( G_PRIORITY_HIGH, conn_cmd, NULL, FALSE,
 				   on_connect_cmd, conn_cmd, NULL);
 
+	/* auth is static, but used when clients register */
+	auth = ipc_str_to_auth(ADMIN_UIDS, strlen(ADMIN_UIDS), "", 0);
+
 	/*
 	 * Create a waiting connection to accept the callback connect from client
 	 */
@@ -1215,7 +1201,7 @@ init_start ()
 	}
 
 	/*Create a source to handle new connect rquests for callback*/
-	G_main_add_IPC_WaitConnection( G_PRIORITY_HIGH, conn_cbk, auth, FALSE,
+	G_main_add_IPC_WaitConnection( G_PRIORITY_HIGH, conn_cbk, NULL, FALSE,
 	                               on_connect_cbk, conn_cbk, NULL);
 
 	/* our child signal handling involves calls with
@@ -1294,10 +1280,7 @@ init_start ()
 	conn_cbk->ops->destroy(conn_cbk);
 	conn_cbk = NULL;
 
-	g_hash_table_destroy(uidlist);
-	if ( NULL != auth ) {
-		free(auth);
-	}
+	ipc_destroy_auth(auth);
 	if (cl_unlock_pidfile(PID_FILE) == 0) {
 		lrmd_debug(LOG_DEBUG, "[%s] stopped", lrm_system_name);
 	}
@@ -1419,6 +1402,7 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 	lrmd_client_t* client = NULL;
 	struct ha_msg* msg = NULL;
 	char *msg_s;
+	int ret;
 
 	client = (lrmd_client_t*)user_data;
 
@@ -1437,7 +1421,7 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 
 
 	/*get the message */
-	msg = msgfromIPC_noauth(ch);
+	msg = msgfromIPC(ch, 0);
 	if (NULL == msg) {
 		lrmd_log(LOG_ERR, "on_receive_cmd: can not receive messages.");
 		return TRUE;
@@ -1455,6 +1439,7 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 	in_type.msg_type = ha_msg_value(msg, F_LRM_TYPE);
 	if( !in_type.msg_type ) {
 		LOG_FAILED_TO_GET_FIELD(F_LRM_TYPE);
+		ha_msg_del(msg);
 		return TRUE;
 	}
 	msg_s = msg2string(msg);
@@ -1469,8 +1454,19 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 
 		lrmd_log(LOG_ERR, "on_receive_cmd: received an unknown msg");
 	} else {
-		int ret;
+		if( !client->app_name && msgmap_p->handler != on_msg_register ) {
+			ha_msg_del(msg);
+			lrmd_log(LOG_ERR, "%s: the client needs to register first", __FUNCTION__);
+			return FALSE;
+		}
 
+		if( client->priv_lvl < msgmap_p->min_priv ) {
+			ha_msg_del(msg);
+			lrmd_log(LOG_ERR, "%s: insufficient privileges for %s (pid %d)"
+			, __FUNCTION__
+			, client->app_name, client->pid);
+			return FALSE;
+		}
 		strncpy(client->lastrequest, in_type.msg_type, sizeof(client->lastrequest));
 		client->lastrequest[sizeof(client->lastrequest)-1]='\0';
 		client->lastreqstart = time(NULL);
@@ -1488,7 +1484,7 @@ on_receive_cmd (IPC_Channel* ch, gpointer user_data)
 	/*delete the msg*/
 	ha_msg_del(msg);
 
-	return TRUE;
+	return ret;
 }
 static void
 remove_repeat_op_from_client(gpointer key, gpointer value, gpointer user_data)
@@ -1624,6 +1620,14 @@ on_msg_register(lrmd_client_t* client, struct ha_msg* msg)
 		, 	client->pid);
 	}
 
+	/* everybody can connect, but only certain UIDs can perform
+	 * administrative actions
+	 */
+	if( client->ch_cmd->ops->verify_auth(client->ch_cmd, auth) == IPC_OK )
+		client->priv_lvl = PRIV_ADMIN;
+	else
+		client->priv_lvl = 0;
+
 	g_hash_table_insert(clients, (gpointer)&client->pid, client);
 	lrmd_debug(LOG_DEBUG, "on_msg_register:client %s [%d] registered"
 	,	client->app_name
@@ -2817,6 +2821,11 @@ on_op_done(lrmd_rsc_t* rsc, lrmd_op_t* op)
 				to_repeatlist(rsc,op);
 		}
 	} else {
+		if (HA_OK != ha_msg_mod_int(op->msg,F_LRM_OPSTATUS,(int)LRM_OP_CANCELLED)) {
+			LOG_FAILED_TO_ADD_FIELD(F_LRM_OPSTATUS);
+			return HA_FAIL;
+		}
+		op_status = LRM_OP_CANCELLED;
 		remove_op_history(op);
 	}
 
diff --git a/lrm/lrmd/lrmd.h b/lrm/lrmd/lrmd.h
index 8e11964..eadea88 100644
--- a/lrm/lrmd/lrmd.h
+++ b/lrm/lrmd/lrmd.h
@@ -128,6 +128,14 @@
  *
  */
 
+/*
+ * Recognized privilege levels
+ */
+
+#define PRIV_ADMIN 8 /* ADMIN_UIDS are administrators */
+#define ADMIN_UIDS "0,"HA_CCMUSER
+#define ADMIN_GIDS "0,"HA_APIGROUP /* unused */
+
 typedef struct
 {
 	char*		app_name;
@@ -144,6 +152,7 @@ typedef struct
 	time_t		lastreqstart;
 	time_t		lastreqend;
 	time_t		lastrcsent;
+	int		priv_lvl; /* client privilege level (depends on uid/gid) */
 }lrmd_client_t;
 
 typedef struct lrmd_rsc lrmd_rsc_t;
diff --git a/lrm/test/README.regression b/lrm/test/README.regression
index f944619..3588172 100644
--- a/lrm/test/README.regression
+++ b/lrm/test/README.regression
@@ -143,6 +143,9 @@ with the '%' sign and may be followed by additional parameters.
 %wait
 	wait for the last background test to finish
 
+%shell
+	feed whatever is in the rest of the line to 'sh -s'
+
 Filters and except files
 
 Some output is necessarily very volatile, such as time stamps.
diff --git a/lrm/test/evaltest.sh b/lrm/test/evaltest.sh
index 014b7a3..f369102 100755
--- a/lrm/test/evaltest.sh
+++ b/lrm/test/evaltest.sh
@@ -71,6 +71,10 @@ specopt_bgrepeat() { # common
 specopt_wait() { # common
 	waitforbgprocs
 }
+specopt_shell() { # run command with shell
+	echo "$rest" | sh -s |  # and execute the command
+		{ [ "$extcheck" ] && $extcheck || cat;}
+}
 specopt() {
 	cmd=`echo $cmd | sed 's/%//'`  # strip leading '%'
 	echo ".`echo $cmd | tr '[a-z]' '[A-Z]'` $rest"  # show what we got
diff --git a/lrm/test/regression.sh.in b/lrm/test/regression.sh.in
index 94d8488..19a8ffe 100755
--- a/lrm/test/regression.sh.in
+++ b/lrm/test/regression.sh.in
@@ -177,7 +177,7 @@ rm_ra() {
 
 cp_ra
 start_lrmd || exit $?
-start_stonithd || exit $?
+# start_stonithd || exit $?
 trap "stop_lrmd; stop_stonithd; rm_ra" EXIT
 
 setenvironment() {
diff --git a/lrm/test/testcases/BSC b/lrm/test/testcases/BSC
index 28e751e..157fb6c 100644
--- a/lrm/test/testcases/BSC
+++ b/lrm/test/testcases/BSC
@@ -1,3 +1,4 @@
 rscmgmt
 metadata
 rscexec
+stonith
diff --git a/lrm/test/testcases/Makefile.am b/lrm/test/testcases/Makefile.am
index 8c7bbae..49728d9 100644
--- a/lrm/test/testcases/Makefile.am
+++ b/lrm/test/testcases/Makefile.am
@@ -21,6 +21,7 @@ MAINTAINERCLEANFILES = Makefile.in
 testcasesdir		= 	$(datadir)/$(PACKAGE_NAME)/lrmtest/testcases
 testcases_SCRIPTS	=	common.filter ra-list.sh rscmgmt.log_filter xmllint.sh
 testcases_DATA	=	BSC basicset metadata metadata.exp rscexec \
-			rscexec.exp rscmgmt rscmgmt.exp
+			rscexec.exp rscmgmt rscmgmt.exp \
+			stonith stonith.exp
 #			shouldn't need this next line...
 EXTRA_DIST =		$(testcases_SCRIPTS) $(testcases_DATA)
diff --git a/lrm/test/testcases/basicset b/lrm/test/testcases/basicset
index 8ca6081..62b9c04 100644
--- a/lrm/test/testcases/basicset
+++ b/lrm/test/testcases/basicset
@@ -1,5 +1,6 @@
 rscmgmt
 metadata
 rscexec
+stonith
 serialize
 flood
diff --git a/lrm/test/testcases/metadata b/lrm/test/testcases/metadata
index cb459a2..d155757 100644
--- a/lrm/test/testcases/metadata
+++ b/lrm/test/testcases/metadata
@@ -8,22 +8,22 @@ types class=ocf
 types class=lsb
 %extcheck ra-list.sh
 types class=heartbeat
-%extcheck ra-list.sh
-types class=stonith
+#%extcheck ra-list.sh
+#types class=stonith
 %extcheck xmllint.sh many
 classmeta class=ocf
 %extcheck xmllint.sh many
 classmeta class=lsb
 %extcheck xmllint.sh many
 classmeta class=heartbeat
-%extcheck xmllint.sh many
-classmeta class=stonith
+#%extcheck xmllint.sh many
+#classmeta class=stonith
 %extcheck xmllint.sh
 meta class=ocf type=Dummy
 %extcheck xmllint.sh
 meta class=lsb type=lrmregtest
 %extcheck xmllint.sh
 meta class=heartbeat type=Dummy
-%extcheck xmllint.sh
-meta class=stonith type=ssh
+#%extcheck xmllint.sh
+#meta class=stonith type=ssh
 provider class=ocf type=IPaddr
diff --git a/lrm/test/testcases/metadata.exp b/lrm/test/testcases/metadata.exp
index 02a1c74..158bad2 100644
--- a/lrm/test/testcases/metadata.exp
+++ b/lrm/test/testcases/metadata.exp
@@ -15,24 +15,17 @@ Cool. RA list passed.
 .EXTCHECK ra-list.sh
 .TRY List types class=heartbeat
 Cool. RA list passed.
-.EXTCHECK ra-list.sh
-.TRY List types class=stonith
-Cool. RA list passed.
 .EXTCHECK xmllint.sh many
 .TRY Meta-data class=ocf
 .EXTCHECK xmllint.sh many
 .TRY Meta-data class=lsb
 .EXTCHECK xmllint.sh many
 .TRY Meta-data class=heartbeat
-.EXTCHECK xmllint.sh many
-.TRY Meta-data class=stonith
 .EXTCHECK xmllint.sh
 .TRY Show meta-data class=ocf type=Dummy provider=heartbeat
 .EXTCHECK xmllint.sh
 .TRY Show meta-data class=lsb type=lrmregtest provider=heartbeat
 .EXTCHECK xmllint.sh
 .TRY Show meta-data class=heartbeat type=Dummy provider=heartbeat
-.EXTCHECK xmllint.sh
-.TRY Show meta-data class=stonith type=ssh provider=heartbeat
 .TRY Show provider class=ocf type=IPaddr
 heartbeat
diff --git a/lrm/test/testcases/rscexec b/lrm/test/testcases/rscexec
index d2c7525..a6770ad 100644
--- a/lrm/test/testcases/rscexec
+++ b/lrm/test/testcases/rscexec
@@ -45,6 +45,7 @@ exec operation=stop
 exec operation=monitor
 exec operation=meta-data
 del
+%stop
 # stonith
 %setenv dflt_class=stonith dftl_rsc=rscexec_rsc_r1-stonith
 add type=null args="hostlist=node1"
diff --git a/lrm/test/testcases/rscexec.exp b/lrm/test/testcases/rscexec.exp
index c961361..a90da79 100644
--- a/lrm/test/testcases/rscexec.exp
+++ b/lrm/test/testcases/rscexec.exp
@@ -173,57 +173,3 @@ The resource 3 operations' information:
 
 .TRY Delete resource rscexec_rsc_r1
 Succeeded in deleting this resource.
-.SETENV dflt_class=stonith dftl_rsc=rscexec_rsc_r1-stonith
-.TRY Add resource rscexec_rsc_r1 class=stonith type=null provider=heartbeat args=hostlist=node1
-Succeeded in adding this resource.
-.TRY Exec rscexec_rsc_r1 op=start timeout=1000 interval=0 target=EVERYTIME args=
-> start succeed (status=0,rc=0): [null]
-
-.TRY Show state rscexec_rsc_r1
-resource state:LRM_RSC_IDLE
-The resource 1 operations' information:
-   operation 'start' [call_id=(removed)]:
-      start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
-      rc=0 (ok), op_status=0 (succeed)
-      parameters: hostlist=node1  
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-> monitor succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=start timeout=1000 interval=0 target=EVERYTIME args=
-> start succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-> monitor succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=stop timeout=1000 interval=0 target=EVERYTIME args=
-> stop succeed (status=0,rc=0): [null]
-
-.TRY Show state rscexec_rsc_r1
-resource state:LRM_RSC_IDLE
-The resource 3 operations' information:
-   operation 'start' [call_id=(removed)]:
-      start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
-      rc=0 (ok), op_status=0 (succeed)
-      parameters: hostlist=node1  
-   operation 'monitor' [call_id=(removed)]:
-      start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
-      rc=0 (ok), op_status=0 (succeed)
-      parameters: hostlist=node1  
-   operation 'stop' [call_id=(removed)]:
-      start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
-      rc=0 (ok), op_status=0 (succeed)
-      parameters: hostlist=node1  
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-> monitor succeed (status=0,rc=7): [null]
-
-.TRY Exec rscexec_rsc_r1 op=stop timeout=1000 interval=0 target=EVERYTIME args=
-> stop succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-> monitor succeed (status=0,rc=7): [null]
-
-.TRY Exec rscexec_rsc_r1 op=meta-data timeout=1000 interval=0 target=EVERYTIME args=
-> meta-data succeed (status=0,rc=0): [null]
-
-.TRY Delete resource rscexec_rsc_r1
-Succeeded in deleting this resource.
diff --git a/lrm/test/testcases/rscmgmt.exp b/lrm/test/testcases/rscmgmt.exp
index 20e2774..6d257e4 100644
--- a/lrm/test/testcases/rscmgmt.exp
+++ b/lrm/test/testcases/rscmgmt.exp
@@ -67,13 +67,13 @@ Resource agent provider:heartbeat
 Succeeded in adding this resource.
 .TRY List resources
 
-Resource ID:r1
-Resource agent class:lsb
+Resource ID:r2
+Resource agent class:ocf
 Resource agent type:lrmregtest
 Resource agent provider:heartbeat
 
-Resource ID:r2
-Resource agent class:ocf
+Resource ID:r1
+Resource agent class:lsb
 Resource agent type:lrmregtest
 Resource agent provider:heartbeat
 .TRY Delete resource r1
diff --git a/lrm/test/testcases/stonith b/lrm/test/testcases/stonith
new file mode 100644
index 0000000..f21cf18
--- /dev/null
+++ b/lrm/test/testcases/stonith
@@ -0,0 +1,2 @@
+%extcheck xmllint.sh many
+%shell stonith -L | while read p; do echo $p:heartbeat; stonith -m -t $p; done
diff --git a/lrm/test/testcases/stonith.exp b/lrm/test/testcases/stonith.exp
new file mode 100644
index 0000000..f9f1042
--- /dev/null
+++ b/lrm/test/testcases/stonith.exp
@@ -0,0 +1,2 @@
+.EXTCHECK xmllint.sh many
+.SHELL stonith -L | while read p; do echo $p:heartbeat; stonith -m -t $p; done

-- 
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