In a recent post, we looked at how to create scheduled services in Oracle Solaris 11.3.  Today we’re going to discover how to interact with them.  SMF tracks certain information that applies only to scheduled services, such as the next time the service is scheduled to run.  It is easy to find this information using familiar tools.

Setup

I’ve created a very simple scheduled service that executes once a day.  To keep things simple, the start method is set to /usr/bin/true.

<?xml version=”1.0″ ?>
<!DOCTYPE service_bundle
  SYSTEM ‘/usr/share/lib/xml/dtd/service_bundle.dtd.1’>
<service_bundle type=”manifest” name=”example/scheduled”>
    <service version=”1″ type=”service” name=”example/scheduled”>
        <scheduled_method recover=”false”
            timeout_seconds=”0″
            interval=”day”
            exec=”/usr/bin/true”/>
        <instance enabled=”true” name=”default”/>
    </service>
</service_bundle>

Once the service is imported, we can start looking at it.

Basics

Let’s start with the most basic question: When is this service going to run next.  We’ve added a new column, nrun, to svcs(1) to display that information.

# svcs -o nrun example/scheduled
NRUN
23:02:56


As you can see, this service is going to run today at 23:02:56.  Recall that the service has an interval of ‘day’ and no constraints, meaning this time has been randomly generated.

Another interesting question is: When did this service last run?  There’s a new column for svcs(1) that shows that as well, lrun.

# svcs -o lrun example/scheduled
LRUN


The dash indicates that there hasn’t been a previous run.  That makes sense given that I only created this service today, so it hasn’t had time to execute yet.  So I’m going to do something Evil and advance time a bit just to get a number.

# date 2330.30
# svcs -o lrun example/scheduled
LRUN
23:02:56


Now that I’ve advanced time past the first scheduled execution time, you can see that the last run field has been populated with the last scheduled run time.  Of course, I advanced the clock so the service didn’t actually run at exactly that time because I compressed most of a day into a few microseconds  On a normal system in normal conditions where Evil operators aren’t mucking with clocks, the actual run time and the scheduled run time will match.

Let’s go look at nrun again…

# svcs -o nrun example/scheduled
NRUN
23:44:43


As you can see, there’s a new execution time.  Remember that only the next smallest unconstrainted time period is kept consistent, and everything else is randomized again.  In our example service, the interval is set to ‘day’.  So it runs in the same hour, 23 both times, but the minute and seconds fields are different.

There’s one more interesting question:  Is the method for my service actually running or not?  Periodic and scheduled services are always ‘online’ so long as their dependencies are met and are enabled, so just looking at the service state doesn’t tell you that much.  Predictably, there’s a new column for that.  It’s called ‘astate’ and corresponds to any auxiliary state a service might have.  Restarters are free to put whatever they want in that field.  The Periodic Restarter uses it to communicate if the method for the service is running or if it’s scheduled to run.

# svcs -o astate example/scheduled
ASTATE
scheduled


Since our service won’t run until 23:44:43, its auxiliarly state is ‘scheduled’ because it is scheduled to run at a later time.  Since our start method is ‘/usr/bin/true’, it’s going to be hard to actually catch the service in a running state.

# svcs -o astate example/scheduled
ASTATE
running


Those three columns represent the truly interesting information about scheduled and periodic services.  Of course, the standard information you’d expect from SMF services is still available as well.

Changing Your Mind

Scheduled services make changing the schedule as easy as reconfiguring anything in SMF.  All you have to do is create a new schedule and refresh the service.  From there, the periodic restarter will pick up the new schedule and recompute the next run time.  Let’s make our service run once a week, on Mondays.

# svccfg -s example/scheduled:default
svc:/example/scheduled:default> setprop scheduled/interval = week
svc:/example/scheduled:default> setprop scheduled/day = astring: Monday
svc:/example/scheduled:default> refresh
svc:/example/scheduled:default>
# svcs -o nrun example/scheduled
NRUN
Nov_09


As you can see, the new schedule is in place and instead of running at 23:44:43 it will run on Monday, November 9th, 2015.

A Wider Worldview

Looking at scheduled services one by one is interesting enough in its own right, but what if you want to look at all of them at once.  svcs(1) has supported the -R option to look at services delegated to a certain restarter for some time now.  Combining that with the new columns allows you to get a complete picture of the scheduled and periodic services installed on your system.

# svcs -o state,nrun,lrun,astate,fmri -R svc:/system/svc/periodic-restarter:default
STATE          NRUN     LRUN     ASTATE      FMRI
disabled       –        –        none        svc:/application/pkg/sysrepo-cache-compact:default
online         Nov_09   23:02:56 scheduled   svc:/example/scheduled:default