Restart OS X After UPS Shutdown

I've been asked a few times how to have an OS X machine start up automatically when power comes back after being shut down by a UPS on battery. Using built-in tools. Well, outside of some kind of third party tools, I never really had a good answer. Until now.

One of the great things about any technical gathering is the exchange of information. Sometimes, it just pays to re-read man pages after you've been using a utility app for a while.

During one of my chats while at Macworld, Nigel Kersten mentioned that it's useful to shut down a server 'dirty' so it will come back after a UPS shuts it down. "How the heck do you do that?" I asked. "shutdown -u", he said. Huh? Sure enough, a quick look at the man page revealed:

-u The system is halted up until the point of removing system power,
but waits before removing power for 5 minutes so that an external
UPS (uninterruptible power supply) can forcibly remove power.
This simulates a dirty shutdown to permit a later automatic power
on. OS X uses this mode automatically with supported UPSs in
emergency shutdowns.

Of course, OS X and OS X server support UPS systems out of the box. Plug one in, and you'll get a new UPS tab in Energy Saver that looks like this:

Es Ups Display

Figure 1: Energy Saver Preference Pane with a UPS connected via USB

You can even configure the characteristics of when to shut down, etc. Note that the man page for shutdown mentions that OS X uses this mode automatically. No mention of OS X Server. Believe it or not, OS X does shut down dirty, correctly, and OS X Server does not! But there's an easy fix.

The file that controls this, and is called when OS X is shutting down due to a UPS being on battery is /usr/libexec/upsshutdown. Like many things on OS X, it's just a shell script. Compare the OS X version with the version on OS X Server. You'll notice that includes the -u flag:

# Take the system down.
#
if [[ -n $1 && "WaitForUPS" == $1 ]] ; then
#
# Wait for UPS to take the system down abruptly and unexpectedly.
#
shutdown -hu now "${MSG}"
else
#
# Gently shutdown the system immediately.
#
shutdown -h now "${MSG}"
fi

Whereas OS Server does not:

${SI_PATH}/Apache/Apache stop
servermgrdctl stop


#
# Shutdown watchdog and its services.
#
${SI_PATH}/Watchdog/Watchdog stop

#
# Wait for watchdog and take the system down cleanly.
#
sleep 10
shutdown -h now "${MSG}"

(and, yes, this is even under OS 10.4.8 on both machines)

Of course, the simple fix is to edit this file on OS X Server and add the "-u" flag. I'm just still a little puzzled how this got added to OS X and not OS X Server. Of course, remember that any modification you make to a system file may get nuked when you run an update, so, if you do change this, remember to check it after any update (or, check the updater and find out ahead of time).

I've even customized this script to go 'properly' shut down other machines that I know are connected to the same UPS.

So, while I thought I knew the shutdown command, it pays to review, as Apple snuck this one in at some point. Hope passing this on help someone else!