本节显示了一个交付 SMF 服务(执行一次性配置)的软件包示例。
以下软件包清单可提供运行一次的服务:
set name=pkg.fmri value=myapp-run-once@1.0 set name=pkg.summary value="Deliver a service that runs once" set name=pkg.description \ value="This example package delivers a service that runs once. The service is marked with a flag so that it will not run again." set name=org.opensolaris.smf.fmri value=svc:/site/myapplication-run-once \ value=svc:/site/myapplication-run-once:default set name=variant.arch value=i386 file lib/svc/manifest/site/myapplication-run-once.xml \ path=lib/svc/manifest/site/myapplication-run-once.xml owner=root group=sys \ mode=0444 restart_fmri=svc:/system/manifest-import:default file lib/svc/method/myapplication-run-once.sh \ path=lib/svc/method/myapplication-run-once.sh owner=root group=bin \ mode=0755 depend fmri=pkg:/shell/ksh93@93.21.0.20110208-0.175.2.0.0.37.1 type=require depend fmri=pkg:/system/core-os@0.5.11-0.175.2.0.0.37.0 type=require
以下脚本执行该服务的配置工作。该方法脚本使用 config/ran 属性,该属性已在服务中设置,以确保脚本仅运行一次。该属性在服务清单中设置为一个值,在方法脚本中设置为另一个值。退出调用中的注释将通过 svcs 命令显示。
#!/bin/sh # Load SMF shell support definitions . /lib/svc/share/smf_include.sh # If nothing to do, exit with temporary disable. ran=$(/usr/bin/svcprop -p config/ran $SMF_FMRI) if [ "$ran" == "true" ] ; then smf_method_exit $SMF_EXIT_TEMP_DISABLE done "service ran" fi # Do the configuration work. # Record that this run-once service has done its work. svccfg -s $SMF_FMRI setprop config/ran = true svccfg -s $SMF_FMRI refresh smf_method_exit $SMF_EXIT_TEMP_DISABLE done "service ran"
以下列表显示了此示例的 SMF 服务清单。列表后介绍了此清单的一些功能。
<?xml version="1.0" ?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> <service_bundle type="manifest" name="myapplication-run-once"> <service name='site/myapplication-run-once' type='service' version='1'> <dependency name='fs-local' grouping='require_all' restart_on='none' type='service'> <service_fmri value='svc:/system/filesystem/local:default' /> </dependency> <dependent name='myapplication-run-once-complete' grouping='optional_all' restart_on='none'> <service_fmri value='svc:/milestone/self-assembly-complete' /> </dependent> <instance enabled='true' name='default'> <exec_method type='method' name='start' exec='/lib/svc/method/myapplication-run-once.sh' timeout_seconds='60'/> <exec_method type='method' name='stop' exec=':true' timeout_seconds='0'/> <property_group name='startd' type='framework'> <propval name='duration' type='astring' value='transient' /> </property_group> <property_group name='config' type='application'> <propval name='ran' type='boolean' value='false' /> </property_group> </instance> <template> <common_name> <loctext xml:lang='C'> Run-once service </loctext> </common_name> <description> <loctext xml:lang='C'> This service checks and sets a property so that it runs only once. This service is a dependency of the self-assembly-complete milestone. </loctext> </description> </template> </service> </service_bundle>
在 dependent 元素中,此服务将自身作为一个依赖项添加到 self-assembly-complete 系统里程碑。
此服务的 startd/duration 属性设置为 transient,所以 svc.startd(1M) 不跟踪此服务的进程。
此服务的 config/ran 属性设置为 false。该服务方法将此属性设置为 true,因此该服务将仅运行一次。
对于 start 方法,此服务的 timeout_seconds 设置为 60。如果 timeout_seconds 设置为 0,SMF 将无限期地等待方法脚本退出。
确保在方法脚本退出调用中加入注释,在服务模板数据中加入服务名称和说明,以帮助用户了解此服务为何仅运行一次。
确保服务清单有效:
$ svccfg validate proto/lib/svc/manifest/site/myapplication-run-once.xml
如发布软件包中所述发布软件包。
安装软件包前后运行 pkg verify。比较每个运行的输出来确保脚本没有尝试修改任何未标记为可编辑的文件。
安装软件包后,检查以下输出:
使用 svcs 命令可显示服务的状态。svcs 命令的不同选项会显示附加信息。日志文件 (-L) 会显示运行的服务方法。注释和服务说明解释了禁用服务的原因。
$ svcs myapplication-run-once STATE STIME FMRI disabled 16:10:26 svc:/site/myapplication-run-once:default $ svcs -x myapplication-run-once svc:/site/myapplication-run-once:default (Run-once service) State: disabled since April 21, 2014 04:10:26 PM PDT Reason: Temporarily disabled by an administrator. See: http://support.oracle.com/msg/SMF-8000-1S See: /var/svc/log/site-myapplication-run-once:default.log Impact: This service is not running. $ svcs -l myapplication-run-once fmri svc:/site/myapplication-run-once:default name Run-once service enabled false (temporary) state disabled next_state none state_time April 21, 2014 04:10:26 PM PDT logfile /var/svc/log/site-myapplication-run-once:default.log restarter svc:/system/svc/restarter:default manifest /lib/svc/manifest/site/myapplication-run-once.xml dependency require_all/none svc:/system/filesystem/local:default (online) $ svcs -xL myapplication-run-once svc:/site/myapplication-run-once:default (Run-once service) State: disabled since April 21, 2014 04:10:26 PM PDT Reason: Temporarily disabled by an administrator. See: http://support.oracle.com/msg/SMF-8000-1S See: /var/svc/log/site-myapplication-run-once:default.log Impact: This service is not running. Log: [ Apr 21 16:10:22 Enabled. ] [ Apr 21 16:10:22 Rereading configuration. ] [ Apr 21 16:10:25 Executing start method ("/lib/svc/method/myapplication-run-once.sh"). ] [ Apr 21 16:10:26 Method "start" exited with status 101. ] [ Apr 21 16:10:26 "start" method requested temporary disable: "service ran" ] Use: 'svcs -Lv svc:/site/myapplication-run-once:default' to view the complete log.
使用 svcs 命令的 -d 选项可显示 myapplication-run-once 服务是 self-assembly-complete 服务的依赖项。
$ svcs -d svc:/milestone/self-assembly-complete:default | grep once disabled 16:37:20 svc:/site/myapplication-run-once:default
检查作为标志使用的属性值,以避免服务再次运行。
$ svcprop -p config/ran myapplication-run-once true
以下 svccfg 命令显示了在服务清单中已将属性值设置为 false,随后又重置为 true。
$ svccfg -s myapplication-run-once:default listprop -l all config/ran config/ran boolean admin true config/ran boolean manifest false
如果启用该服务,您会发现日志文件中没有 "Rereading configuration" 行,而且服务在未重新执行配置工作时便已退出。