smf_method - 方法的服务管理框架约定
服务管理框架 smf(7) 中的 svc.startd(8) 管理的服务类由适合简单 fork(2)-exec(2) 模型的应用程序组成。svc.startd(8) 主守护进程及其他重启程序支持 fork(2)-exec(2) 模型(可能带有附加功能)。svc.startd(8) 守护进程及其他重启程序需要按照本手册页中所述的约定激活、处理或检查服务实例的方法。
方法调用的格式不受约定的控制。在某些情况下,方法调用可能由守护进程或提供服务的其他二进制可执行文件的直接调用组成。对于使用可执行脚本或其他间接可执行文件的情况,约定建议采用以下格式:
/path/to/method_executable abbr_method_name
该建议格式中使用的 abbr_method_name 是支持的方法,如 start 或 stop。在相关重启程序页中提供了重启程序支持的方法集。svc.startd(8) 守护进程支持 start、stop 和 refresh 方法。
除了本页中引用的方法之外,重启程序还可能会定义其他种类的方法。围绕此类扩展的约定将由重启程序定义,可能与此处给出的定义不同。
重启程序向方法提供了四个环境变量,这些变量用于确定调用方法的上下文。
为其调用方法的实例的服务故障管理资源标识符 (Fault Management Resource Identifier, FMRI)。
所调用方法的完整名称,如 start 或 stop。
调用方法的重启程序的服务 FMRI
正在其中运行方法的区域的名称。也可使用 zonename(1) 命令获取此名称。
该方法退出,但检测到服务实例存在一个问题(可能不需要管理员立即干预)。此退出代码还可在 stop 方法中用于指示服务实例未成功停止,稍后应重试 stop 方法。
在方法调用任何持久性进程之前,应从环境中删除这些变量。在下述包含文件中,为使用 Bourne 兼容 shell 脚本编写服务方法的服务作者提供了便利 shell 函数 smf_clear_env。
方法上下文可能会导致设置其他环境变量(如下文所述)。
方法至少由 method 类型的属性组中的三个属性定义。
这些属性包括:
方法可执行字符串。
方法超时之前所经过的秒数。有关更多详细信息,请参见超时部分。
方法类型。当前始终设置为 method。
要进一步完善方法的执行环境,可定义方法上下文。有关更多信息,请参见方法上下文部分。
当重启程序 svc.startd 在方法的 exec 字符串中定义一组标记时,将使用适当的值对这些标记进行解析和扩展。其他重启程序可能不支持方法标记。inet 服务 inetd(8) 的委托重启程序不支持以下方法扩展。
%
重启程序的名称,如 svc.startd
所调用方法的完整名称,如 start 或 stop。
服务的名称
实例的名称
实例的 FMRI
属性的值。prop 可能是以 / 分隔的属性 FMRI、属性组名称和属性名,也可能是 application 属性组中的属性名。这些值可以后跟 ,(逗号)或 :(冒号)。使用分隔符(如果提供)分隔多个值。如果未提供分隔符,将使用空格。出现在字符串值中的以下 shell 元字符将用 \(反斜杠)引起来:
; & ( ) | ^ < > newline space tab \ " '
无效扩展会导致方法失败。
有两个显式标记可用来代替方法命令。
将指定的信号(缺省情况下为 SIGTERM)发送到主实例合同中的所有进程。始终返回 SMF_EXIT_OK。此标记应当用于替换常见的 pkill 调用。
始终返回 SMF_EXIT_OK。此标记应当用于对重启程序是必需的但对特定服务是不必要的方法。
start 方法的必需行为是延迟退出,直到服务实例已经准备好应答请求或以其他方式工作。
以下退出状态代码在 <libscf.h> 和 shell 支持文件中定义。
|
除了上述退出代码以外,方法还可结合 smf_method_exit() 使用以下退出代码,可通过 smf_method_exit(3SCF)、smf_include.sh 和 smf_include.py Python 模块获得以下代码:
|
利用精确的退出代码,使负责的重启程序可以将错误响应分类为间歇性的(值得执行重新启动)或永久性的(要求管理干预)。
每个方法都可以有独立的超时(以秒为单位指定)。方法超时由 timeout_seconds 属性指定。
超时是服务的重启程序用来确定方法已挂起或未在继续执行的最后手段。如果已超时,多数重启程序会将服务置于维护状态。请参见 svc.startd(8)。在指定超时时,建议考虑一定的误差范围,以避免出现方法正在执行但系统因为内存、CPU 或 I/O 负载等原因而暂时响应非常缓慢的情况时,过早地判断为执行失败。
对于预期需要用一两秒的方法,60 秒是一个较好的初始值。300 秒(5 分钟)适用于通常需要用 30 秒的方法。对于经常要用较长时间的方法,应相应地增大超时值。
如果希望快速判断为故障以便提示进行管理干预,则可以使用较短的超时。如果管理干预可能只是清除服务并重新启动方法,请考虑使用较长的超时。
如果 timeout_seconds 设置为 0,则服务无超时。不建议使用此设置,但它适用于绝对需要它的服务。-1 也可用于指定无超时,但已过时。
定义上述退出状态值的一组环境变量通过文件 /lib/svc/share/smf_include.sh 中的便利 shell 函数提供。此文件是 Bourne shell 脚本,可通过源运算符包含在任何 Bourne 兼容 shell 中。
为帮助编写可充当 SMF 方法的脚本以及 /etc/init.d 脚本,提供了 smf_present() shell 函数。如果 smf(7) 工具不可用,smf_present() 会返回非零退出状态。
此类脚本的一个可能的结构如下所示:
if smf_present; then # Shell code to run application as managed service .... smf_clear_env else # Shell code to run application as /etc/init.d script .... fi
此示例显示了所提供的两个便利函数的用法。
/lib/svc/share/smf_include.sh 提供的相同的退出状态集可以在 smf_include 模块中获得。
服务管理工具提供了一种常见机制,可用于设置在其中执行 fork(2)-exec(2) 模型服务的上下文。
所需的方法上下文应由服务开发者提供。所有服务实例都应以最低特权级别和所需的最低安全许可运行,以限制潜在的安全危害。
方法上下文可包含以下属性:
要以一种包含多个 NAME=value 字符串的形式插入方法所在环境的环境变量。
RBAC(Role-Based Access Control,基于角色的访问控制)配置文件的名称,该配置文件与方法可执行文件一起用于标识 exec_attr(5) 中的条目。
数字或文本形式的可选用户 ID。
数字或文本形式的可选组 ID。
一个可选字符串,按数字或文本形式的 ID 指定补充组成员资格。
一个可选字符串,指定 privileges(7) 中所定义的特权集。可在此处指定一个扩展策略。
一个可选字符串,指定 privileges(7) 中所定义的限制特权集。
从中启动方法的起始目录。可将 :home 用作一个标记,指示使用其 uid 启动方法的用户的起始目录。如果未设置该属性,将使用 :home。
数字或文本形式的项目 ID。可将 :default 用作一个标记,为使用其 uid 启动方法的用户指示由 getdefaultproj(3PROJECT)标识的项目。
启动方法的资源池的名称。可将 :default 用作一个标记,指示在上述 project 属性中给出的 project(5) 条目中所指定的池。
一个可选字符串,按 labels(7) 中所述指定进程安全许可。字符串可能是 ADMIN_LOW、ADMIN_HIGH 或 atohexlabel(8) 生成的十六进制字符串。如果未指定,则方法使用 policy.conf(5) 中指定的安全许可启动。缺省值为 ADMIN_HIGH。
指定此服务是否在可信路径中运行的可选字符串。有关更多信息,请参见 tpd(7) 手册页。缺省值是 /。将从 MWAC 策略排除在可信路径中运行的服务。有关更多信息,请参见 mwac(7) 手册页。
An optional boolean that specifies whether this service runs with the PPRIV_DEBUG process flag. Setting this true will result in details of any file access errors or missing required privileges being printed to the system messages file. These messages will describe the missing privilege and for file access, name the file to which access was denied.
通过为服务或实例指定 method_context 属性组,可为整个服务实例设置方法上下文。通过在方法属性组上提供方法上下文属性,方法可能会覆盖实例方法上下文。
无效方法上下文设置始终会导致方法失败,但导致发出警告的无效环境变量除外。
除了上述定义的上下文之外,许多 fork(2)-exec(2) 模型重启程序在作为方法调用可执行文件时还使用以下约定:
argv[] 中参数的设置与 exec 字符串的结果 /bin/sh -c 一致。
文件描述符 0 为 /dev/null。文件描述符 1 和 2 建议为基于服务日志文件。
退出状态值的定义。
退出状态代码的定义。
启动方法可能要使用 smf_method_exit(),以在服务日志中报告服务特定的配置错误消息。
if [ ! -s "$my_config_file" ]; then smf_method_exit $SMF_EXIT_ERR_CONFIG \ missing_or_empty_config_file \ "$my_config_file is missing or empty" fi示例 2 在非全局区域中启动时禁用仅应在全局区域中运行的服务。
仅应在全局区域中运行的服务在非全局区域中启动时,可能要禁用其本身。
if smf_is_nonglobalzone; then smf_method_exit $SMF_EXIT_TEMP_DISABLE global_zone_only \ "$SMF_FMRI is not supported in a local zone" SUNW_OST_OSCMD fi
zonename(1)、exec(2)、fork(2)、getdefaultproj(3PROJECT)、smf_method_exit(3SCF)、exec_attr(5)、project(5)、service_bundle(5)、attributes(7)、mwac(7)、labels(7)、privileges(7)、rbac(7)、smf(7)、smf_bootstrap(7)、tpd(7)、zones(7)、atohexlabel(8)、coreadm(8)、inetd(8)、svc.startd(8)、svccfg(8)
smf(7) 的现有版本不支持多个系统信息库。
当服务配置为以 root 身份但以不同于 limit_privileges 的权限启动时,所生成的进程可识别权限。这可能会出乎开发者的意料,他们本以为 seteuid(<非零 UID>) 能够将权限降为基本或更低的级别。