Saving power on Ubuntu Server

I’ve been meaning to look into this for a while. My Ubuntu server acts as a NAS drive. As such it’s on all the time, but really it needn’t be. So let’s look at what we can do to save some energy by “hibernating” late in the evening and restarting early in the morning…

Let’s start with the /usr/sbin/rtcwake command. This application will tell your Linux OS to go into a sleep/hibernate state and you supply it with a time to wake back up, for example

/usr/sbin/rtcwake -m off 

The -m switch specifies the type of suspend. Options include

  • standby this option is the least energy efficient option and is the default option if you do not set the -m switch, it’s also very fast at resuming a system from sleep.
  • mem this option suspends to RAM, this puts everything into a low powered state (except RAM) and offers significant savings in energy.
  • disk this option suspends disk operations, the contents of memory are written to disk then restored when the computer wakes up.
  • off this option turns the computer off completely
  • no this option allows you to specify the awake time but doesn’t suspect the computer. The idea is that the user would put the machine into hibernation
    and rtcwake would then wake it up again at the specified point in time.

We might wish to set the resume time using either seconds (i.e. how many seconds in the future does the system resume) using the -s options, for example to wake up 10 hours after going to sleep we would specify 36000 seconds, like this

/usr/sbin/rtcwake -m off -s 36000

or to specify a time we use the -t switch which requires the number of seconds since Unix epoch (i.e. Jan 1st 1970, 00:00:00) so we still need to calculate to seconds

/usr/sbin/rtcwake -m off -t $(date +%s -d ‘tomorrow 07:00’)

If your hardware clock is set to local time, you’ll want to use the -l switch, for example

/usr/sbin/rtcwake -m off -l -t $(date +%s -d ‘tomorrow 07:00’)

Below is a script taken from StackOverflow. Just save this script as wakeup.sh or whatever file name and chmod to executable.

#!/bin/sh

# unix time in s that we should wake at
waketime=$(date +%s -d '07:00')

# make sure the time we got is in the future
if [ $(date +%s) -gt $waketime ]; then

        # if not add a day 60s * 60s * 24h
        waketime=$(($waketime + 86400))
fi

# time in S from now till then
dif=$(($waketime - $(date +%s)))

# tell the user
echo
echo "Current Time      :  $(date +%s)"
echo "Wake Time         :  $waketime"
echo "Seconds From Now  :  $dif"
echo
echo "Ctrl-C to Cancel in 5s"
echo
sleep 5

# sleep with rtcwake
/usr/sbin/rtcwake -m off -l -s $dif

echo "Shutdown."#!/bin/sh

But wait, we can run this rtcwake command (or the above script) manually but for my scenario I’d really want want it run automatically. So we add a cronjob as sudo (as rtcwake will need to be run as sudo) i.e.

sudo crontab -e

Now add the following

0 0 * * * /home/putridparrot/wakeup.sh > /home/putridparrot/wakeup.log

As per crontab expectations the arguments are as follows

  • MIN: Minute 0-60
  • HOUR: Hour, 24 hour clock hence 0-23
  • MDAY: Day of the Month, 1-31
  • MON: Month, 1-12 or jan, feb…dec
  • DOW: Day of the week, 0-6 or sun, mon, tue…sat
  • COMMAND: The command to run

So with this knowledge, our script will run at 12:00am every day. I found it useful to create a log of the output of the script, just to ensure I could see it had run. Remember > will create a new file overwriting any existing file or you could use >> to append to an existing file if you prefer (but then you might want a cronjob to delete the file periodically).

You can also check the syslog for CRON jobs via

grep CRON /var/log/syslog