Wake-on-LAN for libvirt based VMs
Go to file
2023-12-15 00:47:10 -08:00
init-scripts Add OpenRC init files, and move to init-scripts. Update README accordingly. 2021-06-18 11:02:21 -07:00
go.mod Switch to libvirt-go and libvirt-go-xml 2023-12-15 00:26:37 -08:00
go.sum Switch to libvirt-go and libvirt-go-xml 2023-12-15 00:26:37 -08:00
LICENSE Initial commit 2021-03-27 13:05:43 -07:00
README.md Take the URI to the libvirtd as a command-line argument. 2023-12-15 00:47:10 -08:00
virtwold.go Take the URI to the libvirtd as a command-line argument. 2023-12-15 00:47:10 -08:00

virtwold

Wake-on-LAN for libvirt based VMs

Introduction

This is a daemon which listens for wake-on-LAN ("WOL") packets, and upon spotting one, tries to start the virtual machine with the associated MAC address.

One use-case (my use case) is to have a gaming VM that doesn't need to be running all the time. NVIDIA Gamestream and Moonlight both have the ability to send WOL packets in an attempt to wake an associated system. For "real" hardware, this works great. Unfortunately, for VMs it doesn't really do anything since there's no physical NIC snooping for the WOL packet. This daemon attempts to solve that.

Mechanics

When started, this daemon will use libpcap to make a listener on the specified network interface, listening for packets that look like they might be wake-on-lan. Due to how pcap works, the current filter is for UDP sent to the broadcast address with a length of 234 bytes (the size of a WOL packet w/security). This seems to generate very low false-positives, doesn't require the NIC to be in promiscuous mode, and overall seems like a decent filter.

Upon receipt of a (probable) WOL packet, the daemon extracts the first MAC address (WOL packets are supposed to repeat the target machine MAC a few times).

With a MAC address in-hand, the program then connects to a libvirtd daemon via , supplied libvirt URI and gets an XML formatted list of every Virtual Machine configured (yuck), and iterates through all interfaces getting the MAC address. That MAC is then compared with the MAC from the WOL packet. If a match is found, the libvirtd daemon is asked to start the associated VM.

Usage

Usage is pretty staightforward, as the command needs two arguments:

  1. The name of the network interface to listen on. Specify this with the --interface flag (e.g., --interface enp44s0).
  2. The URI to the libvirtd to be used. Specify this with the --libvirturi flag (e.g., qemu+tcp:///system).

The daemon will keep running until killed with a SIGINT (^c).

Because this daemon, and wake-on-LAN, operate by MAC addresses, any VMs that are a candidate to be woken must have a hard-coded MAC in their machine configuration.

System Integration

systemd example service

There's a systemd service template example in init-scripts/systemd/virtwold@.service that should make it easy to configure for any interfaces that you need to run on

OpenRC example init script

Systems which use openrc can find an example init script and associated conf file in init-scripts/openrc/. The interface should be adjusted to match your particular needs (e.g., swap eth0 for enp44s0 or something like that).

Gentoo ebuild

An ebuild for Gentoo systems is available in here, although it only installs OpenRC init files (since that's what I use).

Archlinux PKGBUILD

Users of Arch can install virtwold from the PKGBUILD in AUR located here.