Constant Thinking | Technology Thoughts for the Quality Geek | by Constantin Gonzalez
Obsolete Post

This post is probably obsolete

This blog post is older than 5 years and a lot has changed since then: Meanwhile, I have changed employer, blogging platform, software stack, infrastructure, and other technologies I work with and interests I follow.
The stuff I wrote about in this article likely has changed, too, so you may find more recent information about things like Solaris, Oracle/Sun systems, Drupal, etc. somewhere else.
Still, this content is provided for your convenience, in case it is still useful for you. Just don’t expect it to be current or authoritative at this point.
Thanks for stopping by!

Home Server Scripting 4: Wrapping DTrace (and other scripts) Into SMF Services


In the last couple of posts, we used DTrace to notify our media servers and perfected our script a bit.

But the script is still not ready to be used on our home servers yet: It requires manual start and stop, not quite the service oriented automatism we're used to in the Oracle Solaris world.

The next step is to wrap our DTrace script inside a Service Management Facility (SMF) service, then wrap everything into a shell script that will easily install or remove the service whenever we need it.

The Joy of SMF

The Solaris Service Management Facility is one of my favorite features even though it undeservedly doesn't get as much attention as ZFS or Zones. Here's why it's so cool:

  • It lets you list, start, stop and monitor all of your daemons and services with a simple command,

  • It stores all information about your services in a single place, in an open data format,

  • It makes the boot process much more organized, and even parallelizes it for you,

  • And it can do much more for you. Read the SMF(5) man page for more.

In this case, we want to turn last post's DTrace script into an SMF service that can be started, stopped and monitored. Then, we want to wrap everything into a simple shell script that keeps everything together, making it easy to install and de-install.

Let's start by looking at the typical components of an SMF service.

Solaris SMF Service Components

To create an SMF service, we just need three things:

  • An SMF Manifest that describes our service to the system,

  • the actual daemon binary or other script that performs the service (in our case it's a DTrace script),

  • one or more start/stop methods that do the actual work of managing the service. This is what used to be /etc/init.d start/stop scripts in the old days, but you can also tell SMF to just start/kill your process instead.

Wrapping a DTrace Script Into an SMF Service

Sam Falkner blogged about how to wrap a DTrace script inside an SMF service some time ago, including a nice manifest that we can use as a starting point.

Another great help for creating your own SMF manifests is "Manifold": An easy-to-use Python script that asks you some simple questions, then creates the whole manifest for you. Neat!

For our purposes, we should include a dependency on zones (since our media services may should run inside them):

Brian Leonhard recently blogged about restricting privileges for Solaris services, which contains a lot of knowledge that we can use to restrict our DTrace script to just the set of privileges it needs.

Here's what I came up with after analyzing the privileges that we actually need:

We also need to tweak the execution methods to fit our DTrace script's (called dirtrap.d) command line options:

(We'll discuss filling in the %{script/*} bits later).

And finally, we'll use our own properties for the service, reflecting the path to our media and the command we need to restart our media server daemon with:

Wrapping an SMF Service Into a Shell Script Using "Here Documents"

Now that we have wrapped our DTrace script into an SMF service by creating a manifest to go along with it, we're ready to install.

But wait: Like all the other home server management scripts we discussed so far, we'd like to have it all in a single script that includes all the install and de-install work for us, not just the bare components of the service.

Wrapping our DTrace script and the manifest is just a matter of using "Here Documents":

cat > $TMPFILE <<'EOF'
Insert your document here.
Including any $funny $stuff that might be interpreted by the shell.
Which it won't.
At least not until the next line.

For most shells, there's a useful distinction between putting the end of file marker (which can be any word, we're just using "EOF" as a convention) in quotes and not:

  • Putting the word in quotes will tell the shell to ignore anything inside the Here Document that looks like a shell variable or other substitution. Useful if you want to embed shell scripts inside shell scripts.

  • Leaving out the quotes will enable the shell to substitute any variables and substitutables it encounters inside the Here Document with their values. Useful for last-minute customization of your Here Documents.

Consult the "Here Documents" section of the ksh(1) man page for details.

Customizing SMF Services With Instances and Properties

We may have more than one media server that we want to automatically trigger upon updating their files. This is where SMF service instances come in handy: They allow us to define the service once, then use multiple variations of it, distinguishing them through properties.

In our case, we'll specify two properties per instance:

  • The directory to watch,

  • The name of the process to start.

Here's the piece of code that will create and configure the necessary instances of our service. As an example, we'll use "mediatomb" and "mt-daapd" as our daemons and name the instances after them:

# We want to watch two media directories and restart two associated daemons.
INSTANCES="/export/zones/constant/root/export/home/constant/PowerBookHome/Music/iTunes:mt-daapd /krongi/stuff/media:mediatomb"

# Configure and enable all instances of the manifest
for instance in $INSTANCES; do
	directory=$(echo $instance | cut -d: -f1)
	daemon=$(echo $instance | cut -d: -f2)

	svccfg -s media-update add $daemon # Add a new service instance
	svccfg -s media-update:$daemon addpg script application # Add a new property group
	svccfg -s media-update:$daemon \
		"setprop script/directory = astring: $directory"
	svccfg -s media-update:$daemon \
		"setprop script/command = astring: \"/bin/pkill -HUP $daemon\""

	svcadm enable media-update:$daemon # Enable the new service instance.

Notice that the first example instance uses the full path to the loopback mounted media directory inside the zone "constant" (which is: "/export/zones/constant/root/export/home/constant/PowerBookHome/Music/iTunes") because that is the path that dtrace(1M) will see while rsync is updating the media files.

Of course you'll use different paths, just make sure you find the correct and full path to your media directory. It may take some tweaking until you get it right for zones.

One last thing before we finish this article: When de-installing your SMF service in a script, make sure you disable it first in synchronous mode by using the -s switch of svcadm disable. This will let the command wait until the service is really disabled, before proceeding with your script. Otherwise the service may still be (partially) there when you try to delete it, causing unnecessary errors or warnings:

# Disable and delete SMF services
for instance in $INSTANCES; do
	daemon=$(echo $instance | cut -d: -f2)
	svcadm disable -s media-update:$daemon
	svccfg delete media-update:$daemon
svccfg delete media-update


The whole script including comments etc. is available as a free, no-cost, complimentary, open-source and eco-responsible download for your hacking pleasure: Download the media_update script.


DTrace scripts can be easily embedded within SMF services. And both the service script and the service manifest can be embedded themselves inside shell scripts for easy, single-script-to-take-care-of administration.

Your Turn

What do you like most about SMF? What are your favorite SMF hacks? What services did you create SMF manifests for? Share your thoughts and experiences in the comments section below!

By Constantin Gonzalez , 2010-05-14, updated: 2017-10-03 in Home Server.

Related posts:



This is the blog of Constantin Gonzalez, a Solutions Architect at Amazon Web Services, with more than 25 years of IT experience.

The views expressed in this blog are my own and do not necessarily reflect the views of my current or previous employers.

Copyright © 2018 – Constantin Gonzalez – Some rights reserved.
This site uses Google Analytics, Alexa, Feedburner, Amazon Affiliate, Disqus and possibly other web tracking code. See Imprint for details and our information policy. By using this site you agree to not hold the author responsible for anything related to this site.

This page was built using Python, Jinja2, Bootstrap, Font Awesome, AWS Step Functions, and AWS Lambda. It is hosted on Amazon S3 and distributed through Amazon CloudFront.