#!/bin/bash ### BEGIN INIT INFO # Provides: realtime # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: # Default-Stop: 0 1 6 # Short-Description: enable realtime capabilities when needed # Description: The rtai module is loaded when needed and # removed when the job has ended and is used throughout the LinuxCNC # infrastructure. The script has no effect for the PREEMPT realtime kernel. # The script is not meant to be started a boot time - it could be, though. # X-Interactive: false ### END INIT INFO # # @configure_input@ # on @DATE@ # export LANG=C GREP=@GREP@ PS=@PS@ CheckKernel() { case "@KERNEL_VERS@" in "") ;; *) if [ `uname -r` != "@KERNEL_VERS@" ]; then cat 1>&2 << EOF RTAPI requires the real-time kernel @KERNEL_VERS@ to run. Before running this realtime application, reboot and choose this kernel at the boot menu. EOF exit 1 fi esac } RUN_IN_PLACE=@RUN_IN_PLACE@ if [ $RUN_IN_PLACE = yes ]; then # When using RIP make sure PATH includes the directory where rtapi_app # resides PATH=@EMC2_HOME@/bin:$PATH; export PATH fi CheckConfig(){ prefix=@prefix@ exec_prefix=@exec_prefix@ sysconfdir=@sysconfdir@ if [ $RUN_IN_PLACE = yes ]; then RTAPICONF= # check in the LinuxCNC scripts directory # $0 is the command to run this script # strip the script name to leave the path SCRIPT_DIR=${0%/*} # the path might be relative # convert it to an absolute path SCRIPT_DIR=$(cd $SCRIPT_DIR ; pwd -P) # now look for rtapi.conf there if [ -f $SCRIPT_DIR/rtapi.conf ] ; then RTAPICONF=$SCRIPT_DIR/rtapi.conf fi else if [ -f $sysconfdir/linuxcnc/rtapi.conf ]; then RTAPICONF=$sysconfdir/linuxcnc/rtapi.conf fi fi if [ -z "$RTAPICONF" ] ; then echo "Missing rtapi.conf. Check your installation." 1>&2 exit 1 fi INSMOD="@INSMOD@" RMMOD="@RMMOD@" LSMOD="@LSMOD@" FUSER="@FUSER@" # Import the config source $RTAPICONF if [ ! -e $RTLIB_DIR/.runinfo -a -e $RTLIB_DIR/emc2/.runinfo ]; then # installed system: we don't want our modules mixed up with rtai RTLIB_DIR=$RTLIB_DIR/emc2 fi # Export the module path specified in the config. export MODPATH # Generate module lists for loading and unloading # lists contain RTOS modules plus RTAPI and HAL # unload list is in reverse order # any module names that are symlinks are resolved to their real names MODULES_LOAD= MODULES_UNLOAD= case $RTPREFIX in uspace) SHM_DEV=/dev/zero;; esac for MOD in $MODULES ; do eval MOD=\${MODPATH_$MOD} if [ -z "$MOD" ]; then continue; fi if [ -L $MOD ]; then MOD=${MOD%/*}/$(readlink $MOD) fi MODULES_LOAD="$MODULES_LOAD $MOD" MOD="${MOD##*/}" MOD="${MOD%.*}" MODULES_UNLOAD="$MOD $MODULES_UNLOAD" done case $RTPREFIX in (*rtai*) MODULES_LOAD="$MODULES_LOAD $RTLIB_DIR/rtapi$MODULE_EXT $RTLIB_DIR/hal_lib$MODULE_EXT" MODULES_UNLOAD="hal_lib rtapi $MODULES_UNLOAD" SHM_DEV=/dev/rtai_shm ;; (*) MODULES_UNLOAD= esac } CheckStatus(){ case $RTPREFIX in uspace) if [ -z "$($PS -o stat= -o comm= -C rtapi_app | $GREP -v '^Z')" ]; then exit 1 else exit 0 fi ;; *) # check loaded/unloaded status of modules unset NOTLOADED for MOD in $MODULES_UNLOAD ; do if "$LSMOD" | awk '{print $1}' | $GREP -x $MOD >/dev/null ; then echo "$MOD is loaded" else echo "$MOD is not loaded" NOTLOADED=NOT fi done if [ -z $NOTLOADED ]; then exit 0 else exit 1 fi esac } CheckMem(){ # check for user space processes using shared memory if [ -e /dev/mbuff ] ; then # device file exists, check for processes using it if $FUSER -s /dev/mbuff 2>/dev/null; then # at least one process is using it echo "ERROR: Can't remove RTLinux modules, kill the following process(es) first" $FUSER -v /dev/mbuff exit 1 fi elif [ -e /dev/rtai_shm ] ; then # device file exists, check for processes using it if $FUSER -s /dev/rtai_shm 2>/dev/null; then # at least one process is using it echo "ERROR: Can't remove RTAI modules, kill the following process(es) first" $FUSER -v /dev/rtai_shm exit 1 fi fi } Load(){ CheckKernel for MOD in $MODULES_LOAD ; do if ! [ -d /sys/module/`basename $MOD .ko` ]; then $INSMOD $MOD || return $? fi done if [ "$DEBUG" != "" ] && [ -w /proc/rtapi/debug ] ; then echo "$DEBUG" > /proc/rtapi/debug fi } CheckLoaded(){ # this abomination is needed because udev sometimes doesn't # have the device ready for us in time. n=0 while [ $n -lt 100 ]; do [ -w $SHM_DEV ] && return 0 echo "." 1>&2 sleep .1 n=$(($n+1)) done echo "Can't write to $SHM_DEV - aborting" 1>&2 exit 1 } Unload(){ CheckKernel case $RTPREFIX in uspace) rtapi_app exit # wait 5 seconds for rtapi_app to die and be reaped by its parent START=$SECONDS local NPROCS while [ 5 -gt $((SECONDS-START)) ]; do NPROCS=$(ps -C rtapi_app -o stat= -o comm= | $GREP -v '^Z' | wc -l) if [ $NPROCS -eq 0 ]; then break fi sleep 0.1 done NPROCS=$(ps -C rtapi_app -o stat= -o comm= | $GREP -v '^Z' | wc -l) if [ $NPROCS -gt 0 ]; then echo "ERROR: rtapi_app failed to die" 1>&2 fi ipcrm -M 0x48414c32 2>/dev/null ;# HAL_KEY ipcrm -M 0x90280A48 2>/dev/null ;# RTAPI_KEY ipcrm -M 0x48484c34 2>/dev/null ;# UUID_KEY esac for module in $MODULES_UNLOAD ; do $RMMOD $module done } CheckUnloaded(){ # checks to see if all modules were unloaded STATUS= for module in $MODULES_UNLOAD ; do # check to see if the module is installed if "$LSMOD" | awk '{print $1}' | $GREP -x $module >/dev/null ; then echo "ERROR: Could not unload '$module'" STATUS=error fi done if [ -n "$STATUS" ] ; then exit 1 fi } CMD=$1 case "$CMD" in start|load) CheckConfig Load || exit $? CheckLoaded ;; restart|force-reload) CheckConfig CheckMem Unload CheckUnloaded Load || exit $? CheckLoaded ;; stop|unload) CheckConfig CheckMem Unload || exit $? ;; status) CheckConfig CheckStatus ;; *) echo "Usage: $0 {start|load|stop|unload|restart|force-reload|status}" >&2 exit 1 ;; esac exit 0