Last week, we looked at how essential scripting is for administering home servers (one of the 7 tips for home server bliss) and we wrote us a little script for enabling automatic snapshots.
Another thing that you’ll almost certainly want to do on your OpenSolaris home server is enabling power management. This will ensure your server spends as little power as possible when idle, while still being powerful when needed.
There’s a whole community group devoted to power management (no link, opensolaris.org no longer exists) and it’s a good idea to check out their FAQ (no link, opensolaris.org no longer exists) and check in on their discussions (no link, opensolaris.org no longer exists).
How To Configure Power Management in OpenSolaris
To enable power management on OpenSolaris, we need to do two things:
Enable CPU power management: This will tell the system to switch the CPU into a lower power mode when idle.
Enable disk power management: This tells the disks to switch to a lower power mode when there’s no activity for a specified amount of time.
Both can be configured by editing the
power.conf(4) (no link, sun.com no longer exists) file and then calling
pmconfig(1M) (no link, sun.com no longer exists) to make the changes go live.
Let’s write ourselves a script that does all of the configuration automatically, so we just need to call it and all of the system will be optimized for lower power consumption:
Manipulating the power.conf File
We’ll assume full control of the relevant settings in power.conf. Whatever was written there before, after we’re done with it, power management will be enabled. Likewise, if we decide to shut off power management, all settings that concern CPU and disk power management will be gone.
This makes our script more simple: We can create a function that rips off any CPU and disk PM settings, then either write back the result (to disable PM) or attach our own settings (to enable it).
(CPU PM is enabled by default on a fresh install of OpenSolaris 2009.06, but it’s good to not make that assumption in case someone did change
power.conf after all or when switching PM back on after having switched it explicitly off.)
Here’s the piece of code that produces a “clean” version of power.conf, without any CPU or disk power management options:
1 2 3 4 5 6 7
It makes sense to put it into its own function, as we’ll use it for both setting up and tearing down power management.
The Proper Use Of Temporary Files
We’ll use a temporary file to construct our new version of
power.conf for two reasons:
We can exchange the old version with a new one by using
pfexec mvand don’t need to run the whole script with full privileges (which would be needed to make any
We’ll learn how to properly use temporary files in shell scripts.
In fact, Chris Gerhard recently wrote a blog post about how to properly set up temporary files so they clean up after themselves automatically. This is such a good practice that I want to emphasize it here by making it part of our power management script.
So here’s the piece to clean up any CPU and disk power settings from power.conf and make the settings live:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Taking Care Of Ownership And Permissions
But wait! Since we’re exchanging the system’s
power.conf with one of our own, we need to make sure to set the file owners and permissions properly after the exchange. This is a job for another function:
1 2 3 4 5
Of course we’ll need to call this in the function above after the
pfexec mv bit.
Detecting the Disks in the System
Now comes the tricky part: Each disk in the system needs its own entry with its device path in
power.conf. But what’s the best way to detect how many disks there are in the system and what their device paths are?
It turns out that
format(1M) (no link, sun.com no longer exists) is our friend, because the first thing it does after starting it is to present us with a list of all disks, and their device paths.
Very well, but there’s one caveat:
format expects us to use it interactively, but we want to use it in a script. If we called format inside our script, it would wait for the user to navigate its menus by listening on
STDIN, which we really don’t want!
After some tweaking, I found out that you can send an empty input stream into
echo, then it will automatically terminate itself after giving us its list of drives. The reason for this is most probably the
STDIN will return to
format after the (empty) input has been processed and thus,
format will have no option but to terminate.
Here’s the line that gives us all of the disks in the system:
grep to filter out just the lines with the device paths.
Putting it All Together
Now that we have all the pieces, let’s put together our power management configuration script. We’ll abstract away all
pfexec commands and the
power.conf file itself into a block of constants at the beginning to make the code slightly cleaner:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
I hear the following question quite often: “How can I set up power management on my server?”. Now we have a script that does exactly that. We also learned a bit about the handling of temporary files and found a trick for getting a list of all of the disks that are available in the system.
You can tweak the script to your needs of course. Maybe you want to change the times after which CPU or disk PM kicks in. Or maybe you want to preserve the original
power.conf file just in case before meddling with it. Or maybe you don’t want to power manage all of the disks in your system but only some. Feel free to enhance the script and contribute your changes in the comments section of this post.
You can easily observe the effects of CPU power management with the
powertop(1M) (no link, opensolaris.org no longer exists) utility.
Observing the effects of disk power management is trickier: The setting is just forwarded to the disk and it’s up to the drive to decide what to do after the idle time is up. Some disks will spin down, some merely spin slower and some won’t do anything at all. Using a watt-meter and some patience may be the only way to find out what really happens.
Also, it may be difficult to achieve the idle state for your boot drives due to different system activities writing to log files etc. This is why separating data pools from the root pool is a good idea. Some even separate
/var into a USB stick or other solid state media because of this.
What’s your experience with OpenSolaris power management? Do you have ideas on how to improve this script? Have you measured the effects of disk power management on your server or did you find a way to programmatically verify that it works? Share your views in the comments section below!
Getting More Out of This Blog
Update: Gregor suggested in the comments to use
mktemp with it’s path as the GNU and the Solaris version differ slightly. He also suggested to use
basename to strip the script name when generating the temporary file. I just added the mods to the above code sample. Thanks!
Update (18/03/2010): My personal scripting role-model Chris pointed out in his latest blog post “Don’t keep opening those files” that writing to a file in a loop over and over again incurs the overhead of opening and closing the destination file multiple times which is not optimal from a performance point of view.
Here’s an alternative version of the part that creates the disk entries for
power.conf and avoids the loop altogether, opening the destination file just one time:
1 2 3 4 5 6
This should scale ok for arbitrary numbers of disks, say in an X4540 or better.