[mythtv-users] using a second BE to wakeup the main BE?

Andrew Wilson migmog at gmail.com
Thu Nov 30 12:50:51 UTC 2006


I played with nvram wakeup on my backend, but never got it working, so
I took a different approach, much like what you want to do.I have a
Maxtor Shared Storage on 24/7 which is doing the same job as your
toshin.

Below are my scripts which do it. They are not pretty or optimal in
any way, and they contain bugs, but they do work for me. Maybe you
could adapt them for your own purposes.

Note that the wakeupd script is written in a horribly restricted shell.

Brief instructions:
- mount some filesystem from the 24/7 box on the backend. Mine is
mounted as /o, and natively on the NAS as /opt
- configure the backend to execute a script when it needs to wake up again:
  In the database there are two parameters required:
WakeupTimeFormat: set to 'time_t'
SetWakeupTimeCommand: set to '/path/to/set_alarm_clock.sh $time'

The set_alarm_clock.sh writes a file of two lines: the MAC addr of the
box wanting woken up, and a timestamp for when it needs to be woken.

- a script 'wakeupd' on the 24/7 box waking every few secs and
monitoring the shared file. Mine is a daemon 'wakeupd', but it could
be a cron job. A better approach would be to use netstat.

Hope this helps
Andrew

--- set_alarm_clock.sh ---
#!/bin/sh
FILE=/o/WAKEUP/`hostname`
MAC=$(ifconfig -a | grep HWaddr | awk ' { print $5 } ')

# We might have been invoked a la nvram-wakeup
# Intercept the -s, in fact, just take the last arg.
if [ $# == 0 ] ; then
  echo "Usage: $0 <time_t>"
  exit 1
fi


while [ $# != 1 ] ; do shift ; done
WAKETIME=$1
SECS_FROM_NOW=$( expr $WAKETIME - $(date +%s) )
PRINT_DATE=$( date -d "now + $SECS_FROM_NOW seconds" )
echo "`date`: Setting alarm: Wake at $PRINT_DATE" >>
/var/log/mythtv/alarmclock.log
echo $WAKETIME > $FILE
echo $MAC >> $FILE

--- wakeupd ---
#!/opt/bin/ash
# Daemon to wake up hosts.
# To set an alarm clock, the host must write a file containing
# a timestamp in date +%s format (see man date) on the 1st line,
# and its MAC address on the second line. The file must be named
# its hostname
#
# Written to wake up a single host, should not be too hard to
# extend to multiple hosts.
#
# Some shell constructs don't work in this restricted shell
#
# andrew__dont__ at __spam__me__migmog.com

if [ $# -lt 2 ]; then
  # Todo - figure out how to look up ipaddr.
  # Todo - Supply list of hosts instead of single
  echo "Usage: $0 <host> <ip>"
  exit 1
fi
HOST=$1

HOST_IP=$2
LOG=/opt/WAKEUP/debug.log
#LOG=/dev/null

GIVEUPTIMING=600

log() {
  echo "$( date +%D-%R:%S ) $1" >>$LOG
}

# Only has to check if someone has gone to sleep. Will wake up hosts
# bang on time. Host won't go to sleep if it wants woken up again soon
# so we can wait a couple of minutes between pings and still be OK.
# While waking up, we can ping every second and time how long it takes
# for the host to go from 'wake sent' to 'answering pings' which is a
# useful tool for boot time optimisation work.
TIMEOUT=10
REMOTE_ASLEEP=0
WAS_REMOTE_ASLEEP=0
# Time in time_t host wants to wake up at
WAKEUPTIME=0
STOPWATCH=0

export LD_LIBRARY_PATH=/opt/lib:/lib
export PATH=/opt/bin:/bin
touch $LOG


log "Started $0: $* "
cd /opt/WAKEUP
while [ 1 ]
do
  WAS_REMOTE_ASLEEP=$REMOTE_ASLEEP
  ping -c 1 $HOST_IP > /dev/null
  REMOTE_ASLEEP=$?

  if [ "$WAS_REMOTE_ASLEEP" -eq 2 ] ; then
    STATUS="awake"
    if [ "$REMOTE_ASLEEP" -eq 1 ] ; then
      STATUS="asleep"
      WAS_REMOTE_ASLEEP=3
    fi
  fi

  NOW=`date +%s`

  # Has the host gone up or down?
  if [ "$REMOTE_ASLEEP" != "$WAS_REMOTE_ASLEEP" ] ; then
    if [ "$REMOTE_ASLEEP" -eq "1" ] ; then
      # Check for a wakeup directive...
      log "$HOST has gone to sleep"
      # Did host set the alarm clock before going to sleep?
      if [ -f /opt/WAKEUP/$HOST ] ; then
        # if the MSS had a full sed then we could do this
        # WAKEUPTIME=`sed -n 'p1' $HOST`
        # MAC=`sed -n 'p2' $HOST`
        WAKEUPTIME=`cat /opt/WAKEUP/$HOST | head -n 1`
        MAC=`cat /opt/WAKEUP/$HOST | head -n 2 | tail -n 1`
        SECS_FROM_NOW=$(( $WAKEUPTIME - $(date +%s) ))
        MINS_FROM_NOW=$(( $SECS_FROM_NOW / 60 ))
        # MSS 'date' command is not fully featured, doesn't understand this:
        # PRINT_DATE=$(( date -d "now + $SECS_FROM_NOW seconds" ))
        #log "Wake $HOST on $MAC in $SECS_FROM_NOW seconds..."
        log "Wake $HOST on $MAC in $MINS_FROM_NOW minutes..."
        cp $HOST $HOST.found
        ALARM_SET=1
      else
        log "$HOST has not set the alarm clock."
        ALARM_SET=0
      fi
    else
      # Host woken up by this script.
      if [ -f /opt/WAKEUP/$HOST.woken ] ; then
        BOOTTIME=$(( $NOW - $WAKEUPTIME ))
        log "$0 woke $HOST, she took $BOOTTIME seconds to come up."
        rm /opt/WAKEUP/$HOST.woken
      # Was host was woken by the 'wake' command
      elif [ -f /opt/WAKEUP/$HOST.wake ]; then
        WAKEUPTIME=`cat /opt/WAKEUP/$HOST.wake | head -n 1`
        BOOTTIME=$(( $NOW - $WAKEUPTIME ))
        log "Someone else woke $HOST, she took $BOOTTIME seconds to come up."
        rm /opt/WAKEUP/$HOST.wake
      else
        if [ "$WAS_REMOTE_ASLEEP" -lt 2 ] ; then
          log "$HOST has woken up, but I did not kiss her...?"
        fi
      fi
      STOPWATCH=0
    fi
  fi


  if [ "$ALARM_SET" = "1" ] ; then
    if [ $NOW -gt $WAKEUPTIME ] ; then
      log "Waking up $HOST..."
      wakelan -m $MAC
      mv $HOST.found $HOST.woken
      ALARM_SET=0
      STOPWATCH=$NOW
    fi
  fi

  if [ $STOPWATCH -eq 0 ] ; then
    #log "Sleeping."
    sleep $TIMEOUT
  else
    # Stop pinging the network if we're over this threshold
    if [ $(( $NOW - $STOPWATCH )) -gt $GIVEUPTIMING ] ; then
      log "$HOST did not wake up within $GIVEUPTIMING seconds."
      STOPWATCH=0
    fi
    sleep 1
  fi

#log "loop"
done
log "quit"


More information about the mythtv-users mailing list