Something went wrong on our end
-
Erik von Reis authored
If models are already started when requested to start, there's no need to check. Systemd won't mind another request to start. Removing these checks allows the user to specify a list of models to start, stop or restart, and not have to worry if some of them are already in the requested state.
Erik von Reis authoredIf models are already started when requested to start, there's no need to check. Systemd won't mind another request to start. Removing these checks allows the user to specify a list of models to start, stop or restart, and not have to worry if some of them are already in the requested state.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
rtcds.in 16.36 KiB
#!/bin/bash -e
log() {
echo "$@" >&2
}
RTS_VERSION=${RTS_VERSION:-__VERSION__}
if [[ "$RTS_VERSION" =~ ._VERSION_. ]] ; then
log "RTS_VERSION variable not set."
exit 1
fi
# this should define all USER_VARS (see below)
ENV_FILE=${RTS_ENV:-/etc/advligorts/env}
HOST_ENV_FILE=/etc/advligorts/systemd_env_`hostname`
set -o allexport
source "$ENV_FILE" 2>/dev/null || true
if [[ -e $HOST_ENV_FILE ]] ; then
log "found host specific environment file '$HOST_ENV_FILE'"
source $HOST_ENV_FILE 2>/dev/null || true
fi
set +o allexport
SITE=${SITE^^*}
site=${SITE,,*}
IFO=${IFO^^*}
ifo=${IFO,,*}
CHECK_MODEL_IN_HOST=${CHECK_MODEL_IN_HOST:-false}
IS_DOLPHIN_NODE=${IS_DOLPHIN_NODE:-false}
DAQ_STREAMING=${DAQ_STREAMING:-false}
RCG_SRC=${RCG_SRC:-/usr/share/advligorts/src}
RCG_BUILD_ROOT=${RCG_BUILD_ROOT:-/var/cache/advligorts}
RCG_BUILDD=${RCG_BUILDD:-$RCG_BUILD_ROOT/rcg-$RTS_VERSION}
# FIXME: the RCG hard-codes /opt/rtcds as the root
RCG_TARGET=/opt/rtcds/${site}/${ifo}
# search paths for C source code
CDS_SRC=${CDS_SRC:-$RCG_LIB_PATH}
CDS_IFO_SRC=${CDS_IFO_SRC:-$CDS_SRC}
# add RCG module source to lib path
# FIXME: rename RCG_MOD_PATH
RCG_LIB_PATH=$RCG_LIB_PATH:${RCG_SRC}/src/epics/simLink/:${RCG_SRC}/src/epics/simLink/lib
#options from environment variables
ALLOW_MODEL_ENABLE=${ALLOW_MODEL_ENABLE:-true}
USER_VARS=(SITE IFO RCG_LIB_PATH)
LIST_VARS=(RTS_VERSION ${USER_VARS[@]} RCG_SRC RCG_BUILD_ROOT RCG_BUILDD RCG_TARGET)
EXPORT_VARS=(${USER_VARS[@]} site ifo CDS_SRC CDS_IFO_SRC)
# time in seconds to wait before starting another model.
START_DELAY=${START_DELAY:-15}
# set the umask to ensure that all files and directories are made
# group writable
umask 0002
USE_KERNEL_MODELS=${USE_KERNEL_MODELS:-true}
# for all flags, empty string means cleared. Any other string means set.
if $USE_KERNEL_MODELS ; then
log "Build kernel-mode models by default"
USERLAND_FLAG=
NOKERNELSPACE_FLAG=
else
log "Build user mode models by default"
USERLAND_FLAG=0
NOKERNELSPACE_FLAG=0
fi
ALL_FLAG=
FOLLOW_FLAG=
INFO_FLAG=
VERSION_FLAG=
HELP_FLAG=
FORCE_START_FLAG=
# capture all command line flags as variables
params=""
ccmd=""
while (( "$#" )); do
case "$1" in
--all)
ALL_FLAG=0
shift
;;
--user-space|--userland)
USERLAND_FLAG=0
shift
;;
--no-user-space|--no-userland)
USERLAND_FLAG=''
shift
;;
--kernel-space)
NOKERNELSPACE_FLAG=''
shift
;;
--no-kernel-space)
NOKERNELSPACE_FLAG=0
shift
;;
-f)
FOLLOW_FLAG=0
shift
;;
-i)
INFO_FLAG=0
shift
;;
version|-v|--version)
VERSION_FLAG=0
shift
;;
help|-h|--help)
HELP_FLAG=0
shift
;;
--force-start)
FORCE_START_FLAG=0
shift
;;
--*|-*) # unknown flags
log "Error: Unknown flag $1"
exit 1
;;
*) #handle non-flags
params="${params} $1"
shift
;;
esac
done
eval set -- "$params"
##################################################
contains() {
local x=$1
shift
[[ $@ =~ (^|[[:space:]])$x($|[[:space:]]) ]] && return 0 || return 1
}
epics_only_model() {
contains $1 $EPICS_ONLY_MODELS && return 0 || return 1
}
# echo the systemd unit that should be used to control the model
get_model_unit() {
local sys=$1
if epics_only_model ${sys} ; then
echo "rts-epics@${sys}"
else
echo "rts@${sys}.target"
fi
}
check_env() {
for var in ${USER_VARS[*]} ; do
if [ ! "${!var}" ] ; then
log "ERROR: variable '$var' not set."
log "The following environment variables must be set (in e.g. $ENV_FILE):"
for vv in ${USER_VARS[*]} ; do
log " $vv"
done
exit 1
fi
done
for var in ${LIST_VARS[*]} ; do
log "$var=${!var}"
done
for var in ${EXPORT_VARS[*]} ; do
export $var
done
}
prep_buildd() {
if [ -d "$RCG_BUILDD" ] ; then
return
fi
log "creating RCG_BUILDD $RCG_BUILDD..."
if ! mkdir -p "$RCG_BUILDD" 2>/dev/null ; then
log "Could not create build directory '$RCG_BUILDD'."
log "Please create manually (with correct permissions) and try again."
exit 1
fi
log "configuring RCG_BUILDD $RCG_BUILDD..."
cd "$RCG_BUILDD"
"$RCG_SRC"/configure
}
prep_target(){
if [ -d "$RCG_TARGET" ] ; then
return
fi
log "creating RCG_TARGET $RCG_TARGET..."
if ! mkdir -p "$RCG_TARGET" 2>/dev/null ; then
log "Could not create target directory '$RCG_TARGET'."
log "Please create manually (with correct permissions) and try again."
exit 1
fi
mkdir -p ${RCG_TARGET}/{target,chans/tmp}
}
########
_systemctl_list_units() {
systemctl list-units --all --full --plain --no-legend --no-pager rts@*.target \
| awk '{print $1}' \
| sed 's/^rts@\([a-z0-9]*\)\.target$/\1/'
}
list_host_sys_systemd() {
_systemctl_list_units | grep 'iop' || true
_systemctl_list_units | grep -v 'iop' || true
}
list_host_sys() {
if [[ -e /etc/rtsystab ]] && [[ -e /etc/rt_fe.sh ]] ; then
/etc/rt_fe.sh | sed 's/ /\n/g'
else
list_host_sys_systemd
fi
}
# returns 0 if $1 names a system that's designated to run
# on this host
check_sys_in_host() {
if $CHECK_MODEL_IN_HOST && [[ -z $FORCE_START_FLAG ]] ; then
local systems=`list_host_sys`
contains $1 $systems
fi
}
check_unit_available() {
if ! systemctl cat rts@$1.target > /dev/null ; then
log "RTS front end systemd units don't seem to be available. Is the advligorts-fe package installed?"
exit 5
fi
}
check_host_sys_enabled() {
for sys ; do
check_unit_available ${sys}
if ! systemctl is-enabled rts@${sys}.target > /dev/null ; then
log "System '${sys}' is not enabled on this system, first enable with 'enable ${sys}'."
exit 4
fi
done
}
check_host_sys_active() {
for sys ; do
check_unit_available ${sys}
local unit_name=`get_model_unit ${sys}`
if ! systemctl is-active $unit_name > /dev/null ; then
log "System '${sys}' is not active on this system'."
exit 4
fi
done
}
check_host_sys_inactive() {
for sys ; do
check_unit_available ${sys}
local unit_name=`get_model_unit ${sys}`
if systemctl is-active $unit_name > /dev/null ; then
log "System '$sys' is already active on this system'."
exit 4
fi
done
}
########
setup_make_args() {
make_args=''
if [[ -n $USERLAND_FLAG ]] ; then
make_args='RCG_BUILD_USP=YES'
fi
if [[ -n $NOKERNELSPACE_FLAG ]] ; then
make_args="$make_args RCG_BUILD_NO_KOBJ=YES"
fi
}
build_sys() {
cd $RCG_BUILDD
for sys ; do
log "### building $sys..."
setup_make_args
make $sys $make_args
done
}
build_world() {
cd $RCG_BUILDD
log "### building world..."
setup_make_args
make -i World $make_args
}
install_sys() {
cd $RCG_BUILDD
for sys ; do
log "### installing $sys..."
make install-$sys
done
}
install_world() {
cd $RCG_BUILDD
log "### installing world..."
make installWorld
}
start_sys() {
for sys ; do
log "### starting $sys..."
if check_sys_in_host $sys ; then
local unit_name=`get_model_unit ${sys}`
sudo systemctl start $unit_name
# pause needed to avoid timing glitch when user model started immediately after IOP
log "... waiting for start of ${sys} to complete"
sleep $START_DELAY
log "${sys} started"
else
log "$sys can't be run on $(hostname)"
log "Override with the '--force-start' option."
fi
done
}
stop_sys() {
for sys ; do
log "### stopping $sys..."
#${SCRIPTD}/kill${sys}
local unit_name=`get_model_unit ${sys}`
sudo systemctl stop $unit_name
md=waiting
while [ -n "${md}" ]
do
sleep 1
md=$(lsmod | grep "^${sys}\s") || true
done
done
}
enable_sys() {
for sys ; do
log "### enabling $sys..."
sudo systemctl enable rts@${sys}.target
done
}
disable_sys() {
for sys ; do
log "### disabling $sys..."
sudo systemctl disable rts@${sys}.target
done
}
_lsmod() {
local systems=($(list_host_sys))
local rts=(mbuf gpstime)
local dolphin=(dis_kosif dis_ix_ntb dis_ix_dma dis_irm dis_sisci dis_intel_dma)
# FIXME: how to test for needed modules?
if $IS_DOLPHIN_NODE ; then
local modules=(${rts[*]} ${dolphin[*]})
else
local modules=(${rts[*]})
fi
local allloaded=
for m in ${modules[*]}; do
md=$(lsmod | grep "^${m}\s") || true
if [ -z "$md" ] ; then
printf "%-18s ***NOT LOADED***\n" "$m"
allloaded=1
else
echo "$md"
fi
done
if [ "$systems" ] ; then
echo
for m in ${systems[*]}; do
if epics_only_model $m ; then
test 0
else
md=$(lsmod | grep "^${m}\s") || true
if [ -z "$md" ] ; then
printf "%-18s ***NOT LOADED***\n" "$m"
allloaded=1
else
echo "$md"
fi
fi
done
fi
if [ "$allloaded" ] ; then
return 4
fi
}
systems_status() {
local systems=$(list_host_sys)
local subsystems=(epics module awgtpman)
local systems_health=0
echo "System Status"
local header="system"
printf '%-15s' system
for subsys in ${subsystems[*]} ; do
printf '%-15s' ${subsys}
done
echo
echo "------------------------------------------------------"
for sys in ${systems[*]} ; do
printf '%-15s ' $sys
for subsys in ${subsystems[*]} ; do
local subsysstatus='OFF'
if ! epics_only_model $sys || [[ $subsys == 'epics' ]] ; then
if systemctl is-failed "rts-${subsys}@${sys}" > /dev/null ; then
subsysstatus='FAILED'
systems_health=10
else
if systemctl is-active "rts-${subsys}@${sys}" > /dev/null ; then
subsysstatus='ON'
else
systems_health=10
fi
fi
else
subsysstatus='N/A'
fi
printf '%-15s' $subsysstatus
done
echo
done
return $systems_health
}
streamer_status() {
local services=(rts-local_dc rts-transport@cps_xmit)
local streamer_health=0
echo "Streamer Status"
for service in ${services[*]} ; do
local health="OFF"
if systemctl is-failed $service > /dev/null ; then
health="FAILED"
streamer_health=11
else
if systemctl is-active $service > /dev/null ; then
health="ON"
else
streamer_health=11
fi
fi
printf '%-25s%-15s\n' $service $health
done
return $streamer_health
}
global_status() {
echo "Kernel Module Status\n"
echo
local module_health=0
if _lsmod ; then
echo "Kernel Module Status = ALL LOADED"
else
module_health=12
echo "Kernel Module Status = SOME MISSING"
fi
echo
local systems_health=0
echo
if systems_status ; then
echo "Systems Status = ALL ACTIVE"
else
echo "Systems Status = DEGRADED"
systems_health=12
fi
echo
local streamer_health=0
if $DAQ_STREAMING ; then
echo
if streamer_status ; then
echo "Streamer Status = ALL ACTIVE"
else
echo "Streamer Status = DEGRADED"
streamer_health=12
fi
fi
echo
if [[ $systems_health == 0 ]] && [[ $streamer_health == 0 ]] && [[ $module_health == 0 ]] ; then
echo "Overall Status = OK"
return 0
else
echo "Overall Status = DEGRADED"
return 12
fi
}
############################################################
usage() {
if $USE_KERNEL_MODELS ; then
local udefault=""
local kdefault=" (default)"
else
local udefault=" (default)"
local kdefault=""
fi
if $ALLOW_MODEL_ENABLE ; then
local enable_usage="
enable <sys>...|--all enable system start at boot"
else
local enable_usage="
"
fi
echo "Usage: $(basename $0) <command> [options] [args]
Advanced LIGO Real Time System control interface.
Available commands:
build|make <sys>...|--all build system
--user-space|--userland build model in userland $udefault
--no-user-space|--no-userland do not build model in userland $kdefault
--kernel-space build model in kernel space $kdefault
--no-kernel-space do not build model in kernel space $udefault
install <sys>...|--all install system
list|ls list systems for host
${enable_usage}
disable <sys>...|--all disable system start at boot
start <sys>...|--all start systems
--force-start start a model even if it fails some checks
restart <sys>...|--all restart running systems
stop|kill <sys>...|--all stop running systems
status [<sys>] show status for system services
log show logs for system services
-f follow logs
blog <sys> show last build log for system
-i print log paths
lsmod list loaded RTS kernel modules
env print system environment info
version|--version|-v print version
help|--help|-h this help
"
}
if [[ -n $HELP_FLAG ]]; then
usage
exit 0
fi
if [[ -n $VERSION_FLAG ]] ; then
echo $RTS_VERSION
exit 0
fi
if [[ $1 ]] ; then
cmd=$1
shift
else
log "You must specify a command."
log
usage
exit 1
fi
case $cmd in
'build'|'make')
if [ "$EUID" -eq 0 ] ; then
log "*** Error: building as 'root' not allowed"
exit 2
fi
if [[ -n $ALL_FLAG ]] ; then
check_env
prep_buildd
build_world
elif [[ $1 ]] ; then
check_env
prep_buildd
build_sys $@
else
log "You must specify at least one system to build."
exit 2
fi
;;
'install')
if [ "$EUID" -eq 0 ] ; then
log "*** Error: Installing as 'root' not allowed"
exit 2
fi
if [[ -n $ALL_FLAG ]] ; then
check_env
prep_target
install_world
elif [[ $1 ]] ; then
check_env
prep_target
install_sys $@
else
log "You must specify at least one system to install."
exit 2
fi
;;
'start')
if [[ -n $ALL_FLAG ]] ; then
start_sys $(list_host_sys)
elif [[ $1 ]] ; then
start_sys $@
else
log "You must specify at least one system to start (or '--all')."
exit 2
fi
;;
'restart')
if [[ -n $ALL_FLAG ]] ; then
# we do this in reverse so the IOP is stopped last
stop_sys $(list_host_sys | tac)
start_sys $(list_host_sys)
elif [[ $1 ]] ; then
stop_sys $@
start_sys $@
else
log "You must specify at least one system to restart (or '--all')."
exit 2
fi
;;
'stop'|'kill')
if [[ -n $ALL_FLAG ]] ; then
# we do this in reverse so the IOP is stopped last
stop_sys $(list_host_sys | tac)
elif [[ $1 ]] ; then
stop_sys $@
else
log "You must specify at least one system to stop (or '--all')."
exit 2
fi
;;
'enable'|'disable')
if [[ ${cmd} == 'enable' ]] && ! $ALLOW_MODEL_ENABLE ]] ; then
log "Enabling models is not allowed on this host."
log "ALLOW_MODEL_ENABLE environment variable is set to false."
exit 2
fi
if [[ -n $ALL_FLAG ]] ; then
# we do this in reverse so the IOP is stopped last
${cmd}_sys $(list_host_sys | tac)
elif [[ $1 ]] ; then
${cmd}_sys $@
else
log "You must specify at least one system to $cmd (or '--all')."
exit 2
fi
;;
'status')
if [ -z "$1" ] || [[ -n $ALL_FLAG ]] ; then
global_status
else
sys=$1
systemctl status rts@${sys}.target rts-{awgtpman,epics,module}@${sys}.service
fi
;;
'log')
args=
if [[ -n $FOLLOW_FLAG ]] ; then
args="-f"
fi
if [ -z "$1" ] ; then
log "You must specify one system to show log."
exit 2
fi
sys=$1
sudo journalctl $args --unit=rts*${sys}*
;;
'blog')
format=full
if [[ -n $INFO_FLAG ]] ; then
format=info
fi
if [ -z "$1" ] ; then
log "You must specify system to view."
exit 2
fi
olog="${RCG_BUILDD}/${1}.log"
elog="${RCG_BUILDD}/${1}_error.log"
echo $olog
case "$format" in
info)
ls -al "$olog" "$elog"
;;
full)
sed 's/^/stdout:/' < "$olog"
sed 's/^/stderr:/' < "$elog"
;;
esac
;;
'list'|'ls')
list_host_sys
;;
'lsmod'|'lsmods')
_lsmod
;;
'env')
check_env
;;
*)
log "Unknown command: $cmd"
log
usage
exit 1
;;
esac