-o <prefix> Save standard output from each node to file <prefix>.<ip>
-p Run command in parallel on specified nodes.
-q Do not print node addresses (overrides -v).
+ -n Allow nodes to be specified by name.
+ -f Specify nodes file, overrides CTDB_NODES_FILE.
-v Print node address even for a single node.
- <NODES> "all", "ok" (or "healthy"), "con" (or "connected"),
+ <NODES> "all", "any", "ok" (or "healthy"), "con" (or "connected"),
"rm" (or "recmaster"), "lvs" (or "lvsmaster"),
- "natgw" (or "natgwlist");
- or a node number (0 base); or
+ "natgw" (or "natgwlist"); or
+ a node number (0 base); or
+ a hostname (if -n is specified); or
list (comma separated) of <NODES>; or
range (hyphen separated) of node numbers.
EOF
verbose=false
quiet=false
prefix=""
+names_ok=false
+
+ctdb_base="${CTDB_BASE:-/etc/ctdb}"
parse_options ()
{
# $POSIXLY_CORRECT means that the command passed to onnode can
# take options and getopt won't reorder things to make them
# options ot onnode.
- local temp=$(POSIXLY_CORRECT=1 getopt -n "$prog" -o "cho:pqv" -l help -- "$@")
+ local temp=$(POSIXLY_CORRECT=1 getopt -n "$prog" -o "cf:hno:pqv" -l help -- "$@")
[ $? != 0 ] && usage
while true ; do
case "$1" in
-c) current=true ; shift ;;
+ -f) CTDB_NODES_FILE="$2" ; shift 2 ;;
+ -n) names_ok=true ; shift ;;
-o) prefix="$2" ; shift 2 ;;
-p) parallel=true ; shift ;;
-q) quiet=true ; shift ;;
case "$i" in
*-*) seq "${i%-*}" "${i#*-}" 2>/dev/null || invalid_nodespec ;;
# Separate lines for readability.
- all|ok|healthy|con|connected) echo "$i" ;;
+ all|any|ok|healthy|con|connected) echo "$i" ;;
rm|recmaster|lvs|lvsmaster|natgw|natgwlist) echo "$i" ;;
*)
- [ $i -gt -1 ] 2>/dev/null || invalid_nodespec
+ [ $i -gt -1 ] 2>/dev/null || $names_ok || invalid_nodespec
echo $i
esac
done
# Succeeded. Get address. NOTE: this is an optimisation.
# It might be better to get the node number and then get
# the nth node to get the address. This would make things
- # more consistent if /etc/ctdb/nodes actually contained
+ # more consistent if $ctdb_base/nodes actually contained
# hostnames.
nodes="${nodes} ${t##*:}"
fi
fi
}
+get_any_available_node ()
+{
+ local all_nodes="$1"
+
+ # We do a recursive onnode to find which nodes are up and running.
+ local out=$($0 -pq all ctdb pnn 2>&1)
+ local line
+ while read line ; do
+ local pnn="${line#PNN:}"
+ if [ "$pnn" != "$line" ] ; then
+ echo_nth "$pnn" $all_nodes
+ return 0
+ fi
+ # Else must be an error message from a down node.
+ done <<<"$out"
+ return 1
+}
+
get_nodes ()
{
local all_nodes
if [ -n "$CTDB_NODES_SOCKETS" ] ; then
all_nodes="$CTDB_NODES_SOCKETS"
else
- [ -f "$CTDB_NODES_FILE" ] || CTDB_NODES_FILE=/etc/ctdb/nodes
- all_nodes=$(sed -e 's@#.*@@g' -e 's@ *@@g' -e 's@^$@#DEAD@' $CTDB_NODES_FILE)
+ local f="${ctdb_base}/nodes"
+ if [ -n "$CTDB_NODES_FILE" ] ; then
+ f="$CTDB_NODES_FILE"
+ if [ ! -e "$f" -a "${f#/}" = "$f" ] ; then
+ # $f is relative, try in $ctdb_base
+ f="${ctdb_base}/${f}"
+ fi
+ fi
+
+ if [ ! -r "$f" ] ; then
+ echo "${prog}: unable to open nodes file \"${f}\"" >&2
+ exit 1
+ fi
+
+ all_nodes=$(sed -e 's@#.*@@g' -e 's@ *@@g' -e 's@^$@#DEAD@' "$f")
fi
local nodes=""
all)
echo "${all_nodes//#DEAD/}"
;;
+ any)
+ get_any_available_node "$all_nodes" || exit 1
+ ;;
ok|healthy)
get_nodes_with_status "$all_nodes" "healthy" || exit 1
;;
natgw|natgwlist)
get_node_with_property "$all_nodes" "natgwlist" || exit 1
;;
- *)
+ [0-9]|[0-9][0-9]|[0-9][0-9][0-9])
echo_nth $n $all_nodes
+ ;;
+ *)
+ $names_ok || invalid_nodespec
+ echo $n
esac
-
done
}
SSH=fakessh
else
# Could "2>/dev/null || true" but want to see errors from typos in file.
- [ -r /etc/ctdb/onnode.conf ] && . /etc/ctdb/onnode.conf
+ [ -r "${ctdb_base}/onnode.conf" ] && . "${ctdb_base}/onnode.conf"
[ -n "$SSH" ] || SSH=ssh
if [ "$SSH" = "ssh" ] ; then
ssh_opts="-n"