24

11/10

Dynamic server wakeup and sleep

07:26 by skaven. Filed under: How-to

I’m running a FreeBSD server at home. Since I wanted to save some energy I decided to turn it off when all clients are diconnected and turn it on again when a client starts up. So here is how I did this.

I’ve got a Linksys WRT54GL running OpenWRT for DHCP, DNS and wireless access. OpenWRT uses dnsmasq for serving DHCP and DNS and therefore is capable of executing a custom program when giving a lease to a client computer.

You just need to edit the /etc/dnsmasq.conf and add a line like this:

dhcp-script=/bin/serverwakeup

The file /bin/serverwakeup is a simple shell script containing the following lines:

#!/bin/sh
sleep 10
hosts_up=`egrep -c 'edison|newton' /var/dhcp.leases` # change clients names

if [ $hosts_up -ge 1 ]; then
        wol xx:xx:xx:xx:xx:xx # put MAC address of your server here
fi

Since I wanted to start the server only if specific clients are started I decided to filter for the wanted clients before running the WOL functionality. I’m filtering this in the leases file of dnsmasq. The script will wait for 10 seconds after being invoked,so that dnsmasq got more than enough time to write the /etc/dhcp.leases. When you take a look at this file you will find all active leases including the corresponding hostnames. The clients I wanted are named ‘edison’ and ‘newton’. So the script looks for these names in the leases file and counts the number of occurences. When the count is greater or equal 1, the WOL command is invoked.

To shutdown the server after the last client disconnects I placed the follwing script on my server:

#!/bin/sh
scp root@popow /var/dhcp.leases /tmp/
hosts_up=`egrep -c 'edison|newton' /tmp/dhcp.leases` # change clients names
rm /tmp/dhcp.leases
if [ $hosts_up -lt 1 ]; then
        acpiconf -s 4
fi

This script does nearly the same as the script above.It checks the leases file on the OpenWRT router (named ‘popow’) and checks for the clients. If the value of leases fo these clients is less than 1 it invokes the supend command (acpiconf -s 4), which puts the server in S4 state (supend-to-disk).
This script needs to be invoked from time to time to check for the hosts. So I created a cronjob by adding the following lines to /etc/crontab.

#
# Suspend to disk when no other valuable host is online anymore
*/5     *       *       *       *       root    /usr/local/bin/suspender

Update:
I’ve slightly updated the suspender script to reduce the load on the router. The server doesn’t use the router resources to check the leases file anymore. Instead it gets the file from the router, checks it by itself and deletes it afterwards.

Two other things I’ve missed to mention:

  • You need to have the wol-Package installed on your WRT (opkg install wol).
  • You need to have the public SSH key of your server in the authorized_keys file of your router.