SMF on illumos
From girlwiki
Maybe I just suck at finding docs, but SMF feels like a bit of a mess. It seems like Solaris users get some nice tools for creating manifests, but I'm guessing that's post-illumos fork. Refer to this PDF for more in-depth info.
This assumes you're using svc.startd(8) as your "restarter", which mainly affects the exec_method
elements (AIUI). If you (like me) don't know what that means, this is likely the case.
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!-- name seems to be arbitrary. best to set it to the service name -->
<service_bundle type="manifest" name="service_name">
<!--
name is how you'll refer to the service in svcs/svcadm. I typically
use "application/<service_name>", no idea if that's idiomatic or not.
version must be an integer.
-->
<service name="scarlet/my_service" type="service" version="1">
<!-- this sample service should only ever have one instance -->
<single_instance />
<!--
if you want multiple instances, don't use that tag. instead, use:
<create_default_instance enabled="(true|false)" />
depending on whether you want application/my_service:default to exist.
-->
<!--
say this service relies on networking and fs to function. if the
relevant SMF services get refreshed (reconfigured) or restarted,
we need to restart too. so we'll use restart_on='refresh' ('restart' is
implied) and since we need all the services, grouping='require_all'.
-->
<!-- TODO: the DTD seems to imply multiple service_fmri tags work, but
nobody seems to do this. is this ok? works fine for me so far -->
<dependency name="net_fs" grouping="require_all" restart_on="refresh" type="service">
<service_fmri value="svc:/milestone/network:default" />
<service_fmri value="svc:/system/filesystem/local" />
</dependency>
<!-- You can also depend on stuff like files existing! -->
<dependency name="config_file" grouping="require_all" restart_on="refresh" type="path">
<service_fmri value="file://localhost/etc/serviced.conf" />
</dependency>
<!-- name should be 'start', 'refresh' (reconfigure), or 'stop'. -->
<exec_method type="method"
name="start"
exec="/opt/local/bin/serviced --with-args "stuff""
timeout_seconds="60">
<method_context>
<!-- you can add other groups with supp_groups (comma/space delim) -->
<method_credential user='svcuser' group='svcgrp' />
<method_environment>
<envvar name="HOME" value="/var/lib/service" />
</method_environment>
</method_context>
<!--
not sure where it's documented, but ':kill' works to just kill
the service PID.
-->
<exec_method type="method"
name="stop"
exec=":kill"
timeout_methods="60" />
<!-- svc.startd specific options -->
<property_group name="startd" type="framework">
<!--
startd durations:
- 'child': long-running foreground process
- 'contract': "daemonizing" process (uses fork)
- 'transient': similar to systemd's 'oneshot'
-->
<propval name="duration" type="astring" value="child" />
<!-- don't restart on some errors -->
<propval name="ignore_error" type="astring" value="core,signal" />
<!--
if you need a separate session for the service:
<propval name="need_session" type="boolean" value="true" />
there's also utmpx_prefix, but unless your service is *very*
unix-y, you probably don't need this.
-->
</property_group>
<template>
<!-- locale-specific names for your service -->
<common_name>
<loctext xml:lang="C">Sample Service Daemon</loctext>
</common_name>
<!-- optional: link some docs -->
<documentation>
<manpage title="serviced" section="8" manpath="/opt/local/share/man" />
<doc_link name="docs-home" uri="https://example.com/docs/" />
</documentation>
</template>
</service>
</service_bundle>
Okay, but how do I use this?
That's the easy part! As root:
# svccfg import your-manifest.xml
You can now use it like every other service on your system. Use svcs my_service
to see its status, svcadm (enable|disable|refresh|restart) my_service
to do all of those relevant things, etc etc.