[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