Go to main content

手册页第 7 部分:标准、环境、宏、字符集和杂项

退出打印视图

更新时间: 2022年7月27日 星期三
 
 

smf_method(7)

名称

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 是支持的方法,如 startstop。在相关重启程序页中提供了重启程序支持的方法集。svc.startd(8) 守护进程支持 startstoprefresh 方法。

除了本页中引用的方法之外,重启程序还可能会定义其他种类的方法。围绕此类扩展的约定将由重启程序定义,可能与此处给出的定义不同。

环境变量

重启程序向方法提供了四个环境变量,这些变量用于确定调用方法的上下文。

SMF_FMRI

为其调用方法的实例的服务故障管理资源标识符 (Fault Management Resource Identifier, FMRI)。

SMF_METHOD

所调用方法的完整名称,如 startstop

SMF_RESTARTER

调用方法的重启程序的服务 FMRI

SMF_ZONENAME

正在其中运行方法的区域的名称。也可使用 zonename(1) 命令获取此名称。

SMF_EXIT_DEGRADED

该方法退出,但检测到服务实例存在一个问题(可能不需要管理员立即干预)。此退出代码还可在 stop 方法中用于指示服务实例未成功停止,稍后应重试 stop 方法。

在方法调用任何持久性进程之前,应从环境中删除这些变量。在下述包含文件中,为使用 Bourne 兼容 shell 脚本编写服务方法的服务作者提供了便利 shell 函数 smf_clear_env

方法上下文可能会导致设置其他环境变量(如下文所述)。

方法定义

方法至少由 method 类型的属性组中的三个属性定义。

这些属性包括:

exec (astring)

方法可执行字符串。

timeout_seconds (count)

方法超时之前所经过的秒数。有关更多详细信息,请参见超时部分。

type (astring)

方法类型。当前始终设置为 method

要进一步完善方法的执行环境,可定义方法上下文。有关更多信息,请参见方法上下文部分。

方法标记

当重启程序 svc.startd 在方法的 exec 字符串中定义一组标记时,将使用适当的值对这些标记进行解析和扩展。其他重启程序可能不支持方法标记。inet 服务 inetd(8) 的委托重启程序不支持以下方法扩展。

%%

%

%r

重启程序的名称,如 svc.startd

%m

所调用方法的完整名称,如 startstop

%s

服务的名称

%i

实例的名称

%f

实例的 FMRI

%{prop[:,]}

属性的值。prop 可能是以 / 分隔的属性 FMRI、属性组名称和属性名,也可能是 application 属性组中的属性名。这些值可以后跟 ,(逗号)或 :(冒号)。使用分隔符(如果提供)分隔多个值。如果未提供分隔符,将使用空格。出现在字符串值中的以下 shell 元字符将用 \(反斜杠)引起来:

; & ( ) | ^ < > newline space tab  \  " '

无效扩展会导致方法失败。

有两个显式标记可用来代替方法命令。

:kill [-signal]

将指定的信号(缺省情况下为 SIGTERM)发送到主实例合同中的所有进程。始终返回 SMF_EXIT_OK。此标记应当用于替换常见的 pkill 调用。

:是

始终返回 SMF_EXIT_OK。此标记应当用于对重启程序是必需的但对特定服务是不必要的方法。

正在退出和退出状态

start 方法的必需行为是延迟退出,直到服务实例已经准备好应答请求或以其他方式工作。

以下退出状态代码在 <libscf.h> 和 shell 支持文件中定义。

SMF_EXIT_OK
0
方法已退出,已成功执行其操作。
SMF_EXIT_ERR_FATAL
95
方法出现致命性失败,必须通过管理干预才能恢复。
SMF_EXIT_ERR_CONFIG
96
无法恢复的配置错误。返回此退出状态的常见情况是已启用的服务实例缺少必需的配置文件。
SMF_EXIT_ERR_NOSMF
99
方法被错误地在 smf(7) 工具外部调用。依赖于 smf(7) 功能的服务应退出并显示此状态值。
SMF_EXIT_ERR_PERM
100
方法所需的某种形式的权限(如文件访问、特权、授权或其他凭证)在调用时不可用。
SMF_EXIT_ERR_OTHER
non-zero
方法的任何非零退出状态均被视为未知错误。一系列未知错误可能会被重启程序或以重启程序的名义识别为故障。

除了上述退出代码以外,方法还可结合 smf_method_exit() 使用以下退出代码,可通过 smf_method_exit(3SCF)smf_include.shsmf_include.py Python 模块获得以下代码:

SMF_EXIT_TEMP_DISABLE
101
方法顺利退出并请求临时禁用。
SMF_EXIT_TEMP_TRANSIENT
102
方法顺利退出并请求按照服务模型为“瞬态”一样来进行处理。

利用精确的退出代码,使负责的重启程序可以将错误响应分类为间歇性的(值得执行重新启动)或永久性的(要求管理干预)。

超时

每个方法都可以有独立的超时(以秒为单位指定)。方法超时由 timeout_seconds 属性指定。

超时是服务的重启程序用来确定方法已挂起或未在继续执行的最后手段。如果已超时,多数重启程序会将服务置于维护状态。请参见 svc.startd(8)。在指定超时时,建议考虑一定的误差范围,以避免出现方法正在执行但系统因为内存、CPU 或 I/O 负载等原因而暂时响应非常缓慢的情况时,过早地判断为执行失败。

对于预期需要用一两秒的方法,60 秒是一个较好的初始值。300 秒(5 分钟)适用于通常需要用 30 秒的方法。对于经常要用较长时间的方法,应相应地增大超时值。

如果希望快速判断为故障以便提示进行管理干预,则可以使用较短的超时。如果管理干预可能只是清除服务并重新启动方法,请考虑使用较长的超时。

如果 timeout_seconds 设置为 0,则服务无超时。不建议使用此设置,但它适用于绝对需要它的服务。-1 也可用于指定无超时,但已过时。

Shell 编程支持

定义上述退出状态值的一组环境变量通过文件 /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

此示例显示了所提供的两个便利函数的用法。

Python 编程支持

/lib/svc/share/smf_include.sh 提供的相同的退出状态集可以在 smf_include 模块中获得。

方法上下文

服务管理工具提供了一种常见机制,可用于设置在其中执行 fork(2)-exec(2) 模型服务的上下文。

所需的方法上下文应由服务开发者提供。所有服务实例都应以最低特权级别和所需的最低安全许可运行,以限制潜在的安全危害。

方法上下文可包含以下属性:

环境

要以一种包含多个 NAME=value 字符串的形式插入方法所在环境的环境变量。

profile

RBAC(Role-Based Access Control,基于角色的访问控制)配置文件的名称,该配置文件与方法可执行文件一起用于标识 exec_attr(5) 中的条目。

user

数字或文本形式的可选用户 ID。

group

数字或文本形式的可选组 ID。

supp_groups

一个可选字符串,按数字或文本形式的 ID 指定补充组成员资格。

privileges

一个可选字符串,指定 privileges(7) 中所定义的特权集。可在此处指定一个扩展策略。

limit_privileges

一个可选字符串,指定 privileges(7) 中所定义的限制特权集。

working_directory

从中启动方法的起始目录。可将 :home 用作一个标记,指示使用其 uid 启动方法的用户的起始目录。如果未设置该属性,将使用 :home

project

数字或文本形式的项目 ID。可将 :default 用作一个标记,为使用其 uid 启动方法的用户指示由 getdefaultproj(3PROJECT)标识的项目。

resource_pool

启动方法的资源池的名称。可将 :default 用作一个标记,指示在上述 project 属性中给出的 project(5) 条目中所指定的池。

clearance

一个可选字符串,按 labels(7) 中所述指定进程安全许可。字符串可能是 ADMIN_LOWADMIN_HIGHatohexlabel(8) 生成的十六进制字符串。如果未指定,则方法使用 policy.conf(5) 中指定的安全许可启动。缺省值为 ADMIN_HIGH

trusted_path

指定此服务是否在可信路径中运行的可选字符串。有关更多信息,请参见 tpd(7) 手册页。缺省值是 /。将从 MWAC 策略排除在可信路径中运行的服务。有关更多信息,请参见 mwac(7) 手册页。

priv_debug

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。文件描述符 12 建议为基于服务日志文件。

文件

/lib/svc/share/smf_include.sh
/lib/svc/share/smf_exit_codes.sh
/usr/lib/python-version/vendor-packages/smf_include.py

退出状态值的定义。

/usr/include/libscf.h

退出状态代码的定义。

示例

示例 1 在服务日志中报告服务特定的配置错误消息。

启动方法可能要使用 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>) 能够将权限降为基本或更低的级别。