5

I'm doing virtualization with KVM and managing it via the Libvirt daemon.

How do I configure Libvirt or KVM to listen for Wake-On-Lan packets sent the the Virtual Machine's NIC's MAC address and to start the Virtual Machine when such a packet is received?

Azendale
  • 1,505
  • 2
  • 11
  • 14
user130356
  • 260
  • 3
  • 9

3 Answers3

4

I've found Libvirt-wakeonlan which seems to do it. I have no idea how mature it is and how well it works. The approach seems right. https://github.com/simoncadman/libvirt-wakeonlan

user130356
  • 260
  • 3
  • 9
  • 1
    From the author when asked about maturity: It's not particularly mature, it lacks things like logging, and has only really been properly tested under Gentoo Linux. I've been using it for a development environment for about 9 months and it's been completely stable so far, but as far as I know nobody has used in a production environment. – user130356 Feb 02 '13 at 22:41
  • 1
    I made this: https://gitlab.com/-/snippets/2183494 – Gotschi Oct 01 '21 at 13:05
3

you can use my script which essentialy does the same as libvirt-wakeonlan, I made it because I could not get libvirt-wakeonlan to work... this is just a simple script which you can put in a startup script and have it running on boot.

It listens to udp port 9 (port 7 is also used sometimes afaik but guacamole - the remote vnc/rdp I use - sends at port 9) and checks the MAC adress when it sees a magic packet. If there is a vm in virsh with this MAC adress it will wake the machine up.

https://gitlab.com/-/snippets/2183494

#!/bin/bash

nc -dknl -p 9 -u | # listen to udp port 9 for packets, check if it is a magic packet
 stdbuf -o0 xxd -c 6 -p |
 stdbuf -o0 uniq |
 stdbuf -o0 grep -v 'ffffffffffff' |
 while read ; do
    mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"
    # parse mac found in magic packet
    for i in $(virsh list --all --name); do # loop through libvirt machines
        vmmac=$(virsh dumpxml $i | grep "mac address" | awk -F\' '{ print $2}') # get each machines MAC
        if [ $vmmac = $mac ]; then # compare MACs, if match do;
            echo $mac;
            echo $i;
            virsh start $i
            virsh resume $i
        fi
    done
done
Gotschi
  • 131
  • 4
  • Could use some comments, like which packets it acts on (udp/9) and which mac address it will wake up (not just those sent repeatedly, right?) – anx Oct 01 '21 at 13:20
1

As I can't comment yet on Gotschi's answer https://serverfault.com/a/1079289/962574 (no reputation so far), I will add my adjustment here:

I modified the script for myself. Not sure about different netcat versions, but on Fedora some adjustments were necessary.

#!/bin/bash

# listen to udp port 9 for packets, check if it is a magic packet
netcat -dkn -l 9 -u | stdbuf -o0 xxd -c 6 -p | stdbuf -o0 uniq | stdbuf -o0 grep -v 'ffffffffffff' | while read
do
    echo "Got triggered with $REPLY"
    mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"

    # loop through libvirt machines
    for vm in $(virsh list --all --name)
    do
        # Get the MAC address and compare with the magic packet
        vmmac=$(virsh dumpxml $vm | grep "mac address" | awk -F\' '{ print $2}')
        if [ $vmmac = $mac ]
        then
            state=$(virsh list --all|awk -v vm=$vm '{ if ($2 == vm ) print $3 }')
            echo "Found $vm with $mac in $state state"

            # Dependent on the state, resume or start
            [ $state == "paused" ] && virsh -q resume $vm && virsh domtime --domain $vm --now
            [ $state == "shut" ] && virsh -q start $vm
        fi
    done
done
mbo77
  • 11
  • 3