如何在Linux上设立一个软IOC框架
以下说明是基于我们的Debian Linux机器。其它发行版(或其他Unixes)会有不同命令和对于东西有不同位置。这对我添加到本页的Debian /etc/init.d尤其如此。如果你为一个不同发行版创建一个不同的脚本,请添加它到本页。其它人将能够使用它。但基本步骤在所有发行版上相同。我已经认为了解了基本的系统管理任务(创建用户账户等)。
介绍
我们为什么做这件事?
当在生产中使用软IOC时,它们应该被当作重要的系统服务:
- 软IOCs应该由系统启动和停止。
- 应该有后备系统,遇到硬件故障,你可以简单地切换到这个后备系统。
其它目标是:用如用于VME IOCs相同地方法,应用程序开发这应该能够在无需对主机进行root访问下重置软IOC。
- IOC应用开发者应该能够手动启动和停止IOCs。
当多个软IOC共享相同主机(和相同IP地址)时,通道访问不能区分它们。访问安全将不能区分来自不同软IOCs的CA连接。在调试客户端时,CA不能告诉你一个连接去向哪个软IOCs。
- 即使不同软IOCs驻留在相同机器上,通道访问应该能够区分不同的软IOCs。
我曾考虑使用一个虚拟化层(基于VMware)在一个封装环境中运行软IOCs。我发现工作量太高,此层太厚,并且预计的性能损失太大--仅得到了每个软IOIC一个单独IP地址。
在调试和/或尝试查看在一个IOC上发生了什么时,开发者不必要知道数据库运行在一个基于VME上还是在一个基于主机的软IOC上。
- Console访问(以及记录console输出日志)应该是统一的:对于软IOCs和VME IOCs使用相同方式。
实现这个目标所需的设置在文档<<如何为VME和软IOCs设置Console访问和日志>>。
概念
要使访问安全区分软IOCs,在不同用户名下运行它们。
procServ工具将用做一个环境,它允许在后台启动软IOCs并且之后连接到它们的consoles,非常类型VME IOCs的串行consoles。(见EPICS Related Software — EPICS Documentation documentation (epics-controls.org)上procServ链接。之前,使用screen工具,但报告的问题,例如,在console访问后IOCs挂起,使得我们切花到复杂性更低的东西)。
/etc/init.d/softIOC是用于将EPICS软IOC作为系统服务启动的脚本:参考网页https://wiki-ext.aps.anl.gov/epics/index.php/How_to_Set_Up_a_Soft_IOC_Framework_on_Linux
这个脚本的描述:
DESC="EPICS soft IOCs"
这个脚本的完整路径:
SCRIPTNAME=/etc/init.d/softIOC
获取主机名称:
HOST=`uname -n`
设置procServ程序的路径
PROCSERV=/usr/bin/procServ
设置配置文件的完整路径:
CONFFILE=/usr/local/EPICS/program/softIOC/softiocs.orangepi5plus
设置IOC应用程序所在的家目录:
HOMEDIRS=/usr/local/EPICS/program
检查配置文件 , 不能读取配置文件,显示不能找到配置文件,并且以错误码1退出本脚本。
if [ ! -r $CONFFILE ]
then
echo "Error: Can't find configuration file $CONFFILE!"
exit 1
fi
此函数函数:清理环境变量"CA_AUTO" "CA_ADDR" "CA_PORT" "IOC_USER" "PORT"。
clear_options()
{
for option in "CA_AUTO" "CA_ADDR" "CA_PORT" "IOC_USER" "PORT"
do
unset $option;
done
}
clear_options()的测试脚本如下:
echo "=============test clear_options() ====================="
export CA_AUTO="NO"
export CA_ADDR="127.0.0.1"
export CA_PORT=5065
export IOC_USER="blctrl"
export PORT="20000"
echo "CA_AUTO=$CA_AUTO"
echo "CA_ADDR=$CA_ADDR"
echo "CA_PORT=$CA_PORT"
echo "IOC_USER=$IOC_USER"
echo "PORT=$PORT"
echo "call clear_options()"
clear_options
echo "called clear_options()"
echo "CA_AUTO=$CA_AUTO"
echo "CA_ADDR=$CA_ADDR"
echo "CA_PORT=$CA_PORT"
echo "IOC_USER=$IOC_USER"
echo "PORT=$PORT"
echo "===================end================================="
echo ""
测试结果:
=============test clear_options() =====================
CA_AUTO=NO
CA_ADDR=127.0.0.1
CA_PORT=5065
IOC_USER=blctrl
PORT=20000
call clear_options()
called clear_options()
CA_AUTO=
CA_ADDR=
CA_PORT=
IOC_USER=
PORT=
===================end=================================
根据读入参数设置环境变量:
evaluate_options()
{
while [ $# != 0 ]
do # 将第一个参数的小写字符全部替换成大写字母
TAG=`echo $1 | tr [:lower:] [:upper:]`
case "$TAG" in
"#") ;; # 匹配”#”,则进入下次循环
"CA_AUTO" | "CA_ADDR" | "CA_PORT" | "COREDUMPSIZE" | \
"HOMEDIR" | "BOOTDIR" | "IOC_USER" | "PORT" ) # 匹配这些字符
# 测试当前选项值的存在
OPTION=$TAG
shift
if [ -z $TAG -o $TAG = "#" ] # TAG变量为空或者内容为”#”
then
echo "$CONFFILE: Value(s) required for $TAG.";
exit 1
else
VALUE=$1
shift
fi
# 如果多个值跟随,也分配它们
while [ $1 != '#' -a $# != 0 ]
do