For the complete documentation index, see llms.txt. This page is also available as Markdown.

16.5 管理 FreeBSD 中的服务

概述

FreeBSD 使用传统的 BSD init(初始化系统)管理系统服务。与 systemd 等现代初始化系统不同,BSD init 采用基于脚本的服务管理方式。所有其他进程均由 init 直接或间接启动。rc 启动脚本系统用于系统初始化及服务管理。

简单脚本示例如下:

#!/bin/sh
#
# PROVIDE: utility
# REQUIRE: DAEMON
# KEYWORD: shutdown

. /etc/rc.subr

name=utility
rcvar=utility_enable

command="/usr/local/sbin/utility"

load_rc_config $name

#
# 不应在此处修改默认值,请在 /etc/rc.conf 中设置
#
utility_enable=${utility_enable-"NO"}
pidfile=${utility_pidfile-"/var/run/utility.pid"}

run_rc_command "$1"

FreeBSD 提供了两个核心的服务管理命令:service 命令用于控制 rc.d 系统中的服务启动脚本,支持 startstoprestartstatus 等操作,并可列出可用服务。

sysrc 命令用于安全地修改 rc.conf(5) 中的系统配置值。它从 /etc/defaults/rc.conf 中读取 rc_conf_files 变量来确定要操作的文件列表,默认值为 /etc/rc.conf /etc/rc.conf.local,避免手动编辑导致语法错误。修改变量时,若变量已存在于这些文件中,则替换最后出现的那一个;若不存在,则追加到 rc_conf_files 列表中的第一个文件。

目录结构

上述文件在 FreeBSD 源代码中主要位于 libexec/rc 路径下。

注意

不应编辑 /etc/defaults/rc.conf 文件中包含的默认设置。所有系统特定的更改应写入 /etc/rc.conf/etc/rc.conf 文件的优先级高于 /etc/defaults/rc.conf 文件。换言之,/etc/rc.conf 文件将覆盖 /etc/defaults/rc.conf 文件中的同名配置项。

技巧

/etc/rc.conf/etc/rc.conf.local 都由 sh(1) 解析。这使得系统操作员能够创建复杂的配置场景。

管理系统特定的配置

系统配置的主要位置是 /etc/rc.conf。该文件包含广泛的配置信息,系统启动时读取,用于配置系统。它为 rc* 文件提供配置信息。

/etc/rc.conf 中的条目将覆盖 /etc/defaults/rc.conf 中的默认设置。推荐将特定系统的配置放入 /etc/rc.conf.local 文件。

技巧

系统更新不会覆盖 /etc/rc.conf,因此系统配置信息不会丢失。

集群应用程序中,可以采取多种策略,将全站配置与特定系统配置分开,以减少管理开销。

例如,/etc/rc.conf 文件中的这些条目适用于所有系统:

/etc/rc.conf.local 中的这些条目仅适用于该系统:

使用诸如 rsyncpuppet 等应用程序将 /etc/rc.conf 分发到每个系统,而 /etc/rc.conf.local 保持唯一。

常用命令集

BSD init 系统提供了 service 命令作为服务管理的统一接口,配合 sysrc 命令实现服务的启动、停止和开机自启动配置。以下是常用命令集。

启动服务:

停止服务:

临时启动服务(即使未在 rc.conf 文件中启用):

临时停止服务(即使未在 rc.conf 文件中启用):

重启服务:

添加服务并设置开机自启:

注意

service xxx enable 命令并非适用于所有服务,仍有局限,参见:FreeBSD Project. rc keywords: enable, disable, delete cannot manage certain built-in rc startup items.[EB/OL]. [2026-03-26]. https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285543. 下同。

禁用开机启动:

删除启动项:

注意

关键字 enabledisabledelete 参见:FreeBSD Project. Add new rc keywords: enable, disable, delete[EB/OL]. [2026-03-26]. https://reviews.freebsd.org/D17113.

系统服务安装后默认未启用,上述命令无法直接执行,需先启用服务。

编辑 /etc/rc.conf 文件,在文件中添加一行:XXX_enable="YES",其中 XXX 表示服务名称(例如 nginxsamba 等),这是固定格式。

技巧

上述命令中 "YES" 的双引号可省略,系统会自动添加。"NO" 同理。

基本系统服务的脚本路径为 /etc/rc.d/,第三方应用服务的脚本路径为 /usr/local/etc/rc.d/。可直接调用这两个目录下的脚本。

重新加载服务配置:

停止服务:

默认 rc.conf 配置文件的内容与结构

默认 rc.conf 配置文件的源代码位于 libexec/rc/rc.conf,对应提交为 Set virtual_oss_enable="NO" in /etc/defaults/rc.conf

关机与重启

reboothalt 在 FreeBSD 中属于同一程序,根据调用名称的不同而表现出不同行为。而在 Linux 中,这些命令可能是 systemd 的符号链接,行为也不同。FreeBSD 的设计更接近传统 UNIX 的行为。

关机:

  • 使用 shutdown now 不会关机,而是切换到“单用户模式”,将提示:Enter full pathname of shell or RETURN for /bin/sh: 回车后进入单用户模式;

  • 使用 shutdown -h now 不会彻底断电,只会停止系统的运行,提示:The operating system has halted. Please press any key to reboot. 此处按任意键可重启系统;

  • 关机并断电推荐使用 shutdown -p now,该命令通过向 init(8) 发送信号来运行 /etc/rc.shutdown 脚本(源代码位于 libexec/rc/rc.shutdown)有序关闭服务后断电。也可使用 halt -p,该命令直接刷新文件系统缓存并向所有进程发送 SIGTERM 及 SIGKILL 信号后断电,不执行 /etc/rc.shutdown

重启:

  • 重启命令与 Linux 相同,均为 reboot,但参数不通用。

  • FreeBSD 下 reboot 直接刷新文件系统缓存,向所有进程发送 SIGTERM 及 SIGKILL 信号后重启系统,不执行 /etc/rc.shutdown。若需有序关闭服务后重启,应使用 shutdown -r now,该命令通过 init(8) 运行 /etc/rc.shutdown。若需快速重启(跳过向进程发送信号,可能导致数据丢失),可使用 reboot -q 命令,该选项仅刷新文件系统缓存后立即重启。fastbootreboot 的别名,行为与 reboot 相同。

注意

FreeBSD 下,shutdown 命令允许 root 用户和 operator 组成员执行;reboothalt 命令仅限 root 用户执行。

课后习题

  1. 创建一个自定义服务脚本放入 /usr/local/etc/rc.d/ 目录,分析 rc.subr 中依赖关系检查的实现逻辑,评估其与 systemd unit 依赖模型的差异。

  2. 修改 rc_debug 为 YES,追踪一次服务启动的完整流程,对比正常启动与调试启动的输出差异,分析调试输出中各阶段的执行顺序。

  3. 禁用 rc_startmsgs 并修改关键服务的启动顺序(通过 REQUIREBEFORE 关键字),记录系统启动行为的变化。

最后更新于