[Debian-ha-svn-commits] [SCM] cluster suite Debian packaging branch, master, updated. debian/3.0.6-1

Guido Günther agx at sigxcpu.org
Sun Dec 27 14:09:02 UTC 2009


The following commit has been merged in the master branch:
commit b3b823ad7d07c1f5455d860a72da20820f691571
Author: Guido Günther <agx at sigxcpu.org>
Date:   Thu Dec 10 17:47:01 2009 +0100

    Imported Upstream version 3.0.6

diff --git a/cman/cman_tool/join.c b/cman/cman_tool/join.c
index 8e85a58..fa1920e 100644
--- a/cman/cman_tool/join.c
+++ b/cman/cman_tool/join.c
@@ -234,7 +234,7 @@ int join(commandline_t *comline, char *main_envp[])
 		be_daemon();
 
 		sprintf(scratch, "FORKED: %d\n", getpid());
-		err = write(p[1], scratch, strlen(scratch)+1);
+		err = write(p[1], scratch, strlen(scratch));
 
 		execve(COROSYNCBIN, argv, envp);
 
diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c
index 3eedfea..3d38e86 100644
--- a/cman/cman_tool/main.c
+++ b/cman/cman_tool/main.c
@@ -57,9 +57,9 @@ static void print_usage(int subcmd)
 		printf("  -P               Don't set corosync to realtime priority\n");
 		printf("  -X               Use internal cman defaults for configuration\n");
 		printf("  -A               Don't load openais services\n");
-		printf("  -D <fail,warn,none> What to do about the config. Default (without -D) is to validate\n");
-		printf("                   the config. with -D no validation will be done. -Dwarn will print errors\n");
-		printf("                   but allow the operation to continue\n");
+		printf("  -D<fail|warn|none> What to do about the config. Default (without -D) is to\n");
+		printf("                   validate the config. with -D no validation will be done.\n");
+		printf("                   -Dwarn will print errors but allow the operation to continue.\n");
 		printf("\n");
 	}
 
@@ -119,8 +119,8 @@ static void print_usage(int subcmd)
 	if (!subcmd || subcmd == OP_VERSION) {
 		printf("version\n");
 		printf("  -r <config>      A new config version to set on all members\n");
-		printf("  -D <fail,warn,none> What to do about the config. Default (without -D) is to validate\n");
-		printf("                   the config. with -D no validation will be done. -Dwarn will print errors\n");
+		printf("  -D <fail,warn,none> What to do about the config. Default (without -D) is to\n");
+		printf("                   validate the config. with -D no validation will be done. -Dwarn will print errors\n");
 		printf("                   but allow the operation to continue\n");
 		printf("  -S               Don't run ccs_sync to distribute cluster.conf (if appropriate)\n");
 		printf("\n");
@@ -774,6 +774,8 @@ static void version(commandline_t *comline)
 		if (comline->verbose > 1)
 			printf("calling ccs_sync\n");
 		result = system("/usr/bin/ccs_sync");
+		if (result)
+			die("ccs_sync failed.\nIf you have distributed the config file yourself, try re-running with -S\n");
 	}
 	else {
 		if (comline->verbose)
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 4bd3d95..cf68836 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -237,7 +237,7 @@ static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr,
 	/* Check it's not bound to localhost, sigh */
 	get_localhost(if_addr.ss_family, &localhost);
 	if (ipaddr_equal(&localhost, &if_addr)) {
-		sprintf(error_reason, "Node address is localhost, please choose a real host address");
+		sprintf(error_reason, "Node name resolves to localhost, please check /etc/hosts and assign this node a network IP address");
 		return -1;
 	}
 
@@ -705,9 +705,15 @@ static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
 			objdb->object_key_create(object_handle, "join", strlen("join"),
 						 "60", strlen("60")+1);
 		}
+		/* consensus should be 2*token, see bz#544482*/
 		if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
+		        unsigned int token;
+			char calc_consensus[32];
+
+			objdb_get_int(objdb, object_handle, "token", &token, DEFAULT_TOKEN_TIMEOUT);
+			sprintf(calc_consensus, "%d", token*2);
 			objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
-						 "4800", strlen("4800")+1);
+						 calc_consensus, strlen(calc_consensus)+1);
 		}
 
 		/* Set RRP mode appropriately */
diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in
index a58efaf..68fafd6 100644
--- a/cman/init.d/cman.in
+++ b/cman/init.d/cman.in
@@ -101,16 +101,6 @@ fi
 #     indefinitely set the value to -1.
 [ -z "$FENCE_JOIN_TIMEOUT" ] && FENCE_JOIN_TIMEOUT=20
 
-# NET_RMEM_DEFAULT -- minimum value for rmem_default. If this is set
-# higher elsewhere it will not be reduced here.
-# These two values are only really needed for the DLM when using sctp
-# but do no harm.
-[ -z "$NET_RMEM_DEFAULT" ] && NET_RMEM_DEFAULT=4194304
-
-# NET_RMEM_MAX -- minimum value for rmem_max. If this is set
-# higher elsewhere it will not be reduced here.
-[ -z "$NET_RMEM_MAX" ] && NET_RMEM_MAX=4194304
-
 # FENCED_MEMBER_DELAY -- amount of time to delay fence_tool join to allow
 #     all nodes in cluster.conf to become cluster members.  In seconds.
 [ -z "$FENCED_MEMBER_DELAY" ] && FENCED_MEMBER_DELAY=45
@@ -492,28 +482,6 @@ stop_configfs()
 	fi
 }
 
-
-set_networking_params()
-{
-	rmemdefault=/proc/sys/net/core/rmem_default
-
-	[ ! -f $rmemdefault ] && return 0
-
-	if [ "$(cat $rmemdefault)" -lt $NET_RMEM_DEFAULT ]; then
-		echo $NET_RMEM_DEFAULT > $rmemdefault
-		[ "$(cat $rmemdefault)" != $NET_RMEM_DEFAULT ] && return 1
-	fi
-
-	rmemmax="/proc/sys/net/core/rmem_max"
-
-	if [ "$(cat $rmemmax)" -lt $NET_RMEM_MAX ]; then
-		echo $NET_RMEM_MAX > /proc/sys/net/core/rmem_max
-		[ "$(cat $rmemmax)" != $NET_RMEM_MAX ] && return 1
-	fi
-
-	return 0
-}
-
 start_cman()
 {
 	cman_running && return 0
@@ -563,18 +531,6 @@ stop_cman()
 	fi
 }
 
-unfence_self()
-{
-	# fence_node returns 0 on success, 1 on failure, 2 if unconfigured
-	# 0 and 2 are ok. Everything else should report error.
-	fence_node -U > /dev/null 2>&1
-	case $? in
-	0|2)
-		return 0
-	;;
-	esac
-}
-
 start_qdiskd()
 {
 	start_daemon qdiskd "-Q" || return 1
@@ -671,6 +627,20 @@ stop_cmannotifyd()
 	stop_daemon cmannotifyd
 }
 
+unfence_self()
+{
+	# fence_node returns 0 on success, 1 on failure, 2 if unconfigured
+	# 0 and 2 are ok. Everything else should report error.
+	fence_err=$(fence_node -U 2>&1)
+	case $? in
+	0|2)
+		return 0
+	;;
+	esac
+	errmsg="$fence_err"
+	return 1
+}
+
 join_fence_domain()
 {
 	if ! cman_tool status | grep Flags | grep 2node \
@@ -736,10 +706,6 @@ start()
 		none \
 		"Mounting configfs"
 
-	runwrap set_networking_params \
-		none \
-		"Setting network parameters"
-
 	[ "$breakpoint" = "setup" ] && exit 0
 
 	runwrap start_cman \
@@ -748,10 +714,6 @@ start()
 
 	[ "$breakpoint" = "join" ] && exit 0
 
-	runwrap unfence_self \
-		none \
-		"Unfencing self"
-
 	runwrap start_qdiskd \
 		qdiskd_enabled \
 		"Starting qdiskd"
@@ -788,6 +750,10 @@ start()
 
 	[ "$breakpoint" = "daemons" ] && exit 0
 
+	runwrap unfence_self \
+		none \
+		"Unfencing self"
+
 	runwrap join_fence_domain \
 		fence_join_enabled \
 		"Joining fence domain"
@@ -859,35 +825,35 @@ stop()
 cmanstatus()
 {
 	if fence_xvmd_standalone; then
-		errmsg=$( status fence_xvmd 2>&1 ) || return 1
-		return 0
+		errmsg=$( status fence_xvmd 2>&1 )
+		return $?
 	fi
 
-	errmsg=$( status corosync 2>&1 ) || return 1
+	errmsg=$( status corosync 2>&1 ) || return $?
 
 	if ! cman_running; then
 		errmsg="cman is not running"
-		return 1
+		return 3
 	fi
 
 	if qdiskd_enabled; then
-		errmsg=$( status qdiskd 2>&1 ) || return 1
+		errmsg=$( status qdiskd 2>&1 ) || return $?
 	fi
 
 	if groupd_enabled; then
-		errmsg=$( status groupd 2>&1 ) || return 1
+		errmsg=$( status groupd 2>&1 ) || return $?
 	fi
 
-	errmsg=$( status fenced 2>&1 ) || return 1
-	errmsg=$( status dlm_controld 2>&1 ) || return 1
-	errmsg=$( status gfs_controld 2>&1 ) || return 1
+	errmsg=$( status fenced 2>&1 ) || return $?
+	errmsg=$( status dlm_controld 2>&1 ) || return $?
+	errmsg=$( status gfs_controld 2>&1 ) || return $?
 
 	if cmannotifyd_enabled; then
-		errmsg=$( status cmannotifyd 2>&1 ) || return 1
+		errmsg=$( status cmannotifyd 2>&1 ) || return $?
 	fi
 
 	if fence_xvmd_enabled; then
-		errmsg=$( status fence_xvmd 2>&1 ) || return 1
+		errmsg=$( status fence_xvmd 2>&1 ) || return $?
 	fi
 }
 
@@ -915,8 +881,17 @@ restart|reload|force-reload)
 	stop
 	start
 ;;
-status)
+condrestart|try-restart)
 	if cmanstatus; then
+		cmanremove=remove
+		stop
+		start
+	fi
+;;
+status)
+	cmanstatus
+	rtrn=$?
+	if [ "$rtrn" = 0 ]; then
 		if fence_xvmd_standalone; then
 			echo "fence_xvmd standalone is running."
 		else
@@ -924,12 +899,11 @@ status)
 		fi
 	else
 		echo "$errmsg"
-		rtrn=1
 	fi
 ;;
 *)
-	echo "Usage: $0 {start|stop|reload|restart|status}"
-	rtrn=1
+	echo "Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
+	rtrn=2
 ;;
 esac
 
diff --git a/cman/man/cman_tool.8 b/cman/man/cman_tool.8
index 4d400a6..d45e9e9 100644
--- a/cman/man/cman_tool.8
+++ b/cman/man/cman_tool.8
@@ -303,6 +303,9 @@ validated, which is equivalent to -Dfail.
 to use it regardless of its validity.
 .br
 -Dnone (or just -D) will skip the validation completely.
+.br
+The -D switch does not take a space between -D and the parameter. so '-D fail' will cause
+an error. Use -Dfail.
 .SH "NODES" OPTIONS
 .TP
 .I -a
diff --git a/cman/man/qdisk.5 b/cman/man/qdisk.5
index 7a00a25..f578e92 100644
--- a/cman/man/qdisk.5
+++ b/cman/man/qdisk.5
@@ -278,6 +278,24 @@ this value is 1 (on).  This option can be changed while qdiskd is
 running.
 
 .in 9
+\fImaster_wins\fP\fB="\fP0\fB"\fP
+.in 12
+If set to 1 (on), only the qdiskd master will advertise its votes
+to CMAN.  In a network partition, only the qdisk master will provide
+votes to CMAN.  Consequently, that node will automatically "win" in
+a fence race.
+
+This option requires careful tuning of the CMAN timeout, the qdiskd
+timeout, and CMAN's quorum_dev_poll value.  As a rule of thumb,
+CMAN's quorum_dev_poll value should be equal to Totem's token timeout
+and qdiskd's timeout (interval*tko) should be less than half of
+Totem's token timeout.
+
+This option only takes effect if there are no heuristics
+configured.  Usage of this option in configurations with more than
+two cluster nodes is undefined and should not be done.
+
+.in 9
 \fIallow_kill\fP\fB="\fP1\fB"\fP
 .in 12
 If set to 0 (off), qdiskd will *not* instruct to kill nodes it thinks
diff --git a/cman/qdisk/disk.h b/cman/qdisk/disk.h
index b00c580..c5b3d18 100644
--- a/cman/qdisk/disk.h
+++ b/cman/qdisk/disk.h
@@ -54,7 +54,8 @@ typedef enum {
 	RF_ALLOW_KILL = 0x10,
 	RF_UPTIME = 0x20,
 	RF_CMAN_LABEL = 0x40,
-	RF_IOTIMEOUT = 0x80
+	RF_IOTIMEOUT = 0x80,
+	RF_MASTER_WINS = 0x100
 } run_flag_t;
 
 
diff --git a/cman/qdisk/iostate.c b/cman/qdisk/iostate.c
index f195c45..0199da4 100644
--- a/cman/qdisk/iostate.c
+++ b/cman/qdisk/iostate.c
@@ -49,11 +49,12 @@ io_state(iostate_t state)
 	pthread_mutex_lock(&state_mutex);
 	main_state = state;
 	main_incarnation++; /* it does not matter if this wraps. */
-	pthread_mutex_unlock(&state_mutex);
 
 	/* Optimization: Don't signal on STATE_NONE */
 	if (state != STATE_NONE)
 		pthread_cond_broadcast(&state_cond);
+
+	pthread_mutex_unlock(&state_mutex);
 }
 
 
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
index 87934c9..eb3ab3c 100644
--- a/cman/qdisk/main.c
+++ b/cman/qdisk/main.c
@@ -1106,7 +1106,8 @@ quorum_loop(qd_ctx *ctx, node_info_t *ni, int max)
 						"Halting qdisk operations\n");
 					return -1;
 				}
-				if (!errors)
+				if (!errors && 
+				    (!(ctx->qc_flags & RF_MASTER_WINS)))
 					cman_poll_quorum_device(ctx->qc_cman_admin, 1);
 			}
 		}
@@ -1557,6 +1558,15 @@ get_static_config_data(qd_ctx *ctx, int ccsfd)
 			ctx->qc_scoremin = 0;
 	}
 
+	/* Get master-wins flag for when we transition -> offline */
+	/* default = off, so, 1 to turn on */
+	snprintf(query, sizeof(query), "/cluster/quorumd/@master_wins");
+	if (ccs_get(ccsfd, query, &val) == 0) {
+		if (atoi(val))
+			ctx->qc_flags |= RF_MASTER_WINS;
+		free(val);
+	}
+
 	/* Get cman_label */
 	snprintf(query, sizeof(query), "/cluster/quorumd/@cman_label");
 	if (ccs_get(ccsfd, query, &val) == 0) {
@@ -1626,6 +1636,13 @@ get_config_data(qd_ctx *ctx, struct h_data *h, int maxh, int *cfh)
 
 	*cfh = configure_heuristics(ccsfd, h, maxh);
 
+	if (*cfh) {
+		if (ctx->qc_flags & RF_MASTER_WINS) {
+			logt_print(LOG_WARNING, "Master-wins mode disabled\n");
+			ctx->qc_flags &= ~RF_MASTER_WINS;
+		}
+	}
+
 	logt_print(LOG_DEBUG, "Quorum Daemon: %d heuristics, "
 		   "%d interval, %d tko, %d votes\n",
 		   *cfh, ctx->qc_interval, ctx->qc_tko, ctx->qc_votes);
diff --git a/cman/qdisk/scandisk.c b/cman/qdisk/scandisk.c
index 0b1688f..20a77f2 100644
--- a/cman/qdisk/scandisk.c
+++ b/cman/qdisk/scandisk.c
@@ -624,7 +624,7 @@ static int sysfs_is_disk(char *path)
 static int scansysfs(struct devlisthead *devlisthead, const char *path, int level, int parent_holder)
 {
 	struct devnode *startnode;
-	int i, n, maj, min, has_holder = 0;
+	int i, n, maj, min, has_holder;
 	struct dirent **namelist;
 	struct stat sb;
 	char newpath[MAXPATHLEN];
@@ -642,6 +642,8 @@ static int scansysfs(struct devlisthead *devlisthead, const char *path, int leve
 				if (S_ISLNK(sb.st_mode))
 					continue;
 
+			has_holder = parent_holder;
+
 			if (sysfs_is_dev(newpath, &maj, &min) > 0) {
 				startnode =
 				    alloc_list_obj(devlisthead, maj,
@@ -655,12 +657,10 @@ static int scansysfs(struct devlisthead *devlisthead, const char *path, int leve
 
 				if (!parent_holder)
 					has_holder =
-					startnode->sysfsattrs.holders =
 					    sysfs_has_subdirs_entries(newpath,
 								      "holders");
-				else
-					has_holder =
-					startnode->sysfsattrs.holders = parent_holder;
+
+				startnode->sysfsattrs.holders = has_holder;
 
 				startnode->sysfsattrs.slaves =
 				    sysfs_has_subdirs_entries(newpath,
diff --git a/config/plugins/ldap/99cluster.ldif b/config/plugins/ldap/99cluster.ldif
index 6c4ee4b..c2ec09b 100644
--- a/config/plugins/ldap/99cluster.ldif
+++ b/config/plugins/ldap/99cluster.ldif
@@ -1,4 +1,4 @@
-# Auto-generated @ 2009-10-02 14:49:14
+# Auto-generated @ 2009-12-07 14:40:21
 dn: cn=schema
 attributeTypes: (
   1.3.6.1.4.1.2312.8.1.1.15 NAME 'rhcsAlias'
@@ -247,6 +247,18 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.243 NAME 'rhcsIo-timeout'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.244 NAME 'rhcsMaster-wins'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
   1.3.6.1.4.1.2312.8.1.1.124 NAME 'rhcsScore'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
@@ -529,7 +541,25 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.46 NAME 'rhcsSelf'
+  1.3.6.1.4.1.2312.8.1.1.267 NAME 'rhcsKey'
+  EQUALITY integerMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.268 NAME 'rhcsDevices'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.50 NAME 'rhcsAction'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.269 NAME 'rhcsAptpl'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
@@ -553,13 +583,19 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.50 NAME 'rhcsAction'
+  1.3.6.1.4.1.2312.8.1.1.51 NAME 'rhcsOption'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.51 NAME 'rhcsOption'
+  1.3.6.1.4.1.2312.8.1.1.59 NAME 'rhcsExec'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.60 NAME 'rhcsVmware-type'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
@@ -571,25 +607,31 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.61 NAME 'rhcsVmware-datacenter'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
   1.3.6.1.4.1.2312.8.1.1.53 NAME 'rhcsVerbose'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.54 NAME 'rhcsSwitch'
+  1.3.6.1.4.1.2312.8.1.1.245 NAME 'rhcsVersion'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.55 NAME 'rhcsIdentity-file'
+  1.3.6.1.4.1.2312.8.1.1.246 NAME 'rhcsHelp'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.56 NAME 'rhcsSsl'
+  1.3.6.1.4.1.2312.8.1.1.247 NAME 'rhcsSeparator'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
@@ -607,19 +649,85 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.59 NAME 'rhcsExec'
+  1.3.6.1.4.1.2312.8.1.1.248 NAME 'rhcsHmc-version'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.60 NAME 'rhcsVmware-type'
+  1.3.6.1.4.1.2312.8.1.1.249 NAME 'rhcsCmd-prompt'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
 attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.61 NAME 'rhcsVmware-datacenter'
+  1.3.6.1.4.1.2312.8.1.1.250 NAME 'rhcsInet4-only'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.251 NAME 'rhcsInet6-only'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.252 NAME 'rhcsIpport'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.55 NAME 'rhcsIdentity-file'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.253 NAME 'rhcsSnmp-version'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.254 NAME 'rhcsCommunity'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.255 NAME 'rhcsSnmp-auth-prot'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.256 NAME 'rhcsSnmp-sec-level'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.257 NAME 'rhcsSnmp-priv-prot'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.258 NAME 'rhcsSnmp-priv-passwd'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.259 NAME 'rhcsSnmp-priv-passwd-script'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.260 NAME 'rhcsUdpport'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
@@ -655,6 +763,54 @@ attributeTypes: (
   SINGLE-VALUE
   )
 attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.261 NAME 'rhcsCipher'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.262 NAME 'rhcsMethod'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.263 NAME 'rhcsDrac-version'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.264 NAME 'rhcsModule-name'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.54 NAME 'rhcsSwitch'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.265 NAME 'rhcsIo-fencing'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.56 NAME 'rhcsSsl'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.4.1.2312.8.1.1.266 NAME 'rhcsRibcl'
+  EQUALITY caseExactIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
   1.3.6.1.4.1.2312.8.1.1.9 NAME 'rhcsAgent'
   EQUALITY caseExactIA5Match
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
@@ -1368,24 +1524,6 @@ attributeTypes: (
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
-attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.224 NAME 'rhcsBlade'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.225 NAME 'rhcsLpan'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.4.1.2312.8.1.1.226 NAME 'rhcsPserver'
-  EQUALITY caseExactIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.1 NAME 'rhcsCluster' SUP top STRUCTURAL
      MUST ( rhcsConfig-version $ name )
@@ -1412,7 +1550,7 @@ objectClasses: (
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.29 NAME 'rhcsQuorumd' SUP top STRUCTURAL
      MUST ( cn )
-     MAY ( rhcsMax-error-cycles $ rhcsAllow-kill $ rhcsParanoid $ rhcsStop-cman $ rhcsPriority $ rhcsReboot $ rhcsScheduler $ rhcsStatus-file $ rhcsLabel $ rhcsDevice $ rhcsMin-score $ rhcsVotes $ rhcsTko $ rhcsInterval )
+     MAY ( rhcsMaster-wins $ rhcsIo-timeout $ rhcsMax-error-cycles $ rhcsAllow-kill $ rhcsParanoid $ rhcsStop-cman $ rhcsPriority $ rhcsReboot $ rhcsScheduler $ rhcsStatus-file $ rhcsLabel $ rhcsDevice $ rhcsMin-score $ rhcsVotes $ rhcsTko $ rhcsInterval )
    )
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.30 NAME 'rhcsHeuristic' SUP top STRUCTURAL
@@ -1483,7 +1621,7 @@ objectClasses: (
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.5 NAME 'rhcsFencedevice' SUP top STRUCTURAL
      MUST ( rhcsAgent $ name )
-     MAY ( rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsMulticast-ttl $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsVmware-datacenter $ rhcsVmware-type $ rhcsExec $ rhcsManaged $ rhcsPartition $ rhcsSsl $ rhcsIdentity-file $ rhcsSwitch $ rhcsVerbose $ rhcsSecure $ rhcsOption $ rhcsAction $ rhcsRpowerpath $ rhcsCserver $ rhcsServers $ rhcsSelf $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
+     MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsMethod $ rhcsCipher $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsMulticast-ttl $ rhcsMulticast-address $ rhcsIp-family $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsIdentity-file $ rhcsIpport $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsDebug $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsOption $ rhcsRpowerpath $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsAction $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
    )
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.21 NAME 'rhcsRm' SUP top STRUCTURAL
@@ -1637,5 +1775,5 @@ objectClasses: (
 objectClasses: (
      1.3.6.1.4.1.2312.8.1.2.6 NAME 'rhcsDevice' SUP top STRUCTURAL
      MUST ( name )
-     MAY ( rhcsNode $ rhcsLanplus $ rhcsPserver $ rhcsLpan $ rhcsIpaddr $ rhcsNodename $ rhcsBlade $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsAuth $ rhcsRetrans $ rhcsMulticast-ttl $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsVmware-datacenter $ rhcsVmware-type $ rhcsExec $ rhcsManaged $ rhcsPartition $ rhcsSsl $ rhcsIdentity-file $ rhcsSwitch $ rhcsPort $ rhcsVerbose $ rhcsSecure $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsOption $ rhcsAction )
+     MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsMethod $ rhcsCipher $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsMulticast-ttl $ rhcsMulticast-address $ rhcsIp-family $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsIdentity-file $ rhcsIpport $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsDebug $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsOption $ rhcsRpowerpath $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsAction $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
    )
diff --git a/config/plugins/ldap/ldap-base.csv b/config/plugins/ldap/ldap-base.csv
index f8a3681..690b92f 100644
--- a/config/plugins/ldap/ldap-base.csv
+++ b/config/plugins/ldap/ldap-base.csv
@@ -1,4 +1,4 @@
-# Max attribute value: 242
+# Max attribute value: 269
 # Max object class value: 58
 obj,rhcsCluster,cluster,1
 obj,rhcsCman,cman,3
@@ -299,3 +299,30 @@ obj,rhcsDrbd,drbd,58
 attr,rhcsResource,resource,240
 attr,rhcsUpgrading,upgrading,241
 attr,rhcsDisallowed,disallowed,242
+attr,rhcsIo-timeout,io_timeout,243
+attr,rhcsMaster-wins,master_wins,244
+attr,rhcsVersion,version,245
+attr,rhcsHelp,help,246
+attr,rhcsSeparator,separator,247
+attr,rhcsHmc-version,hmc_version,248
+attr,rhcsCmd-prompt,cmd_prompt,249
+attr,rhcsInet4-only,inet4_only,250
+attr,rhcsInet6-only,inet6_only,251
+attr,rhcsIpport,ipport,252
+attr,rhcsSnmp-version,snmp_version,253
+attr,rhcsCommunity,community,254
+attr,rhcsSnmp-auth-prot,snmp_auth_prot,255
+attr,rhcsSnmp-sec-level,snmp_sec_level,256
+attr,rhcsSnmp-priv-prot,snmp_priv_prot,257
+attr,rhcsSnmp-priv-passwd,snmp_priv_passwd,258
+attr,rhcsSnmp-priv-passwd-script,snmp_priv_passwd_script,259
+attr,rhcsUdpport,udpport,260
+attr,rhcsCipher,cipher,261
+attr,rhcsMethod,method,262
+attr,rhcsDrac-version,drac_version,263
+attr,rhcsModule-name,module_name,264
+attr,rhcsIo-fencing,io_fencing,265
+attr,rhcsRibcl,ribcl,266
+attr,rhcsKey,key,267
+attr,rhcsDevices,devices,268
+attr,rhcsAptpl,aptpl,269
diff --git a/config/tools/ldap/rng2ldif/tree.c b/config/tools/ldap/rng2ldif/tree.c
index 85a02ce..69fa139 100644
--- a/config/tools/ldap/rng2ldif/tree.c
+++ b/config/tools/ldap/rng2ldif/tree.c
@@ -3,6 +3,8 @@
 #include <string.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <assert.h>
 
 #include "zalloc.h"
 #include "value-list.h"
@@ -141,6 +143,43 @@ find_obj(struct ldap_object_node *objs, const char *name)
 }
 
 
+static xmlNodePtr 
+find_ref(xmlNodePtr curr_node)
+{
+	xmlNodePtr n;
+	char *name;
+	char *tmp_name;
+
+	dbg_printf("Trying to parse ref tag\n");
+	name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
+
+	n = xmlDocGetRootElement(curr_node->doc);
+	n = n->xmlChildrenNode;
+	for (; n; n = n->next) {
+		if (n->type != XML_ELEMENT_NODE)
+			continue;
+		if (strcasecmp((char *)n->name, "define"))
+			continue;
+		
+		tmp_name = (char *)xmlGetProp(n, "name");
+		if (!tmp_name)
+			continue;
+		if (strcmp(tmp_name, name))
+			continue;
+
+		break;
+	}
+
+	if (!n) {
+		fprintf(stderr, "Error in RelaxNG schema!\n");
+		fprintf(stderr, "Unterminated reference: %s\n",
+			name);
+		exit(1);
+	}
+
+	return n->xmlChildrenNode;
+}
+
 
 static int
 find_optional_attributes(xmlNodePtr curr_node, int in_block,
@@ -162,6 +201,10 @@ find_optional_attributes(xmlNodePtr curr_node, int in_block,
 	for (node = curr_node; node; node = node->next) {
 		if (node->type != XML_ELEMENT_NODE)
 			continue;
+		if (!strcasecmp((char *)node->name, "ref")) {
+			find_optional_attributes(
+				find_ref(node), 1, curr_obj, attrs, ids);
+		}
 		if (!strcasecmp((char *)node->name, "choice")) {
 			find_optional_attributes(node->xmlChildrenNode, 1,
 						 curr_obj,
@@ -315,6 +358,33 @@ parse_element_tag(xmlNodePtr curr_node,
 }
 
 
+#if 0
+static struct ldap_object_node *
+parse_ref_tag(xmlNodePtr curr_node,
+    	      struct ldap_object_node **objs,
+	      struct ldap_attr_node **attrs,
+	      struct idinfo *ids)
+{
+	xmlXPathObjectPtr xobj;
+	xmlXPathContextPtr xctx;
+	char query[1024];
+	char *n;
+	
+	dbg_printf("Trying to parse ref tag\n");
+	n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
+
+	snprintf(query, sizeof(query), "//define[@name=\"%s\"]", n);
+	xctx = xmlXPathNewContext(curr_node->doc);
+	assert(xctx);
+	xobj = xmlXPathEvalExpression((xmlChar *)query, xctx);
+
+	printf("%d nodes match %s\n", xobj->nodesetval->nodeNr, query);
+
+	assert(0);
+	return NULL;
+}
+#endif
+
 int
 find_objects(xmlNodePtr curr_node,
 	     struct ldap_object_node **objs,
diff --git a/config/tools/xml/ccs_config_validate.in b/config/tools/xml/ccs_config_validate.in
index e241cd3..55ab4aa 100644
--- a/config/tools/xml/ccs_config_validate.in
+++ b/config/tools/xml/ccs_config_validate.in
@@ -63,7 +63,7 @@ check_opts() {
 		;;
 		-C)
 			shift
-			COROSYNC_DEFAULT_CONFIG_IFACE=$1:cmanpreconfig
+			export COROSYNC_DEFAULT_CONFIG_IFACE=$1:cmanpreconfig
 			loaderoverride=1
 			if [ -n "$runtimetest" ] || \
 			   [ -n "$filetest" ] || \
@@ -74,8 +74,8 @@ check_opts() {
 		;;
 		-l)
 			shift
-			COROSYNC_CLUSTER_CONFIG_FILE=$1
-			COROSYNC_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig
+			export COROSYNC_CLUSTER_CONFIG_FILE=$1
+			export COROSYNC_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig
 			filetest=1
 			if [ -n "$loaderoverride" ] || \
 			   [ -n "$runtimetest" ] || \
@@ -86,7 +86,7 @@ check_opts() {
 		;;
 		-f)
 			shift
-			COROSYNC_CLUSTER_CONFIG_FILE=$1
+			export COROSYNC_CLUSTER_CONFIG_FILE=$1
 			unset COROSYNC_DEFAULT_CONFIG_IFACE
 			noloadtest=1
 			if [ -n "$loaderoverride" ] || \
@@ -157,8 +157,10 @@ lecho "Config interface set to: $COROSYNC_DEFAULT_CONFIG_IFACE"
 if [ -n "$noloadtest" ]; then
 	cp $COROSYNC_CLUSTER_CONFIG_FILE $tempfile
 else
+	export CMAN_PIPE=2
 	if ! ccs_config_dump > $tempfile; then
 		[ -z "$notempfilerm" ] && rm -f $tempfile
+		echo
 		echo "Unable to get the configuration" >&2
 		exit 255
 	fi
diff --git a/config/tools/xml/cluster.rng.in b/config/tools/xml/cluster.rng.in
index 887c477..2ad60e8 100644
--- a/config/tools/xml/cluster.rng.in
+++ b/config/tools/xml/cluster.rng.in
@@ -307,6 +307,12 @@ To validate your cluster.conf against this schema, run:
    <optional>
     <attribute name="max_error_cycles" rha:description="" rha:sample=""/>
    </optional>
+   <optional>
+    <attribute name="io_timeout" rha:description="" rha:sample=""/>
+   </optional>
+   <optional>
+    <attribute name="master_wins" rha:description="" rha:sample=""/>
+   </optional>
    <zeroOrMore>
     <element name="heuristic" rha:description="">
      <attribute name="program" rha:description="The program used to
@@ -746,448 +752,9 @@ To validate your cluster.conf against this schema, run:
      </attribute>
      <attribute name="agent" rha:description="Specifies a fence agent to
          be used." rha:sample="fence_apc"/>
-     <optional>
-      <choice>
-       <!-- begin specific fence devices -->
-
-       <!-- begin non-generated device definitions -->
-       <!-- RPS10 -->
-       <group rha:description="RPS10 Serial Switch" >
-        <attribute name="device" rha:description="The device the switch
-            is connected to on the controlling host."
-            rha:sample="/dev/ttys2"/>
-        <attribute name="port" rha:description="The switch outlet
-            number." rha:sample="2"/>
-       </group>
-       <!--FIXME: Determine if the following group should exclude
-       the auth and lanplus attributes. Those attributes apply only to
-       the impilan fence device.-->
-       <!-- Brocade, McData, SANBox2, Bladecenter,bullpap, ipmilan -->
-       <group>
-        <attribute name="ipaddr" rha:description="IP address or the name
-            of the device." rha:sample="rack007"/>
-        <optional>
-        <attribute name="login" rha:description="The login name used to
-            access the device. " rha:sample="admin"/>
-        </optional>
-        <optional>
-        <attribute name="passwd" rha:description="The password used to
-            authenticate the connection to the
-            device." rha:sample="pa$$word"/>
-        </optional>
-        <optional>
-        <attribute name="passwd_script" rha:description="The script that
-            supplies a password for access to the fence device. Using
-            this supersedes the Password parameter." rha:sample=""/>
-        </optional>
-        <optional>
-         <attribute name="auth" rha:description="For IPMI LAN
-             only. Authentication Type: none, password,
-             md2, or md5" rha:sample=""/>
-        </optional>
-        <optional>
-         <attribute name="lanplus" rha:description="For IPMI LAN only.
-             Set value to either True or 1; leave out for false."
-             rha:sample="True"/>
-        </optional>
-       </group>
-       <!-- Vixel -->
-       <group>
-        <optional>
-         <attribute name="ipaddr" rha:description="IP address or the
-             name of the device." rha:sample="10.1.0.1"/>
-        </optional>
-        <optional>
-        <attribute name="passwd" rha:description="The password used to
-            authenticate the connection to the
-            device." rha:sample="pa$$word"/>
-        </optional>
-        <optional>
-         <attribute name="passwd_script" rha:description="The script
-             that supplies a password for access to the
-             fence device. Using this supersedes the Password
-             parameter." rha:sample=""/>
-        </optional>
-       </group>
-       <!-- scsi reservations -->
-       <group>
-        <attribute name="nodename" rha:description="Name of the node to
-            be fenced. Refer to fence_scsi(8) for more
-            information." rha:sample=""/>
-        <attribute name="self" rha:description="" rha:sample=""/>
-       </group>
-       <!-- GNBD -->
-       <group>
-        <attribute name="servers" rha:description="The hostname of each
-            GNBD to disable. For multiple hostnames, separate each
-            hostname with a space." rha:sample=""/>
-       </group>
-       <!-- Egenera -->
-       <!-- FIXME: Note that in the schema web page each is listed as a
-       parameter. Likewise for Conga. In addition, Conga shows Ipan
-       and pserver parameters. Also, in Conga, the esh parameter is
-       an optional ESH path. Presumably those should be attributes in
-       the schema. We need more invormation on this. -->
-       <group>
-        <attribute name="cserver" rha:description="The hostname (and
-            optionally the username in the form of username at hostname)
-            assigned to the device. Refer to the fence_egenera(8) man
-            page for more information." rha:sample=""/>
-       </group>
-       <!-- FIXME: It appears that xCat is no longer supported. Found no
-       fence agents for x Cat in RHEL 5.3. -->
-       <!-- xCAT -->
-       <group>
-        <attribute name="rpowerpath" rha:description="" rha:sample=""/>
-       </group>
-       <!-- end non-generated device definitions -->
-
-       <!-- begin auto-generated device definitions -->
-      <!-- fence_alom -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_apc -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="switch"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_bladecenter -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="identity_file"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
 
-      <!-- fence_drac5 -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
+     <ref name="FENCEDEVICEOPTIONS"/>
 
-      <!-- fence_eps -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <optional>
-          <attribute name="login"/>
-        </optional>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_ilo -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="ssl"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_ldom -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="identity_file"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_lpar -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="partition"/>
-        </optional>
-        <optional>
-          <attribute name="managed"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_virsh -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="identity_file"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_vmware -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <attribute name="login"/>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="exec"/>
-        </optional>
-        <optional>
-          <attribute name="vmware_type"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="vmware_datacenter"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_wti -->
-      <group>
-        <optional>
-          <attribute name="action"/>
-        </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
-        </optional>
-        <attribute name="ipaddr"/>
-        <optional>
-          <attribute name="login"/>
-        </optional>
-        <optional>
-          <attribute name="passwd"/>
-        </optional>
-        <optional>
-          <attribute name="passwd_script"/>
-        </optional>
-        <optional>
-          <attribute name="secure"/>
-        </optional>
-        <optional>
-          <attribute name="verbose"/>
-        </optional>
-      </group>
-
-      <!-- fence_xvm -->
-      <group>
-        <optional>
-          <attribute name="debug"/>
-        </optional>
-        <optional>
-          <attribute name="ip_family"/>
-        </optional>
-        <optional>
-          <attribute name="multicast_address"/>
-        </optional>
-        <optional>
-          <attribute name="port"/>
-        </optional>
-        <optional>
-          <attribute name="multicast_ttl"/>
-        </optional>
-        <optional>
-          <attribute name="retrans"/>
-        </optional>
-        <optional>
-          <attribute name="auth"/>
-        </optional>
-        <optional>
-          <attribute name="hash"/>
-        </optional>
-        <optional>
-          <attribute name="key_file"/>
-        </optional>
-        <optional>
-          <attribute name="domain"/>
-        </optional>
-        <optional>
-          <attribute name="use_uuid"/>
-        </optional>
-        <optional>
-          <attribute name="option"/>
-        </optional>
-        <optional>
-          <attribute name="timeout"/>
-        </optional>
-      </group>
-       <!-- end auto-generated device definitions -->
-
-       <group>
-        <optional>
-         <empty/>
-        </optional>
-       </group>
-
-       <!-- end specific fence devices -->
-      </choice>
-     </optional>
     </element>
   </zeroOrMore>
  </element>
@@ -2447,411 +2014,1330 @@ To validate your cluster.conf against this schema, run:
    <attribute name="name" rha:description="" rha:sample="">
     <data type="IDREF"/>
    </attribute>
-   <choice>
-      <!-- begin node fence specific devices -->
 
-      <!-- begin auto-generated device definitions -->
-      <!-- fence_alom -->
+   <ref name="FENCEDEVICEOPTIONS"/>
+
+  </element>
+ </define>
+<!-- end node fence definitions -->
+
+
+<!-- begin fence attribute group definitions -->
+ <define name="FENCEDEVICEOPTIONS">
+     <optional>
+      <choice>
+       <!-- begin specific fence devices -->
+
+       <!-- begin non-generated device definitions -->
+       <!-- RPS10 -->
+       <group rha:description="RPS10 Serial Switch" >
+        <attribute name="device" rha:description="The device the switch
+            is connected to on the controlling host."
+            rha:sample="/dev/ttys2"/>
+        <attribute name="port" rha:description="The switch outlet
+            number." rha:sample="2"/>
+       </group>
+       <!--FIXME: Determine if the following group should exclude
+       the auth and lanplus attributes. Those attributes apply only to
+       the impilan fence device.-->
+       <!-- Brocade, McData, SANBox2, Bladecenter,bullpap, ipmilan -->
+       <group>
+        <attribute name="ipaddr" rha:description="IP address or the name
+            of the device." rha:sample="rack007"/>
+        <optional>
+        <attribute name="login" rha:description="The login name used to
+            access the device. " rha:sample="admin"/>
+        </optional>
+        <optional>
+        <attribute name="passwd" rha:description="The password used to
+            authenticate the connection to the
+            device." rha:sample="pa$$word"/>
+        </optional>
+        <optional>
+        <attribute name="passwd_script" rha:description="The script that
+            supplies a password for access to the fence device. Using
+            this supersedes the Password parameter." rha:sample=""/>
+        </optional>
+        <optional>
+         <attribute name="auth" rha:description="For IPMI LAN
+             only. Authentication Type: none, password,
+             md2, or md5" rha:sample=""/>
+        </optional>
+        <optional>
+         <attribute name="lanplus" rha:description="For IPMI LAN only.
+             Set value to either True or 1; leave out for false."
+             rha:sample="True"/>
+        </optional>
+       </group>
+       <!-- Vixel -->
+       <group>
+        <optional>
+         <attribute name="ipaddr" rha:description="IP address or the
+             name of the device." rha:sample="10.1.0.1"/>
+        </optional>
+        <optional>
+        <attribute name="passwd" rha:description="The password used to
+            authenticate the connection to the
+            device." rha:sample="pa$$word"/>
+        </optional>
+        <optional>
+         <attribute name="passwd_script" rha:description="The script
+             that supplies a password for access to the
+             fence device. Using this supersedes the Password
+             parameter." rha:sample=""/>
+        </optional>
+       </group>
+       <!-- scsi reservations -->
+       <group>
+        <optional>
+         <attribute name="nodename" rha:description="Name of the node to
+            be fenced. Refer to fence_scsi(8) for more
+            information." rha:sample=""/>
+        </optional>
+        <optional>
+         <attribute name="key" rha:description="" rha:sample="33">
+          <data type="positiveInteger"/>
+         </attribute>
+        </optional>
+        <optional>
+         <attribute name="devices" rha:description="List of devices
+	    to fence (separated by commas)." rha:sample="/dev/sdb,/dev/sdc"/>
+        </optional>
+        <optional>
+         <attribute name="action" rha:description="Fencing action to
+	    take (off or on)." rha:sample="off"/>
+        </optional>
+        <optional>
+         <attribute name="logfile" rha:description="Location to output
+	    logs from fence_scsi." rha:sample="/var/log/fence_scsi.log"/>
+        </optional>
+        <optional>
+         <attribute name="aptpl" rha:description="" rha:sample=""/>
+        </optional>
+       </group>
+       <!-- GNBD -->
+       <group>
+        <attribute name="servers" rha:description="The hostname of each
+            GNBD to disable. For multiple hostnames, separate each
+            hostname with a space." rha:sample=""/>
+       </group>
+       <!-- Egenera -->
+       <!-- FIXME: Note that in the schema web page each is listed as a
+       parameter. Likewise for Conga. In addition, Conga shows Ipan
+       and pserver parameters. Also, in Conga, the esh parameter is
+       an optional ESH path. Presumably those should be attributes in
+       the schema. We need more invormation on this. -->
+       <group>
+        <attribute name="cserver" rha:description="The hostname (and
+            optionally the username in the form of username at hostname)
+            assigned to the device. Refer to the fence_egenera(8) man
+            page for more information." rha:sample=""/>
+       </group>
+       <!-- FIXME: It appears that xCat is no longer supported. Found no
+       fence agents for x Cat in RHEL 5.3. -->
+       <!-- xCAT -->
+       <group>
+        <attribute name="rpowerpath" rha:description="" rha:sample=""/>
+       </group>
+       <!-- end non-generated device definitions -->
+
+       <!-- begin auto-generated device definitions -->
+      <!-- fence_vmware -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
-        <attribute name="login"/>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="exec" rha:description="Command to execute" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="vmware_type" rha:description="Type of VMware to connect" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="vmware_datacenter" rha:description="Show only machines in specified datacenter" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_apc -->
+
+      <!-- fence_lpar -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="partition" rha:description="Partition name" />
+        </optional>
+        <optional>
+          <attribute name="managed" rha:description="Managed system name" />
+        </optional>
+        <optional>
+          <attribute name="hmc_version" rha:description="Force HMC version to use (3 or 4)" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="switch"/>
+          <attribute name="verbose" rha:description="Verbose mode" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
+
       <!-- fence_bladecenter -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="identity_file" rha:description="Identity file for ssh" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="identity_file"/>
+          <attribute name="verbose" rha:description="Verbose mode" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_drac5 -->
+
+      <!-- fence_intelmodular -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="snmp_version" rha:description="Specifies SNMP version to use (1,2c,3)" />
+        </optional>
+        <optional>
+          <attribute name="community" rha:description="Set the community string" />
+        </optional>
+        <optional>
+          <attribute name="snmp_auth_prot" rha:description="Set authentication protocol (MD5|SHA)" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="snmp_sec_level" rha:description="Set security level (noAuthNoPriv|authNoPriv|authPriv)" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="snmp_priv_prot" rha:description="Set privacy protocol (DES|AES)" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="snmp_priv_passwd" rha:description="Set privacy protocol password" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="snmp_priv_passwd_script" rha:description="Script to run to retrieve privacy password" />
+        </optional>
+        <optional>
+          <attribute name="udpport" rha:description="UDP/TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_eps -->
+
+      <!-- fence_ifmib -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="snmp_version" rha:description="Specifies SNMP version to use (1,2c,3)" />
+        </optional>
+        <optional>
+          <attribute name="community" rha:description="Set the community string" />
+        </optional>
+        <optional>
+          <attribute name="snmp_auth_prot" rha:description="Set authentication protocol (MD5|SHA)" />
         </optional>
         <optional>
-          <attribute name="login"/>
+          <attribute name="snmp_sec_level" rha:description="Set security level (noAuthNoPriv|authNoPriv|authPriv)" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="snmp_priv_prot" rha:description="Set privacy protocol (DES|AES)" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="snmp_priv_passwd" rha:description="Set privacy protocol password" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="snmp_priv_passwd_script" rha:description="Script to run to retrieve privacy password" />
+        </optional>
+        <optional>
+          <attribute name="udpport" rha:description="UDP/TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_ilo -->
+
+      <!-- fence_eps -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
         </optional>
         <optional>
-          <attribute name="ssl"/>
+          <attribute name="verbose" rha:description="Verbose mode" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
+
       <!-- fence_ldom -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="login" rha:description="Login Name" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
         <optional>
-          <attribute name="identity_file"/>
+          <attribute name="secure" rha:description="SSH connection" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="identity_file" rha:description="Identity file for ssh" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_lpar -->
+
+      <!-- fence_xvm -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Specify (CCS) / increment (command line) debug level" />
+        </optional>
+        <optional>
+          <attribute name="ip_family" rha:description="IP Family ([auto], ipv4, ipv6)" />
+        </optional>
+        <optional>
+          <attribute name="multicast_address" rha:description="Multicast address (default=225.0.0.12 / ff02::3:1)" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="IP port (default=1229)" />
+        </optional>
+        <optional>
+          <attribute name="multicast_ttl" rha:description="Multicast time-to-live (in hops; default=2)" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="retrans" rha:description="Multicast retransmit time (in 1/10sec; default=20)" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="auth" rha:description="Authentication (none, sha1, [sha256], sha512)" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="hash" rha:description="Packet hash strength (none, sha1, [sha256], sha512)" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="key_file" rha:description="Shared key file (default=/etc/cluster/fence_xvm.key)" />
         </optional>
         <optional>
-          <attribute name="partition"/>
+          <attribute name="domain" rha:description="Virtual machine (domain name) to fence" />
         </optional>
         <optional>
-          <attribute name="managed"/>
+          <attribute name="use_uuid" rha:description="Treat 'domain' as UUID instead of domain name" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="action" rha:description="Fencing action (null, off, [reboot])" />
+        </optional>
+        <optional>
+          <attribute name="timeout" rha:description="Fencing timeout (in seconds; default=30)" />
         </optional>
       </group>
 
-      <!-- fence_virsh -->
+
+      <!-- fence_ipmilan -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="auth" rha:description="IPMI Lan Auth type (md5, password, or none)" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IPMI Lan IP to talk to" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Password (if required) to control power on IPMI device" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password (if required)" />
+        </optional>
+        <optional>
+          <attribute name="lanplus" rha:description="Use Lanplus" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Username/Login (if required) to control power on IPMI device" />
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Operation to perform. Valid operations: on, off, reboot, status, list, monitor or metadata" />
+        </optional>
+        <optional>
+          <attribute name="timeout" rha:description="Timeout (sec) for IPMI operation" />
+        </optional>
+        <optional>
+          <attribute name="cipher" rha:description="Ciphersuite to use (same as ipmitool -C parameter)" />
+        </optional>
+        <optional>
+          <attribute name="method" rha:description="Method to fence (onoff or cycle)" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+      </group>
+
+
+      <!-- fence_rsa -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="secure" rha:description="SSH connection" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
         </optional>
         <optional>
-          <attribute name="identity_file"/>
+          <attribute name="verbose" rha:description="Verbose mode" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
         </optional>
       </group>
 
-      <!-- fence_vmware -->
+
+      <!-- fence_virsh -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="identity_file" rha:description="Identity file for ssh" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="exec"/>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
         </optional>
         <optional>
-          <attribute name="vmware_type"/>
+          <attribute name="verbose" rha:description="Verbose mode" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="debug" rha:description="Write debug information to given file" />
         </optional>
         <optional>
-          <attribute name="vmware_datacenter"/>
+          <attribute name="version" rha:description="Display version information and exit" />
         </optional>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
+
       <!-- fence_wti -->
       <group>
         <optional>
-          <attribute name="action"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
         </optional>
-        <optional> <!-- lhh - compat -->
-          <attribute name="option"/>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
         </optional>
         <optional>
-          <attribute name="login"/>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
         </optional>
         <optional>
-          <attribute name="passwd"/>
+          <attribute name="login" rha:description="Login Name" />
         </optional>
         <optional>
-          <attribute name="passwd_script"/>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
         <optional>
-          <attribute name="secure"/>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
-        <attribute name="port"/>
         <optional>
-          <attribute name="verbose"/>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
 
-      <!-- fence_xvm -->
+
+      <!-- fence_drac5 -->
       <group>
         <optional>
-          <attribute name="debug"/>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
         </optional>
         <optional>
-          <attribute name="ip_family"/>
+          <attribute name="action" rha:description="Fencing Action" />
         </optional>
         <optional>
-          <attribute name="multicast_address"/>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
         </optional>
         <optional>
-          <attribute name="port"/>
+          <attribute name="login" rha:description="Login Name" />
         </optional>
         <optional>
-          <attribute name="multicast_ttl"/>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
         </optional>
         <optional>
-          <attribute name="retrans"/>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
         </optional>
         <optional>
-          <attribute name="auth"/>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
         </optional>
         <optional>
-          <attribute name="hash"/>
+          <attribute name="secure" rha:description="SSH connection" />
         </optional>
         <optional>
-          <attribute name="key_file"/>
+          <attribute name="drac_version" rha:description="Force DRAC version to use" />
         </optional>
         <optional>
-          <attribute name="domain"/>
+          <attribute name="module_name" rha:description="DRAC/MC module name" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
         </optional>
         <optional>
-          <attribute name="use_uuid"/>
+          <attribute name="version" rha:description="Display version information and exit" />
         </optional>
         <optional>
-          <attribute name="option"/>
+          <attribute name="help" rha:description="Display help and exit" />
         </optional>
         <optional>
-          <attribute name="timeout"/>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
         </optional>
       </group>
-      <!-- end auto-generated device definitions -->
 
-      <!-- begin non-generated device definitions -->
-        <!-- Brocade, Vixel, McData, SANBox2 -->
-        <group>
-         <attribute name="port"/>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- BladeCenter -->
-        <group>
-         <attribute name="blade"/>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- xCAT, manual -->
-        <group>
-         <attribute name="nodename"/>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-	<!-- GNBD -->
-        <group>
-         <attribute name="nodename"/>
-	 <optional>
-	  <attribute name="ipaddr"/>
-	 </optional>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- bullpap -->
-        <group>
-         <attribute name="domain"/>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- Egenera -->
-        <group>
-         <attribute name="lpan"/>
-         <attribute name="pserver"/>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- ILO, ipmilan -->
-        <group>
-         <optional>
-          <empty/>
-         </optional>
-         <optional>
-          <attribute name="lanplus"/>
-         </optional>
-         <optional>
-          <attribute name="option"/>
-         </optional>
-        </group>
-        <!-- scsi reservations -->
-        <group>
-         <optional>
-          <attribute name="node"/>
-         </optional>
-        </group>
-        <!-- xvm -->
-        <group>
-         <optional>
-          <attribute name="domain"/>
-         </optional>
-        </group>
-      <!-- end non-generated device definitions -->
 
-   <!-- end node fence specific devices -->
-   </choice>
-  </element>
- </define>
-<!-- end node fence definitions -->
+      <!-- fence_ilo_mp -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+
+      <!-- fence_apc -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="switch" rha:description="Physical switch number on device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+
+      <!-- fence_alom -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="secure" rha:description="SSH connection" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+      </group>
+
+
+      <!-- fence_ibmblade -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="snmp_version" rha:description="Specifies SNMP version to use (1,2c,3)" />
+        </optional>
+        <optional>
+          <attribute name="community" rha:description="Set the community string" />
+        </optional>
+        <optional>
+          <attribute name="snmp_auth_prot" rha:description="Set authentication protocol (MD5|SHA)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_sec_level" rha:description="Set security level (noAuthNoPriv|authNoPriv|authPriv)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_prot" rha:description="Set privacy protocol (DES|AES)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd" rha:description="Set privacy protocol password" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd_script" rha:description="Script to run to retrieve privacy password" />
+        </optional>
+        <optional>
+          <attribute name="udpport" rha:description="UDP/TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+
+      <!-- fence_sanbox2 -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="io_fencing" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="cmd_prompt" rha:description="Force command prompt" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+
+      <!-- fence_apc_snmp -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="snmp_version" rha:description="Specifies SNMP version to use (1,2c,3)" />
+        </optional>
+        <optional>
+          <attribute name="community" rha:description="Set the community string" />
+        </optional>
+        <optional>
+          <attribute name="snmp_auth_prot" rha:description="Set authentication protocol (MD5|SHA)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_sec_level" rha:description="Set security level (noAuthNoPriv|authNoPriv|authPriv)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_prot" rha:description="Set privacy protocol (DES|AES)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd" rha:description="Set privacy protocol password" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd_script" rha:description="Script to run to retrieve privacy password" />
+        </optional>
+        <optional>
+          <attribute name="udpport" rha:description="UDP/TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+
+      <!-- fence_ilo -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="ssl" rha:description="SSL connection" />
+        </optional>
+        <optional>
+          <attribute name="ribcl" rha:description="Force ribcl version to use" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="ipport" rha:description="TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+      </group>
+
+
+      <!-- fence_cisco_mds -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional>
+        <optional>
+          <attribute name="action" rha:description="Fencing Action" />
+        </optional>
+        <optional>
+          <attribute name="ipaddr" rha:description="IP Address or Hostname" />
+        </optional>
+        <optional>
+          <attribute name="login" rha:description="Login Name" />
+        </optional>
+        <optional>
+          <attribute name="passwd" rha:description="Login password or passphrase" />
+        </optional>
+        <optional>
+          <attribute name="passwd_script" rha:description="Script to retrieve password" />
+        </optional>
+        <optional>
+          <attribute name="port" rha:description="Physical plug number or name of virtual machine" />
+        </optional>
+        <optional>
+          <attribute name="snmp_version" rha:description="Specifies SNMP version to use (1,2c,3)" />
+        </optional>
+        <optional>
+          <attribute name="community" rha:description="Set the community string" />
+        </optional>
+        <optional>
+          <attribute name="snmp_auth_prot" rha:description="Set authentication protocol (MD5|SHA)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_sec_level" rha:description="Set security level (noAuthNoPriv|authNoPriv|authPriv)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_prot" rha:description="Set privacy protocol (DES|AES)" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd" rha:description="Set privacy protocol password" />
+        </optional>
+        <optional>
+          <attribute name="snmp_priv_passwd_script" rha:description="Script to run to retrieve privacy password" />
+        </optional>
+        <optional>
+          <attribute name="udpport" rha:description="UDP/TCP port to use for connection with device" />
+        </optional>
+        <optional>
+          <attribute name="inet4_only" rha:description="Forces agent to use IPv4 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="inet6_only" rha:description="Forces agent to use IPv6 addresses only" />
+        </optional>
+        <optional>
+          <attribute name="verbose" rha:description="Verbose mode" />
+        </optional>
+        <optional>
+          <attribute name="debug" rha:description="Write debug information to given file" />
+        </optional>
+        <optional>
+          <attribute name="version" rha:description="Display version information and exit" />
+        </optional>
+        <optional>
+          <attribute name="help" rha:description="Display help and exit" />
+        </optional>
+        <optional>
+          <attribute name="separator" rha:description="Separator for CSV created by operation list" />
+        </optional>
+      </group>
+
+       <!-- end auto-generated device definitions -->
+
+       <group>
+        <optional>
+         <empty/>
+        </optional>
+       </group>
+
+       <!-- end specific fence devices -->
+      </choice>
+     </optional>
+  </define>
+<!-- end fence attribute group definitions -->
 
 </grammar>
diff --git a/fence/agents/bladecenter/fence_bladecenter.py b/fence/agents/bladecenter/fence_bladecenter.py
index 64b7351..708fc84 100644
--- a/fence/agents/bladecenter/fence_bladecenter.py
+++ b/fence/agents/bladecenter/fence_bladecenter.py
@@ -99,7 +99,7 @@ def main():
 
 	atexit.register(atexit_handler)
 
-	all_opt["power_wait"]["default"] = "5"
+	all_opt["power_wait"]["default"] = "10"
 	all_opt["cmd_prompt"]["default"] = "system>"
 
 	options = check_input(device_opt, process_input(device_opt))
diff --git a/fence/agents/drac/fence_drac.pl b/fence/agents/drac/fence_drac.pl
index 5cc1a52..55d512d 100644
--- a/fence/agents/drac/fence_drac.pl
+++ b/fence/agents/drac/fence_drac.pl
@@ -139,7 +139,7 @@ sub login
 		fail "failed: telnet failed: ". $t->errmsg."\n" ;
 
 	# Determine DRAC version
-  if (/Dell Embedded Remote Access Controller \(ERA\)\nFirmware Version/m)
+  if (/Dell Embedded Remote Access Controller \(ERA(\/O)?\)\nFirmware Version/m)
   {
     $drac_version = $DRAC_VERSION_III_XT;
   } else {
diff --git a/fence/agents/ilo/fence_ilo.py b/fence/agents/ilo/fence_ilo.py
index 9207ec1..10d888c 100755
--- a/fence/agents/ilo/fence_ilo.py
+++ b/fence/agents/ilo/fence_ilo.py
@@ -61,6 +61,7 @@ def main():
 	atexit.register(atexit_handler)
 
 	all_opt["login_timeout"]["default"] = "10"
+	all_opt["retry_on"]["default"] = "3"
 
 	pinput = process_input(device_opt)
 	pinput["-z"] = 1
diff --git a/fence/agents/ipmilan/ipmilan.c b/fence/agents/ipmilan/ipmilan.c
index c25a9a5..e0b92fb 100644
--- a/fence/agents/ipmilan/ipmilan.c
+++ b/fence/agents/ipmilan/ipmilan.c
@@ -889,6 +889,7 @@ main(int argc, char **argv)
 	memset(passwd, 0, sizeof(passwd));
 	memset(user, 0, sizeof(user));
 	memset(op, 0, sizeof(op));
+	memset(method, 0, sizeof(method));
 
 	if (argc > 1) {
 		/*
diff --git a/fence/agents/lib/fence2rng.xsl b/fence/agents/lib/fence2rng.xsl
new file mode 100644
index 0000000..8d23ed9
--- /dev/null
+++ b/fence/agents/lib/fence2rng.xsl
@@ -0,0 +1,20 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" indent="yes"/>
+<xsl:template name="capitalize">
+	<xsl:param name="value"/>
+	<xsl:variable name="normalized" select="translate($value, '_abcdefghijklmnopqrstuvwrxyz', '-ABCDEFGHIJKLMNOPQRSTUVWRXYZ')"/>
+	<xsl:value-of select="$normalized"/>
+</xsl:template>
+<xsl:template match="/resource-agent">
+      <!-- <xsl:value-of select="@name"/> -->
+      <group>
+        <optional>
+          <attribute name="option"/> <!-- deprecated; for compatibility.  use "action" -->
+        </optional><xsl:for-each select="parameters/parameter">
+        <optional>
+          <attribute name="<xsl:value-of select="@name"/>" rha:description="<xsl:value-of select="normalize-space(shortdesc)"/>" />
+        </optional></xsl:for-each>
+      </group>
+
+</xsl:template>
+</xsl:stylesheet>
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index e30a87a..8c702b8 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -347,9 +347,17 @@ all_opt = {
 		"getopt" : "M",
 		"longopt" : "missing-as-off",
 		"help" : "--missing-as-off               Missing port returns OFF instead of failure",
-		"order" : 200}
+		"order" : 200 },
+	"retry_on" : {
+		"getopt" : "F:",
+		"longopt" : "retry-on",
+		"help" : "--retry-on <attempts>          Count of attempts to retry power on",
+		"default" : "1",
+		"order" : 200 }
 }
 
+common_opt = [ "retry_on" ]
+
 class fspawn(pexpect.spawn):
 	def log_expect(self, options, pattern, timeout):
 		result = self.expect(pattern, timeout)
@@ -460,6 +468,12 @@ def metadata(avail_opt, options, docs):
 
 def process_input(avail_opt):
 	global all_opt
+	global common_opt
+
+	##
+	## Add options which are available for every fence agent
+	#####
+	avail_opt.extend(common_opt)
 
 	##
 	## Set standard environment
@@ -559,7 +573,13 @@ def process_input(avail_opt):
 ######
 def check_input(device_opt, opt):
 	global all_opt
+	global common_opt
 
+	##
+	## Add options which are available for every fence agent
+	#####
+	device_opt.extend(common_opt)
+	
 	options = dict(opt)
 	options["device_opt"] = device_opt
 
@@ -715,9 +735,15 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
 		if status == "on":
 			print "Success: Already ON"
 		else:
-			set_power_fn(tn, options)
-			time.sleep(int(options["-G"]))
-			if wait_power_status(tn, options, get_power_fn):
+			power_on = False
+			for i in range(1,1 + int(options["-F"])):
+				set_power_fn(tn, options)
+				time.sleep(int(options["-G"]))
+				if wait_power_status(tn, options, get_power_fn):
+					power_on = True
+					break
+
+			if power_on:
 				print "Success: Powered ON"
 			else:
 				fail(EC_WAITING_ON)
@@ -739,10 +765,19 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
 			if wait_power_status(tn, options, get_power_fn) == 0:
 				fail(EC_WAITING_OFF)
 		options["-o"] = "on"
-		set_power_fn(tn, options)
-		time.sleep(int(options["-G"]))
-		if wait_power_status(tn, options, get_power_fn) == 0:
+
+		power_on = False
+		for i in range(1,1 + int(options["-F"])):
+			set_power_fn(tn, options)
+			time.sleep(int(options["-G"]))
+			if wait_power_status(tn, options, get_power_fn) == 1:
+				power_on = True
+				break
+
+		if power_on == False:
+			# this should not fail as not was fenced succesfully
 			sys.stderr.write('Timed out waiting to power ON\n')
+
 		print "Success: Rebooted"
 	elif options["-o"] == "status":
 		print "Status: " + status.upper()
diff --git a/fence/agents/lib/fencing_snmp.py.py b/fence/agents/lib/fencing_snmp.py.py
index d6f6ab4..94f5af5 100644
--- a/fence/agents/lib/fencing_snmp.py.py
+++ b/fence/agents/lib/fencing_snmp.py.py
@@ -80,7 +80,7 @@ class FencingSnmp:
 		try:
 			self.log_command(command)
 
-			(res_output,res_code)=pexpect.run(command,int(options["-Y"])+int(options["-y"])+additional_timemout,True)
+			(res_output,res_code)=pexpect.run(command,int(self.options["-Y"])+int(self.options["-y"])+additional_timemout,True)
 
 			if (res_code==None):
 				fail(EC_TIMED_OUT)
diff --git a/fence/agents/rsb/fence_rsb.py b/fence/agents/rsb/fence_rsb.py
index 77ac26b..8397f36 100644
--- a/fence/agents/rsb/fence_rsb.py
+++ b/fence/agents/rsb/fence_rsb.py
@@ -74,6 +74,8 @@ def main():
 
   result = 0
 
+  completed_action = 0
+
   #set up regex list
   USERNAME = 0
   PASSWORD = 1
@@ -88,7 +90,7 @@ def main():
   regex_list.append("user name\s*:")
   regex_list.append("pass phrase\s*:")
   regex_list.append("[Ee]nter\s+[Ss]election[^\r\n]*:")
-  regex_list.append("[pP]ower Status:")
+  regex_list.append("[pP]ower Status\s*:")
   regex_list.append("[Ee]rror\s*:")
   regex_list.append("[Pp]ress any key to continue")
   regex_list.append("really want to")
@@ -277,7 +279,15 @@ def main():
       sock.close()
       sys.exit(1)
 
-    buf = sock.read_eager()
+    try:
+      buf = sock.read_eager()
+    except EOFError:
+      if completed_action == 1:
+      	# action was completed succesfully, connection closed is OK
+        sys.exit(result)
+      else:
+        raise
+	         
     if i == USERNAME:
       if verbose:
         print "Sending login: %s\n" % login
@@ -318,6 +328,7 @@ def main():
             if verbose:
               print "Power off was successful"
             if action == POWER_OFF:
+              completed_action = 1
               depth += 1
               sock.write("0\r")
             else:
@@ -345,6 +356,7 @@ def main():
           elif power_command_issued and power_state == 1:
             if verbose:
               print "Power on was successful"
+            completed_action = 1
             depth += 1
             sock.write("0\r")
           elif tries > 0:
@@ -381,6 +393,7 @@ def main():
           os.write(standard_err, ("FENCE: Cannot determine power state: %s" % buf))
           sys.exit(1)
         depth = 2
+        completed_action = 1
 
     elif i == DONE:
       break
diff --git a/fence/agents/scsi/Makefile b/fence/agents/scsi/Makefile
index 969e369..17f31ef 100644
--- a/fence/agents/scsi/Makefile
+++ b/fence/agents/scsi/Makefile
@@ -1,7 +1,7 @@
 include ../../../make/defines.mk
 
-TARGET= fence_scsi fence_scsi_test
-SBINDIRT=fence_scsi fence_scsi_test
+TARGET= fence_scsi
+SBINDIRT=fence_scsi
 
 include $(OBJDIR)/make/fencebuild.mk
 
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index d95198b..e58a5b1 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -1,22 +1,8 @@
 #!/usr/bin/perl
 
+use File::Basename;
 use Getopt::Std;
 use IPC::Open3;
-use POSIX;
-
-my $ME = $0;
-
-END {
-  defined fileno STDOUT or return;
-  close STDOUT and return;
-  warn "$ME: failed to close standard output: $!\n";
-  $? ||= 1;
-}
-
-$_ = $0;
-s/.*\///;
-my $pname = $_;
-my @device_list;
 
 #BEGIN_VERSION_GENERATION
 $RELEASE_VERSION="";
@@ -24,373 +10,599 @@ $REDHAT_COPYRIGHT="";
 $BUILD_DATE="";
 #END_VERSION_GENERATION
 
-sub usage
+my $ME = fileparse ($0, ".pl");
+
+################################################################################
+
+sub log_debug ($)
 {
-    print "Usage\n";
-    print "\n";
-    print "$pname [options]\n";
-    print "\n";
-    print "Options:\n";
-    print "  -n <node>		ip address or hostname of node to fence\n";
-    print "  -h			usage\n";
-    print "  -u			unfence\n";
-    print "  -v			verbose\n";
-    print "  -V			version\n";
+    my ($msg) = @_;
 
-    exit 0;
+    print STDOUT "[debug]: $msg\n" unless defined ($opt_q);
 }
 
-sub version
+sub log_error ($)
 {
-    print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-    print "$REDHAT_COPYRIGHT\n" if ($REDHAT_COPYRIGHT);
+    my ($msg) = @_;
+
+    print STDERR "[error]: $msg\n" unless defined ($opt_q);
 }
 
-sub fail_usage
+sub do_action_on ($@)
 {
-    ($msg) = @_;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($node_key, @devices) = @_;
+
+    key_write ($node_key);
 
-    print STDERR $msg."\n" if $msg;
-    print STDERR "Please use '-h' for usage.\n";
+    foreach $dev (@devices) {
+	do_register_ignore ($node_key, $dev);
 
-    exit 1;
+	if (!get_reservation_key ($dev)) {
+	    do_reserve ($node_key, $dev);
+	}
+    }
 }
 
-sub check_sg_persist
+sub do_action_off ($@)
 {
-    my ($in, $out, $err);
-    my $cmd = "sg_persist -V";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($node_key, @devices) = @_;
 
-    waitpid($pid, 0);
+    my $host_key = key_read ();
 
-    die "unable to execute sg_persist.\n" if ($?>>8);
+    if ($host_key eq $node_key) {
+	log_error ($self);
+	exit (1);
+    }
+
+    foreach $dev (@devices) {
+	my @keys = grep { /$node_key/ } get_registration_keys ($dev);
 
-    close ($in);
-    close ($out);
-    close ($err);
+	if (scalar (@keys) != 0) {
+	    do_preempt_abort ($host_key, $node_key, $dev);
+	}
+    }
 }
 
-sub get_cluster_id
+sub do_action_status ($@)
 {
-    my ($in, $out, $err);
-    my $cmd = "cman_tool status";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    waitpid($pid, 0);
+    my ($node_key, @devices) = @_;
 
-    die "unable to execute cman_tool.\n" if ($?>>8);
+    my $dev_count = 0;
+    my $key_count = 0;
 
-    my $cluster_id;
+    foreach $dev (@devices) {
+	my @keys = grep { /$node_key/ } get_registration_keys ($dev);
 
-    while (<$out>) {
-	chomp;
+	if (scalar (@keys) != 0) {
+	    $dev_count++;
+	}
+    }
 
-	my ($name, $value) = split(/\s*:\s*/, $_);
+    if ($dev_count != 0) {
+	exit (0);
+    }
+    else {
+	exit (2);
+    }
+}
 
-	if ($name eq "Cluster Id") {
-	    $cluster_id = $value;
-	    last;
+sub do_register ($$$)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($host_key, $node_key, $dev) = @_;
+
+    if (substr ($dev, 5) =~ /^dm/) {
+	my @slaves = get_mpath_slaves ($dev);
+
+	foreach (@slaves) {
+	    do_register ($node_key, $_);
 	}
+	return;
     }
 
-    close ($in);
-    close ($out);
-    close ($err);
+    my $cmd = "sg_persist -n -o -G -K $host_key -S $node_key -d $dev";
+    $cmd .= " -Z" if (defined $opt_a);
+
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
 
-    return $cluster_id;
+    die "[error]: $self\n" if ($?>>8);
+
+    close (IN);
+    close (OUT);
+    close (ERR);
 }
 
-sub get_node_id
+sub do_register_ignore ($$)
 {
-    ($node) = @_;
-
-    my ($in, $out, $err);
-    my $cmd = "ccs_tool query /cluster/clusternodes/clusternode[\@name=\\\"$node\\\"]/\@nodeid";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    waitpid($pid, 0);
+    my ($node_key, $dev) = @_;
 
-    die "Unable to execute ccs_tool.\n" if ($?>>8);
+    if (substr ($dev, 5) =~ /^dm/) {
+	my @slaves = get_mpath_slaves ($dev);
 
-    while (<$out>) {
-        chomp;
-        $node_id = $_;
+	foreach (@slaves) {
+	    do_register_ignore ($node_key, $_);
+	}
+	return;
     }
 
-    close ($in);
-    close ($out);
-    close ($err);
+    my $cmd = "sg_persist -n -o -I -S $node_key -d $dev";
+    $cmd .= " -Z" if (defined $opt_a);
+
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
 
-    return $node_id;
+    close (IN);
+    close (OUT);
+    close (ERR);
 }
 
-sub get_host_name
+sub do_reserve ($$)
 {
-    my ($in, $out, $err);
-    my $cmd = "cman_tool status";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    waitpid($pid, 0);
+    my ($host_key, $dev) = @_;
 
-    die "unable to execute cman_tool.\n" if ($?>>8);
+    my $cmd = "sg_persist -n -o -R -T 5 -K $host_key -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
 
-    my $host_name;
+    waitpid ($pid, 0);
 
-    while (<$out>) {
-	chomp;
+    die "[error]: $self\n" if ($?>>8);
 
-	my ($name, $value) = split(/\s*:\s*/, $_);
+    close (IN);
+    close (OUT);
+    close (ERR);
+}
 
-	if ($name eq "Node name") {
-	    $host_name = $value;
-	    last;
-	}
-    }
+sub do_release ($$)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($host_key, $dev) = @_;
 
-    close ($in);
-    close ($out);
-    close ($err);
+    my $cmd = "sg_persist -n -o -L -T 5 -K $host_key -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
 
-    return $host_name;
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
+
+    close (IN);
+    close (OUT);
+    close (ERR);
 }
 
-sub get_node_name
+sub do_preempt ($$$)
 {
-    return $opt_n;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($host_key, $node_key, $dev) = @_;
+
+    my $cmd = "sg_persist -n -o -P -T 5 -K $host_key -S $node_key -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
+
+    close (IN);
+    close (OUT);
+    close (ERR);
 }
 
-sub get_key
+sub do_preempt_abort ($$$)
 {
-    ($node) = @_;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    my $cluster_id = get_cluster_id;
-    my $node_id = get_node_id($node);
+    my ($host_key, $node_key, $dev) = @_;
 
-    if ($node_id == 0) {
-	die "unable to determine nodeid for node '$node'\n";
-    }
+    my $cmd = "sg_persist -n -o -A -T 5 -K $host_key -S $node_key -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
 
-    my $key = sprintf "%.4x%.4x", $cluster_id, $node_id;
+    die "[error]: $self ($dev)\n" if ($?>>8);
 
-    return $key;
+    close (IN);
+    close (OUT);
+    close (ERR);
 }
 
-sub get_options_stdin
+sub key_read ()
 {
-    my $opt;
-    my $line = 0;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    while (defined($in = <>)) {
+    open (\*FILE, "</var/lib/cluster/fence_scsi.key") or die "$!\n";
 
-	$_ = $in;
-	chomp;
+    chomp (my $key = <FILE>);
 
-	## strip leading and trailing whitespace
-	##
-	s/^\s*//;
-	s/\s*$//;
+    close (FILE);
 
-	## skip comments
-	##
-	next if /^#/;
+    return ($key);
+}
 
-	$line += 1;
-	$opt = $_;
+sub key_write ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-	next unless $opt;
+    open (\*FILE, ">/var/lib/cluster/fence_scsi.key") or die "$!\n";
 
-	($name, $value) = split(/\s*=\s*/, $opt);
+    print FILE "$_[0]\n";
 
-	if ($name eq "")
-	{
-	    print STDERR "parse error: illegal name in option $line\n";
-	    exit 2;
-	}
-	elsif ($name eq "agent")
-	{
-	    ## ignore this
-	}
-	elsif ($name eq "node")
-	{
-	    $opt_n = $value;
-	}
-	elsif ($name eq "nodename")
-	{
-	    $opt_n = $value;
-	}
-	elsif ($name eq "action")
-	{
-	    ## if "action=on", the we are performing an unfence operation.
-	    ## any other value for "action" is ignored. the default is a
-	    ## fence operation.
-	    ##
-	    if ($value eq "on") {
-		$opt_u = $value;
-	    }
+    close (FILE);
+}
+
+sub get_key ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my $key = sprintf ("%.4x%.4x", get_cluster_id (), get_node_id ($_[0]));
+
+    return ($key);
+}
+
+sub get_node_id ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my $cmd = "cman_tool nodes -n $_[0] -F id";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
+
+    chomp (my $node_id = <OUT>);
+
+    close (IN);
+    close (OUT);
+    close (ERR);
+
+    return ($node_id);
+}
+
+sub get_cluster_id ()
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my $cmd = "cman_tool status";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
+
+    my $cluster_id;
+
+    while (<OUT>) {
+	chomp;
+
+	my ($param, $value) = split (/\s*:\s*/, $_);
+
+	if ($param =~ /^cluster\s+id/i) {
+	    $cluster_id = $value;
 	}
     }
+
+    close (IN);
+    close (OUT);
+    close (ERR);
+
+    return ($cluster_id);
 }
 
-sub get_scsi_devices
+sub get_devices_clvm ()
 {
-    my ($in, $out, $err);
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    my $cmd = "vgs --config 'global { locking_type = 0 }'" .
-              "    --noheadings --separator : -o vg_attr,pv_name 2> /dev/null";
+    my $cmd = "vgs --noheadings " .
+              "    --separator : " .
+              "    --sort pv_uuid " .
+              "    --options vg_attr,pv_name " .
+              "    --config 'global { locking_type = 0 } " .
+              "              devices { preferred_names = [ \"^/dev/dm\" ] }'";
 
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
 
-    waitpid($pid, 0);
+    waitpid ($pid, 0);
 
-    die "unable to execute vgs.\n" if ($?>>8);
+    die "[error]: $self\n" if ($?>>8);
 
-    while (<$out>) {
+    my @devices;
+
+    while (<OUT>) {
 	chomp;
 
-	my ($attrs, $dev) = split(/:/, $_);
+	my ($vg_attr, $pv_name) = split (/:/, $_);
 
-	if ($attrs =~ /.*c$/) {
-	    $dev =~ s/\(.*\)//;
-	    push(@device_list, $dev);
+	if ($vg_attr =~ /c$/) {
+	    push (@devices, $pv_name);
 	}
     }
 
-    close ($in);
-    close ($out);
-    close ($err);
+    close (IN);
+    close (OUT);
+    close (ERR);
+
+    return (@devices);
 }
 
-sub create_registration
+sub get_devices_scsi ()
 {
-    my ($key, $dev) = @_;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    my ($in, $out, $err);
-    my $cmd = "sg_persist -n -d $dev -o -I -S $key";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    opendir (\*DIR, "/sys/block/") or die "$!\n";
 
-    waitpid($pid, 0);
+    my @devices = grep { /^sd/ } readdir (DIR);
 
-    die "unable to create registration.\n" if ($?>>8);
+    closedir (DIR);
 
-    close ($in);
-    close ($out);
-    close ($err);
+    return (@devices);
 }
 
-sub create_reservation
+sub get_mpath_name ($)
 {
-    my ($key, $dev) = @_;
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($dev) = @_;
 
-    my ($in, $out, $err);
-    my $cmd = "sg_persist -n -d $dev -o -R -K $key -T 5";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    if ($dev =~ /^\/dev\//) {
+	$dev = substr ($dev, 5);
+    }
+
+    open (\*FILE, "/sys/block/$dev/dm/name") or die "$!\n";
 
-    waitpid($pid, 0);
+    chomp (my $name = <FILE>);
 
-    die "unable to create reservation.\n" if ($?>>8);
+    close (FILE);
 
-    close ($in);
-    close ($out);
-    close ($err);
+    return ($name);
 }
 
-sub fence_node
+sub get_mpath_uuid ($)
 {
-    my $host_name = get_host_name;
-    my $host_key = get_key($host_name);
+    (my $self = (caller(0))[3]) =~ s/^main:://;
 
-    my $node_name = get_node_name;
-    my $node_key = get_key($node_name);
+    my ($dev) = @_;
 
-    my ($in, $out, $err);
+    if ($dev =~ /^\/dev\//) {
+	$dev = substr ($dev, 5);
+    }
 
-    foreach $dev (@device_list)
-    {
-	## check that the key we are attempting to remove
-	## is actually registered with the device. if the key is not
-	## registered, there is nothing to do for this device.
-	##
-	system ("sg_persist -n -d $dev -i -k | grep -qiE \"^[[:space:]]*0x$key\"");
-
-	if (($?>>8) != 0) {
-	    next;
-	}
+    open (\*FILE, "/sys/block/$dev/dm/uuid") or die "$!\n";
 
-	if ($host_key eq $node_key) {
-	    ## this sg_persist command is for the case where you attempt to
-	    ## fence yourself (ie. the local node is the same at the node to
-	    ## be fence). this will not work if the node is the reservation
-	    ## holder, since you can't unregister while holding the reservation.
-	    ##
-	    my $cmd = "sg_persist -n -d $dev -o -G -K $host_key -S 0";
-	}
-	else {
-	    ## this sg_persist command will remove the registration for $host_key.
-	    ## the local node will also become the reservation holder, regardless
-	    ## of which node was holding the reservation prior to the fence operation.
-	    ##
-	    my $cmd = "sg_persist -n -d $dev -o -A -K $host_key -S $node_key -T 5";
+    chomp (my $uuid = <FILE>);
+
+    close (FILE);
+
+    return ($name);
+}
+
+sub get_mpath_slaves ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($dev) = @_;
+
+    if ($dev =~ /^\/dev\//) {
+	$dev = substr ($dev, 5);
+    }
+
+    opendir (\*DIR, "/sys/block/$dev/slaves/") or die "$!\n";
+
+    my @slaves = grep { !/^\./ } readdir (DIR);
+
+    if ($slaves[0] =~ /^dm/) {
+	@slaves = get_mpath_slaves ($slaves[0]);
+    }
+    else {
+	@slaves = map { "/dev/$_" } @slaves;
+    }
+
+    closedir (DIR);
+
+    return (@slaves);
+}
+
+sub get_registration_keys ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($dev) = @_;
+
+    my $cmd = "sg_persist -n -i -k -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
+
+    waitpid ($pid, 0);
+
+    die "[error]: $self\n" if ($?>>8);
+
+    my @keys;
+
+    while (<OUT>) {
+    	chomp;
+
+	if ($_ =~ s/^\s+0x//i) {
+	    push (@keys, $_);
 	}
+    }
+
+    close (IN);
+    close (OUT);
+    close (ERR);
+
+    return (@keys);
+}
+
+sub get_reservation_key ($)
+{
+    (my $self = (caller(0))[3]) =~ s/^main:://;
+
+    my ($dev) = @_;
+
+    my $cmd = "sg_persist -n -i -r -d $dev";
+    my $pid = open3 (\*IN, \*OUT, \*ERR, $cmd) or die "$!\n";
 
-	my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
+    waitpid ($pid, 0);
 
-	waitpid($pid, 0);
+    die "[error]: $self\n" if ($?>>8);
 
-	die "unable to execute sg_persist.\n" if ($?>>8);
+    my $key;
 
-	close ($in);
-	close ($out);
-	close ($err);
+    while (<OUT>) {
+    	chomp;
+
+	if ($_ =~ s/^\s+key=0x//i) {
+	    $key = $_;
+	    last;
+	}
     }
+
+    close (IN);
+    close (OUT);
+    close (ERR);
+
+    return ($key);
 }
 
-sub unfence_node
+sub get_options_stdin ()
 {
-    my $host_name = get_host_name;
-    my $host_key = get_key($host_name);
+    my $num = 0;
 
-    foreach $dev (@device_list)
+    while (<STDIN>)
     {
-	create_registration ($host_key, $dev);
+	chomp;
+
+	s/^\s*//;
+	s/\s*$//;
 
-	## check to see if a reservation already exists.
-	## if no reservation exists, this node/key will become
-	## the reservation holder.
-	##
-	system ("sg_persist -n -d $dev -i -r | grep -qiE \"^[[:space:]]*Key=0x\"");
+	next if (/^#/);
 
-	if (($?>>8) != 0) {
-	    create_reservation ($host_key, $dev);
+	$num++;
+
+	next unless ($_);
+
+	my ($opt, $arg) = split (/\s*=\s*/, $_);
+
+	if ($opt eq "") {
+	    exit (1);
+	}
+	elsif ($opt eq "aptpl") {
+	    $opt_a = $arg;
+	}
+	elsif ($opt eq "devices") {
+	    $opt_d = $arg;
+	}
+	elsif ($opt eq "logfile") {
+	    $opt_f = $arg;
+	}
+	elsif ($opt eq "key") {
+	    $opt_k = $arg;
+	}
+	elsif ($opt eq "nodename") {
+	    $opt_n = $arg;
+	}
+	elsif ($opt eq "action") {
+	    $opt_o = $arg;
 	}
     }
 }
 
+sub print_usage ()
+{
+    print "Usage:\n";
+    print "\n";
+    print "$ME [options]\n";
+    print "\n";
+    print "Options:\n";
+    print "  -a               Use APTPL flag\n";
+    print "  -d <devices>     Devices to be used for action\n";
+    print "  -f <logfile>     File to write debug/error output\n";
+    print "  -h               Usage\n";
+    print "  -k <key>         Key to be used for current action\n";
+    print "  -n <nodename>    Name of node to operate on\n";
+    print "  -o <action>      Action: off (default), on, or status\n";
+    print "  -q               Quiet mode\n";
+    print "  -V               Version\n";
+
+    exit (0);
+}
+
+sub print_version ()
+{
+    print "$ME $RELEASE_VERSION $BUILD_DATE\n";
+    print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
+
+    exit (0);
+}
+
+################################################################################
+
 if (@ARGV > 0) {
+    getopts ("ad:f:hk:n:o:qV") or die "$!\n";
 
-    getopts("hn:uvV") || fail_usage;
+    print_usage if (defined $opt_h);
+    print_version if (defined $opt_V);
+}
+else {
+    get_options_stdin ();
+}
 
-    usage if defined $opt_h;
-    version if defined $opt_V;
+if (defined $opt_f) {
+    open (LOG, ">$opt_f") or die "$!\n";
+    open (STDOUT, ">&LOG");
+    open (STDERR, ">&LOG");
+}
 
-    if (!defined $opt_u) {
-	fail_usage "No '-n' flag specified." unless defined $opt_n;
-    }
+if ((!defined $opt_n) && (!defined $opt_k)) {
+    log_error ("No '-n' or '-k' flag specified.");
+    exit (1);
+}
 
-} else {
+if (defined $opt_k) {
+    $key = $opt_k;
+}
+else {
+    $key = get_key ($opt_n);
+}
 
-    get_options_stdin();
+if (defined $opt_d) {
+    @devices = split (/\s*,\s*/, $opt_d);
+}
+else {
+    @devices = get_devices_clvm ();
+}
 
+if (!defined $opt_o) {
+    $opt_o = "off";
 }
 
-## get a list of scsi devices. this call will build a list of devices
-## (device_list) by querying clvm for a list of devices that exist in
-## volume groups that have the cluster bit set.
-##
-get_scsi_devices;
+if ($opt_o =~ /^on$/i) {
+    do_action_on ($key, @devices);
+}
+elsif ($opt_o =~ /^off$/i) {
+    do_action_off ($key, @devices);
+}
+elsif ($opt_o =~ /^status/i) {
+    do_action_status ($key, @devices);
+}
+else {
+    log_error ("unknown action '$opt_o'");
+    exit (1);
+}
 
-if ($opt_u) {
-    unfence_node;
-} else {
-    fence_node;
+if (defined $opt_f) {
+    close (LOG);
 }
diff --git a/fence/agents/scsi/fence_scsi_test.pl b/fence/agents/scsi/fence_scsi_test.pl
deleted file mode 100644
index cba3c21..0000000
--- a/fence/agents/scsi/fence_scsi_test.pl
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/perl
-
-use POSIX;
-use IPC::Open3;
-use Getopt::Std;
-
-my @devices;
-my %results;
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$REDHAT_COPYRIGHT="";
-$BUILD_DATE="";
-#END_VERSION_GENERATION
-
-sub get_scsi_block_devices
-{
-    my $block_dir = "/sys/block";
-
-    opendir(DIR, $block_dir) or die "$!\n";
-
-    my @block_devices = grep { /^sd*/ } readdir(DIR);
-
-    closedir(DIR);
-
-    for $block_dev (@block_devices)
-    {
-	push(@devices, "/dev/" . $block_dev);
-    }
-}
-
-sub get_cluster_vol_devices
-{
-    my ($in, $out, $err);
-
-    my $cmd = "vgs --config 'global { locking_type = 0 }'" .
-              "    --noheadings --separator : -o vg_attr,pv_name";
-
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
-    waitpid($pid, 0);
-
-    die "[error] unable to execute vgs command.\n" if WEXITSTATUS($?);
-
-    while (<$out>)
-    {
-	chomp;
-
-	my ($vg_attr, $pv_name) = split(/:/, $_);
-
-	if ($vg_attr =~ /.*c$/)
-	{
-	    ###### DEBUG ######
-	    print "DEBUG: pv_name = $pv_name\n";
-
-	    push(@devices, $pv_name);
-	}
-    }
-
-    close($in);
-    close($out);
-    close($err);
-}
-
-sub register_device
-{
-    my ($dev, $key) = @_;
-    my ($in, $out, $err);
-
-    my $cmd = "sg_persist -n -d $dev -o -G -S $key";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
-    waitpid($pid, 0);
-
-    $results{$dev}[0] = WEXITSTATUS($?);
-
-    close($in);
-    close($out);
-    close($err);
-}
-
-sub unregister_device
-{
-    my ($dev, $key) = @_;
-    my ($in, $out, $err);
-
-    my $cmd = "sg_persist -n -d $dev -o -G -K $key -S 0";
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
-    waitpid($pid, 0);
-
-    $results{$dev}[1] = WEXITSTATUS($?);
-
-    close($in);
-    close($out);
-    close($err);
-}
-
-sub test_devices
-{
-    my $key = "0xDEADBEEF";
-
-    foreach $dev (@devices)
-    {
-	register_device($dev, $key);
-	unregister_device($dev, $key);
-    }
-}
-
-sub check_config_fence
-{
-    my ($in, $out, $err);
-    my $cmd = "ccs_tool query /cluster/fencedevices/fencedevice[\@agent=\\\"fence_scsi\\\"]";
-
-    my $pid = open3($in, $out, $err, $cmd) or die "$!\n";
-
-    waitpid($pid, 0);
-
-    return ($?>>8);
-}
-
-sub print_results
-{
-    my $device_count = scalar(@devices);
-
-    my $failure_count = 0;
-    my $success_count = 0;
-
-    print "\nAttempted to register with devices:\n";
-    print "-------------------------------------\n";
-
-    for $dev (@devices)
-    {
-	print "\t$dev\t";
-	if ($results{$dev}[0] == 0)
-	{
-	    $success_count++;
-	    print "Success\n";
-	}
-	else
-	{
-	    $failure_count++;
-	    print "Failure\n";
-	}
-    }
-
-    print "-------------------------------------\n";
-    print "Number of devices tested: $device_count\n";
-    print "Number of devices passed: $success_count\n";
-    print "Number of devices failed: $failure_count\n\n";
-
-    if ($failure_count != 0)
-    {
-	exit(1);
-    }
-}
-
-sub print_usage
-{
-    print "\nUsage: fence_scsi_test [-c|-s] [-d] [-h]\n\n";
-
-    print "Options:\n\n";
-
-    print "  -c     Cluster mode. This mode is intended to test\n";
-    print "         SCSI persistent reservation capabilties for\n";
-    print "         devices that are part of existing clustered\n";
-    print "         volumes. Only devices in LVM cluster volumes\n";
-    print "         will be tested.\n\n";
-    print "  -s     SCSI mode. This mode is intended to test SCSI\n";
-    print "         persistent reservation capabilities for all SCSI\n";
-    print "         devices visible on a node.\n\n";
-    print "  -d     Debug flag. This will print debugging information\n";
-    print "         such as the actual commands being run to register\n";
-    print "         and unregister a device.\n\n";
-    print "  -h     Help. Prints out this usage information.\n\n";
-}
-
-sub test_tools_path
-{
-    my $tool_name = "sg_persist";
-    
-    for my $path ( split /:/, $ENV{PATH} ) {
-        if ( -f "$path/$tool_name" && -x _ ) {
-          return;
-        }
-    }
-    
-    die "No $tool_name command available, please install the sg3_utils package.\n"
-}
-
-### MAIN #######################################################################
-
-test_tools_path;
-
-if (getopts("cdhst:v") == 0)
-{
-    print_usage;
-    exit(1);
-}
-
-if ($opt_h)
-{
-    print_usage;
-    exit(0);
-}
-
-if ($opt_c)
-{
-    print "\nTesting devices in cluster volumes...\n";
-    get_cluster_vol_devices;
-    test_devices;
-    print_results;
-}
-
-if ($opt_s)
-{
-    print "\nTesting all SCSI block devices...\n";
-    get_scsi_block_devices;
-    test_devices;
-    print_results;
-}
-
-if ($opt_t)
-{
-    if ($opt_t eq "fence")
-    {
-	exit check_config_fence;
-    }
-}
-
-if (!$opt_c && !$opt_s && !$opt_t)
-{
-    print "\nPlease specify either cluster or SCSI mode.\n";
-    print_usage;
-    exit(1);
-}
diff --git a/fence/agents/xvm/Makefile b/fence/agents/xvm/Makefile
index 6215263..5b10360 100644
--- a/fence/agents/xvm/Makefile
+++ b/fence/agents/xvm/Makefile
@@ -1,12 +1,9 @@
-TARGET1= fence_xvm
-TARGET2= fence_xvmd
-TARGET3= testprog
+TARGET1= fence_xvmd
+TARGET2= testprog
 
-SBINDIRT=$(TARGET1) $(TARGET2)
+SBINDIRT=$(TARGET1)
 
-MANTARGET= fence_xvm.8
-
-all: ${TARGET1} ${TARGET2} ${MANTARGET}
+all: ${TARGET1}
 
 include ../../../make/defines.mk
 include $(OBJDIR)/make/cobj.mk
@@ -14,22 +11,19 @@ include $(OBJDIR)/make/clean.mk
 include $(OBJDIR)/make/install.mk
 include $(OBJDIR)/make/uninstall.mk
 
-OBJS1=	fence_xvm.o \
-	ip_lookup.o
-
-OBJS2=	fence_xvmd.o \
+OBJS1=	fence_xvmd.o \
 	virt.o \
 	options-ccs.o \
 	vm_states.o \
-	xml.o
+	xml.o \
+	mcast.o \
+	simple_auth.o \
+	tcp.o \
+	options.o \
+	debug.o
 
-OBJS3=	xml-standalone.o
 
-SHAREDOBJS=	mcast.o \
-		simple_auth.o \
-		tcp.o \
-		options.o \
-		debug.o
+OBJS2=	xml-standalone.o
 
 CFLAGS += -D_GNU_SOURCE
 CFLAGS += -I${ccsincdir} -I${cmanincdir}
@@ -44,30 +38,19 @@ STANDALONE_CFLAGS += -DSTANDALONE
 LDFLAGS += -L${nsslibdir} -lnss3
 LDFLAGS += -L${logtlibdir} -llogthread
 LDFLAGS += -L${libdir}
+LDFLAGS += -L${ccslibdir} -lccs -L${cmanlibdir} -lcman
+LDFLAGS += -L${virtlibdir} -lvirt
+LDFLAGS += -L${openaislibdir} -lSaCkpt
 
-EXTRA_LDFLAGS += -L${ccslibdir} -lccs -L${cmanlibdir} -lcman
-EXTRA_LDFLAGS += -L${virtlibdir} -lvirt
-EXTRA_LDFLAGS += -L${openaislibdir} -lSaCkpt
 XML_LDFLAGS += `xml2-config --libs`
 
 ${TARGET1}: ${SHAREDOBJS} ${OBJS1}
-	$(CC) -o $@ $^ $(LDFLAGS)
+	$(CC) -o $@ $^ $(XML_LDFLAGS) $(LDFLAGS)
 
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
-	$(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(XML_LDFLAGS) $(LDFLAGS)
-
-${TARGET3}: ${OBJS3}
+${TARGET2}: ${OBJS2}
 	$(CC) -o $@ $^ $(XML_LDFLAGS)
 
-$(MANTARGET): $(TARGET1) ${SRCDIR}/fence/agents/lib/fence2man.xsl
-	set -e && \
-	./$(TARGET1) -o metadata > .$@.tmp && \
-	xsltproc ${SRCDIR}/fence/agents/lib/fence2man.xsl .$@.tmp > $@
-
 clean: generalclean
-	rm -f $(MANTARGET) .$(MANTARGET).tmp
 
 -include $(OBJS1:.o=.d)
 -include $(OBJS2:.o=.d)
--include $(OBJS3:.o=.d)
--include $(SHAREDOBJS:.o=.d)
diff --git a/fence/agents/xvm/fence_xvm.c b/fence/agents/xvm/fence_xvm.c
deleted file mode 100644
index 3191718..0000000
--- a/fence/agents/xvm/fence_xvm.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * @file fence_xvmd.c: Implementation of server daemon for Xen virtual
- * machine fencing.  This uses SA AIS CKPT b.1.0 checkpointing API to 
- * store virtual machine states.
- *
- * Author: Lon Hohberger <lhh at redhat.com>
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/un.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread.h>
-#include <libgen.h>
-#include <nss.h>
-#include <liblogthread.h>
-
-/* Local includes */
-#include "xvm.h"
-#include "ip_lookup.h"
-#include "simple_auth.h"
-#include "options.h"
-#include "tcp.h"
-#include "mcast.h"
-#include "debug.h"
-
-#define LOG_DAEMON_NAME "fence_xvm"
-
-static int
-tcp_wait_connect(int lfd, int retry_tenths)
-{
-	int fd;
-	fd_set rfds;
-	int n;
-	struct timeval tv;
-
-	dbg_printf(3, "Waiting for connection from XVM host daemon.\n");
-	FD_ZERO(&rfds);
-	FD_SET(lfd, &rfds);
-	tv.tv_sec = retry_tenths / 10;
-	tv.tv_usec = (retry_tenths % 10) * 100000;
-
-	n = select(lfd + 1, &rfds, NULL, NULL, &tv);
-	if (n == 0) {
-		errno = ETIMEDOUT;
-		return -1;
-	} else if (n < 0) {
-		return -1;
-	}
-
-	fd = accept(lfd, NULL, 0);
-	if (fd < 0)
-		return -1;
-
-	return fd;
-}
-
-
-static int
-tcp_exchange(int fd, fence_auth_type_t auth, void *key,
-	      size_t key_len, int timeout)
-{
-	char ret;
-	fd_set rfds;
-	struct timeval tv;
-
-	/* Ok, we're connected */
-	dbg_printf(3, "Issuing TCP challenge\n");
-	if (tcp_challenge(fd, auth, key, key_len, timeout) <= 0) {
-		/* Challenge failed */
-		logt_print(LOG_ERR, "Invalid response to challenge\n");
-		return 0;
-	}
-
-	/* Now they'll send us one, so we need to respond here */
-	dbg_printf(3, "Responding to TCP challenge\n");
-	if (tcp_response(fd, auth, key, key_len, timeout) <= 0) {
-		logt_print(LOG_ERR, "Invalid response to challenge\n");
-		return 0;
-	}
-
-	dbg_printf(2, "TCP Exchange + Authentication done... \n");
-
-	FD_ZERO(&rfds);
-	FD_SET(fd, &rfds);
-	tv.tv_sec = timeout;
-	tv.tv_usec = 0;
-
-	ret = 1;
-	dbg_printf(3, "Waiting for return value from XVM host\n");
-	if (select(fd + 1, &rfds, NULL, NULL, &tv) <= 0)
-		return -1;
-
-	/* Read return code */
-	if (read(fd, &ret, 1) < 0)
-		return -1;
-
-	close(fd);
-	if (ret == 0)
-		logt_print(LOG_INFO, "Remote: Operation was successful\n");
-	else
-		logt_print(LOG_INFO, "Remote: Operation failed\n");
-	return ret;
-}
-
-
-static int
-send_multicast_packets(ip_list_t *ipl, fence_xvm_args_t *args, void *key,
-		       size_t key_len)
-{
-	fence_req_t freq;
-	int mc_sock;
-	ip_addr_t *ipa;
-	struct sockaddr_in tgt4;
-	struct sockaddr_in6 tgt6;
-	struct sockaddr *tgt;
-	socklen_t tgt_len;
-
-	for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) {
-
-		if (ipa->ipa_family != args->family) {
-			dbg_printf(2, "Ignoring %s: wrong family\n", ipa->ipa_address);
-			continue;
-		}
-
-		if (args->family == PF_INET) {
-			mc_sock = ipv4_send_sk(ipa->ipa_address, args->addr,
-					       args->port,
-					       (struct sockaddr *)&tgt4,
-					       sizeof(struct sockaddr_in),
-					       args->ttl);
-			tgt = (struct sockaddr *)&tgt4;
-			tgt_len = sizeof(tgt4);
-			
-		} else if (args->family == PF_INET6) {
-			mc_sock = ipv6_send_sk(ipa->ipa_address, args->addr,
-					       args->port,
-					       (struct sockaddr *)&tgt6,
-					       sizeof(struct sockaddr_in6),
-					       args->ttl);
-			tgt = (struct sockaddr *)&tgt6;
-			tgt_len = sizeof(tgt6);
-		} else {
-			dbg_printf(2, "Unsupported family %d\n", args->family);
-			return -1;
-		}
-
-		if (mc_sock < 0)
-			continue;
-
-		/* Build our packet */
-		memset(&freq, 0, sizeof(freq));
-		strncpy((char *)freq.domain, args->domain,
-			sizeof(freq.domain));
-		freq.request = args->op;
-		freq.hashtype = args->hash;
-
-		/* Store source address */
-		if (ipa->ipa_family == PF_INET) {
-			freq.addrlen = sizeof(struct in_addr);
-			/* XXX Swap order for in_addr ? XXX */
-			inet_pton(PF_INET, ipa->ipa_address, freq.address);
-		} else if (ipa->ipa_family == PF_INET6) {
-			freq.addrlen = sizeof(struct in6_addr);
-			inet_pton(PF_INET6, ipa->ipa_address, freq.address);
-		}
-
-		freq.flags = 0;
-		if (args->flags & F_USE_UUID)
-			freq.flags |= RF_UUID;
-		freq.family = ipa->ipa_family;
-		freq.port = args->port;
-
-		sign_request(&freq, key, key_len);
-
-		dbg_printf(3, "Sending to %s via %s\n", args->addr,
-		        ipa->ipa_address);
-
-		sendto(mc_sock, &freq, sizeof(freq), 0,
-		       (struct sockaddr *)tgt, tgt_len);
-
-		close(mc_sock);
-	}
-
-	return 0;
-}
-
-
-/* TODO: Clean this up!!! */
-static int
-fence_xen_domain(fence_xvm_args_t *args)
-{
-	ip_list_t ipl;
-	char key[MAX_KEY_LEN];
-	int lfd, key_len = 0, fd;
-	int attempts = 0;
-	
-	if (args->auth != AUTH_NONE || args->hash != HASH_NONE) {
-		key_len = read_key_file(args->key_file, key, sizeof(key));
-		if (key_len < 0) {
-			logt_print(LOG_INFO,
-				   "Could not read %s; trying without "
-			           "authentication\n", args->key_file);
-			args->auth = AUTH_NONE;
-			args->hash = HASH_NONE;
-		}
-	}
-
-	/* Do the real work */
-	if (ip_build_list(&ipl) < 0) {
-		logt_print(LOG_ERR, "Error building IP address list\n");
-		return 1;
-	}
-
-	switch (args->auth) {
-		case AUTH_NONE:
-		case AUTH_SHA1:
-		case AUTH_SHA256:
-		case AUTH_SHA512:
-			if (args->family == PF_INET) {
-				lfd = ipv4_listen(args->port, 10);
-			} else {
-				lfd = ipv6_listen(args->port, 10);
-			}
-			break;
-		/*case AUTH_X509:*/
-			/* XXX Setup SSL listener socket here */
-		default:
-			return 1;
-	}
-
-	if (lfd < 0) {
-		logt_print(LOG_ERR, "Failed to listen: %s\n", strerror(errno));
-		return 1;
-	}
-
-	attempts = args->timeout * 10 / args->retr_time;
-
-	logt_print(LOG_INFO, "Sending fence request for %s\n", 
-		   args->domain);
-
-	do {
-		if (send_multicast_packets(&ipl, args, key, key_len)) {
-			return -1;
-		}
-
-		switch (args->auth) {
-			case AUTH_NONE:
-			case AUTH_SHA1:
-			case AUTH_SHA256:
-			case AUTH_SHA512:
-				fd = tcp_wait_connect(lfd, args->retr_time);
-				if (fd < 0 && (errno == ETIMEDOUT ||
-					       errno == EINTR))
-					continue;
-				break;
-			/* case AUTH_X509:
-				... = ssl_wait_connect... */
-			break;
-		default:
-			return 1;
-		}
-
-		break;
-	} while (--attempts);
-
-	if (fd < 0) {
-		if (attempts <= 0) {
-			logt_print(LOG_ERR,
-				   "Timed out waiting for response\n");
-			return 1;
-		}
-		logt_print(LOG_ERR, "Fencing failed: %s\n", strerror(errno));
-		return -1;
-	}
-
-	switch (args->auth) {
-		case AUTH_NONE:
-		case AUTH_SHA1:
-		case AUTH_SHA256:
-		case AUTH_SHA512:
-			return tcp_exchange(fd, args->auth, key, key_len,
-					    args->timeout);
-			break;
-		/* case AUTH_X509: 
-			return ssl_exchange(...); */
-		default:
-			return 1;
-	}
-
-	return 1;
-}
-
-
-int
-main(int argc, char **argv)
-{
-	fence_xvm_args_t args;
-	const char *my_options = "di:a:p:T:r:C:c:k:H:uo:t:?hV";
-
-	/* Print to stderr.  Fenced will report our output for us */
-	logt_init(LOG_DAEMON_NAME, LOG_MODE_OUTPUT_STDERR,
-		  SYSLOGFACILITY, SYSLOGLEVEL, SYSLOGLEVEL, NULL);
-
-	args_init(&args);
-
-	if (argc == 1) {
-		args_get_stdin(my_options, &args);
-	} else {
-		args_get_getopt(argc, argv, my_options, &args);
-	}
-
-	if (args.flags & F_HELP) {
-		args_usage(argv[0], my_options, 0);
-
-                printf("With no command line argument, arguments are "
-                       "read from standard input.\n");
-                printf("Arguments read from standard input take "
-                       "the form of:\n\n");
-                printf("    arg1=value1\n");
-                printf("    arg2=value2\n\n");
-
-		args_usage(argv[0], my_options, 1);
-		exit(0);
-	}
-
-	if (args.flags & F_METADATA) {
-		args_metadata(argv[0], my_options);
-		exit(0);
-	}
-
-	if (args.flags & F_VERSION) {
-		printf("%s %s\n", basename(argv[0]), XVM_VERSION);
-		printf("fence release %s\n", RELEASE_VERSION);
-		exit(0);
-	}
-
-	args_finalize(&args);
-	dset(args.debug);
-	
-	if (args.debug > 0) {
-		logt_conf(LOG_DAEMON_NAME, LOG_MODE_OUTPUT_STDERR,
-			  SYSLOGFACILITY, LOG_DEBUG, LOG_DEBUG, NULL);
-		args_print(&args);
-	}
-
-	/* Additional validation here */
-	if (!args.domain) {
-		logt_print(LOG_ERR, "No domain specified!\n");
-		args.flags |= F_ERR;
-	}
-
-	if (args.flags & F_ERR) {
-		args_usage(argv[0], my_options, (argc == 1));
-		exit(1);
-	}
-
-	/* Initialize NSS; required to do hashing, as silly as that
-	   sounds... */
-	if (NSS_NoDB_Init(NULL) != SECSuccess) {
-		logt_print(LOG_ERR, "Could not initialize NSS\n");
-		return 1;
-	}
-
-	return fence_xen_domain(&args);
-}
diff --git a/fence/agents/xvm/ip_lookup.c b/fence/agents/xvm/ip_lookup.c
deleted file mode 100644
index 3867c52..0000000
--- a/fence/agents/xvm/ip_lookup.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/** @file
- * Build lists of IPs on the system, excepting loopback ipv6 link-local
- */
-#include <asm/types.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <netdb.h>
-#include <liblogthread.h>
-
-#ifndef IFA_MAX
-#include <linux/if_addr.h>
-#endif
-
-/* Local includes */
-#include "ip_lookup.h"
-#include "debug.h"
-
-static int
-send_addr_dump(int fd, int family)
-{
-	struct nlmsghdr *nh;
-	struct rtgenmsg *g;
-	char buf[256];
-	struct sockaddr_nl addr;
-
-	memset(&addr,0,sizeof(addr));
-	addr.nl_family = PF_NETLINK;
-
-	memset(buf, 0, sizeof(buf));
-	nh = (struct nlmsghdr *)buf;
-	g = (struct rtgenmsg *)(buf + sizeof(struct nlmsghdr));
-
-	nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
-	nh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
-	nh->nlmsg_type = RTM_GETADDR;
-	g->rtgen_family = family;
-
-	return sendto(fd, buf, nh->nlmsg_len, 0, (struct sockaddr *)&addr,
-	   	      sizeof(addr));
-}
-
-
-static int
-add_ip(ip_list_t *ipl, char *ipaddr, char family)
-{
-	ip_addr_t *ipa;
-
-	if (family == PF_INET6) {
-		/* Avoid loopback */
-		if (!strcmp(ipaddr, "::1"))
-			return -1;
-
-		/* Avoid link-local addresses */
-		if (!strncmp(ipaddr, "fe80", 4))
-			return -1;
-		if (!strncmp(ipaddr, "fe90", 4))
-			return -1;
-		if (!strncmp(ipaddr, "fea0", 4))
-			return -1;
-		if (!strncmp(ipaddr, "feb0", 4))
-			return -1;
-	}
-	
-	dbg_printf(4, "Adding IP %s to list (family %d)\n", ipaddr, family);
-
-	ipa = malloc(sizeof(*ipa));
-	if (!ipa)
-		return -1;
-	memset(ipa, 0, sizeof(*ipa));
-	ipa->ipa_family = family;
-	ipa->ipa_address = strdup(ipaddr);
-
-	TAILQ_INSERT_TAIL(ipl, ipa, ipa_entries);
-
-	return 0;
-}
-
-
-static int
-add_ip_addresses(int family, ip_list_t *ipl)
-{
-	/* List ipv4 addresses */
-	struct nlmsghdr *nh;
-	struct ifaddrmsg *ifa;
-	struct rtattr *rta, *nrta;
-	struct nlmsgerr *err;
-	char buf[10240];
-	char outbuf[256];
-	int x, fd, len;
-
-	dbg_printf(5, "Connecting to Netlink...\n");
-	fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
-	if (fd < 0) {
-		perror("socket");
-		exit(1);
-	}
-	
-	dbg_printf(5, "Sending address dump request\n");
-	send_addr_dump(fd, family);
-	memset(buf, 0, sizeof(buf));
-	
-	dbg_printf(5, "Waiting for response\n");
-	x = recvfrom(fd, buf, sizeof(buf), 0, NULL, 0);
-	if (x < 0) {
-		perror("recvfrom");
-		return -1;
-	}
-	
-	dbg_printf(5, "Received %d bytes\n", x);
-
-	nh = (struct nlmsghdr *)buf;
-	while (NLMSG_OK(nh, x)) {
-
-		switch(nh->nlmsg_type) {
-		case NLMSG_DONE:
-			close(fd);
-    			return 0;
-
-		case NLMSG_ERROR:
-			err = (struct nlmsgerr*)NLMSG_DATA(nh);
-			if (nh->nlmsg_len <
-			    NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
-				fprintf(stderr, "ERROR truncated");
-			} else {
-				errno = -err->error;
-				perror("RTNETLINK answers");
-			}
-			close(fd);
-			return -1;
-
-		case RTM_NEWADDR:
-			break;
-
-		default:
-			nh = NLMSG_NEXT(nh, x);
-			continue;
-		}
-
-		/* RTM_NEWADDR */
-		len = NLMSG_PAYLOAD(nh,0);
-		ifa = NLMSG_DATA(nh);
-
-		/* Make sure we got the type we expect back */
-		if (ifa->ifa_family != family) {
-			nh = NLMSG_NEXT(nh, x);
-			continue;
-		}
-
-		rta = (struct rtattr *)((char *)ifa + sizeof(*ifa));
-		len -= sizeof(*ifa);
-		do {
-			/* Make sure we've got a valid rtaddr field */
-			if (!RTA_OK(rta, len)) {
-				dbg_printf(5, "!RTA_OK(rta, len)\n");
-				break;
-			}
-
-			if (rta->rta_type == IFA_ADDRESS) {
-				inet_ntop(family, RTA_DATA(rta), outbuf,
-					  sizeof(outbuf) );
-				add_ip(ipl, outbuf, family);
-			}
-
-			if (rta->rta_type == IFA_LABEL) {
-				dbg_printf(5, "Skipping label: %s\n",
-					(char *)RTA_DATA(rta));
-			}
-
-			nrta = RTA_NEXT(rta, len);
-			if (!nrta)
-				break;
-
-			len -= ((char *)nrta - (char *)rta);
-			rta = nrta;
-		} while (RTA_OK(rta, len));
-
-		nh = NLMSG_NEXT(nh, x);
-	}
-
-	dbg_printf(5, "Closing Netlink connection\n");
-	close(fd);
-	return 0;
-}
-
-
-int
-ip_search(ip_list_t *ipl, char *ip_name)
-{
-	ip_addr_t *ipa;
-	
-	dbg_printf(5, "Looking for IP address %s in IP list %p...", ip_name, ipl);
-	ipa = ipl->tqh_first;
-	for (ipa = ipl->tqh_first; ipa; ipa = ipa->ipa_entries.tqe_next) {
-		if (!strcmp(ip_name, ipa->ipa_address)) {
-			dbg_printf(4,"Found\n");
-			return 0;
-		}
-	}
-	dbg_printf(5, "Not found\n");
-	return 1;
-}
-
-
-int
-ip_free_list(ip_list_t *ipl)
-{
-	ip_addr_t *ipa;
-	
-	dbg_printf(5, "Tearing down IP list @ %p\n", ipl);
-	while ((ipa = ipl->tqh_first)) {
-		TAILQ_REMOVE(ipl, ipa, ipa_entries);
-		free(ipa->ipa_address);
-		free(ipa);
-	}
-	return 0;
-}
-
-
-int
-ip_build_list(ip_list_t *ipl)
-{
-	dbg_printf(5, "Build IP address list\n");
-	TAILQ_INIT(ipl);
-	if (add_ip_addresses(PF_INET6, ipl) < 0) {
-		ip_free_list(ipl);
-		return -1;
-	}
-	if (add_ip_addresses(PF_INET, ipl) < 0) {
-		ip_free_list(ipl);
-		return -1;
-	}
-	return 0;
-}
-
-
-/**
-  Look up the interface name which corresponds to the given hostname and
-  return the list of matching attrinfo structures.  We do this by looking
-  up all the possible physical and virtual network interfaces on the machine
-  and checking the hostname/IP mappings for each active IP address incurred.
-
-  @param nodename	Interface name
-  @param ret_ai		Structure pointer to allocate & return.
-  @return		-1 on failure or 0 on success.
- */
-int
-ip_lookup(char *nodename, struct addrinfo **ret_ai)
-{
-	char ip_name[256];
-	struct addrinfo *ai = NULL;
-	struct addrinfo *n;
-	void *p;
-	ip_list_t ipl;
-	int ret = -1;
-
-	dbg_printf(5, "Looking for IP matching %s\n", nodename);
-	/* Build list of IP addresses configured locally */
-	if (ip_build_list(&ipl) < 0)
-		return -1;
-
-	/* Get list of addresses for the host-name/ip */
-	if (getaddrinfo(nodename, NULL, NULL, &ai) != 0) 
-		return -1;
-	
-
-	/* Traverse list of addresses for given host-name/ip */
-	for (n = ai; n; n = n->ai_next) {
-		if (n->ai_family != PF_INET && n->ai_family != PF_INET6)
-			continue;
-
-		if (n->ai_family == PF_INET)
-			p = &(((struct sockaddr_in *)n->ai_addr)->sin_addr);
-		else
-			p = &(((struct sockaddr_in6 *)n->ai_addr)->sin6_addr);
-
-		if (!inet_ntop(n->ai_family, p, ip_name,
-			       sizeof(ip_name)))
-			continue;
-
-		/* Search local interfaces for this IP address */
-		if (ip_search(&ipl, ip_name) != 0)
-			continue;
-
-		/* Found it */
-		ret = 0;
-		break;
-	}
-
-	/* Clean up */
-	if (!ret_ai)
-		freeaddrinfo(ai);
-	else
-		*ret_ai = ai;
-
-	ip_free_list(&ipl);
-
-	return ret;
-}
-
diff --git a/fence/agents/xvm/ip_lookup.h b/fence/agents/xvm/ip_lookup.h
deleted file mode 100644
index a3e4568..0000000
--- a/fence/agents/xvm/ip_lookup.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/** @file
- * Header for ip_lookup.c
- */
-#ifndef _IP_LOOKUP_H
-#define _IP_LOOKUP_H
-
-#include <sys/queue.h>
-
-typedef struct _ip_address {
-	TAILQ_ENTRY(_ip_address) ipa_entries;
-	char ipa_family;
-	char *ipa_address;
-} ip_addr_t;
-
-typedef TAILQ_HEAD(_ip_list, _ip_address) ip_list_t;
-
-int ip_search(ip_list_t *ipl, char *ip_name);
-int ip_free_list(ip_list_t *ipl);
-int ip_build_list(ip_list_t *ipl);
-int ip_lookup(char *, struct addrinfo **);
-
-#endif
diff --git a/fence/agents/xvm/options.c b/fence/agents/xvm/options.c
index 0e5d394..c0914a5 100644
--- a/fence/agents/xvm/options.c
+++ b/fence/agents/xvm/options.c
@@ -350,19 +350,24 @@ static struct arg_info _arg_info[] = {
 	  "Shared key file (default=" DEFAULT_KEY_FILE ")",
 	  assign_key },
 
-	{ 'o', "-o <operation>", "option",
+	{ '\xff', NULL, "option",
 	  0, "string", "reboot",
 	  "Fencing operation (null, off, [reboot])",
 	  assign_op },
 
+	{ 'o', "-o <action>", "action",
+	  0, "string", "reboot",
+	  "Fencing action (null, off, [reboot])",
+	  assign_op },
+
 	{ 'H', "-H <domain>", "domain",
 	  1, "string", NULL,
-	  "Xen host (domain name) to fence",
+	  "Virtual machine (domain name) to fence",
 	  assign_domain },
 
 	{ 'u', "-u", "use_uuid",
 	  0, "string", NULL,
-	  "Treat <domain> as UUID instead of domain name",
+	  "Treat 'domain' as UUID instead of domain name",
 	  assign_uuid_lookup },
 
 	{ 't', "-t <timeout>", "timeout",
diff --git a/fence/fenced/cpg.c b/fence/fenced/cpg.c
index 6714687..c9d86f3 100644
--- a/fence/fenced/cpg.c
+++ b/fence/fenced/cpg.c
@@ -2157,6 +2157,7 @@ int setup_cpg_daemon(void)
 	sprintf(name.value, "fenced:daemon");
 	name.length = strlen(name.value) + 1;
 
+	log_debug("cpg_join %s ...", name.value);
  retry:
 	error = cpg_join(cpg_handle_daemon, &name);
 	if (error == CPG_ERR_TRY_AGAIN) {
diff --git a/fence/man/fence_scsi.8 b/fence/man/fence_scsi.8
index eaab222..f1a29ea 100644
--- a/fence/man/fence_scsi.8
+++ b/fence/man/fence_scsi.8
@@ -4,74 +4,74 @@
 fence_scsi - I/O fencing agent for SCSI persistent reservations
 
 .SH SYNOPSIS
-.B 
+.B
 fence_scsi
 [\fIOPTION\fR]...
 
 .SH DESCRIPTION
-fence_scsi is an I/O fencing agent which can be used with the SCSI
-devices that support persistent reservations (SPC-2 or greater).
+fence_scsi is an I/O fencing agent that uses SCSI-3 persistent
+reservations to control access to shared storage devices. These
+devices must support SCSI-3 persistent reservations (SPC-3 or greater)
+as well as the "preempt-and-abort" subcommand.
 
-SCSI persistent reservations work by having each node in the cluster
-register with the SCSI device. Registration is done using a unique key
-(based on the node's IP address). Each node that will perform I/O
-operations to the shared storage must register with the device. This
-is done at system startup with the scsi_reserve init script. This
-script will discover all clustered volumes as well as the underlying
-SCSI device(s). Device discovery is done via the lvs command (see
-lvs(8)) and is subject to any filtering rules defined in the lvm.conf
-file.
+The fence_scsi agent works by having each node in the cluster register
+a unique key with the SCSI devive(s). Once registered, a single node
+will become the reservation holder by creating a "write exclusive,
+registrants only" reservation on the device(s). The result is that
+only registered nodes may write to the device(s). When a node failure
+occurs, the fence_scsi agent will remove the key belonging to the
+failed node from the device(s). The failed node will no longer be able
+to write to the device(s). A manual reboot is required.
 
-After generating the node's unique key, the script will register the
-node with the SCSI device(s) that were discovered. Once the node is
-registered, the script will attempt to create a reservation. Unlike
-registrations, of which there are multiple registrants (one for each
-node in the cluster), there is only one reservation holder. If a
-reservation does not already exist for a device, the script will
-create a reservation using the node's unique key.
+Keys are either be specified manually (see -k option) or generated
+automatically (see -n option). Automatic key generation requires that
+cman be running. Keys will then be generated using the cluster ID and
+node ID such that each node has a unique key that can be determined by
+any other node in the cluster.
 
-It is important to distinguish between registrations and
-reservations. As mentioned above, each node that will perform I/O
-operations to the SCSI device must register. As a result, there will
-be multiple registrations for a given SCSI device. In contrast, there
-can only be one reservation per SCSI device. It is not important which
-node holds the reservation. The reservation simply tells the device
-how the registrants are allowed to access the device. For our
-purposes, the reservation type is "write exclusive, registrants only".
-With this reservation type, only registered nodes will be able to
-write to the device.
-
-When the cluster must fence a node, it simply revokes a node's
-registration, or "unregisters" the node. This operation also uses the
-node's unique key. By deriving the unique key based on the errant
-node's IP address, the cluster can "unregister" the key. As a
-result, the errant node will no longer be able to write to the SCSI
-device.
-
-Note that the node that holds the reservation for a device must also
-be registered with that device. When the situation arises where the
-node that is being fenced is also the reservation holder, the
-reservation must be moved. This is handled by using the
-"preempt-and-abort command" which will transfer the reservation from
-the node that is being fenced to the node that is performing the
-fencing. This operation will maintain the reservation while
-"unregistering" the node being fenced.
-
-At system shutdown, the scsi_reserve script will attempt to
-"unregister" the node from all devices. The exception is when the
-node happens to be the reservation holder. In this case, the script
-does nothing, due to the fact that there may be other nodes using the
-device and the reservation must remain intact.
-
-fence_scsi accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent.  fence_scsi
-can be run by itself with command line options.  This is useful for testing 
-and for turning outlets on or off from scripts.
+Devices can either be specified manually (see -d option) or discovered
+automatically. Multiple devices can be specified manually by using a
+comma-separated list. If no devices are specified, the fence_scsi
+agent will attempt to discover devices by looking for cluster volumes
+and extracting the underlying devices. Devices may be device-mapper
+multipath devices or raw devices. If using a device-mapper multipath
+device, the fence_scsi agent will find the underlying devices (paths)
+and created registrations for each path.
 
 .SH OPTIONS
 .TP
-\fB-n\fP \fInode\fR
-Name of the node to be fenced.
+\fB-o\fP \fIaction\fR
+Fencing action. This value can be "on", "off", or "status". All
+actions require either a key (see -k option) or node name (see -n
+option). For "on", the agent will attempt to register with the
+device(s) and create a reservation if none exists. The "off" action
+will attempt to remove a node's key from the device(s). The "status"
+action will report whether or not a node's key is currently register
+with one or more of the devices. The default action if "off".
+.TP
+\fB-d\fP \fIdevices\fR
+List of devices to use for current operation. Devices can be
+comma-separated list of raw device (eg. /dev/sdc) or device-mapper
+multipath devices (eg. /dev/dm-3). Each device must support SCSI-3
+persistent reservations.
+.TP
+\fB-f\fP \fIlogfile\fR
+Log output to file.
+.TP
+\fB-n\fP \fInodename\fR
+Name of the node to be fenced. The node name is used to generate the
+key value used for the current operation. This option will be ignored
+when used with the -k option.
+.TP
+\fB-k\fP \fIkey\fR
+Key to use for the current operation. This key should be unique to a
+node. For the "on" action, the key specifies the key use to register
+the local node. For the "off" action, this key specifies the key to be
+removed from the device(s).
+.TP
+\fB-a\fP
+Use the APTPL flag for registrations. This option is only used for the
+"on" action.
 .TP
 \fB-h\fP
 Print out a help message describing available options, then exit.
@@ -84,24 +84,26 @@ Print out a version message, then exit.
 
 .SH STDIN PARAMETERS
 .TP
-\fIagent = < param >\fR
+\fIagent = "param"\fR
 This option is used by fence_node(8) and is ignored by fence_scsi.
 .TP
-\fInodename = < hostname | ip >\fR
-Name of the node to be fenced.
+\fInodename = "param"\fR
+Same as -n option.
 .TP
-\fIself = < nodename >\fR
-Name of the node that will perform the fencing operation.
+\fIaction = "param" \fR
+Same as -o option.
 .TP
-\fIverbose = < param >\fR
-Verbose output.
-
-.SH LIMITATIONS
-The fence_scsi fencing agent requires a minimum of three nodes in the
-cluster to operate.  For SAN devices connected via fiber channel,
-these must be physical nodes.  SAN devices connected via iSCSI may use
-virtual or physical nodes.  In addition, fence_scsi cannot be used in
-conjunction with qdisk.
+\fIdevices = "param"\fR
+Same as -d option.
+.TP
+\fIlogfile = "param"\fR
+Same as -f option
+.TP
+\fIkey = "param"\fR
+Same as -k option.
+.TP
+\fIaptpl = "1"
+Enable the APTPL flag. Default is 0 (disable).
 
 .SH SEE ALSO
-fence(8), fence_node(8), sg_persist(8), lvs(8), lvm.conf(5)
+fence(8), fence_node(8), sg_persist(8), vgs(8), cman_tool(8), cman(5)
diff --git a/gfs-kernel/src/gfs/eattr.c b/gfs-kernel/src/gfs/eattr.c
index 0558300..71f7e70 100644
--- a/gfs-kernel/src/gfs/eattr.c
+++ b/gfs-kernel/src/gfs/eattr.c
@@ -1546,56 +1546,49 @@ gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er)
  * Returns: errno
  */
 
-int
-gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er)
+int gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er)
 {
+	struct buffer_head *bh;
+	struct gfs_ea_header *ea;
+	unsigned int size;
+	struct buffer_head *dibh;
 	int error;
 
 	if (!ip->i_di.di_eattr)
 		return ea_init_i(ip, er, NULL);
 
-	{
-		struct buffer_head *bh;
-		struct gfs_ea_header *ea;
-		unsigned int size;
-
-		ea_calc_size(ip->i_sbd, er, &size);
+	ea_calc_size(ip->i_sbd, er, &size);
 
-		error = gfs_dread(ip->i_gl, ip->i_di.di_eattr,
+	error = gfs_dread(ip->i_gl, ip->i_di.di_eattr,
 				  DIO_START | DIO_WAIT, &bh);
-		if (error)
-			return error;
-
-		if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) {
-			brelse(bh);
-			return -EIO;
-		}
+	if (error)
+		return error;
 
-		ea = GFS_EA_BH2FIRST(bh);
-		if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) {
-			ea = ea_split_ea(ea);
-			ea_write(ip, ea, er);
-			brelse(bh);
-			return 0;
-		}
+	if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) {
+		brelse(bh);
+		return -EIO;
+	}
 
+	ea = GFS_EA_BH2FIRST(bh);
+	if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) {
+		ea = ea_split_ea(ea);
+		ea_write(ip, ea, er);
 		brelse(bh);
+		return 0;
 	}
 
+	brelse(bh);
+
 	error = ea_set_block(ip, er, NULL);
 	gfs_assert_withdraw(ip->i_sbd, error != -ENOSPC);
 	if (error)
 		return error;
 
-	{
-		struct buffer_head *dibh;
-		error = gfs_get_inode_buffer(ip, &dibh);
-		if (error)
-			return error;
-		gfs_dinode_out(&ip->i_di, dibh->b_data);
-		brelse(dibh);
-	}
-
+	error = gfs_get_inode_buffer(ip, &dibh);
+	if (error)
+		return error;
+	gfs_dinode_out(&ip->i_di, dibh->b_data);
+	brelse(dibh);
 	return error;
 }
 
@@ -1608,10 +1601,9 @@ gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er)
  * Returns: errno
  */
 
-static int
-ea_acl_chmod_unstuffed(struct gfs_inode *ip,
-		       struct gfs_ea_header *ea,
-		       char *data)
+static int ea_acl_chmod_unstuffed(struct gfs_inode *ip,
+				  struct gfs_ea_header *ea, char *data,
+				  int *trans)
 {
 	struct gfs_sbd *sdp = ip->i_sbd;
 	struct buffer_head **bh;
@@ -1625,9 +1617,12 @@ ea_acl_chmod_unstuffed(struct gfs_inode *ip,
 	if (!bh)
 		return -ENOMEM;
 
-	error = gfs_trans_begin(sdp, 1 + nptrs, 0);
-	if (error)
-		goto out;
+	if (get_transaction == NULL) {
+		error = gfs_trans_begin(sdp, 1 + nptrs, 0);
+		if (error)
+			goto out;
+		*trans = 1;
+	}
 
 	for (x = 0; x < nptrs; x++) {
 		error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs),
@@ -1667,15 +1662,14 @@ ea_acl_chmod_unstuffed(struct gfs_inode *ip,
 		brelse(bh[x]);
 	}
 
- out:
+out:
 	kfree(bh);
-
 	return error;
 
- fail:
+fail:
 	gfs_trans_end(sdp);
+	*trans = 0;
 	kfree(bh);
-
 	return error;
 }
 
@@ -1689,24 +1683,28 @@ ea_acl_chmod_unstuffed(struct gfs_inode *ip,
  * Returns: errno
  */
 
-int
-gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el,
-		 struct iattr *attr, char *data)
+int gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el,
+		     struct iattr *attr, char *data)
 {
+	struct gfs_sbd *sdp = ip->i_sbd;
 	struct buffer_head *dibh;
 	int error;
+	int trans = 0;
 
 	if (GFS_EA_IS_STUFFED(el->el_ea)) {
-		error = gfs_trans_begin(ip->i_sbd, 2, 0);
-		if (error)
-			return error;
+		if (get_transaction == NULL) {
+			error = gfs_trans_begin(ip->i_sbd, 2, 0);
+			if (error)
+				return error;
+			trans = 1;
+		}
 
 		gfs_trans_add_bh(ip->i_gl, el->el_bh);
-		memcpy(GFS_EA2DATA(el->el_ea),
-		       data,
+		memcpy(GFS_EA2DATA(el->el_ea), data,
 		       GFS_EA_DATA_LEN(el->el_ea));
-	} else
-		error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
+	} else {
+		error = ea_acl_chmod_unstuffed(ip, el->el_ea, data, &trans);
+	}
 
 	if (error)
 		return error;
@@ -1721,7 +1719,8 @@ gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el,
 		brelse(dibh);
 	}
 
-	gfs_trans_end(ip->i_sbd);
+	if (trans)
+		gfs_trans_end(ip->i_sbd);
 
 	return error;
 }
diff --git a/gfs-kernel/src/gfs/gfs.h b/gfs-kernel/src/gfs/gfs.h
index 7a0578d..23a640f 100644
--- a/gfs-kernel/src/gfs/gfs.h
+++ b/gfs-kernel/src/gfs/gfs.h
@@ -1,7 +1,7 @@
 #ifndef __GFS_DOT_H__
 #define __GFS_DOT_H__
 
-#define RELEASE_VERSION "3.0.4"
+#define RELEASE_VERSION "3.0.6"
 
 #include "lm_interface.h"
 
diff --git a/gfs-kernel/src/gfs/ops_file.c b/gfs-kernel/src/gfs/ops_file.c
index fa72924..6a64958 100644
--- a/gfs-kernel/src/gfs/ops_file.c
+++ b/gfs-kernel/src/gfs/ops_file.c
@@ -808,6 +808,7 @@ do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset,
 	int alloc_required, journaled;
 	ssize_t count;
 	int error;
+	unsigned int posix = sdp->sd_args.ar_posix_acls ? 4 : 0;
 
 	journaled = gfs_is_jdata(ip);
 
@@ -845,7 +846,7 @@ do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset,
 
 		error = gfs_trans_begin(sdp,
 					1 + al->al_rgd->rd_ri.ri_length +
-					ind_blocks +
+					ind_blocks + posix +
 					((journaled) ? data_blocks : 0), 1);
 		if (error)
 			goto fail_ipres;
@@ -853,7 +854,7 @@ do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset,
 		/* Trans may require:
 		   A modified dinode. */
 
-		error = gfs_trans_begin(sdp,
+		error = gfs_trans_begin(sdp, posix +
 					1 + ((journaled) ? data_blocks : 0), 0);
 		if (error)
 			goto fail_ipres;
diff --git a/gfs2/convert/gfs2_convert.c b/gfs2/convert/gfs2_convert.c
index bc6312d..4034e74 100644
--- a/gfs2/convert/gfs2_convert.c
+++ b/gfs2/convert/gfs2_convert.c
@@ -209,6 +209,9 @@ static int convert_rgs(struct gfs2_sbd *sbp)
 		/* rg_freemeta is a gfs1 structure, so libgfs2 doesn't know to */
 		/* convert from be to cpu. We must do it now. */
 		rgd->rg.rg_free = rgd1->rg_free + be32_to_cpu(rgd1->rg_freemeta);
+		/* Zero it out so we don't add it again in case something breaks */
+		/* later on in the process and we have to re-run convert */
+		rgd1->rg_freemeta = 0;
 
 		sbp->blks_total += rgd->ri.ri_data;
 		sbp->blks_alloced += (rgd->ri.ri_data - rgd->rg.rg_free);
@@ -276,7 +279,7 @@ static void mp_gfs1_to_gfs2(struct gfs2_sbd *sbp, int gfs1_h, int gfs2_h,
 
 	/* figure out multiplication factors for each height - gfs2 */
 	memset(&gfs2factor, 0, sizeof(gfs2factor));
-	gfs2factor[gfs1_h - 1] = 1ull;
+	gfs2factor[gfs2_h - 1] = 1ull;
 	for (h = gfs2_h - 1; h > 0; h--)
 		gfs2factor[h - 1] = gfs2factor[h] * gfs2_inptrs;
 
@@ -564,6 +567,7 @@ static int adjust_indirect_blocks(struct gfs2_sbd *sbp, struct gfs2_buffer_head
 		blk->mp.mp_list[di_height - 1] = ptrnum;
 		mp_gfs1_to_gfs2(sbp, di_height, gfs2_hgt, &blk->mp, &gfs2mp);
 		memcpy(&blk->mp, &gfs2mp, sizeof(struct metapath));
+		blk->height -= di_height - gfs2_hgt;
 		if (len)
 			fix_metatree(sbp, ip, blk, ptr1, len);
 		osi_list_del(tmp);
diff --git a/gfs2/fsck/main.c b/gfs2/fsck/main.c
index f74e09d..68e8428 100644
--- a/gfs2/fsck/main.c
+++ b/gfs2/fsck/main.c
@@ -259,6 +259,70 @@ static int check_system_inodes(struct gfs2_sbd *sdp)
 	return 0;
 }
 
+static void check_statfs(struct gfs2_sbd *sdp)
+{
+	osi_list_t *tmp;
+	struct rgrp_list *rgd;
+	struct gfs2_rindex *ri;
+	struct gfs2_statfs_change sc;
+	char buf[sizeof(struct gfs2_statfs_change)];
+	int count;
+
+	/* Read the current statfs values */
+	count = gfs2_readi(sdp->md.statfs, buf, 0,
+			   sdp->md.statfs->i_di.di_size);
+	if (count == sizeof(struct gfs2_statfs_change))
+		gfs2_statfs_change_in(&sc, buf);
+
+	/* Calculate the real values from the rgrp information */
+	sdp->blks_total = 0;
+	sdp->blks_alloced = 0;
+	sdp->dinodes_alloced = 0;
+
+	for (tmp = sdp->rglist.next; tmp != &sdp->rglist; tmp = tmp->next) {
+		rgd = osi_list_entry(tmp, struct rgrp_list, list);
+		ri = &rgd->ri;
+		sdp->blks_total += ri->ri_data;
+		sdp->blks_alloced += (ri->ri_data - rgd->rg.rg_free);
+		sdp->dinodes_alloced += rgd->rg.rg_dinodes;
+	}
+
+	/* See if they match */
+	if (sc.sc_total == sdp->blks_total &&
+	    sc.sc_free == (sdp->blks_total - sdp->blks_alloced) &&
+	    sc.sc_dinodes == sdp->dinodes_alloced) {
+		log_info( _("The statfs file is accurate.\n"));
+		return;
+	}
+	log_err( _("The statfs file is wrong:\n\n"));
+	log_err( _("Current statfs values:\n"));
+	log_err( _("blocks:  %lld (0x%llx)\n"),
+		sc.sc_total, sc.sc_total);
+	log_err( _("free:    %lld (0x%llx)\n"),
+		sc.sc_free, sc.sc_free);
+	log_err( _("dinodes: %lld (0x%llx)\n\n"),
+		sc.sc_dinodes, sc.sc_dinodes);
+
+	log_err( _("Calculated statfs values:\n"));
+	log_err( _("blocks:  %lld (0x%llx)\n"),
+		sdp->blks_total, sdp->blks_total);
+	log_err( _("free:    %lld (0x%llx)\n"),
+		sdp->blks_total - sdp->blks_alloced,
+		sdp->blks_total - sdp->blks_alloced);
+	log_err( _("dinodes: %lld (0x%llx)\n"),
+		sdp->dinodes_alloced, sdp->dinodes_alloced);
+
+	errors_found++;
+	if (!query(&opts, _("Okay to fix the master statfs file? (y/n)"))) {
+		log_err( _("The statfs file was not fixed.\n"));
+		return;
+	}
+
+	do_init_statfs(sdp);
+	log_err( _("The statfs file was fixed.\n"));
+	errors_corrected++;
+}
+
 int main(int argc, char **argv)
 {
 	struct gfs2_sbd sb;
@@ -384,6 +448,9 @@ int main(int argc, char **argv)
 		error = FSCK_CANCELED;
 	}
 	update_sys_files = (opts.no ? not_updated : updated);
+
+	check_statfs(sbp);
+
 	/* Free up our system inodes */
 	inode_put(sbp->md.inum, update_sys_files);
 	inode_put(sbp->md.statfs, update_sys_files);
@@ -398,8 +465,9 @@ int main(int argc, char **argv)
 	if (lf_dip)
 		inode_put(lf_dip, update_sys_files);
 
-	if (!opts.no)
+	if (!opts.no && errors_corrected)
 		log_notice( _("Writing changes to disk\n"));
+
 	bsync(&sbp->buf_list);
 	bsync(&sbp->nvbuf_list);
 	destroy(sbp);
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 3d7b28a..bc2507e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -687,7 +687,8 @@ extern int build_statfs(struct gfs2_sbd *sdp);
 extern int build_rindex(struct gfs2_sbd *sdp);
 extern int build_quota(struct gfs2_sbd *sdp);
 extern int build_root(struct gfs2_sbd *sdp);
-extern int do_init(struct gfs2_sbd *sdp);
+extern int do_init_inum(struct gfs2_sbd *sdp);
+extern int do_init_statfs(struct gfs2_sbd *sdp);
 extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
 extern int gfs2_next_rg_meta(struct rgrp_list *rgd, uint64_t *block, int first);
 extern int gfs2_next_rg_metatype(struct gfs2_sbd *sdp, struct rgrp_list *rgd,
diff --git a/gfs2/libgfs2/misc.c b/gfs2/libgfs2/misc.c
index 91bcc51..d8fe515 100644
--- a/gfs2/libgfs2/misc.c
+++ b/gfs2/libgfs2/misc.c
@@ -180,7 +180,7 @@ int mount_gfs2_meta(struct gfs2_sbd *sdp)
 	if(!mkdtemp(sdp->metafs_path))
 		return -1;
 
-	ret = mount(sdp->path_name, sdp->metafs_path, "gfs2", 0, "meta");
+	ret = mount(sdp->device_name, sdp->metafs_path, "gfs2", 0, "meta");
 	if (ret) {
 		rmdir(sdp->metafs_path);
 		return -1;
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 734efde..8e9ad86 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -368,42 +368,42 @@ int build_root(struct gfs2_sbd *sdp)
 	return 0;
 }
 
-int do_init(struct gfs2_sbd *sdp)
+int do_init_inum(struct gfs2_sbd *sdp)
 {
-	{
-		struct gfs2_inode *ip = sdp->md.inum;
-		uint64_t buf;
-		int count;
-
-		buf = cpu_to_be64(sdp->md.next_inum);
-		count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
-		if (count != sizeof(uint64_t))
-			return -1;
+	struct gfs2_inode *ip = sdp->md.inum;
+	uint64_t buf;
+	int count;
 
-		if (sdp->debug)
-			printf("\nNext Inum: %"PRIu64"\n",
-			       sdp->md.next_inum);
-	}
+	buf = cpu_to_be64(sdp->md.next_inum);
+	count = gfs2_writei(ip, &buf, 0, sizeof(uint64_t));
+	if (count != sizeof(uint64_t))
+		return -1;
 
-	{
-		struct gfs2_inode *ip = sdp->md.statfs;
-		struct gfs2_statfs_change sc;
-		char buf[sizeof(struct gfs2_statfs_change)];
-		int count;
+	if (sdp->debug)
+		printf("\nNext Inum: %"PRIu64"\n",
+		       sdp->md.next_inum);
+	return 0;
+}
 
-		sc.sc_total = sdp->blks_total;
-		sc.sc_free = sdp->blks_total - sdp->blks_alloced;
-		sc.sc_dinodes = sdp->dinodes_alloced;
+int do_init_statfs(struct gfs2_sbd *sdp)
+{
+	struct gfs2_inode *ip = sdp->md.statfs;
+	struct gfs2_statfs_change sc;
+	char buf[sizeof(struct gfs2_statfs_change)];
+	int count;
 
-		gfs2_statfs_change_out(&sc, buf);
-		count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
-		if (count != sizeof(struct gfs2_statfs_change))
-			return -1;
+	sc.sc_total = sdp->blks_total;
+	sc.sc_free = sdp->blks_total - sdp->blks_alloced;
+	sc.sc_dinodes = sdp->dinodes_alloced;
 
-		if (sdp->debug) {
-			printf("\nStatfs:\n");
-			gfs2_statfs_change_print(&sc);
-		}
+	gfs2_statfs_change_out(&sc, buf);
+	count = gfs2_writei(ip, buf, 0, sizeof(struct gfs2_statfs_change));
+	if (count != sizeof(struct gfs2_statfs_change))
+		return -1;
+
+	if (sdp->debug) {
+		printf("\nStatfs:\n");
+		gfs2_statfs_change_print(&sc);
 	}
 	return 0;
 }
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index ee43bbd..4c1d94f 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -633,7 +633,8 @@ void main_mkfs(int argc, char *argv[])
 	build_rindex(sdp);
 	build_quota(sdp);
 
-	do_init(sdp);
+	do_init_inum(sdp);
+	do_init_statfs(sdp);
 
 	/* Cleanup */
 
diff --git a/group/dlm_controld/Makefile b/group/dlm_controld/Makefile
index cd6c950..f9a2d05 100644
--- a/group/dlm_controld/Makefile
+++ b/group/dlm_controld/Makefile
@@ -47,7 +47,7 @@ PCMK_CFLAGS += `xml2-config --cflags`
 LDFLAGS += -L${dlmlibdir} -ldlm 
 LDFLAGS += -L${logtlibdir} -llogthread
 LDFLAGS += -L${openaislibdir} -lSaCkpt
-LDFLAGS += -L${corosynclibdir} -lcpg 
+LDFLAGS += -L${corosynclibdir} -lcpg -lconfdb
 LDFLAGS += -L../lib -lgroup
 LDFLAGS += -L${libdir}
 
diff --git a/group/dlm_controld/action.c b/group/dlm_controld/action.c
index 229823b..65918aa 100644
--- a/group/dlm_controld/action.c
+++ b/group/dlm_controld/action.c
@@ -1,6 +1,9 @@
 #include "dlm_daemon.h"
 #include "config.h"
 
+#include <corosync/corotypes.h>
+#include <corosync/confdb.h>
+
 static int dir_members[MAX_NODES];
 static int dir_members_count;
 static int comms_nodes[MAX_NODES];
@@ -12,6 +15,58 @@ static char mg_name[DLM_LOCKSPACE_LEN+1];
 #define SPACES_DIR    "/sys/kernel/config/dlm/cluster/spaces"
 #define COMMS_DIR     "/sys/kernel/config/dlm/cluster/comms"
 
+static int detect_protocol(void)
+{
+	confdb_handle_t handle;
+	hdb_handle_t totem_handle;
+	char key_value[256];
+	size_t value_len;
+	int rv, proto = -1;
+	confdb_callbacks_t callbacks = {
+		.confdb_key_change_notify_fn = NULL,
+		.confdb_object_create_change_notify_fn = NULL,
+		.confdb_object_delete_change_notify_fn = NULL
+	};
+
+	rv = confdb_initialize(&handle, &callbacks);
+	if (rv != CS_OK) {
+		log_error("confdb_initialize error %d", rv);
+		return -1; 
+	}
+
+	rv = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
+	if (rv != CS_OK) {
+		log_error("confdb_object_find_start error %d", rv);
+		goto out;
+	}
+
+	rv = confdb_object_find(handle, OBJECT_PARENT_HANDLE,
+				"totem", strlen("totem"), &totem_handle);
+	if (rv != CS_OK) {
+		log_error("confdb_object_find error %d", rv);
+		goto out;
+	}
+
+	rv = confdb_key_get(handle, totem_handle,
+			    "rrp_mode", strlen("rrp_mode"),
+			    key_value, &value_len);
+	if (rv != CS_OK) {
+		log_error("confdb_key_get error %d", rv);
+		goto out;
+	}
+
+	key_value[value_len] = '\0';
+	log_debug("totem/rrp_mode = '%s'", key_value);
+
+	if (!strcmp(key_value, "none"))
+		proto = PROTO_TCP;
+	else
+		proto = PROTO_SCTP;
+ out:
+	confdb_finalize(handle);
+	return proto;
+}
+
 /* look for an id that matches in e.g. /sys/fs/gfs/bull\:x/lock_module/id
    and then extract the "x" as the name */
 
@@ -796,6 +851,91 @@ static int set_configfs_debug(int val)
 	return 0;
 }
 
+#define NET_RMEM_DEFAULT 4194304
+#define NET_RMEM_MAX 4194304
+
+static int set_proc_rmem(void)
+{
+	char path[PATH_MAX];
+	char buf[32];
+	int fd, rv;
+
+	memset(path, 0, PATH_MAX);
+	snprintf(path, PATH_MAX, "/proc/sys/net/core/rmem_default");
+
+	fd = open(path, O_RDWR);
+	if (fd < 0) {
+		log_error("%s: open failed: %d", path, errno);
+		return fd;
+	}
+
+	memset(buf, 0, sizeof(buf));
+
+	rv = read(fd, buf, sizeof(buf));
+	if (rv < 0) {
+		log_error("%s: read failed: %d", path, errno);
+		close(fd);
+		return rv;
+	}
+
+	if (atoi(buf) >= NET_RMEM_DEFAULT) {
+		close(fd);
+		goto next;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	snprintf(buf, 32, "%d", NET_RMEM_DEFAULT);
+
+	rv = do_write(fd, buf, strlen(buf));
+	if (rv < 0) {
+		log_error("%s: write failed: %d", path, errno);
+		close(fd);
+		return rv;
+	}
+
+	close(fd);
+	log_debug("set %s %s", path, buf);
+
+ next:
+	memset(path, 0, PATH_MAX);
+	snprintf(path, PATH_MAX, "/proc/sys/net/core/rmem_max");
+
+	fd = open(path, O_RDWR);
+	if (fd < 0) {
+		log_error("%s: open failed: %d", path, errno);
+		return fd;
+	}
+
+	memset(buf, 0, sizeof(buf));
+
+	rv = read(fd, buf, sizeof(buf));
+	if (rv < 0) {
+		log_error("%s: read failed: %d", path, errno);
+		close(fd);
+		return rv;
+	}
+
+	if (atoi(buf) >= NET_RMEM_MAX) {
+		close(fd);
+		goto out;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	snprintf(buf, 32, "%d", NET_RMEM_MAX);
+
+	rv = do_write(fd, buf, strlen(buf));
+	if (rv < 0) {
+		log_error("%s: write failed: %d", path, errno);
+		close(fd);
+		return rv;
+	}
+
+	close(fd);
+	log_debug("set %s %s", path, buf);
+ out:
+	return 0;
+}
+
 void clear_configfs(void)
 {
 	clear_configfs_comms();
@@ -824,9 +964,19 @@ int setup_configfs(void)
 		set_configfs_debug(cfgk_debug);
 	if (cfgk_timewarn != -1)
 		set_configfs_timewarn(cfgk_timewarn);
-	if (cfgk_protocol != -1)
+
+	if (cfgk_protocol == PROTO_DETECT) {
+		rv = detect_protocol();
+		if (rv == PROTO_TCP || rv == PROTO_SCTP)
+			cfgk_protocol = rv;
+	}
+
+	if (cfgk_protocol == PROTO_TCP || cfgk_protocol == PROTO_SCTP)
 		set_configfs_protocol(cfgk_protocol);
 
+	if (cfgk_protocol == PROTO_SCTP)
+		set_proc_rmem();
+
 	return 0;
 }
 
diff --git a/group/dlm_controld/config.c b/group/dlm_controld/config.c
index 16c4efb..1720e7a 100644
--- a/group/dlm_controld/config.c
+++ b/group/dlm_controld/config.c
@@ -25,9 +25,6 @@
 #include "config.h"
 #include "ccs.h"
 
-#define PROTO_TCP  0
-#define PROTO_SCTP 1
-
 int ccs_handle;
 
 /* when not set in cluster.conf, a node's default weight is 1 */
@@ -199,6 +196,8 @@ static void read_ccs_protocol(const char *path, int *config_val)
 		val = PROTO_TCP;
 	else if (!strncasecmp(str, "sctp", 4))
 		val = PROTO_SCTP;
+	else if (!strncasecmp(str, "detect", 6))
+		val = PROTO_DETECT;
 	else {
 		log_error("ignore invalid value %s for %s", str, path);
 		return;
@@ -235,6 +234,7 @@ int setup_ccs(void)
 {
 	int cd, rv;
 
+	/* skip things that cannot be changed while running */
 	if (ccs_handle)
 		goto update;
 
@@ -270,7 +270,6 @@ int setup_ccs(void)
 			read_ccs_int(GFS_PLOCK_OWNERSHIP_PATH, &cfgd_plock_ownership);
 	}
 
-
 	/* The following can be changed while running */
  update:
 	if (!optd_plock_debug) {
diff --git a/group/dlm_controld/dlm_daemon.h b/group/dlm_controld/dlm_daemon.h
index 0ca895a..dd6c7cc 100644
--- a/group/dlm_controld/dlm_daemon.h
+++ b/group/dlm_controld/dlm_daemon.h
@@ -66,6 +66,12 @@
 #define GROUP_LIBGROUP	2
 #define GROUP_LIBCPG	3
 
+/* cfgk_protocol */
+
+#define PROTO_TCP  0
+#define PROTO_SCTP 1
+#define PROTO_DETECT 2
+
 extern int daemon_debug_opt;
 extern int daemon_quit;
 extern int cluster_down;
diff --git a/group/dlm_controld/main.c b/group/dlm_controld/main.c
index 712bed6..af96527 100644
--- a/group/dlm_controld/main.c
+++ b/group/dlm_controld/main.c
@@ -1089,6 +1089,9 @@ static void print_usage(void)
 	printf("  -D		Enable debugging to stderr and don't fork\n");
 	printf("  -L		Enable debugging to log file\n");
 	printf("  -K		Enable kernel dlm debugging messages\n");
+	printf("  -r <num>	dlm kernel lowcomms protocol, 0 tcp, 1 sctp, 2 detect\n");
+	printf("                2 selects tcp if corosync rrp_mode is \"none\", otherwise sctp\n");
+	printf("                Default is 2\n");
 	printf("  -g <num>	groupd compatibility mode, 0 off, 1 on, 2 detect\n");
 	printf("		0: use libcpg, no backward compat, best performance\n");
 	printf("		1: use libgroup for compat with cluster2/rhel5\n");
@@ -1118,17 +1121,13 @@ static void print_usage(void)
 	printf("  -V		Print program version information, then exit\n");
 }
 
-#define OPTION_STRING "LDKg:f:q:d:p:Pl:o:t:c:a:hV"
+#define OPTION_STRING "LDKg:f:q:d:p:Pl:o:t:c:a:hVr:"
 
 static void read_arguments(int argc, char **argv)
 {
 	int cont = 1;
 	int optchar;
 
-	/* we don't allow these to be set on command line, should we? */
-	optk_timewarn = 0;
-	optk_timewarn = 0;
-
 	while (cont) {
 		optchar = getopt(argc, argv, OPTION_STRING);
 
@@ -1153,6 +1152,11 @@ static void read_arguments(int argc, char **argv)
 			cfgk_debug = 1;
 			break;
 
+		case 'r':
+			optk_protocol = 1;
+			cfgk_protocol = atoi(optarg);
+			break;
+
 		case 'f':
 			optd_enable_fencing = 1;
 			cfgd_enable_fencing = atoi(optarg);
@@ -1359,7 +1363,7 @@ int optd_drop_resources_age;
 
 int cfgk_debug                  = -1;
 int cfgk_timewarn               = -1;
-int cfgk_protocol               = -1;
+int cfgk_protocol               = PROTO_DETECT;
 int cfgd_groupd_compat          = DEFAULT_GROUPD_COMPAT;
 int cfgd_debug_logfile		= DEFAULT_DEBUG_LOGFILE;
 int cfgd_enable_fencing         = DEFAULT_ENABLE_FENCING;
diff --git a/group/tool/main.c b/group/tool/main.c
index f039584..39cc1a2 100644
--- a/group/tool/main.c
+++ b/group/tool/main.c
@@ -621,7 +621,6 @@ int main(int argc, char **argv)
 
 		switch (version) {
 		case -1:
-			printf("groupd not running\n");
 			break;
 		case -EAGAIN:
 			printf("groupd compatibility mode 2 (pending)\n");
diff --git a/make/official_release_version b/make/official_release_version
index 20b9a9b..440ebd0 100644
--- a/make/official_release_version
+++ b/make/official_release_version
@@ -1,2 +1,2 @@
 SONAME "3.0"
-VERSION "3.0.4"
+VERSION "3.0.6"
diff --git a/rgmanager/init.d/rgmanager.in b/rgmanager/init.d/rgmanager.in
index 37539ba..38f7b1f 100644
--- a/rgmanager/init.d/rgmanager.in
+++ b/rgmanager/init.d/rgmanager.in
@@ -88,6 +88,7 @@ start)
 		success
 	else
 		if $RGMGRD $RGMGR_OPTS; then
+			touch $LOCK_FILE
 			success
 		else
 			failure
@@ -96,10 +97,17 @@ start)
 	fi
 	echo
 ;;
-restart|condrestart)
+restart)
 	$0 stop
 	$0 start
 ;;
+condrestart|try-restart)
+	if status $RGMGRD > /dev/null 2>&1; then
+		$0 stop
+		$0 start
+		rtrn=$?
+	fi
+;;
 reload|force-reload)
 	# not required anymore
 	# return not implemented
@@ -126,8 +134,8 @@ stop)
 	rm -f $LOCK_FILE
 ;;
 *)
-	echo "usage: $0 {start|restart|condrestart|reload|status|stop}"
-	rtrn=1
+	echo "usage: $0 {start|stop|restart|condrestart|try-restart|reload|force-reload|status}"
+	rtrn=2
 ;;
 esac
 
diff --git a/rgmanager/src/daemons/restree.c b/rgmanager/src/daemons/restree.c
index 4ae0848..a4d2926 100644
--- a/rgmanager/src/daemons/restree.c
+++ b/rgmanager/src/daemons/restree.c
@@ -1376,8 +1376,9 @@ _res_op_internal(resource_node_t __attribute__ ((unused)) **tree,
 		   incarnations there are. */
 		pthread_mutex_lock(&node->rn_resource->r_mutex);
 		if (node->rn_state == RES_STARTED) {
-			assert(node->rn_resource->r_incarnations > 0);
-			--node->rn_resource->r_incarnations;
+			assert(node->rn_resource->r_incarnations >= 0);
+			if (node->rn_resource->r_incarnations > 0)
+				--node->rn_resource->r_incarnations;
 		}
 
 		node->rn_flags &= ~RF_NEEDSTOP;
diff --git a/rgmanager/src/daemons/rg_state.c b/rgmanager/src/daemons/rg_state.c
index ab18202..2346c44 100644
--- a/rgmanager/src/daemons/rg_state.c
+++ b/rgmanager/src/daemons/rg_state.c
@@ -825,6 +825,11 @@ svc_migrate(const char *svcName, int target)
 		return RG_EINVAL;
 	}
 
+	if (m->cn_member == 0) {
+		free_member_list(membership);
+		return RG_ENODE;
+	}
+
 	count_resource_groups_local(m);
 	if (m->cn_svcexcl ||
 	    (m->cn_svccount && is_exclusive(svcName))) {
@@ -1640,14 +1645,14 @@ svc_start_remote(const char *svcName, int request, uint32_t target)
  * @param new_owner	Member who actually ends up owning the service.
  */
 int
-handle_relocate_req(char *svcName, int request, int preferred_target,
+handle_relocate_req(char *svcName, int orig_request, int preferred_target,
 		    int *new_owner)
 {
 	cluster_member_list_t *allowed_nodes = NULL, *backup = NULL;
 	cman_node_t *m;
-	int target = preferred_target, me = my_id();
-	int ret, x;
 	rg_state_t svcStatus;
+	int target = preferred_target, me = my_id();
+	int ret, x, request = orig_request;
 	
 	get_rg_state_local(svcName, &svcStatus);
 	if (svcStatus.rs_state == RG_STATE_DISABLED ||
@@ -1749,6 +1754,13 @@ handle_relocate_req(char *svcName, int request, int preferred_target,
 				 */
 				return 0;
 			}
+
+			/*
+			 * Failed to start on that node.
+			 * Use the START_RECOVER operation on subsequent
+			 * attempts.
+			 */
+			request = RG_START_RECOVER;
 		}
 	}
 
@@ -1783,6 +1795,10 @@ handle_relocate_req(char *svcName, int request, int preferred_target,
 			return 0;
 		case RG_EDEPEND:
 		case RG_EFAIL:
+			/* Uh oh - we failed to relocate to this node.
+			   ensure that we tell the next node to start it from
+			   the 'recovering' state. */
+			request = RG_START_RECOVER;
 			memb_mark_down(allowed_nodes, target);
 			continue;
 		case RG_EABORT:
@@ -1815,7 +1831,7 @@ handle_relocate_req(char *svcName, int request, int preferred_target,
 	 * We got sent here from handle_start_req.
 	 * We're DONE.
 	 */
-	if (request == RG_START_RECOVER) {
+	if (orig_request == RG_START_RECOVER) {
 		_svc_stop_finish(svcName, 0, RG_STATE_STOPPED);
 		return RG_EFAIL;
 	}
@@ -2041,7 +2057,8 @@ handle_start_remote_req(char *svcName, int req)
 	if (need_check)
 		pthread_mutex_unlock(&exclusive_mutex);
 
-	if (svc_stop(svcName, RG_STOP_RECOVER) == 0)
+	if (svc_stop(svcName, central_events_enabled() ?
+		     RG_STATE_STOPPED : RG_STOP_RECOVER) == 0)
 		return RG_EFAIL;
 
 	svc_fail(svcName);
diff --git a/rgmanager/src/daemons/service_op.c b/rgmanager/src/daemons/service_op.c
index aa36f41..a508f1e 100644
--- a/rgmanager/src/daemons/service_op.c
+++ b/rgmanager/src/daemons/service_op.c
@@ -187,7 +187,88 @@ service_op_stop(char *svcName, int do_disable, int event_type)
 
 
 /*
-   TODO
-   service_op_migrate()
+   service_op_migrate() - send a virtual machine to another host
+   in the cluster
  */
+int
+service_op_migrate(char *svcName,
+		   int target_node)
+{
+	SmMessageSt msg;
+	int msg_ret;
+	msgctx_t ctx;
+	rg_state_t svcStatus;
+	int msgtarget = my_id();
+
+	/* Build the message header */
+	msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
+	msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
+	msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER; 
+	msg.sm_hdr.gh_length = sizeof (SmMessageSt);
+
+	msg.sm_data.d_action = RG_MIGRATE;
+
+	strncpy(msg.sm_data.d_svcName, svcName,
+		sizeof(msg.sm_data.d_svcName));
+
+	msg.sm_data.d_ret = 0;
+	msg.sm_data.d_svcOwner = target_node;
+
+	/* Open a connection to the local node - it will decide what to
+	   do in this case. XXX inefficient; should queue requests
+	   locally and immediately forward requests otherwise */
+
+	if (get_service_state_internal(svcName, &svcStatus) < 0)
+		return RG_EFAIL;
+	if (svcStatus.rs_owner > 0) {
+		if (member_online(svcStatus.rs_owner)) {
+			msgtarget = svcStatus.rs_owner;
+		}
+
+		if (msgtarget <= 0) {
+			return RG_EFAIL;
+		}
+	}
+
+	if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2)< 0) {
+		logt_print(LOG_ERR,
+		       "#58: Failed opening connection to member #%d\n",
+		       my_id());
+		return -1;
+	}
+
+	/* Encode */
+	swab_SmMessageSt(&msg);
+
+	/* Send stop message to the other node */
+	if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) < 
+	    (int)sizeof (SmMessageSt)) {
+		logt_print(LOG_ERR, "Failed to send complete message\n");
+		msg_close(&ctx);
+		return -1;
+	}
+
+	/* Check the response */
+	do {
+		msg_ret = msg_receive(&ctx, &msg,
+				      sizeof (SmMessageSt), 10);
+		if ((msg_ret == -1 && errno != ETIMEDOUT) ||
+		    (msg_ret > 0)) {
+			break;
+		}
+	} while(1);
 
+	if (msg_ret != sizeof (SmMessageSt)) {
+		logt_print(LOG_WARNING, "Strange response size: %d vs %d\n",
+		       msg_ret, (int)sizeof(SmMessageSt));
+		return 0;	/* XXX really UNKNOWN */
+	}
+
+	/* Got a valid response from other node. */
+	msg_close(&ctx);
+
+	/* Decode */
+	swab_SmMessageSt(&msg);
+
+	return msg.sm_data.d_ret;
+}
diff --git a/rgmanager/src/daemons/slang_event.c b/rgmanager/src/daemons/slang_event.c
index de8aa61..29ae9f2 100644
--- a/rgmanager/src/daemons/slang_event.c
+++ b/rgmanager/src/daemons/slang_event.c
@@ -580,6 +580,63 @@ out:
 }
 
 
+static int
+sl_migrate_service(void)
+{
+	char *svcname = NULL;
+	int target_node = 0;
+	int nargs, t, newowner = 0, ret = -1;
+
+	nargs = SLang_Num_Function_Args;
+
+	/* Takes one, two, or three */
+	if (nargs != 2) {
+		SLang_verror(SL_Syntax_Error,
+		     (char *)"%s: Wrong # of args (%d), must be 2: service_name target_node\n",
+		     __FUNCTION__, nargs);
+		return -1;
+	}
+
+	t = SLang_peek_at_stack();
+	if (t != SLANG_INT_TYPE) {
+		SLang_verror(SL_Syntax_Error,
+			     (char *)"%s: expected type %d got %d\n",
+			     __FUNCTION__, SLANG_INT_TYPE, t);
+		goto out;
+	}
+
+	if (SLang_pop_integer(&target_node) < 0) {
+		SLang_verror(SL_Syntax_Error,
+		    (char *)"%s: Failed to pop integer from stack!\n",
+		    __FUNCTION__);
+		goto out;
+	}
+
+	t = SLang_peek_at_stack();
+	if (t != SLANG_STRING_TYPE) {
+		SLang_verror(SL_Syntax_Error,
+			     (char *)"%s: expected type %d got %d\n",
+			     __FUNCTION__,
+			     SLANG_STRING_TYPE, t);
+		goto out;
+	}
+
+	if (SLpop_string(&svcname) < 0) {
+		goto out;
+	}
+
+	ret = service_op_migrate(svcname, target_node);
+
+	if (ret == 0)
+		ret = target_node;
+out:
+	if (svcname)
+		free(svcname);
+	_user_return = ret;
+	return ret;
+}
+
+
 /* Take an array of integers given its length and
    push it on to the S/Lang stack */
 void
@@ -979,6 +1036,8 @@ static SLang_Intrin_Fun_Type rgmanager_slang[] =
 			 SLANG_INT_TYPE),
 	MAKE_INTRINSIC_0((char *)"service_start", sl_start_service,
 			 SLANG_INT_TYPE),
+	MAKE_INTRINSIC_0((char *)"service_migrate", sl_migrate_service,
+			 SLANG_INT_TYPE),
 	MAKE_INTRINSIC_S((char *)"service_status", sl_service_status,
 			 SLANG_VOID_TYPE),
 	MAKE_INTRINSIC_S((char *)"service_freeze", sl_service_freeze,
diff --git a/rgmanager/src/resources/SAPDatabase b/rgmanager/src/resources/SAPDatabase
index 4733f33..d6972fd 100644
--- a/rgmanager/src/resources/SAPDatabase
+++ b/rgmanager/src/resources/SAPDatabase
@@ -88,7 +88,7 @@ Resource script for SAP databases. It manages a SAP database of any type as an H
 <shortdesc lang="en">SAP database resource agent</shortdesc>
 
 <parameters>
- <parameter name="SID" unique="1" required="1">
+ <parameter name="SID" unique="1" required="1" primary="1">
   <longdesc lang="en">The unique SAP system identifier. e.g. P01</longdesc>
   <shortdesc lang="en">SAP system ID</shortdesc>
   <content type="string" default="" />
diff --git a/rgmanager/src/resources/SAPInstance b/rgmanager/src/resources/SAPInstance
index c04886f..94643c9 100644
--- a/rgmanager/src/resources/SAPInstance
+++ b/rgmanager/src/resources/SAPInstance
@@ -80,7 +80,7 @@ Resource script for SAP. It manages a SAP Instance as an HA resource.
 <shortdesc lang="en">SAP instance resource agent</shortdesc>
 
 <parameters>
- <parameter name="InstanceName" unique="1" required="1">
+ <parameter name="InstanceName" unique="1" required="1" primary="1">
   <longdesc lang="en">The full qualified SAP instance name. e.g. P01_DVEBMGS00_sapp01ci</longdesc>
   <shortdesc lang="en">instance name: SID_INSTANCE_VIR-HOSTNAME</shortdesc>
   <content type="string" default="" />
diff --git a/rgmanager/src/resources/apache.sh b/rgmanager/src/resources/apache.sh
index bb225aa..ca0325f 100644
--- a/rgmanager/src/resources/apache.sh
+++ b/rgmanager/src/resources/apache.sh
@@ -62,7 +62,7 @@ verify_all()
 	fi
 
 	if [ ! -r "$APACHE_serverConfigFile" ]; then
-		clog_check_file_exist $CLOG_FAILED_NOT_READABLE "$APACHE_config_file"
+		clog_check_file_exist $CLOG_FAILED_NOT_READABLE "$APACHE_serverConfigFile"
 		return $OCF_ERR_ARGS
 	fi
 
@@ -80,11 +80,11 @@ verify_all()
 		$OCF_RESKEY_httpd_options &> /dev/null
 		
 	if [ $? -ne 0 ]; then
-		clog_check_syntax $CLOG_FAILED "$APACHE_config_file"
+		clog_check_syntax $CLOG_FAILED "$APACHE_serverConfigFile"
 		return $OCF_ERR_GENERIC
 	fi
 
-	clog_check_syntax $CLOG_SUCCEED "$APACHE_config_file"
+	clog_check_syntax $CLOG_SUCCEED "$APACHE_serverConfigFile"
 
 	return 0
 }
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
index 7809b20..84e6d72 100644
--- a/rgmanager/src/resources/default_event_script.sl
+++ b/rgmanager/src/resources/default_event_script.sl
@@ -585,11 +585,11 @@ define default_user_event_handler()
 
 		ret = service_unfreeze(service_name);
 
-	}
+	} else if (user_request == USER_MIGRATE) {
 
-	%
-	% todo - migrate
-	%
+		ret = service_migrate(service_name, user_target);
+
+	}
 
 	return ret;
 }
diff --git a/rgmanager/src/resources/fs.sh.in b/rgmanager/src/resources/fs.sh.in
index 1cf8668..640e7f3 100644
--- a/rgmanager/src/resources/fs.sh.in
+++ b/rgmanager/src/resources/fs.sh.in
@@ -1001,6 +1001,7 @@ Cannot mount $dev on $mp, the device or mount point is already in use!"
         ext3)     typeset fsck_needed="" ;;
         jfs)      typeset fsck_needed="" ;;
         xfs)      typeset fsck_needed="" ;;
+	vxfs)	  typeset fsck_needed="" ;;
         ext2)     typeset fsck_needed=yes ;;
         minix)    typeset fsck_needed=yes ;;
         vfat)     typeset fsck_needed=yes ;;
diff --git a/rgmanager/src/resources/ip.sh b/rgmanager/src/resources/ip.sh
index 445e873..f974fa9 100644
--- a/rgmanager/src/resources/ip.sh
+++ b/rgmanager/src/resources/ip.sh
@@ -564,6 +564,13 @@ ipv6()
 			ocf_log info "Removing IPv6 address $addr from $dev"
                 fi
 		
+		if [ "$1" = "add" ]; then
+			ocf_log debug "Pinging addr ${addr%%/*} from dev $dev"
+			if ping_check inet6 ${addr%%/*} $dev; then
+				ocf_log err "IPv6 address collision ${addr%%/*}"
+				return 1
+			fi
+		fi
 		/sbin/ip -f inet6 addr $1 dev $dev $addr
 		[ $? -ne 0 ] && return 1
 		
@@ -636,6 +643,13 @@ ipv4()
 			ocf_log info "Removing IPv4 address $addr from $dev"
 		fi
 		
+		if [ "$1" = "add" ]; then
+			ocf_log debug "Pinging addr ${addr%%/*} from dev $dev"
+			if ping_check inet ${addr%%/*} $dev; then
+				ocf_log err "IPv4 address collision ${addr%%/*}"
+				return 1
+			fi
+		fi
 		/sbin/ip -f inet addr $1 dev $dev $addr
 		[ $? -ne 0 ] && return 1
 		
diff --git a/rgmanager/src/resources/oracledb.sh.in b/rgmanager/src/resources/oracledb.sh.in
index 809605e..5ba3370 100644
--- a/rgmanager/src/resources/oracledb.sh.in
+++ b/rgmanager/src/resources/oracledb.sh.in
@@ -278,7 +278,7 @@ start_db()
 	rm -f $tmpfile
 
 	# Dump logfile to /var/log/messages
-	initlog -q -c "cat $logfile"
+	logger -f $logfile
 
 	if [ $rv -ne 0 ]; then
 		echo "ORACLE_HOME Incorrectly set?"
@@ -326,7 +326,7 @@ stop_db()
 	rm -f $tmpfile
 
 	# Dump logfile to /var/log/messages
-	initlog -q -c "cat $logfile"
+	logger -f $logfile
 
 	if [ $rv -ne 0 ]; then
 		echo "ORACLE_HOME Incorrectly set?"
@@ -362,12 +362,12 @@ force_cleanup()
 	# Patch from Shane Bradley to fix 471266
 	pids=`ps ax | grep $ORACLE_HOME | grep "ora_.*_${ORACLE_SID}" | grep -v grep | awk '{print $1}'`
 
-	initlog -n $SCRIPT -s "<err> Not all Oracle processes exited cleanly, killing"
+	logger -t $SCRIPT "<err> Not all Oracle processes exited cleanly, killing"
 	
 	for pid in $pids; do
 		kill -9 $pid
 		if [ $? -eq 0 ]; then
-			initlog -n $SCRIPT -s "Killed $pid"
+			logger -t $SCRIPT "Killed $pid"
 		fi
 	done
 
@@ -428,7 +428,7 @@ get_db_status()
 		for (( i=$RESTART_RETRIES ; i; i-- )) ; do
 			# this db process is down - stop and
 			# (re)start all ora_XXXX_$ORACLE_SID processes
-			initlog -q -n $SCRIPT -s "Restarting Oracle Database..."
+			logger -t $SCRIPT "Restarting Oracle Database..."
 			stop_db
 			if [ $? != 0 ] ; then
 				# stop failed - return 1
diff --git a/rgmanager/src/resources/samba.sh b/rgmanager/src/resources/samba.sh
index 81fd8cb..f7c134b 100644
--- a/rgmanager/src/resources/samba.sh
+++ b/rgmanager/src/resources/samba.sh
@@ -69,7 +69,7 @@ generate_config_file()
 	echo "pid directory = \"$SAMBA_pid_dir\"" >> "$generated_file"
 	echo "interfaces = $ip_addresses" >> "$generated_file"
 	echo "bind interfaces only = Yes" >> "$generated_file"
-	echo "netbios name = \"$OCF_RESKEY_name\"" >> "$generated_file"
+	echo "netbios name = ${OCF_RESKEY_name/ /_}" >> "$generated_file"
 	echo >> "$generated_file"	
 	sed 's/^[[:space:]]*pid directory/### pid directory/i;s/^[[:space:]]*interfaces/### interfaces/i;s/^[[:space:]]*bind interfaces only/### bind interfaces only/i;s/^[[:space:]]*netbios name/### netbios name/i' \
 	     < "$original_file" >> "$generated_file"
diff --git a/rgmanager/src/resources/smb.sh b/rgmanager/src/resources/smb.sh
index c2a9d9d..e62678b 100644
--- a/rgmanager/src/resources/smb.sh
+++ b/rgmanager/src/resources/smb.sh
@@ -583,6 +583,9 @@ share_start_stop()
 		mkdir -p "$SAMBA_PID_DIR/$OCF_RESKEY_name"
 		mkdir -p "$SAMBA_LOCK_DIR/$OCF_RESKEY_name"
 
+		[ -f "$SMBD_COMMAND" ] || exit $OCF_ERR_INSTALLED
+		[ -f "$NMBD_COMMAND" ] || exit $OCF_ERR_INSTALLED
+
 		# Kick off the per-service smbd
 		$SMBD_COMMAND $smbd_options "$conf"
 		ret_val=$?
diff --git a/rgmanager/src/resources/vm.sh b/rgmanager/src/resources/vm.sh
index 2dbeb5b..3ec8b87 100644
--- a/rgmanager/src/resources/vm.sh
+++ b/rgmanager/src/resources/vm.sh
@@ -563,9 +563,106 @@ do_status()
 }
 
 
+#
+# virsh "path" attribute support
+#
+check_config_file()
+{
+	declare path=$1
+
+	if [ -f "$path/$OCF_RESKEY_name" ]; then
+		echo $path/$OCF_RESKEY_name
+		return 2
+	elif [ -f "$path/$OCF_RESKEY_name.xml" ]; then
+		echo $path/$OCF_RESKEY_name.xml
+		return 2
+	fi
+
+	return 0
+}
+
+
+parse_input()
+{
+	declare delim=$1
+	declare input=$2
+	declare func=$3
+	declare inp
+	declare value
+
+	while [ -n "$input" ]; do
+		value=${input/$delim*/}
+		if [ -n "$value" ]; then
+			eval $func $value
+			if [ $? -eq 2 ]; then
+				return 0
+			fi
+		fi
+		inp=${input/$value$delim/}
+		if [ "$input" = "$inp" ]; then
+			inp=${input/$value/}
+		fi
+		input=$inp
+	done
+}
+
+
+search_config_path()
+{
+	declare config_file=$(parse_input ":" "$OCF_RESKEY_path" check_config_file)
+
+	if [ -n "$config_file" ]; then
+		export OCF_RESKEY_xmlfile=$config_file
+		return 0
+	fi
+
+	return 1
+}
+
+
+choose_management_tool()
+{
+	declare -i is_xml
+
+	#
+	# Don't override user value for use_virsh if one is given
+	#
+	if [ -n "$OCF_RESKEY_use_virsh" ]; then
+		return 0
+	fi
+
+	which xmllint &> /dev/null
+	if [ $? -ne 0 ]; then
+		ocf_log warning "Could not find xmllint; assuming virsh mode"
+		export OCF_RESKEY_use_virsh=1
+		unset OCF_RESKEY_path
+		return 0
+	fi
+
+	xmllint $OCF_RESKEY_xmlfile &> /dev/null
+	is_xml=$?
+
+	if [ $is_xml -eq 0 ]; then
+		ocf_log debug "$OCF_RESKEY_xmlfile is XML; using virsh"
+		export OCF_RESKEY_use_virsh=1
+		unset OCF_RESKEY_path
+	else
+		ocf_log debug "$OCF_RESKEY_xmlfile is not XML; using xm"
+		export OCF_RESKEY_use_virsh=0
+		unset OCF_RESKEY_xmlfile
+	fi
+
+	return 0
+}
+
+
+
 validate_all()
 {
-	[ "$(id -u)" = "0" ] || return 1
+	if [ "$(id -u)" != "0" ]; then
+	       ocf_log err "Cannot control VMs. as non-root user."
+	       return 1
+	fi
 
 	#
 	# If someone selects a hypervisor, honor it.
@@ -589,19 +686,54 @@ validate_all()
 			ocf_log err "Cannot use $OCF_RESKEY_hypervisor hypervisor without using virsh"
 			return $OCF_ERR_ARGS
 		fi
+
+		if [ -n "$OCF_RESKEY_xmlfile" ]; then
+			ocf_log err "Cannot use xmlfile if use_virsh is set to 0"
+			return $OCF_ERR_ARGS
+		fi
 	else
-	
+
 		#
-		# If no path is set, use virsh.  Otherwise, use xm.
-		# xm only works with Xen.
+		# Virsh path support.
 		#
-		if [ -z "$OCF_RESKEY_path" ] ||
-		   [ "$OCF_RESKEY_path" = "/etc/xen" ]; then
-			echo "Management tool: virsh"
-			export OCF_RESKEY_use_virsh=1
+		if [ -n "$OCF_RESKEY_path" ] &&
+		   [ "$OCF_RESKEY_path" != "/etc/xen" ]; then
+			if [ -n "$OCF_RESKEY_xmlfile" ]; then
+				ocf_log warning "Using $OCF_RESKEY_xmlfile instead of searching $OCF_RESKEY_path"
+			else
+				search_config_path
+				if [ $? -ne 0 ]; then
+					ocf_log warning "Could not find $OCF_RESKEY_name or $OCF_RESKEY_name.xml in search path $OCF_RESKEY_path"
+					unset OCF_RESKEY_xmlfile
+				else
+					ocf_log debug "Using $OCF_RESKEY_xmlfile"
+				fi
+				choose_management_tool
+			fi
 		else
-			echo "Management tool: xm"
-			export OCF_RESKEY_use_virsh=0
+			export OCF_RESKEY_use_virsh=1
+		fi
+	fi
+
+	if [ "$OCF_RESKEY_use_virsh" = "0" ]; then
+
+		echo "Management tool: xm"
+		which xm &> /dev/null
+		if [ $? -ne 0 ]; then
+			ocf_log err "Cannot find 'xm'; is it installed?"
+			return $OCF_ERR_INSTALLED
+		fi
+
+		if [ "$OCF_RESKEY_hypervisor" != "xen" ]; then
+			ocf_log err "Cannot use $OCF_RESKEY_hypervisor hypervisor without using virsh"
+			return $OCF_ERR_ARGS
+		fi
+	else
+		echo "Management tool: virsh"
+		which virsh &> /dev/null
+		if [ $? -ne 0 ]; then
+			ocf_log err "Cannot find 'virsh'; is it installed?"
+			return $OCF_ERR_INSTALLED
 		fi
 	fi
 
@@ -655,7 +787,7 @@ validate_all()
 
 virsh_migrate()
 {
-	declare $target=$1
+	declare target=$1
 	declare rv=1
 
 	#
@@ -680,17 +812,11 @@ virsh_migrate()
 		ocf_log err "$err"
 
 		if [ "$err" != "${err/does not exist/}" ]; then
-			return $OCF_NOT_RUNNING
+			return $OCF_ERR_CONFIGURED
 		fi
 		if [ "$err" != "${err/Domain not found/}" ]; then
-			return $OCF_NOT_RUNNING
-		fi
-		if [ "$err" != "${err/Connection refused/}" ]; then
 			return $OCF_ERR_CONFIGURED
 		fi
-		if [ "$err" != "${err/unable to start guest/}" ]; then
-			return $OCF_NOT_RUNNING
-		fi
 
 		return $OCF_ERR_GENERIC
 	fi
@@ -799,7 +925,21 @@ case $1 in
 	migrate)
 		validate_all || exit $OCF_ERR_ARGS
 		migrate $2 # Send VM to this node
-		exit $?
+		rv=$?
+		if [ $rv -eq $OCF_ERR_GENERIC ]; then
+			# Catch-all: If migration failed with
+			# an unhandled error, do a status check
+			# to see if the VM is really dead.
+			#
+			# If the VM is still in good health, return
+			# a value to rgmanager to indicate the 
+			# non-critical error
+			do_status > /dev/null
+			if [ $? -eq 0 ]; then
+				rv=$OCF_NOT_RUNNING
+			fi
+		fi
+		exit $rv
 		;;
 	reload)
 		exit 0
diff --git a/rgmanager/src/utils/clusvcadm.c b/rgmanager/src/utils/clusvcadm.c
index e63e30d..0257178 100644
--- a/rgmanager/src/utils/clusvcadm.c
+++ b/rgmanager/src/utils/clusvcadm.c
@@ -366,6 +366,11 @@ main(int argc, char **argv)
 			if (!svctarget)
 				return 1;
 		}
+		if (action == RG_MIGRATE && 
+		    memb_online(membership, svctarget) == 0) {
+			printf("'%s' is offline\n", nodename);
+			return 1;
+		}
 	} else {
 		svctarget = 0;
 		/*

-- 
cluster suite Debian packaging



More information about the Debian-ha-svn-commits mailing list