176 lines
4.5 KiB
Bash
Executable File
176 lines
4.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
|
|
# (1) Init.
|
|
#--------------------------------------------------------#
|
|
# (1) Get current absolute dir
|
|
ROOT=$(dirname `realpath $0`);
|
|
|
|
# (2) Check argc
|
|
test $# -lt 2 && echo -e "error: too few arguments\n\n\e[1mUSAGE\e[0m\n\tmaster <key> <host> <port> <dir>\n\n\e[1mARGUMENTS\e[0m\n\t<key>\tThe key of the pool\n\t<host>\tThe host where the pool is hosted\n\t<port>\tTo port where the pool is bound\n\t<dir>\tThe folder containing ONLY the logger daemons\n" && exit 1;
|
|
|
|
# (3) Check @PORT range #
|
|
MIN_PORT=1024;
|
|
MAX_PORT=49151;
|
|
test "$3" -gt "$MAX_PORT" -o "$3" -lt "$MIN_PORT" && echo "error: <port> must be between $MIN_PORT and $MAX_PORT" && exit 1;
|
|
|
|
# (4) Set argument explicit names #
|
|
POOL_KEY="$1";
|
|
POOL_HOST="$2";
|
|
POOL_PORT="$3";
|
|
LOGGER_DIR="`realpath $4`";
|
|
|
|
# (5) Check @LOGGER_DIR #
|
|
test ! -d "$LOGGER_DIR" && echo "error: <dir> is not a valid folder." && exit 1;
|
|
|
|
# (6) init logger variables #
|
|
declare -A OUTPUT_PID; # will contain each bind-output PIDs
|
|
declare -A LOGGER_PID; # will contain each logger PIDs
|
|
|
|
# (7) get logger list #
|
|
LOGGERS=(`ls $LOGGER_DIR`);
|
|
|
|
# (8) If no logger -> exit #
|
|
test "${#LOGGERS[@]}" -eq 0 && echo "error: no logger found in <dir>." && exit 1;
|
|
|
|
# (9) Get local IP address #
|
|
LOCAL_IP="`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'`";
|
|
|
|
test -z "$LOCAL_IP" && echo "error: cannot get local IP address." && exit 1;
|
|
|
|
|
|
|
|
|
|
# (2) Set exit management
|
|
#--------------------------------------------------------#
|
|
# (1) On-Exit routine #
|
|
on_exit(){
|
|
|
|
echo "- killing 'bind-output' sub processes";
|
|
|
|
for logger_name in "${!OUTPUT_PID[@]}"; do
|
|
|
|
# kill each logger OUTPUT
|
|
echo " - killing output@$logger_name";
|
|
kill -INT ${OUTPUT_PID[$logger_name]} 2>/dev/null;
|
|
|
|
done;
|
|
|
|
for logger_name in "${!LOGGER_PID[@]}"; do
|
|
|
|
# kill each logger OUTPUT
|
|
echo " - killing logger@$logger_name";
|
|
kill -INT ${LOGGER_PID[$logger_name]} 2>/dev/null;
|
|
|
|
done;
|
|
|
|
echo "- killing 'master' output socket";
|
|
kill -INT $MASTER_PID 2>/dev/null;
|
|
|
|
echo "- killing 'master' loop";
|
|
# kill -INT $LOOP_PID 2>/dev/null;
|
|
|
|
}
|
|
|
|
trap "on_exit;" HUP INT KILL TERM;
|
|
|
|
|
|
|
|
|
|
|
|
# (3) Connect to pool
|
|
#--------------------------------------------------------#
|
|
# (1) Bind-output #
|
|
echo "+ connect to $POOL_HOST:$POOL_PORT";
|
|
MASTER_PID="`$ROOT/bind-output master $POOL_HOST $POOL_PORT`";
|
|
|
|
echo " + flush connection before using it";
|
|
# $ROOT/write master "";
|
|
|
|
# (4) Launch master manager
|
|
#--------------------------------------------------------#
|
|
# (1) For each logger
|
|
PORT="$MIN_PORT";
|
|
for logger_name in "${LOGGERS[@]}"; do
|
|
|
|
echo " + logger '$logger_name'";
|
|
|
|
# Find an available port
|
|
while true; do
|
|
|
|
# if port not in use -> use it
|
|
ss -tl4 "( sport = :$PORT )" | grep "$PORT" >/dev/null 2>&1 || break;
|
|
|
|
# else try next port (+1)
|
|
PORT="`expr $PORT + 1`";
|
|
|
|
done;
|
|
|
|
# listen for pool response (port number)
|
|
echo " + listen $PORT";
|
|
FREEPORT_PID="`$ROOT/bind-input freeport $PORT`";
|
|
|
|
# send port request
|
|
echo " + sending port request";
|
|
$ROOT/write master "$POOL_KEY:$logger_name:$LOCAL_IP:$PORT";
|
|
|
|
echo " + waiting for response";
|
|
RESP="";
|
|
timeout=8; # 4sec = 8 x .5sec
|
|
while [ "$timeout" -gt "0" ]; do
|
|
|
|
RESP="`$ROOT/read freeport`";
|
|
|
|
# if empty answer, try again in .5 sec
|
|
if [ -z "$RESP" ]; then
|
|
# echo " + empty response (remaining $timeout)";
|
|
timeout="`expr $timeout - 1`";
|
|
sleep .5;
|
|
continue;
|
|
|
|
# else -> stop reading
|
|
else
|
|
# echo " + got response '$RESP'";
|
|
break;
|
|
fi
|
|
|
|
done;
|
|
|
|
# closing listen socket
|
|
echo " + received '$RESP'";
|
|
echo " + stop listening on $PORT";
|
|
kill -INT $FREEPORT_PID 2>/dev/null;
|
|
|
|
# empty response -> ignore
|
|
test -z "$RESP" && echo " - no answer > aborting" && continue;
|
|
|
|
# not a number -> ignore
|
|
echo -n "$RESP" | grep -P '^\d+$' >/dev/null || ( echo " - invalid format > aborting"; exit 1 ) || continue;
|
|
|
|
# Create output bound
|
|
echo " + connecting to $POOL_HOST:$RESP";
|
|
OUTPUT_PID[$logger_name]="`$ROOT/bind-output master_$logger_name $POOL_HOST $RESP`";
|
|
|
|
echo " + launching logger";
|
|
# launch logger bound to output
|
|
( $LOGGER_DIR/$logger_name | cat > /tmp/outbuf_master_$logger_name )&
|
|
LOGGER_PID[$logger_name]=$!;
|
|
|
|
echo " + background proccess"
|
|
|
|
# increment port for next logger
|
|
PORT="`expr $PORT + 1`";
|
|
|
|
done;
|
|
|
|
|
|
# When all loggers are bound, destroy pool connection
|
|
echo "+ close connection to $POOL_HOST:$POOL_PORT ";
|
|
kill -INT $MASTER_PID 2>/dev/null;
|
|
|
|
echo " + waiting for ${#LOGGER_PID[@]} inputs/loggers to end";
|
|
for logger_name in "${!LOGGER_PID[@]}"; do
|
|
|
|
wait ${LOGGER_PID[$logger_name]};
|
|
|
|
done; |