Waking virtual machines up

From ComputeMode
Jump to: navigation, search

This page aims at explaining (non-exhaustively) how to emulate the Wake-On-Lan functions using virtual machines.

There is a lot of ways to do this, notably :

* you can write a high-level service that will listen to custom queries on the virtual network, this is really simple (let's use UDP broadcast messages)
* you can write a ethernet-level daemon that will listen to WOL queries on the virtual network, this is rather complex, but do not require changes in the ComputeMode appliances
* ...

Waking up through custom UDP packets

With VirtualBox

Here is a python script to run on the host system :

#!/usr/bin/env python

import re, shlex, socket, subprocess, sys

def vmnamebymac(mac):
    vmname = None
    cmd = "VBoxManage list -l vms"
    args = shlex.split(cmd)
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
    while True:
        line = proc.stdout.readline()
        if (not line):
            break
        namematches = re.match(r"^Name: *(.*)$", line)
        if (namematches != None):
            vmname = namematches.group(1)
        nicmatches = re.match(r"^NIC \d+: *MAC: "+mac+",.*$", line)
        if (nicmatches != None):
            return vmname
    return None

def vmstart(name):
    cmd = "VBoxManage startvm %s" % name
    args = shlex.split(cmd)
    subprocess.call(args)

def main(argv=None):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("172.28.255.255", 6666))
    while(True):
        data, addr = sock.recvfrom(1024)
        matches = re.match(r"ICANHAS (.*)\?", str(data))
        if (matches == None):
            continue
        vmname = vmnamebymac(re.sub(r":", "", matches.group(1)).upper())
        if (vmname != None):
            vmstart(vmname)

if __name__ == "__main__":
    sys.exit(main())

Then change the /etc/oar/wake_up_nodes.sh with the following to send a UDP request instead of WOL packet :

#!/bin/bash
# Sample script for energy saving (wake-up)

NODES=`cat`

for NODE in $NODES
do
    for prop in `/usr/bin/oarnodes --sql "network_address='$NODE'"|egrep "^properties"`; do
        res=`echo $prop|egrep "^mac_address"`
        if [ "$res" != "" ]; then
            MAC_ADDR=`/bin/echo $res|/bin/sed -e "s/mac_address=//"|sed -e "s/,//"`
        fi
    done

    if [ "$MAC_ADDR" != "" ]; then
        #/usr/bin/sudo /usr/sbin/etherwake $MAC_ADDR
        echo "ICANHAS $MAC_ADDR?"|nc -u -b -w 1 172.28.255.255 6666
    fi
done
exit 0

And restart the oar-server service.

Personal tools
Namespaces

Variants
Actions
user portal
developer portal
wiki stuff
Tools