Green backups with BackupPC and WOL

In an effort to reduce power consumption, I’ve moved most systems I use regularly onto a pair of virtual servers, enabling me to keep many machines off most of the time, except for occasional use.  There are still a few physical machines, and I do prefer to have current backups of everything, so I decided to use the wake-on-LAN protocol, which seems to work for most modern computers hard-wired to ethernet (on the same segment.)

I started with this post by Salik Rafiq, but my first problem was that I didn’t want to turn every machine on, back it up, and then just leave it on.  Nor did I particularly want to turn every machine off after being backed up, since it’s not unusual for a machine to be backed up while I’m actually using it for something.  The obvious solution is to store whether or not a machine is actually on, then return it to that state afterward.

I made a few other changes, which I’ll briefly outline:

  • My BackupPC sends 5 arguments to ping, so I lazily hacked in arguments 3 and 4.  (There are much more elegant ways to do this.) so this script assumes that the last argument is the machine name.
  • I replaced “ethwake” with “wakeonlan,” for the sake of simplicity (not that etherwake doesn’t work, but since WOL packets require a hardware address anyway, why not just use the hardware address?)
  • Related to the above, I retrieve and store the hardware addresses for each machine using the simple command “arp -a machine > machine.wol” which gives me a file with the hardware address for each machine.
  • Note that I use the hardcoded directory “/usr/tools/wol” for both hardware and state information.  The $WOLDIR directory is used for hardware and state information.

As with Salik’s original script, this replaces the “ping” command for BackupPC, and is reasonable to use with every machine, whether or not it supports wake-on-lan.

#!/bin/bash

#this script is totally designed for the backuppc ping command
#which is the first thing it does before it starts a backup
#this is a substitute which pings the machine, if it is not
#awake then it wakes it using a magic packet - using the wol.bsh script
#then pings again to make sure

PING=/bin/ping
argnum=$(($#-1))
ARGS=${@:1:$argnum}
WAKEHOST="${!#}"
ETHWAKE=/usr/bin/wakeonlan
WOLDIR=/usr/tools/wol
SLEEPTIME=3m

logger "Backuppc pinging $ARGS $WAKEHOST"

function getwol {
	if [ -f $WOLDIR/$1.wol ]; then
	   hwaddr=$(cat $WOLDIR/$1.wol | cut -d" " -f4)
	else
	   logger "No MAC address for $1"
	   exit -1
	fi
}

function fwol {
        TO_WAKEUP=$1
	getwol $1
        sudo $ETHWAKE $hwaddr
}

$PING $ARGS $WAKEHOST >>/dev/null 2>&1

if [ $? -ne 0 ]; then
        fwol $WAKEHOST
        if [ "$WOL_RES" = "FAIL" ]; then
                exit 1
        fi
	echo "OFF" > $WOLDIR/$WAKEHOST.state
        sleep $SLEEPTIME
        $PING $ARGS $WAKEHOST
        if [ $? -eq 0 ]
        then
           logger "success waking $WAKEHOST."
        else
           logger "unable to wake $WAKEHOST."
           exit 1
        fi
else
   $PING $ARGS $WAKEHOST
   echo "ON" > $WOLDIR/$WAKEHOST.state
fi

exit 0

To turn the machines back on, I updated my postcmd.sh script (see this post for details) to look up the machine state, and if it was off before, turn it off now:

#!/bin/bash
WINEXE=/usr/bin/winexe
UNAME="Username"
PWD="Password"
WRKGRP="WORKGROUP"
BOX=$1
PID=$($WINEXE -U $UNAME -W $WRKGRP --password=$PWD //$BOX 'cmd /c echo '1'
> c:\backuppc\wake.up')
echo "Rsync and shadow copy unloaded"
if [ -f /usr/tools/wol/$BOX.state ]; then
   read wasoff < /usr/tools/wol/$BOX.state
   if [ "$wasoff" = "OFF" ]; then
      $WINEXE -U $UNAME --password=$PWD //$BOX 'shutdown -f -s -c "Backup
Complete"'
   fi
fi

Although it only recognizes “on” and “off” as valid machine states (it doesn’t detect nor return a system to hibernated, sleeping, etc. states) it at least takes care of the simple function of turning machines on, backing them up, then turning them back off.

For systems that don’t support wake-on-lan, like those connected through wireless, I’m considering using X10.

Share