HOW-TO:Set up Wake-on-LAN for Ubuntu: Difference between revisions

From Official Kodi Wiki
Jump to navigation Jump to search
>TheGremlyn
(Added pre-check to see if the system is already up and a note regarding hostname use and ping functionality.)
>TheGremlyn
(Added a section to the end with brief overview of real world use and including the script in .bashrc)
Line 220: Line 220:
     sys_exit()
     sys_exit()
</source>
</source>
Replace the sample MAC address[es] with the original ones. The "hostname" part doesn't have to be the actual hostname though, and could be any thing - it's mainly to substitute the hard-to-remember MAC address with something easier to type whilst running the script. Note that if you don't use the hostname, the ping will not work, but the Wake-On-LAN will.  
Replace the sample MAC address[es] with the original ones. The "hostname" part doesn't have to be the actual hostname though, and could be any thing - it's mainly to substitute the hard-to-remember MAC address with something easier to type whilst running the script. Note that if you don't use the hostname, the ping will not work, but the Wake-On-LAN will. If your hostname is long but you still want to use it for ping functionality, see [[#Finishing Touches]].


Don't forget to change the file-mode to 755:
Don't forget to change the file-mode to 755:
Line 229: Line 229:
  WOL request has been sent to htpc [00:24:7c:a2:e4:d0]
  WOL request has been sent to htpc [00:24:7c:a2:e4:d0]
If everything goes well as describe above, you should be seeing the machine in the other room is booting up.
If everything goes well as describe above, you should be seeing the machine in the other room is booting up.
=== Finishing Touches ===
<div id="Finishing Touches"></div>
With the script finished and working, you can make it even easier to run from the command line or other scripts. One way is to include it in your .bashrc file, found in your user's home directory. Pull it up in your preferred text editor:
<source lang="bash">vi /home/[user]/.bashrc</source>
* Note: does not require sudo; replace [user] with your username.
Scroll to the bottom of the file, and add one or more of the following lines, depending on what you need to do:
<source lang="bash">
# User Defined Aliases
alias htpcwol="wake-on-lan mylonghtpchostname-1"
alias htpcssh="wake-on-lan mylonghtpchostname-1; ssh user@mylonghtpchostname-1"
</source>
The first alias above merely wakes the host up remotely, the second wakes it up and then connects you via SSH. Aliases like this are a huge time saver if you use the command for remote access often.


[[Category:How-to|Wake]]
[[Category:How-to|Wake]]
[[Category:Linux]]
[[Category:Linux]]
[[Category:XBMC Live]]
[[Category:XBMC Live]]

Revision as of 20:22, 10 August 2012

If you are not one of the lucky ones with a built-in start-up controller (so that the remote can be used to start the computer) or if the computer is in the other room/floor, sometimes it's pretty annoying to go to the upstairs, for example, just to push a button. Wake-On-LAN is a network standard, which provides the ability to switch on remote computers through special network packets, called Magic Packet from sleeping, hibernating, or powered-off state. It only works with WOL compliant BIOS and NIC.

Before we start

First off, the motherboard should support the WOL (Wake On LAN) and it should be enabled in the BIOS. Different BIOS/motherboard do it differently; on ASUS (P5N7A-VM), it's under Power > APM Configuration and in there "Resume On PCIE Wake" and "Resume On LAN(MAC)" should be enabled.

Enabling WOL in the OS

Even though WOL works in network layer 2, OS support is still one of the important things to make it work. Even if you see the light on the Ethernet port is on after the halt/shutdown, the OS shuts off the Ethernet internally. One must tell Ethernet controller to WOL when boots up and tell "halt" script not to bring down controller during shut-down.

Install ethtool

I found "ethtool" is one of the easiest to use to enable WOL; install it first if it's not there yet.

sudo apt-get install ethtool

Set Wake-on-LAN options

Run the following command to enable it:

sudo ethtool -s eth0 wol g
  • Note: Not all devices support this.

This can be verified running ethtool on ethX (where X is the name/number of the Ethernet device).

sudo ethtool eth0

You should see something like this ("g" indicates Wake on MagicPacket is enabled):

Settings for eth0:
	Supported ports: [ MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Full 
	.....
        .....
	Auto-negotiation: on
	Supports Wake-on: g
	Wake-on: g
	Link detected: yes

Get it enabled at system start-up

Debian/Ubuntu uses Sys-V like init system for executing commands during the system bootup and shutdown time. If you wish to add a new service to start when the machine boots the script should be added to the directory /etc/init.d/ and then the "/etc/rc{runlevel}.d/" symlinks cause the script to be executed.

The init.d script

Create a file, say "wake-on-lan" in the "/etc/init.d/" (just copy & paste the entire code in the terminal)

sudo cat << EOF >> /etc/init.d/wake-on-lan
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: wake-on-lan
# Required-Start: \$network
# Required-Stop: \$local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Enable Wake-On-Lan 
### END INIT INFO
#
. /lib/lsb/init-functions

do_start() {
    ethtool -s eth0 wol g
    exit
} 

do_stop() {
    ethtool -s eth0 wol d
    exit
}

case "\$1" in
  start )
        do_start
        ;;
  restart|reload|force-reload )
        echo "Error: argument '\$1' not supported" >&2
        exit 3
        ;;
  stop )
        do_stop
        ;;
  * )
        echo "Usage: \$0 start|stop" >&2
        exit 3
        ;;
esac
EOF
sudo chmod 755 /etc/init.d/wake-on-lan

Automatic start-up at boot

Method 1: update-rc.d

sudo update-rc.d wake-on-lan defaults

This will add the appropriate [System-V style init script] symlinks to the wake-on-lan script so that it is sent the start and stop commands at the appropriate time.

Method 2: sysv-rc-conf

"sysv-rc-conf" is run-level configuration for Sys-V like init script links. From the man page: sysv-rc-conf gives an easy to use interface for managing "/etc/rc{runlevel}.d/" symlinks. sysv-rc-conf is not installed by default and needs to be installed first.

sudo apt-get install sysv-rc-conf

and when done, we enable the wake-on-lan service for runlevel 2,3,4 & 5, using --level option

sudo sysv-rc-conf --level 2345 wake-on-lan on

If everything goes well, you should see the WOL is enabled for the above run-levels.

xbmc@htpc:~$ sysv-rc-conf --list | grep wake
wake-on-lan  2:on	3:on	4:on	5:on

That's all, the machine is now ready to be waken-up by WOL magic packet.

Extra info

Wake-on-LAN is platform-independent; any application that sends "magic packets" can wake up computers from shutdown state (as long mains power is not off) regardless of OS it boots into afterward. There are a number of tools available for Windows in the net. I use this script to create a magic-packet from Linux. The "node_lst" section (at the top of the script) should be modified to reflect actual MAC address of the machine in question. Put the script in the "/usr/local/bin" and change the permission to 775, so that it can be called from any where without specifying the actual path.

The script: wake-on-lan

sudo vi /usr/local/bin/wake-on-lan

Use any editor you are comfortable with to use and then copy & paste the script below.

exec /usr/bin/python -x "$0" "$@"
# -*- coding: ISO-8859-15 -*-
#
# wake-on-lan
# $Id: wake-on-lan.cin,v 1.4 2011/10/25 22:46:40 das Exp $
# S. Das, London

## --- Local nodes -------------------------- ##
## Modify this to put your own hostname/MAC 
## address pair here. The format is:
## "abc xx:xx:xx:xx:xx:xx", where "abc" could
## be any name you like and the "xx:xx..." is
## the MAC address of the machine the magic
## packet is going to be sent. 
  
node_lst = [
	'pcbk 00:18:8b:c9:29:73',
	'htpc 00:24:7c:a2:e4:d0'
]

## --- don't change anything below --------- ##

from time import sleep
import sys,re,commands
import struct,socket,time

retval = 0

X = '([a-zA-Z0-9]{2}[:|\-|.]?){5}[a-zA-Z0-9]{2}$'
S = re.compile(r'\s+')

mmap = {}

## First argument 'None' in str.translate is new in 2.6. 
## Previously, it was a string of 256 characters 
if sys.version_info < (2, 6):
    f1_arg = ''.join(chr(i) for i in xrange(256))
else:
    f1_arg = None

## broadcast address
sysOS = "uname -s"
BSD = "ifconfig | grep -w broadcast | cut -d\  -f 6"
LNX = "ip -o addr show | grep -w inet | grep -e eth | cut -d\  -f 9"
#
if commands.getoutput(sysOS) == "Linux":
    bCast = commands.getoutput(LNX)
elif commands.getoutput(sysOS) == "Darwin":
    bCast = commands.getoutput(BSD)
else:
    print "System not supported!!"
    sys_exit()

def WakeOnLan(mac_address):
    
    ## Building the Wake-On-LAN "Magic Packet"...
    ## Pad the synchronization stream.
    data = "".join(['FFFFFFFFFFFF', mac_address * 20])
    msg = ""

    ## Split up the hex values and pack.
    for i in range(0, len(data), 2):
        msg = "".join([msg, struct.pack('B', int(data[i: i + 2], 16))])

    #print "DaTa: %s\nMsG: %s\n" % (data,msg) 
    
    ## ...and send it to the broadcast address using UDP
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    s.sendto(msg, (bCast, 9))
    s.close()

def sys_exit():
    sys.stdout.flush()
    sys.exit(1)

## check if hostname is provided
if len(sys.argv) != 2:
    print "Usage: %s <hostname>" % sys.argv[0]
    sys_exit()

for i in node_lst:
    # strip off everything from first "#" found
    i = i.split('#',1)[0]
    if not re.search(X, i):
	continue

    h = S.split(i,1)[0]			## host name
    m = S.split(i,1)[-1]		## MAC address
    mmap[h] = m.strip('\t|" "')
 
## A count up timer with a msg
def timer(m,x):
    for i in range(1,x):
	sys.stdout.write('\r%s\b%d' % (m,i))
	sys.stdout.flush()
	sleep(1)
	sys.stdout.write('\r  \b') 

for j, k in mmap.iteritems():
    if sys.argv[1] == j:
        if not re.search(X.replace('zA-Z','fA-F'), k):
            print "Invalid MAC address [",k,"]; nothing to do!!"
            sys_exit()
        else:
            c,t = commands.getstatusoutput('ping -c 2 %s' % j)
            if c != 0:
                WakeOnLan(k.translate(f1_arg,':.-'))
                print "WOL request has been sent to %s [%s]" % (j,k)
                timer('Waiting for %s wake up..... ' % j, 10)
                c,t = commands.getstatusoutput('ping -c 2 %s' % j)

                if c == 0:
                    print "%s is up and running........\n" % j
                else: print "The host: %s is not running yet, try again!!\n" % j
            else: print "%s is up and running........\n" % j
            break
else:
    print "Host [%s] doesn't exist!!" % sys.argv[1]
    sys_exit()

Replace the sample MAC address[es] with the original ones. The "hostname" part doesn't have to be the actual hostname though, and could be any thing - it's mainly to substitute the hard-to-remember MAC address with something easier to type whilst running the script. Note that if you don't use the hostname, the ping will not work, but the Wake-On-LAN will. If your hostname is long but you still want to use it for ping functionality, see #Finishing Touches.

Don't forget to change the file-mode to 755:

  • Note: This script works on Mac OS X too.
sudo chmod 755 /usr/local/bin/wake-on-lan

Run the script like this: wake-on-lan <hostname>; and the output should be something like this:

[admin@b_server WOL]$ wake-on-lan htpc
WOL request has been sent to htpc [00:24:7c:a2:e4:d0]

If everything goes well as describe above, you should be seeing the machine in the other room is booting up.

Finishing Touches

With the script finished and working, you can make it even easier to run from the command line or other scripts. One way is to include it in your .bashrc file, found in your user's home directory. Pull it up in your preferred text editor:

vi /home/[user]/.bashrc
  • Note: does not require sudo; replace [user] with your username.

Scroll to the bottom of the file, and add one or more of the following lines, depending on what you need to do:

# User Defined Aliases
alias htpcwol="wake-on-lan mylonghtpchostname-1"
alias htpcssh="wake-on-lan mylonghtpchostname-1; ssh user@mylonghtpchostname-1"

The first alias above merely wakes the host up remotely, the second wakes it up and then connects you via SSH. Aliases like this are a huge time saver if you use the command for remote access often.