1 嵌入式 Solaris
本节介绍 OTP 中与 Solaris 相关的操作系统特定部分。
1.1 内存使用
Solaris 在具有 64 MB 总内存的系统上大约占用 17 MB 的 RAM。这为应用程序留下了大约 47 MB 的空间。如果系统使用交换,这些数字无法改善,因为不必要的守护进程会被交换出去。但是,如果禁用交换,或者系统中的交换空间资源有限,那么有必要终止不必要的守护进程。
1.2 磁盘空间使用
通过使用核心用户支持安装,可以最大限度地减少 Solaris 需要的磁盘空间。它需要大约 80 MB 的磁盘空间。这只会安装启动和运行 Solaris 所需的最小软件。通过删除不必要的单个文件,可以进一步减少磁盘空间。但是,除非磁盘空间是关键资源,否则所需要的努力和所涉及的风险是不可接受的。
1.3 安装嵌入式系统
本节介绍如何安装嵌入式系统。将考虑以下主题
- 创建用户和安装目录
- 安装嵌入式系统
- 配置启动时自动启动
- 使硬件看门狗可用
- 更改重启权限
- 设置 TERM 环境变量
- 添加补丁
- 在应用程序 os_mon 中安装模块 os_sup
本节中的几个过程需要具备 Solaris 操作系统的专业知识。对于其中大多数,需要超级用户权限。
创建用户和安装目录
建议由普通用户运行嵌入式环境,即没有超级用户权限的用户。
在本节中,假设用户名为 otpuser,并且该用户的 home 目录为
/export/home/otpuser
还假设在 otpuser 的 home 目录中,有一个名为 otp 的目录,其完整路径为
/export/home/otpuser/otp
该目录是嵌入式环境的 **安装目录**。
安装嵌入式系统
安装嵌入式系统的过程与普通系统相同(请参见安装指南),除了以下内容
- 压缩的磁带归档文件需要解压缩到上面定义的安装目录中。
- 无需将启动脚本链接到标准目录,例如 /usr/local/bin。
配置启动时自动启动
真正的嵌入式系统必须在系统启动时启动。本节介绍实现此目标所需配置。
如果将下面显示的脚本文件添加到目录 /etc/rc3.d 中,则嵌入式系统和所有应用程序将自动启动。该文件必须由 root 拥有并可读。它的名称不能任意指定;建议使用以下名称
S75otp.system
有关初始化(和终止)脚本以及其命名的更多详细信息,请参见 Solaris 文档。
#!/bin/sh # # File name: S75otp.system # Purpose: Automatically starts Erlang and applications when the # system starts # Author: [email protected] # Resides in: /etc/rc3.d # if [ ! -d /usr/bin ] then # /usr not mounted exit fi killproc() { # kill the named process(es) pid=`/usr/bin/ps -e | /usr/bin/grep -w $1 | /usr/bin/sed -e 's/^ *//' -e 's/ .*//'` [ "$pid" != "" ] && kill $pid } # Start/stop processes required for Erlang case "$1" in 'start') # Start the Erlang emulator # su - otpuser -c "/export/home/otpuser/otp/bin/start" & ;; 'stop') killproc beam ;; *) echo "Usage: $0 { start | stop }" ;; esac
上面脚本中提到的文件 /export/home/otpuser/otp/bin/start 正是 **启动 Erlang** 中描述的 start 脚本。该 start 脚本中的脚本变量 $OTPROOT 对应于本节中使用的以下示例路径
/export/home/otpuser/otp
需要相应地编辑 start 脚本。
上面脚本中使用 killproc 过程可以与对 erl_call 的调用结合使用,例如
$SOME_PATH/erl_call -n Node init stop
要优雅地关闭 Erlang,请参见 erl_interface 中的 erl_call(1) 手册页,了解有关 erl_call 用法的详细信息。但是,这要求 Erlang 作为分布式节点运行,而这并非总是如此。
不要删除 killproc 过程。其目的是从运行级别 3(具有网络资源的多用户模式)迁移到运行级别 2(没有此类资源的多用户模式),Erlang 不应在此模式下运行。
使硬件看门狗可用
对于在 Force Computers 的 VME 板上运行的 Solaris,可以激活板载硬件看门狗,前提是将 VME 总线驱动程序添加到操作系统中(另请参见安装问题)。
另请参见内核中的 heart(3) 手册页。
更改重启权限
如果要在 **启动 Erlang** 中的 start 脚本中设置 HEART_COMMAND 环境变量,并且如果要将其值设置为 Solaris reboot 命令的路径,即
HEART_COMMAND=/usr/sbin/reboot
那么必须更改 /usr/sbin/reboot 的所有权和文件权限,如下所示
chown 0 /usr/sbin/reboot chmod 4755 /usr/sbin/reboot
另请参见内核中的 heart(3) 手册页。
设置 TERM 环境变量
当 Erlang 运行时系统从 S75otp.system 脚本自动启动时,必须设置 TERM 环境变量。以下是最小设置
TERM=sun
这需要添加到 start 脚本中。
添加补丁
为了使 Solaris 2.5.1 上的刷新文件系统数据到磁盘功能正常运行,必须将编号为 103640-02 的特定版本补丁添加到操作系统中。可能还需要其他补丁,请参见发行版 README 文件 <ERL_INSTALL_DIR>/README。
在应用程序 os_mon 中安装模块 os_sup
以下四个安装过程需要超级用户权限
安装
-
复制 syslogd 的 Solaris 标准配置文件
- 复制 syslogd 的 Solaris 标准配置文件。该文件通常名为 syslog.conf 并且位于目录 /etc 中。
- 副本的文件名必须为 syslog.conf.ORIG。目录位置是可选的;通常它为 /etc。执行此操作的简单方法是发出以下命令
cp /etc/syslog.conf /etc/syslog.conf.ORIG
-
创建 Erlang 特定的 syslogd 配置文件
- 创建之前制作的备份副本的编辑副本。
- 文件名必须为 syslog.conf.OTP。路径必须与备份副本相同。
- 配置文件的格式可以在 syslog.conf(5) 手册页中找到,方法是发出命令 man syslog.conf。
- 通常会添加一行,该行将声明
- 要由 Erlang 监督的信息类型
- 接收信息的命名管道(实际上是一个命名管道)的名称
- 例如,如果只想监督来自 UNIX 内核的信息,则该行将以 kern.LEVEL 开头。有关 LEVEL 的可能值,请参见 syslog.conf(5)。
- 在至少一个制表符字符之后,添加的行将包含 syslogd 在其中写入其信息的命名管道的完整名称。路径必须与文件 syslog.conf.ORIG 和 syslog.conf.OTP 的路径相同。文件名必须为 syslog.otp。
- 如果文件 syslog.conf.ORIG 和 syslog.conf.OTP 的目录为 /etc,则 syslog.conf.OTP 中的行如下所示
kern.LEVEL /etc/syslog.otp
-
检查配置文件的文件权限
- 配置文件应具有 rw-r--r-- 文件权限,并且由 root 拥有。
- 执行此操作的简单方法是发出以下命令
chmod 644 /etc/syslog.conf chmod 644 /etc/syslog.conf.ORIG chmod 644 /etc/syslog.conf.OTP
- 注意,如果文件 syslog.conf.ORIG 和 syslog.conf.OTP 不在目录 /etc 中,则必须修改第二和第三条命令中的文件路径。
-
修改 mod_syslog 实用程序的文件权限和所有权
- 必须修改 mod_syslog 实用程序的文件权限和所有权。
-
二进制可执行文件的完整名称是从应用程序 os_mon 在文件系统中的位置派生的,方法是添加 /priv/bin/mod_syslog。因此,二进制可执行文件的通用完整名称为
<$OTPROOT>/lib/os_mon-<REV>/priv/bin/mod_syslog
**示例:** 如果 otp-root 的路径为 /usr/otp,则 os_mon 应用程序的路径为 /usr/otp/lib/os_mon-1.0(假设修订版为 1.0),并且二进制可执行文件的完整名称为 /usr/otp/lib/os_mon-1.0/priv/bin/mod_syslog。
- 二进制可执行文件必须由 root 拥有,具有 rwsr-xr-x 文件权限,特别是用户的 setuid 位必须设置。
-
执行此操作的简单方法是发出以下命令
cd <$OTPROOT>/lib/os_mon-<REV>/priv/bin/mod_syslog chmod 4755 mod_syslog chown root mod_syslog
测试应用程序配置文件
以下过程不需要 root 权限
- 确保应用程序 os_mon 中 os_sup 模块的配置参数正确。
-
浏览应用程序配置文件(**不要** 编辑它)。应用程序配置文件的完整名称是从 os_mon 应用程序在文件系统中的位置派生的,方法是添加 /ebin/os_mon.app。
因此,该文件的通用完整名称为
<$OTPROOT>/lib/os_mon-<REV>/ebin/os_mon.app.
**示例:** 如果 otp-root 的路径为 /usr/otp,则 os_mon 应用程序的路径为 /usr/otp/lib/os_mon-1.0 (假设修订版为 1.0),并且二进制可执行文件的完整名称为 /usr/otp/lib/os_mon-1.0/ebin/os_mon.app。
- 确保以下配置参数具有正确的值
参数 | 功能 | 标准值 |
start_os_sup | 指定是否要启动 os_sup。 | 硬件上的第一个实例为 true;其他实例为 false |
os_sup_own | (1)备份副本和(2)Erlang 特定的 syslogd 配置文件的目录 | "/etc" |
os_sup_syslogconf | syslogd 的 Solaris 标准配置文件的完整名称 | "/etc/syslog.conf" |
error_tag | 发送到 Erlang 运行时系统中的错误记录器的消息的标记 | std_error |
如果 os_mon.app 中列出的值不适合您的需求,**不要** 编辑该文件。相反,在 **系统配置文件** 中 **覆盖** 这些值,该文件的完整路径名在命令行上提供给 erl。
**示例:** 应用程序配置文件的内容
[{os_mon, [{start_os_sup, true}, {os_sup_own, "/etc"}, {os_sup_syslogconf, "/etc/syslog.conf"}, {os_sup_errortag, std_error}]}].
相关文档
请参见 os_mon(3) 应用程序、内核中的 application(3) 手册页以及 ERTS 中的 erl(1) 手册页。
安装问题
硬件看门狗计时器由 heart 端口程序控制,需要安装包含 VME 总线驱动程序的包 FORCEvme。但是,该驱动程序可能会与 Sun 的 mcp 驱动程序发生冲突,导致系统拒绝启动。要解决此问题,需要将以下行添加到 /etc/system 中
- exclude: drv/mcp
- exclude: drv/mcpzsa
- exclude: drv/mcpp
建议添加这些行以避免冲突。冲突可能导致系统无法启动。
1.4 启动 Erlang
本节描述嵌入式系统如何启动。涉及四个程序,它们通常位于 <ERL_INSTALL_DIR>/bin 目录中。唯一的例外是 start 程序,它可以位于任何地方,并且也是唯一需要由用户修改的程序。
在嵌入式系统中,通常没有交互式 Shell。但是,操作员可以通过命令 to_erl 连接到 Erlang 系统。然后操作员连接到 Erlang Shell,并可以发出普通的 Erlang 命令。通过此 Shell 与系统的所有交互都会记录在一个特殊的目录中。
基本上,过程如下
- 机器启动时调用 start 程序。
- 它调用 run_erl,它设置操作员可以连接到系统的环境。
- 它调用 start_erl,它调用 erlexec 的正确版本(位于 <ERL_INSTALL_DIR>/erts-EVsn/bin 中),并使用正确的 boot 和 config 文件。
1.5 程序
start
机器启动时会调用此程序。它可以修改或重写以适应特殊的系统。默认情况下,它必须名为 start 并位于 <ERL_INSTALL_DIR>/bin 中。可以使用另一个启动程序,方法是在 SASL 应用程序中使用配置参数 start_prg。
启动程序必须调用 run_erl,如下所示。它还必须接受一个可选参数,该参数默认为 <ERL_INSTALL_DIR>/releases/start_erl.data。
此程序用于设置静态参数和环境变量,例如 -sname Name 和 HEART_COMMAND 以重启机器。
<RELDIR> 目录是安装新发布包的地方,也是发布处理程序保存有关发布信息的目录。有关更多信息,请参阅 SASL 中的 release_handler(3) 手册页。
以下脚本说明了程序的默认行为
#!/bin/sh # Usage: start [DataFile] # ROOTDIR=/usr/local/otp if [ -z "$RELDIR" ] then RELDIR=$ROOTDIR/releases fi START_ERL_DATA=${1:-$RELDIR/start_erl.data} $ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \ $ROOTDIR $RELDIR $START_ERL_DATA" > /dev/null 2>&1 &
以下脚本说明了节点被命名为 cp1 的修改,并且环境变量 HEART_COMMAND 和 TERM 已添加到前面的脚本中
#!/bin/sh # Usage: start [DataFile] # HEART_COMMAND=/usr/sbin/reboot TERM=sun export HEART_COMMAND TERM ROOTDIR=/usr/local/otp if [ -z "$RELDIR" ] then RELDIR=$ROOTDIR/releases fi START_ERL_DATA=${1:-$RELDIR/start_erl.data} $ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl \ $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1" > /dev/null 2>&1 &
如果一个无盘和/或只读客户端节点即将启动,文件 start_erl.data 将位于主节点的客户端目录中。因此,START_ERL_DATA 行应如下所示
CLIENTDIR=$ROOTDIR/clients/clientname START_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}
run_erl
此程序用于启动仿真器,但您不会连接到 Shell。to_erl 用于连接到 Erlang Shell。
Usage: run_erl pipe_dir/ log_dir "exec command [parameters ...]"
这里
- pipe_dir/ 应该是 /tmp/(to_erl 默认使用此名称)。
- log_dir 是写入日志文件的位置。
- command [parameters] 会被执行。
- 写入 stdin 和 stdout 的所有内容都会记录在 log_dir 中。
日志文件写入 log_dir。每个日志文件都有一个格式为 erlang.log.N 的名称,其中 N 是一个从 1 到 5 的生成号。每个日志文件最多保存 100 kB 文本。随着时间的推移,日志文件目录中会出现以下日志文件
erlang.log.1 erlang.log.1, erlang.log.2 erlang.log.1, erlang.log.2, erlang.log.3 erlang.log.1, erlang.log.2, erlang.log.3, erlang.log.4 erlang.log.2, erlang.log.3, erlang.log.4, erlang.log.5 erlang.log.3, erlang.log.4, erlang.log.5, erlang.log.1 ...
最新的日志文件在每行的最右边。也就是说,最新的文件是数字最大的文件,或者如果已经有四个文件,则是最右边文件前面的文件。
打开日志文件(用于追加或创建)时,会向文件写入时间戳。如果在 15 分钟内没有向日志文件写入任何内容,则会插入一条记录,表明我们还活着。
to_erl
此程序用于连接到使用 run_erl 启动的正在运行的 Erlang 运行时系统。
Usage: to_erl [pipe_name | pipe_dir]
这里 pipe_name 默认为 /tmp/erlang.pipe.N。
要在不退出 Erlang 系统的情况下断开 Shell 连接,请键入 Ctrl-D。
start_erl
此程序使用参数 -boot 和 -config 启动 Erlang 仿真器。它从一个名为 start_erl.data 的文件中读取这些文件所在位置的数据,该文件位于 <RELDIR> 中。每个新版本都会引入一个新的数据文件。此文件由 Erlang 中的发布处理程序自动生成。
以下脚本说明了程序的行为
#!/bin/sh # # This program is called by run_erl. It starts # the Erlang emulator and sets -boot and -config parameters. # It should only be used at an embedded target system. # # Usage: start_erl RootDir RelDir DataFile [ErlFlags ...] # ROOTDIR=$1 shift RELDIR=$1 shift DataFile=$1 shift ERTS_VSN=`awk '{print $1}' $DataFile` VSN=`awk '{print $2}' $DataFile` BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` export EMU export ROOTDIR export BINDIR export PROGNAME export RELDIR exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $*
如果一个带有 SASL 配置参数 static_emulator 设置为 true 的无盘和/或只读客户端节点即将启动,则必须更改 -boot 和 -config 标志。
由于这样的客户端无法读取新的 start_erl.data 文件(该文件无法动态更改),因此启动和配置文件始终从相同的位置获取(但如果安装了新版本,则内容会更新)。
每当新版本永久化时,release_handler 会将这些文件复制到主节点的客户端目录中的 bin 目录。
假设与上面相同的 CLIENTDIR,最后一行应如下所示
exec $BINDIR/erlexec -boot $CLIENTDIR/bin/start \ -config $CLIENTDIR/bin/sys $*