mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
0352224262
This will replace the ctdb CLI tool "lvs" and "lvsmaster" options. It also makes LVS daemon support unnecessary. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
221 lines
4.5 KiB
Bash
Executable File
221 lines
4.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
if [ -z "$CTDB_BASE" ] ; then
|
|
export CTDB_BASE="/usr/local/etc/ctdb"
|
|
fi
|
|
|
|
. "${CTDB_BASE}/functions"
|
|
loadconfig "ctdb"
|
|
|
|
# Default LVS nodes file location
|
|
[ -n "$CTDB_LVS_NODES" ] || CTDB_LVS_NODES="${CTDB_BASE}/lvs_nodes"
|
|
|
|
[ -n "$CTDB_SOCKET" ] && export CTDB_SOCKET
|
|
|
|
############################################################
|
|
|
|
usage ()
|
|
{
|
|
cat <<EOF
|
|
$0 <option>
|
|
|
|
<option> is one of:
|
|
master Display node number of master node
|
|
list List node number and private IP address of usable nodes in group
|
|
status Show status of all nodes in LVS group
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
nodestatus_X=""
|
|
# Fields are:
|
|
# Node|IP|Disconnected|Banned|Disabled|Unhealthy|Stopped|Inactive|PartiallyOnline|ThisNode
|
|
get_nodestatus_X ()
|
|
{
|
|
# Result is cached in global variable nodestatus_X
|
|
[ -n "$nodestatus_X" ] || \
|
|
nodestatus_X=$(ctdb -X nodestatus all |
|
|
sed -e '1d' -e 's@^|@@' -e 's@|$@@')
|
|
}
|
|
|
|
get_nodestatus ()
|
|
{
|
|
# Result is cached in global variable nodestatus
|
|
[ -n "$nodestatus" ] || nodestatus=$(ctdb nodestatus all)
|
|
case $? in
|
|
# ctdb nodestatus returns 255 on failure
|
|
0|255) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
get_lvs_nodes ()
|
|
{
|
|
# Result is cached in global variable lvs_nodes
|
|
if [ -n "$lvs_nodes" ] ; then
|
|
return
|
|
fi
|
|
|
|
if [ ! -r "$CTDB_LVS_NODES" ] ; then
|
|
return 1
|
|
fi
|
|
|
|
lvs_nodes=$(cat "$CTDB_LVS_NODES") || return 1
|
|
|
|
# Sanity check file contents here
|
|
while read _ip _options ; do
|
|
# Skip comments
|
|
case "$_ip" in
|
|
\#*) continue ;;
|
|
esac
|
|
case "$_options" in
|
|
slave-only|"") : ;;
|
|
*) die "${prog}: Invalid options \"${_options}\" in \"$CTDB_LVS_NODES\""
|
|
esac
|
|
done <<EOF
|
|
$lvs_nodes
|
|
EOF
|
|
|
|
return 0
|
|
}
|
|
|
|
# Print PNN and IP address of given nodes meeting the criteria for
|
|
# usable LVS nodes. That is, either those that are healthy or, if no
|
|
# healthy nodes, then nodes that are active and not-disabled.
|
|
# Return codes: 0 = nodes found, 255 = no nodes found, 10 = error.
|
|
filter_nodes ()
|
|
{
|
|
# $_ns is an @-delimited list of nodes to be considered
|
|
_ns="$1"
|
|
|
|
get_nodestatus_X
|
|
[ -n "$nodestatus_X" ] || return 10
|
|
|
|
# Now filter by $_ns and by status of nodes...
|
|
|
|
# Note that the 2 awk invocations below have "||" between
|
|
# them, so the first to succeed will print the nodes.
|
|
|
|
# First try for a fully active and healthy node, so must not
|
|
# be DISABLED, UNHEALTHY or INACTIVE (last covers
|
|
# DISCONNECTED, BANNED or STOPPED)
|
|
awk -F '|' -v ns="$_ns" '
|
|
BEGIN { ret = 255 }
|
|
ns ~ "@" $2 "@" && $5 == 0 && $6 == 0 && $8 == 0 {
|
|
print $1, $2 ; ret=0
|
|
}
|
|
END { exit ret }
|
|
' <<EOF ||
|
|
$nodestatus_X
|
|
EOF
|
|
# Not found? UNHEALTHY do, so node must not be INACTIVE or
|
|
# DISABLED
|
|
awk -F '|' -v ns="$_ns" '
|
|
BEGIN { ret = 255 }
|
|
ns ~ "@" $2 "@" && $5 == 0 && $8 == 0 {
|
|
print $1, $2 ; ret=0
|
|
}
|
|
END { exit ret }
|
|
' <<EOF
|
|
$nodestatus_X
|
|
EOF
|
|
}
|
|
|
|
# Print the PNN of the LVS master node
|
|
find_master ()
|
|
{
|
|
get_lvs_nodes || \
|
|
die "${prog}: LVS nodes file \"$CTDB_LVS_NODES\" not found"
|
|
|
|
# $_ms is an @-delimited list of nodes that are allowed to be the master
|
|
_ms="@"
|
|
while read _ip _options ; do
|
|
case "$_options" in
|
|
"") _ms="${_ms}${_ip}@" ;;
|
|
esac
|
|
done <<EOF
|
|
$lvs_nodes
|
|
EOF
|
|
|
|
_master_candidates=$(filter_nodes "$_ms") || return $?
|
|
echo "${_master_candidates%% *}"
|
|
}
|
|
|
|
# Print the PNN of the LVS master node, verbose version
|
|
show_master ()
|
|
{
|
|
_master_pnn=$(find_master)
|
|
case "$?" in
|
|
0)
|
|
echo "Node ${_master_pnn} is LVS master"
|
|
exit 0
|
|
;;
|
|
255)
|
|
echo "There is no LVS master"
|
|
exit 255
|
|
;;
|
|
*)
|
|
exit 10
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# List all usable nodes in the LVS group
|
|
nodes_list ()
|
|
{
|
|
get_lvs_nodes || \
|
|
die "${prog}: LVS nodes file \"$CTDB_LVS_NODES\" not found"
|
|
|
|
# $_ns is a @-delimited list of nodes in the LVS group
|
|
_ns="@"
|
|
while read _ip _options ; do
|
|
_ns="${_ns}${_ip}@"
|
|
done <<EOF
|
|
$lvs_nodes
|
|
EOF
|
|
|
|
_usable_nodes=$(filter_nodes "$_ns")
|
|
case $? in
|
|
0) : ;;
|
|
255) exit 0 ;; # Return 0 even if no usable nodes
|
|
*) exit 10 ;;
|
|
esac
|
|
|
|
awk '{ print $1 ":" $2 }'<<EOF
|
|
$_usable_nodes
|
|
EOF
|
|
}
|
|
|
|
# Print the status of all nodes in the LVS group, along with a count
|
|
nodes_status ()
|
|
{
|
|
get_lvs_nodes || \
|
|
die "${prog}: LVS nodes file \"$CTDB_LVS_NODES\" not found"
|
|
get_nodestatus
|
|
[ -n "$nodestatus" ] || exit 10
|
|
|
|
# $_ns is a @-delimited list of nodes in the LVS group
|
|
_ns="@"
|
|
while read _ip _options ; do
|
|
_ns="${_ns}${_ip}@"
|
|
done <<EOF
|
|
$lvs_nodes
|
|
EOF
|
|
|
|
# Print status of nodes in $_ns, along with node count
|
|
awk -v ns="$_ns" 'ns ~ "@" $2 "@" { print }' <<EOF
|
|
$nodestatus
|
|
EOF
|
|
}
|
|
|
|
# For backward compatibility
|
|
prog=$(basename "$0")
|
|
cmd="$1"
|
|
|
|
case "$cmd" in
|
|
master) show_master ;;
|
|
list) nodes_list ;;
|
|
status) nodes_status ;;
|
|
*) usage ;;
|
|
esac
|