This section shows an example of a package that delivers an SMF service that performs a one-time configuration.
The following package manifest delivers the run-once service:
set name=pkg.fmri firstname.lastname@example.org 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:/email@example.com,5.11-0.175.3.0.0.19.0 type=require depend fmri=pkg:/firstname.lastname@example.org,5.11-0.175.3.0.0.19.0 type=require
The following script does the configuration work of the service. This method script uses a property, config/ran, that has been set in the service to ensure that the script runs only once. The property is set to one value in the service manifest and to another value in the method script. The comment in the exit call will be displayed by the svcs command.
#!/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"
The following listing shows the SMF service manifest for this example. Some features of this manifest are described following the listing.
<?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>
In the dependent element, this service adds itself as a dependency to the self-assembly-complete system milestone.
This service has a startd/duration property set to transient so that svc.startd(8) does not track processes for this service.
This service has a config/ran property set to false. The service method sets this property to true so that the service will run only one time.
This service has timeout_seconds set to 60 for the start method. If timeout_seconds is set to 0, SMF will wait indefinitely for the method script to exit.
Be sure to include a comment in the method script exit and a service name and description in the service template data to help users understand why this service runs only one time.
Make sure the service manifest is valid:
$ svccfg validate proto/lib/svc/manifest/site/myapplication-run-once.xml
Publish your package as described in Publish the Package.
Run pkg verify before and after installing the package. Compare the output of each run to ensure that the script does not attempt to modify any files that are not marked as editable.
After you install the package, check the following output:
Use the svcs command to show the state of the service. Different options of the svcs command show additional information. The log file (-L) shows that the service method ran. Comments and service description explain why the service is disabled.
$ 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 March 30, 2015 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 March 30, 2015 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 March 30, 2015 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: [ 2015 Mar 30 16:10:22 Enabled. ] [ 2015 Mar 30 16:10:22 Rereading configuration. ] [ 2015 Mar 30 16:10:25 Executing start method ("/lib/svc/method/myapplication-run-once.sh"). ] [ 2015 Mar 30 16:10:26 Method "start" exited with status 101. ] [ 2015 Mar 30 16:10:26 "start" method requested temporary disable: "service ran" ] Use: 'svcs -Lv svc:/site/myapplication-run-once:default' to view the complete log.
Use the -d option of the svcs command to show that the myapplication-run-once service is a dependency of the self-assembly-complete service.
$ svcs -d svc:/milestone/self-assembly-complete:default | grep once disabled 16:37:20 svc:/site/myapplication-run-once:default
Check the value of the property that is being used as a flag to prevent the service from running again.
$ svcprop -p config/ran myapplication-run-once true
The following svccfg command shows that the value of the property was set to false in the service manifest and then later was reset to true.
$ svccfg -s myapplication-run-once:default listprop -l all config/ran config/ran boolean admin true config/ran boolean manifest false
If you enable the service, you see that the "Rereading configuration" line is absent from the log file, and the service exited without re-doing the configuration work.