OpenRC用户指南
目的与描述
OpenRC是适用于类Unix操作系统的初始化系统。它负责整个系统(包括各项服务)的启动和关闭。
它源自Gentoo的“基础布局”软件包,该软件包是一种定制的纯Shell启动解决方案。(这种解决方案既难以维护和调试,性能也不是很好)
出于性能和灵活性方面的考虑,其大部分核心部分是用C99编写的,而其他部分则使用的是符合POSIX标准的shell脚本。
目前,它的C语言代码量约为10000行,shell脚本代码量约为4000行。
众所周知,OpenRC可在Linux、许多BSD系统(至少包括FreeBSD、OpenBSD、DragonFlyBSD )以及HURD系统上运行。
服务是有状态的(也就是说,如果已经执行了“启动”操作,再次执行“启动”会提示“该服务已启动”)。
openrc启动
通常,PID1(又名 init)会调用 OpenRC 二进制文件(默认情况下为 /sbin/openrc)。
(默认设置假定在此情况下使用 sysvinit)
OpenRC会扫描运行级别(默认路径是 /etc/runlevels)并构建一个依赖图,然后启动所需的服务脚本,既可以按顺序执行(默认方式),也可以并行执行。
当所有服务脚本启动后,OpenRC就会终止,它不会以守护进程的形式持续运行。不过,OpenRC可以与诸如monit、runit或s6等工具进行集成。
关闭
当系统运行级别变更为 0 或 6,或者执行reboot、halt等命令时,OpenRC会停止所有已启动的服务,并运行shutdown运行级别里的服务。
openrc修改服务脚本
任何服务都可以随时通过执行 ‘rc-service someservice start’、‘rc-service someservice stop’ 等来启动/停止/重启。 另一种不太受欢迎的方法是直接运行服务脚本,例如 ‘/etc/init.d/service start’、’/etc/init.d/service stop’ 等。
OpenRC会处理依赖性问题,例如启动apache会先启动network,而停止network会先停止apache。
有一个特殊的命令 ‘zap’ 可以让 OpenRC ‘忘记’ 服务已启动;这对于将崩溃的服务重置为 Stopped 状态非常有用,而无需调用服务脚本的(可能已损坏的)Stop 函数。
在没有任何参数的情况下调用 ‘openrc’ 将尝试重置所有服务,以便满足当前运行级别;如果您手动启动Apache,它将被停止,如果Squid死亡但处于当前运行级别,它将重新启动。
OpenRC运行级别
OpenRC 有一个运行级别的概念,类似于sysvinit提供的功能。运行级别基本上就是一组需要启动的服务集合。它们不是用随机的数字来命名,而是有具体的名称,用户如果需要也可以创建自己的运行级别。例如,可以定义一个启用了“everything”的默认运行级别,以及一个禁用了一些服务的“powersaving”运行级别。
rc-status工具会打印出所有当前活动的运行级别以及其中服务的状态:
1# rc-status
2 * Caching service dependencies ... [ ok ]
3Runlevel: default
4 modules [ started ]
5 lvm [ started ]
所有运行级别都以文件夹的形式存在于 /etc/runlevels/ 中,其中包含指向实际服务脚本的符号链接。
使用参数调用 openrc(例如 openrc default)会切换到该运行级别,可根据需要启动和停止服务。
管理运行级别通常通过 rc-update 工具来完成,但如果愿意,当然也可以手动操作。
例如:rc-update add nginx default —— 将nginx添加到 default 运行级别。
注意:rc-update 不会启动nginx!你仍然需要触发 rc,或者手动运行服务脚本,或者用 rc-service nginx start 来启动它。
默认启动会按顺序使用 sysinit、boot 和 default 这三个运行级别。关机会使用shutdown运行级别。
conf.d的魔力
大多数服务脚本需要默认值。如果专门去source某些任意文件,会显得很幼稚。按约定,对于 /etc/init.d/ 中的任何脚本,openrc-run 都会 source /etc/conf.d/ 中与之匹配的文件。
这样可以轻松设置各种与启动相关的杂项。例如:
1conf.d/foo:
2START_OPTS="--extraparameter sausage"
3
4init.d/foo:
5start() {
6 /usr/sbin/foo-daemon ${START_OPTS}
7}
这种分离的最大优势在于,大多数情况下都可以避免去编辑服务脚本本身。
启动停止守护进程
OpenRC有自己修改版的s-s-d,它在历史上与 Debian 的s-s-d相关,且大部分语法兼容,但是从头重写的。
它有助于启动守护进程、将其转入后台、创建 PID 文件,以及许多其他与守护进程管理相关的便捷功能。
/etc/rc.conf配置文件
这个文件管理OpenRC的默认配置,其中包含了一些针对各个服务脚本的变量示例。
其中包括 rc_parallel(用于并行启动)、rc_log(将所有启动消息记录到文件中),以及另外一些变量。
openrc中的ulimit和CGroups
可以通过 rc_ulimit 变量为每个服务设置 ulimit 值。
在 Linux 下,OpenRC 也可以使用cgroups进行进程管理。在正确配置内核之后,应使用 /etc/rc.conf 中的 rc_cgroup_mode 设置来控制使用的是cgroups 第一版、第二版,还是两者都使用。默认情况下,如果两者都可用,则两者都使用。
通过更改服务 conf.d 文件中的某些设置,可以针对每个服务实施资源限制。这些设置在默认的 /etc/rc.conf 中的 LINUX CGROUPS RESOURCE MANAGEMENT 部分有详细说明。
openrc处理孤儿进程
有可能会进入这样一种状态:有一些属于某个服务的孤儿进程仍在运行。例如,如果你用supervise-daemon监视某个服务,而supervise-daemon 因未知原因死掉了。处理这种情况的方式因系统而异。
在启用了 cgroups 的 Linux 系统上,cgroup_cleanup 命令会被添加到所有服务中。当服务停止时,你可以通过以下方式手动运行它:
# rc-service someservice cgroup_cleanup
可以将 rc_cgroup_cleanup 设置改为 yes,使其在服务停止时自动执行此操作。
openrc缓存
出于性能方面的考虑,OpenRC 会缓存预先解析过的服务元数据(例如 depend)。其默认位置是 /${RC_SVCDIR}/cache。
该缓存使用 mtime 来检查文件是否过期。只要任何服务脚本发生变化,它就会重新 source 相关文件并更新缓存。
openrc便捷函数
OpenRC在libeinfo中为许多常见的输出任务提供了包装函数。
这样可以打印带颜色编码的状态提示以及其他内容。
为了使输出保持一致,随附的服务脚本都使用ebegin/eend来打印美观的消息。
openrc用户服务——实验性功能
OpenRC 持为用户管理服务。
init 脚本从 /etc/user/init.d 和 ${XDG_CONFIG_HOME}/rc/init.d 加载;如果 XDG_CONFIG_HOME 未设置,则从 ~/.config 加载。
~/.config/rc/conf.d 中的配置应覆盖 /etc/user/conf.d,同样,~/.config/rc/rc.conf 中设置的选项会覆盖 /etc/rc.conf。
运行级别保存在 ~/.config/rc/runlevels 中。
openrc 以及所有 rc-* 工具都提供 --user/-U 标志,用于操作用户模式的服务和运行级别。
在调用 openrc --user 之前,必须先设置 XDG_RUNTIME_DIR 变量,因为它用于存储 openrc 自身及其所运行服务的状态。
openrc自动启动
OpenRC 支持通过 PAM 模块自动管理用户服务会话。
将 pam_openrc.so 添加到首选登录方式(即 login、ssh)的 PAM 配置中,并为 openrc-user 设置 PAM 配置,使其类似于通常登录会话的配置(如果 XDG_RUNTIME_DIR 是通过 PAM 模块设置的,则应当包含它,以及通常用户会话所需的一切)。
openrc开机启动
要在启动时启动某个特定会话,可以对用户系统服务进行多路复用,方法是将 init.d/user 符号链接到 init.d/user.$username,其中username是你希望在启动时启动的目标用户。