forked from epicsdeb/sysv-rc-softioc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
softioc
231 lines (186 loc) · 5.22 KB
/
softioc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#
# Debian init script for EPICS soft iocs
#
# The IOC name is determined from the script name.
#
# i.e. ln -s softioc /etc/init.d/softioc-MYIOCNAME
#
# Expects /etc/default/epics-softioc to exist and contain (at minimum)
# a line like:
#
# SOFTBASE=/epics/iocs
# or
# SOFTBASE=/epics/iocs:/home/epics/iocs
#
# First /etc and then these directories are search for $prefix/MYIOCNAME/config
#
# It sources all files matching $prefix/config/global until it finds
# $prefix/MYIOCNAME/config at which point it sources this file and then
# starts procServ.
#
# When started procServ is used to cd to $prefix/MYIOCNAME and runs ./st.cmd
#
# The environment of the IOC is determined by the config scripts
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin
LOGNAME="$(basename "$(readlink -f "$0")")"
. /lib/lsb/init-functions
warn () {
logger -p daemon.warning -t "$LOGNAME" "Warning: $1" || true
log_warning_msg "$1"
}
die () {
logger -p daemon.err -t "$LOGNAME" "Error: $1" || true
log_failure_msg "$1"
exit 1
}
LIBRARY=/usr/share/sysv-rc-softioc/library.sh
[ -f "$LIBRARY" ] || die "Missing $LIBRARY"
. "$LIBRARY"
iocinit
PROCSERV=/usr/bin/procServ
NAME=$(basename $0)
#IOC=${NAME#softioc-}
IOC=$(echo "$NAME"|cut -f '2-' -d '-')
#
# The script is in /etc/init.d/softioc
# For ioc NAME:
# ln -s softioc /etc/init.d/softioc-NAME
#
if [ "$NAME" = "softioc" ]; then
echo "$0 is meant to be a symlink with a name like 'softioc-NAME'"
echo "where 'NAME' is the name of a softioc instance"
echo "example: ln -s softioc /etc/init.d/softioc-myioc"
exit 0
fi
IOCBASE="`findbase "$IOC"`"
[ $? -ne 0 -o -z "$IOCBASE" ] && die "Failed to find ioc $IOC in $IOCPATH"
GLOBALBASE="$IOCBASE/config"
INSTBASE="$IOCBASE/$IOC"
# Modify environment before including global config
#
# NAME is the ioc instance name to be used for consistance checking
NAME=invalid
# PORT to be used by procServ
PORT=invalid
# USER to run procServ (if not set defaults to $IOC)
unset USER
# Computer that this softioc runs on. Used to prevent copy+paste
# errors and duplicate PV names. (optional)
unset HOST
unset CHDIR
# By default write logfile. Set to 0 or '' to disable.
LOG=1
INSTCONF="$INSTBASE/config"
CHDIR="$INSTBASE"
if [ -f "$GLOBALBASE/config" ]
then
cd "$GLOBALBASE"
. "$GLOBALBASE/config"
fi
cd "$INSTBASE" || die "Failed to cd to $INSTBASE"
. "$INSTCONF"
# provide defaults for things not set by any config
# default user name is softioc instance name
USER="${USER:-${IOC}}"
EXEC="${EXEC:-${CHDIR}/st.cmd}"
# consistency checking
[ "$NAME" = "invalid" ] && die "Configuration does not set IOC name"
[ "$NAME" = "$IOC" ] || die "Configuration name ($NAME) does not match IOC instance ($IOC)"
# The port to use for procServ
[ "$PORT" = "invalid" ] && die "Configuration does not set port"
if [ -n "$HOST" ]; then
if [ "$HOST" != "$(hostname -s)" -a "$HOST" != "$(hostname -f)" ]; then
die "This softioc instance runs on '$HOST' not this host '$(hostname -f)'"
fi
fi
# The official runtime environment
export HOSTNAME="$(hostname -s)"
export IOCNAME="$NAME"
export TOP="$INSTBASE"
export EPICS_HOST_ARCH=`/usr/lib/epics/startup/EpicsHostArch`
export PROCPORT="$PORT"
# also USER
PID=/var/run/softioc-$IOC.pid
LOGFILE=/var/log/softioc-${IOC}.log
check_status() {
if [ "$1" = "-q" ];then
status_of_proc -p "$PID" "procServ" "$IOC" 2>&1 >/dev/null
else
status_of_proc -p "$PID" "procServ" "$IOC"
fi
return $?
}
# Verify that user $1 exists on this system
check_user() {
id "$USER" 2>&1 >/dev/null || die "Account User: $USER or group softioc is\
missing on this system"
}
PROCARGS="-q -c $CHDIR -i ^D^C^] -p $PID -n $IOC --restrict"
if [ -n "$LOG" -a "$LOG" != 0 ]; then
PROCARGS="$PROCARGS --logfile=$LOGFILE"
fi
case "$1" in
start)
check_user
logger -p daemon.info -t "$LOGNAME" "Starting softioc: $IOC" || true
log_daemon_msg "Starting softioc" "$IOC "
# Needed so that the pid file can be written by $USER
# procServ will put in the correct pid
touch $PID || die "Failed to create pid file"
chown "$USER" $PID || die "Failed to chmod pid file"
# same for log file
if [ -n "$LOG" -a "$LOG" != 0 ]; then
touch $LOGFILE || die "Failed to create log file"
chown "$USER" $LOGFILE || die "Failed to chmod log file"
fi
start-stop-daemon --start --pidfile $PID \
--chdir "$CHDIR" --startas $PROCSERV --name procServ \
--chuid "$USER" \
-- $PROCARGS $PORT $EXEC
sleep 2
if check_status -q; then
logger -p daemon.info -t "$LOGNAME" "Running" || true
log_end_msg 0
else
logger -p daemon.err -t "$LOGNAME" "Failed to start" || true
log_failure_msg
log_end_msg 1
exit 1
fi
;;
stop)
logger -p daemon.info -t "$LOGNAME" "Stopping softioc: $IOC" || true
log_daemon_msg "Stopping softioc" "$IOC "
start-stop-daemon --stop --quiet --pidfile $PID \
--user "$USER" --name procServ \
--retry=TERM/30/KILL/5
R=$?
logger -p daemon.info -t "$LOGNAME" "Stopping softioc: $IOC ($R)" || true
log_end_msg $R
rm -f "$PID"
;;
status)
echo -n "Status of softioc $IOC : "
check_status
exit $?
;;
restart|reload|force-reload)
$0 stop
[ $? -ne 0 ] && exit 0
sleep 2
$0 start
exit $?
;;
info)
echo "IOC: $IOC"
echo "USER: $USER"
echo "PORT: $PORT"
echo "BASE: $CHDIR"
echo "EXEC: $EXEC"
;;
*)
die "Usage: $0 {start|stop|restart|status|info}"
;;
esac
exit 0