Effectively restarting kvm/libvirt network

Have you ever found yourself in a situation where kvm guests lost connectivity just after adding a new IP/MAC mapping ? well, You are not alone , and I were there too lately. The internet is full of examples of how to solve this issue, they're more or less good and if one of them worked for you, you don't have to continue reading this post :P But if you still looking for a more elegant and effective solution, this what this post is about.

So, the issue occur when restarting libvirt network alone which cause the guests to lose connectivity with the host until their network interfaces are re-attached.

Below is a script to effectively restart the default libvirt network after its definition has been changed (adding new static MAC/IP mappings). It re-attaches the interfaces by obtaining the information about them from the current libvirt definitions:

#!/bin/bash

set -e  
set -u

NET_NAME=default  
NET_HOOK=/etc/libvirt/hooks/qemu

virsh net-destroy $NET_NAME  
virsh net-start $NET_NAME

VMS=$( virsh list | tail -n +3 | head -n -1 | awk '{ print $2; }' )

for m in $VMS ; do

    echo "$m"
    MAC_ADDR=$(virsh domiflist "$m" |grep -o -E "([0-9a-f]{2}:){5}([0-9a-f]{2})")
    NET_MODEL=$(virsh domiflist "$m" | tail -n +3 | head -n -1 | awk '{ print $4; }')

    set +e
    virsh detach-interface "$m" network --mac "$MAC_ADDR" && sleep 3
    virsh attach-interface "$m" network $NET_NAME --mac "$MAC_ADDR" --model "$NET_MODEL"
    set -e

    $NET_HOOK "$m" stopped && sleep 3
    $NET_HOOK "$m" start

done  

As you can see, the script has the following dependencies: virsh (obviously)/ tail / head / grep / awk. Also, note that it assumes that the guests have exactly 1 NAC each attached to the given network! the script is also available on github.