[libvirt] virtual switch - how to store state information

Laine Stump laine at laine.org
Fri Jul 1 19:35:25 UTC 2011

(If you already know about my work on putting a logical switch 
abstraction into libvirt's <network>, skip to part 2)


The rudimentary logical network switch capability I'm currently 
implementing (see https://bugzilla.redhat.com/show_bug.cgi?id=643947) is 
intended to allow a guest's interface XML to be free of any specific 
physical network device name, particularly in bridge and direct modes. 
It does this by expanding the definition of a libvirt <network> to 
include cases that merely describe a host-configured bridge, or a host 
interface (or pool of interfaces) that can be used by a guest in one of 
the 'direct' modes (bridge, private, vepa, or passthrough). It will also 
allow certain details of the guest's network connection to be configured 
by "portgroups" in the <network> definition (initially this will be 
limited to a portgroup containing a <virtualportprofile> and bandwidth 
limiting information).

For example, in the past, a guest that wanted to connect to interface 
eth10 using the direct (aka 'macvtap') "vepa" mode would need to have 
this <interface> in its guest XML:

<interface type='direct'>
<mac address='52:54:00:34:a5:aa'/>
<source dev='eth10' mode='vepa'/>
<model type='virtio'/>
<virtualport type='802.1Qbg'>
<parameters managerid='33' typeid='89' typeidversion='3'/>

With my new code, you can instead define a <network> with connections on 
several physical ethernets:

<forward mode='vepa'>
<interface dev='eth10'/>
<interface dev='eth11'/>
<interface dev='eth12'/>
<interface dev='eth13'/>
<interface dev='eth14'/>
<interface dev='eth15'/>
<interface dev='eth16'/>
<interface dev='eth17'/>
<portgroup name='accounting'>
<virtualport type='802.1Qbg'>
<parameters managerid='44' typeid='54' typeidversion='1'/>
<portgroup name='engineering' default='yes'>
<virtualport type='802.1Qbg'>
<parameters managerid='33' typeid='89' typeidversion='3'/>

and then tell the domain's <interface> to get the information from the 

<interface type='network'>
<mac address='52:54:00:34:a5:aa'/>
<source network='test' portgroup='engineering'/>
<model type='virtio'/>

When libvirt sets up the interface connection, it will grab the config 
for network 'test', see that the forward mode is 'vepa', decide which 
physical ethernet to use, add in any extra stuff from the <portgroup>, 
and use that as the information for connection. In this manner, 1) it 
will remove the hardcoded device name from the domain config, making it 
possible to migrate the domain to other hardware, and 2) share a pool of 
physical devices over a group of domains.


After I've determined which physical device to use, I need to save that 
information for as long as the domain is running, so that if libvirtd is 
restarted, it won't be lost (in some configs, only a single guest can 
use any particular netdev at a given time, so we want to be able to 
manage allocation of the devices without leaking any). My current idea 
is to save this in the domain <interface> XML that's put in the state 
directory, but make sure that it's never put into the XML returned by 
virsh dumpxml. What I'm thinking of is to add an <actual> subelement 
under <interface>, like this:

<interface type='network'>
<mac address='52:54:00:34:a5:aa'/>
<source network='test' porgroup='engineering'/>
<model type='virtio'/>
<actual type='direct'/>
<source dev='eth10' mode='vepa'/>
<virtualport type='802.1Qbg'>
<parameters managerid='33' typeid='89' typeidversion='3'/>

This will be a private/internal thing used only within libvirt, however 
it does need to be stable, since it has to be understandable by a 
libvirtd that has started up while guests are running (eg during a 
libvirt upgrade). So I want to make sure I'm doing something reasonable. 
So, it is?

Should <actual> contain *everything* from the parent interface, plus the 
items that are changed? Or should it contain only:

    * type attribute
    * source element
    * <bridge name=.../> (if applicable)
    * <virtualport> (and other items that might come from <portgroup> in 
the future

(i.e. the things that have changed)?

I *think* the answer is that it should just contain the items that have 
changed, and there should be a wrapper API around the virDomainNetDef 
object for retrieving things like type (if (def->actual) return 
def->actual.type; else return def->type; and similar) to make sure that 
all functions use the correct data.

More information about the libvir-list mailing list