Contribute  :  Advanced Search  :  Directory  :  Forum  :  FAQ's  :  My Downloads  :  Links  :  Polls  
AFP548 Changing the world one server at a time.
Welcome to AFP548
Thursday, July 29 2010 @ 09:33 am MDT
   

Make Your Own Startup Items

ArticlesLearning to roll your own startup items can be handy.

Have you ever needed an extra service like a mail scanner or FileMaker Pro Server to start on automaticly on your Mac OS X Server? Or did you know that you can use custom startup items on your workstations to help combat Apple's obsession with fast boot times that sometimes messes with your enterprise integration?

Read on to learn about this essential tool in your sysadmin toolbox...

Getting Started...

Making custom startup items on Mac OS X is easy to do. Joel wrote an article about this long ago for 10.2 and you can take a look at Joel's old article here, but I'm going to update it some for 10.3 and give a few more specific reasons to use a startup item in this article.

Apple has created the SystemStarter mechanism to solve the problems that have dogged the traditional UNIX startup scripts over the years. Rather than use a fairly static set of scripted startup items, Mac OS X systems can dynamically load startup items in the fastest order possible based on dependancies and startup order preferences. Multiple items can launch at once, and items might not even be launched at all if they are not needed or if they can't find the needed services. For example the mail services won't even bother trying to startup if the network never comes up. If they do come up they will wait for the network to come ready first.

All of this means that 10.3 computers can start very fast. Sometimes they startup too fast...

Case Study

The other day we setup a Mac OS X Server. This Xserve is an OD master that supplies user info and home folders to a group of six G5 workstations. We setup the server and a test user to get the home folders working with. Everything seemed fine, and then the bottom dropped out...

The network home folders would not survive a reboot. Once the Mac was setup in Directory Access you could logout and back in as a network user just fine. If you rebooted though the user would login and get the dreaded "Your home folder can not be found at this time..." error. If we cleared Directory Access and set it up again the homes came back until the Mac rebooted. Strange, no?

We discovered that restarting DirectoryService with a killall DirectoryService made the homes mount up just fine. What was happening is that DirectoryService was getting ahead of the home folder mount. If only there were a way to restart DirectoryService before the login window appeared to make sure that the system was primed and ready to go.

(FWIW, this sort of fix will probably only work on 10.3 since it has the fancy-pants dynamic automounting.)

Inside a Startup Item

If you take a look in /System/Library/StartupItems you will see a long list of directories. Take a look in the DirectoryServices folder. Inside you see three items, a script with the same name as the enclosing folder, a StartupParameters.plist file, and another directory named Resources. Briefly, here is what each of them do:

  • The Resources directory typically contains the alternate languages needed for display in the SystemStarter window at boot time. It can also contain any other scripts that you want your item to run.

  • The StartupParameters.plist is a standard XML plist file. It contains a few keys that tell the system what service -if any- the item provides, what services -if any- the item requires, and what services -if any- the item uses. The big difference between the 'uses' and 'requires' keys is that the 'uses' one is a non-binding request for SystemStarter to follow. In other words it would be nice if the services listed in 'uses' were running, but if not, go ahead an attempt to start the item. The 'requires' key items are ones that must be running for this item to start.

    You can edit this file with any editor you like, but it's easist with Apple's Property List Editor.

  • Finally, the script itself. In general Apple wants you to follow a template that they provide in the developer docs...

    #!/bin/sh

    . /etc/rc.common

    StartService()
    {
    your start code
    }

    StopService()
    {
    your stop code
    }

    RestartService()
    {
    your restart code
    }

    RunService "$1"


    Technicaly Apple says that all three routines need to be in there and that you can just leave the unused ones empty or put a return 0; in them. For really simple things, like my killall DirectoryService item, though I just put whatever script I need in there and leave the start, stop, restart routines out all together. Is it by the book that way? No, but I find it works for what I need.

  • You can find all sorts of detail in Apple's boot docs. Go ahead, click the link and read the pages then come back. I'll wait... There, now don't you feel smarter already?

    Now back to our story...

    Since the NFS startup item does the Mac OS X automounts, you might think that you could just change the 'Requires' key in the DirectoryServices startup item to need the NFS services. This would work except that the NFS already requires the DirectoryServices item. (DirectoryServices by the way isn't actually started by it's startup script. mach_init loads DS as needed, the startup item just returns a valid startup message so that other items know that it is running.) What we really need to do here is restart DS after the NFS item is up and running so that the automount can get picked up.

    I created a directory at /Library/StartupItems/SlowDown to be the home for my startup item. Then I cheated and copied the plist and script from another startup item into the new directory. This way all I need to do is edit them to make them match what I want to do. I ended up with a script that looks like this:

    #!/bin/sh

    . /etc/rc.common

    ConsoleMessage "Restarting DS in 5"
    /bin/sleep 1
    ConsoleMessage "Restarting DS in 4"
    /bin/sleep 1
    ConsoleMessage "Restarting DS in 3"
    /bin/sleep 1
    ConsoleMessage "Restarting DS in 2"
    /bin/sleep 1
    ConsoleMessage "Restarting DS in 1"
    /bin/sleep 1

    /usr/bin/killall DirectoryService

    exit 0


    I like to use the countdown for two reasons. One it gives us a bit of extra time for the system to settle down a bit before we start whacking DS. Two, it lets the users know that something is going on.

    Then I made my StartupParameters.plist file and ended up with an item that depends on Network, System Log, and NFS to start. I would show it to you, but GeekLog doesn't like letting me enter the raw XML. You can just read it when you download the zip file. :)

    I didn't bother putting a Resources directory in the item as I didn't need it. You can put one in there if you like and use or ignore it as needed.

    Next I made sure that the script was executable and gave it a dry run with a sudo SystemStarter -n -D. This command will run through the entire SystemStarter sequence without actually starting anything. It will show you the dependancies and the process that the system uses to determine the order to execute startup items. In this case my item seems to run last, perfect.

    Give it a go!

    We dropped the item into the /Library/StartupItems folder on a problem Mac and rebooted. The network home was there and ready once the Mac came up. At this point now we can distribute it to the other Macs with ARD or ssh and put it onto our base image. (Yes, you read that right. We do install images for as few as six Macs. It still saves hours and hours and hours over the course of supporting and installing new systems.)

    (I'm not claiming that this is going to fix every home folder issue that is out there, it was created for a specific need, but it might help you out.)

    Wrapping up...

    All said and done, custom startup items can help you do lots of things, from starting custom processes to fixing boot issues. I use two on my main Mac OS X Server, one to start the FileMaker Server and another to start my amvasid/clamav/spamassassin combo.

    As always, read the docs and check out Joel's older startup item article as well. You can download the SlowDown startup item from our servers and take a look at how it is put together.

    You can find the SystemStarter man page here.

    Have fun!

    Story Options

    Advertising

    Make Your Own Startup Items | 5 comments | Create New Account
    The following comments are owned by whomever posted them. This site is not responsible for what they say.
    Make Your Own Startup Items
    Authored by: Anonymous on Tuesday, October 19 2004 @ 06:58 pm MDT
    Good article. I might simplify that countdown loop a bit with a loop like this.


    for f in 5 4 3 2 1; do
    ConsoleMessage "Restarting DS in $f"
    sleep 1
    done
    Make Your Own Startup Items
    Authored by: Anonymous on Wednesday, November 24 2004 @ 10:09 pm MST
    I think it would also be useful to know how to execute the start/stop/restart
    the service from the CLI.
    sudo SystemStarter Start NameOfYourStartupItem
    sudo SystemStarter Stop NameOfYourStartupItem
    sudo SystemStarter Restart NameOfYourStartupItem
    Make Your Own Startup Items / SlowDown-Script
    Authored by: Anonymous on Wednesday, March 02 2005 @ 05:43 am MST
    Hi,

    we had the same problem on our network, that network-based Homedirectories would not mount properly at startup.
    So i tried the SlowDown script provided here. Everything looked good so far.
    But the SlowDown-script would not work properly on G5 machines.
    A Message popped up every time saying that an error occured and login is not possible. It seems that DirecoryServices would not come up quick enough again after the kill was forced.

    So i modified the Startup-parameters of the SlowDown-script to provide the name "SlowDown" and also modified th Startup-Parameters of Loginwindow to require "SlowDown".
    Now Loginwindow waits till the SlowDown-script has finished and DirectoryServices is up again and everything woks fine now.

    here the modifications i made to the files:

    ---
    SlowDown script:
    ---
    #!/bin/sh

    . /etc/rc.common

    ConsoleMessage "Vorbereitung der Homelaufwerke ...5"
    /bin/sleep 1
    ConsoleMessage "Vorbereitung der Homelaufwerke ...4"
    /bin/sleep 1
    ConsoleMessage "Vorbereitung der Homelaufwerke ...3"
    /bin/sleep 1
    ConsoleMessage "Vorbereitung der Homelaufwerke ...2"
    /bin/sleep 1
    ConsoleMessage "Vorbereitung der Homelaufwerke ...1"
    /bin/sleep 1

    /usr/bin/killall DirectoryService
    ConsoleMessage "Vorbereitung der Homelaufwerke abgeschlossen"
    /usr/sbin/DirectoryService
    /bin/sleep 2

    exit 0
    ---

    i don't know if the call for /usr/sbin/DirectoryService is needed at all...

    ---
    SlowDown StartupParameters.plist:
    ---
    {
    Description = "HomeDirectories";
    Provides = ("SlowDown");
    Requires = ("Network", "System Log", "NFS");
    OrderPreference = "None";
    }
    ---

    Loginwindow StartupParameters.plist:
    ---
    {
    Description = "login window";
    Provides = ("Multiuser Login Prompt");
    Requires = ("Disks", "SecurityServer", "SlowDown",
    "DirectoryServices");
    Uses = ("Core Graphics");
    OrderPreference = "Early";
    }
    ---

    Greetings,

    J. W.