#!/bin/sh
#
# $Id$

set -e

PROGRAM=gfarmbb
TMPDIR=/tmp/gfarmbb-scratch
PERIOD=-1
SHELL_TYPE=bsh
MOPTIONS=direct_io
LOGIN_NODE_ACCESS=false
ID=`hostname`
EXCLUDE_GFMD=-a

usage() {
    echo "usage: $PROGRAM [-h hostfile] [-scr scratch_dir] [-m mount_point] [options] start | stop | status"
    echo ""
    echo "options:"
    echo "        -mpi mpirun_cmd"
    echo "            setup using MPI."
    echo "        -e"
    echo "            excludes Gfmd node from file system nodes."
    echo "        -h hostfile"
    echo "            specifies a hostfile."
    echo "        -scr scratch_dir"
    echo "            specifies a scratch directory. ($TMPDIR)"
    echo "        -conf conf_dir"
    echo "            specifies a shared configuration directory. ($CONFDIR)"
    echo "        -l"
    echo "            enables Gfarm/BB access from login nodes."
    echo "        -L log_dir"
    echo "            specifies a log directory. ($TMPDIR/log)"
    echo "        -m mount_point"
    echo "            specifies a mount point."
    echo "        -p period"
    echo "            specifies a period for a Gfarm shared key in second."
    echo "            Default is 86400 seconds (1 day)."
    echo "        -c"
    echo "            generates C-shell commands on stdout."
    echo "        -s"
    echo "            generates Bourne shell commands on stdout."
    echo "            This is default."
    exit 1
}

err() {
    [ $# -gt 0 ] && echo >&2 $*
    exit 1
}

while [ $# -gt 0 ]; do
    case $1 in
	start|stop|status) mode=$1 ;;
	-mpi) shift; MPIRUN="$1" ;;
	-e) EXCLUDE_GFMD= ;;
	-h) shift; HOSTFILE=$1 ;;
	-scr) shift; TMPDIR=$1 ;;
	-conf) shift; CONFDIR=$1 ;;
	-l) LOGIN_NODE_ACCESS=true ;;
	-L) shift; LOGDIR=$1 ;;
	-m) shift; MDIR=$1 ;;
	-p) shift; PERIOD=$1 ;;
	-c) SHELL_TYPE=csh ;;
	-s) SHELL_TYPE=bsh ;;
	-*) echo "unknown option: $1"
	    usage ;;
	*) usage ;;
	esac
	shift
done

# sanity check
[ X"$MPIRUN" != X -a X"$CONFDIR" = X ] && err -mpi option requires -conf option

: ${CONFDIR:=$TMPDIR/etc}
: ${LOGDIR:=$TMPDIR/log}
: ${USER:=`whoami`}

if [ X"$MPIRUN" != X ]; then
    prun() {
	$MPIRUN sh -c "$*"
    }
    alias prun-all=prun
    alias prun-verb=prun
    alias pcp=:
elif [ X"$HOSTFILE" != X ]; then
    [ -e $HOSTFILE ] || err $HOSTFILE: no such host file

    alias prun="gfarm-prun $EXCLUDE_GFMD -p -h $HOSTFILE"
    alias prun-all="gfarm-prun -a -p -h $HOSTFILE"
    alias prun-verb="gfarm-prun -a -v -h $HOSTFILE"
    alias pcp="gfarm-pcp -p -h $HOSTFILE"
else
    alias prun="sh -c"
    alias prun-all="sh -c"
    alias prun-verb="sh -c"
    alias pcp=:
fi

start() {
    [ X"$GFARMBB_START_HOOK" != X ] && prun-all "$GFARMBB_START_HOOK"

    [ -d $TMPDIR/etc ] || mkdir -p $TMPDIR/etc
    [ -d $TMPDIR/etc ] || err $TMPDIR: no such scratch directory
    [ -d $CONFDIR ] || mkdir -p $CONFDIR
    [ -d $CONFDIR ] || err $CONFDIR: no such config directory
    [ -d $LOGDIR ] || mkdir -p $LOGDIR
    [ -d $LOGDIR ] || err $LOGDIR: no such log directory

    GFARM_CONFIG_FILE=$CONFDIR/gfarm2.conf
    export GFARM_CONFIG_FILE
    GFMD_CONF=$TMPDIR/etc/gfmd.conf
    GFSD_CONF=$CONFDIR/gfsd.conf
    USERMAP_FILE=$CONFDIR/usermap
    SHARED_KEY_FILE=$CONFDIR/.gfarm_shared_key
    prun "mkdir -p $TMPDIR/etc $LOGDIR"
    config-gfarm --prefix $TMPDIR --confdir $CONFDIR -S -N -A $USER -b none > /dev/null

    echo metadb_server_listen_backlog 2048 >> $GFMD_CONF
    echo metadb_server_max_descriptors 262144 >> $GFMD_CONF
    echo metadb_server_long_term_lock_type mutex >> $GFMD_CONF
    echo metadb_server_nfs_root_squash_support disable >> $GFMD_CONF
    echo metadb_db_access_type none >> $GFMD_CONF
    echo schedule_idle_load_thresh 200 >> $GFMD_CONF
    echo atime disable >> $GFMD_CONF
    echo replica_check disable >> $GFMD_CONF
    echo log_level warning >> $GFMD_CONF
    echo log_file $LOGDIR/gfmd-$ID.log >> $GFMD_CONF
    echo shared_key_file $SHARED_KEY_FILE >> $GFMD_CONF

    echo log_level warning >> $GFSD_CONF
    echo log_file $LOGDIR/gfsd-$ID.log >> $GFSD_CONF
    echo shared_key_file $SHARED_KEY_FILE >> $GFSD_CONF

    echo log_level warning >> $GFARM_CONFIG_FILE
    echo schedule_idle_load_thresh 200 >> $GFARM_CONFIG_FILE
    echo gfsd_connection_cache 256 >> $GFARM_CONFIG_FILE
    echo gfmd_authentication_timeout 120 >> $GFARM_CONFIG_FILE
    echo schedule_rpc_timeout 120 >> $GFARM_CONFIG_FILE
    echo network_receive_timeout 120 >> $GFARM_CONFIG_FILE
    echo rdma_mr_reg_mode dynamic >> $GFARM_CONFIG_FILE
    echo shared_key_file $SHARED_KEY_FILE >> $GFARM_CONFIG_FILE

    gfkey -c -p $PERIOD
    if $LOGIN_NODE_ACCESS; then
	sed 's|'$SHARED_KEY_FILE'|'$HOME/.gfarm_shared_key-$ID'|' $GFARM_CONFIG_FILE > $HOME/.gfarm2rc-$ID
	cp -p $SHARED_KEY_FILE $HOME/.gfarm_shared_key-$ID
    fi
    $TMPDIR/etc/init.d/gfmd start
    pcp $GFARM_CONFIG_FILE $GFSD_CONF $USERMAP_FILE $SHARED_KEY_FILE $TMPDIR/etc > /dev/null
    prun "config-gfsd --prefix $TMPDIR --confdir $CONFDIR -S > /dev/null"
    if [ X"$MDIR" != X ]; then
	gfmkdir -p $MDIR || :
	prun "env GFARMFS_ROOT=$MDIR mount.gfarm2fs $GFARM_CONFIG_FILE $MDIR $MOPTIONS > /dev/null || :"
    fi
    if [ $SHELL_TYPE = bsh ]; then
	echo "GFARM_CONFIG_FILE=$GFARM_CONFIG_FILE; export GFARM_CONFIG_FILE;"
    else
	echo "setenv GFARM_CONFIG_FILE $GFARM_CONFIG_FILE;"
    fi
}

stop() {
    prun-all "umount.gfarm2fs > /dev/null 2>&1 || :"
    prun-all "pkill gfsd > /dev/null 2>&1 || :"
    prun-all "pkill gfmd > /dev/null 2>&1 || :"
    prun-all "rm -rf $TMPDIR > /dev/null 2>&1 || :"
    rm -rf $CONFDIR
    if $LOGIN_NODE_ACCESS; then
	rm -f $HOME/.gfarm2rc-$ID $HOME/.gfarm_shared_key-$ID
    fi
    if [ X"$GFARMBB_STOP_HOOK" != X ]; then
	prun-all "$GFARMBB_STOP_HOOK || :"
    fi
}

status() {
    echo "[df]"
    prun-verb "df -t fuse.gfarm2fs 2>&1 || :"
    echo "[ls -la $TMPDIR]"
    prun-verb "ls -la $TMPDIR 2>&1 || :"
    echo "[ps]"
    prun-verb "ps -ef | grep gf | egrep -v '(grep|status|beegfs)' || :"
    echo "[netstat]"
    prun-verb "netstat -an | grep gf || :"
    if [ X"$MDIR" != X ]; then
	echo "[ls -la $MDIR]"
	prun-verb "ls -la $MDIR 2>&1 || :"
    fi
}

which config-gfarm > /dev/null 2>&1 || err no gfarm installation
#which mount.gfarm2fs > /dev/null 2>&1 || err no gfarm2fs installation

case $mode in
start)
    stop > /dev/null 2>&1
    start ;;
stop)
    stop ;;
status)
    status ;;
*)
    usage ;;
esac

exit 0
