<br><tt><font size=2>libvir-list-bounces@redhat.com wrote on 03/08/2010
07:29:42 PM:<br>
</font></tt>
<br><tt><font size=2>> Using a bridge to connect a qemu NIC to a host
interface offers a fair<br>
> amount of flexibility to reconfigure the host without restarting the
VM.<br>
> For example, if the bridge connects host interface eth0 to the qemu
tap0<br>
> interface, eth0 can be hot-removed and hot-plugged without affecting
the<br>
> VM.  Similarly, if the bridge connects host VLAN interface vlan0
to the<br>
> qemu tap0 interface, the admin can easily replace vlan0 with vlan1<br>
> without the VM noticing.<br>
> <br>
> Using the macvtap driver instead of a kernel bridge, the host interface<br>
> is much more tightly tied to the VM.  Qemu communicates with
the macvtap<br>
> interface through a file descriptor, and the macvtap interface is
bound<br>
> permanently to a specific host interface when it is first created.<br>
> What's more, if the underlying host interface disappears, the macvtap<br>
> interface vanishes along with it, leaving the VM holding a file<br>
> descriptor for a deleted file.<br>
> <br>
> To avoid race conditions during system startup, I would like libvirt
to</font></tt>
<br>
<br><tt><font size=2>The problem I guess is that the underlying interface
can disappear at any time due to hotplug leaving you with a race condition
at other times as well until a watcher thread detects the change and can
act, no?</font></tt>
<br><tt><font size=2><br>
> allow starting up the VM with a NIC even if the underlying host<br>
> interface doesn't yet exist, deferring creation of the macvtap interface<br>
> (analogous to starting up the VM with a tap interface bound to an
orphan<br>
> bridge).  To support adding and removing a host interface without</font></tt>
<br>
<br><tt><font size=2>What do you pass to Qemu command line? Currently we
pass a file descriptor of the tap interface...</font></tt>
<br><tt><font size=2><br>
> restarting the VM, I would like libvirt to react to the (re)appearance<br>
> of the underlying host interface, creating a new macvtap interface
and<br>
> passing the new fd to qemu to reconnect to the NIC.</font></tt>
<br>
<br><tt><font size=2>How do you handle the macvtap description in the VM
configuration? Currently we have the 'direct' interface description where
the link device is written into the domain description:</font></tt>
<br>
<br><tt><font size=3> <devices><br>
    <interface type='direct'/><br>
    ...<br>
    <interface type='direct'><br>
      <source dev='eth0' mode='vepa'/><br>
    </interface><br>
  </devices><br>
</font></tt>
<br><a href=http://libvirt.org/formatdomain.html#elementsNICSDirect><tt><font size=2>http://libvirt.org/formatdomain.html#elementsNICSDirect</font></tt></a>
<br>
<br><tt><font size=2>Are you reflecting the change to 'eth0' also in case
the hotplugged device was to appear under another name?</font></tt>
<br>
<br><tt><font size=2>> </font></tt>
<br><tt><font size=2>> (It would also be nice if libvirt allowed the
user to change which<br>
> underlying host interface the qemu NIC is connected to.  I'm
ignoring<br>
> this issue for now, except to note that implementing the above features<br>
> should make this easier.)</font></tt>
<br><tt><font size=2>> <br>
> The libvirt API already supports domainAttachDevice and<br>
> domainDetachDevice to add or remove an interface while the VM is<br>
> running.  In the qemu implementation, these commands add or remove
the<br>
> VM NIC device as well as reconfiguring the host side.  This works
only<br>
> if the OS and application running in the VM can handle PCI hotplug
and<br>
> dynamically reconfigure its network.  I would like to isolate
the VM<br>
> from changes to the host network setup, whether you use macvtap or
a<br>
> bridge.</font></tt>
<br>
<br><tt><font size=2>So currently you would have to attach and detach the
direct device. Now in your implementation a host unplug would automatically
cause the macvtap to get unplugged and if a host interface appears it would
automatically recreate a macvtap linking it to this host interface? Under
what conditions does this work? Does the new interface have to have the
same name? I wondering, because some scripts I believe check for the MAC
address of the device and if it doesn't match the one expected for eth0,
it may appear as eth1. How are cases handled where I would like it to reconnect
to vlan 100 of the newly connected host interface but I probably have to
run some command to first create that vlan 100 interface?</font></tt>
<br><tt><font size=2><br>
> <br>
> The changes I think are needed to implement this include:<br>
> <br>
> 1. Refactor qemudDomainAttachNetDevice/qemudDomainDetachNetDevice,
which<br>
> currently handle both backend (host) setup and adding/removing the
VM<br>
> NIC device; move the backend setup code into separate functions that
can<br>
> called separately without affecting VM devices.<br>
> <br>
> 2. Implement a thread or task that watches for changes to the underlying<br>
> host interface for each configured macvtap interface, and reacts by<br>
> invoking the appropriate backend setup code.</font></tt>
<br>
<br><tt><font size=2>I suppose the backend setup code is provided and not
some external script that the user can run to for example have the vlan
100 interface created on host hotplug.</font></tt>
<br>
<br>
<br><tt><font size=2>   Stefan</font></tt>
<br><tt><font size=2><br>
> <br>
> 3. Change qemudBuildCommandLine to defer backend setup if qemu supports<br>
> the necessary features for doing it later (e.g. the host_net_add monitor<br>
> command).<br>
> <br>
> 4. Implement appropriate error handling and reporting, and any necessary<br>
> changes to the configuration schema.<br>
> <br>
> The following patches are a partial implementation of the above as
a<br>
> proof of concept.<br>
> <br>
> Patch 1 implements change (1) above, moving the backend setup code
to<br>
> new functions<br>
> qemudDomainConnectNetBackend/qemudDomainDisconnectNetBackend, and<br>
> calling these functions from the existing<br>
> qemudDomainAttachNetDevice/qemudDomainDetachNetDevice.  I think
this<br>
> change is useful on its own: it breaks up two monster functions into<br>
> more manageable pieces, and eliminates some code duplication (e.g.
the<br>
> try_remove clause at the end of qemudDomainAttachNetDevice).<br>
> <br>
> Patch 2 is a godawful hack roughly implementing changes (2) and (3)<br>
> above (did I mention that this is a proof of concept?).  It spawns
a<br>
> thread that simply tries reconnecting the backend of each macvtap<br>
> interface once a second.  As long as the interface is already
up, the<br>
> reconnection fails. If the macvtap interface goes away because the<br>
> underlying host interface disappears, the reconnection fails until
the<br>
> host interface reappears.<br>
> <br>
> I ran into two major issues while implementing (2) and (3):<br>
> <br>
> - Can we use the existing virEvent functions to invoke the reconnection<br>
> process, triggered either by a timer or by an event from the host?
 It<br>
> seems like this ought to work, but it appears that communication between<br>
> libvirt and the qemu monitor relies on an event, and since all events<br>
> run in the same thread, there's no way for an event to call the monitor.<br>
> <br>
> - Should the reconnection process use udev or hal to get notifications,<br>
> or leverage the node device code which itself uses udev or hal?<br>
> Currently there doesn't appear to be a way to get notifications of<br>
> changes to node devices; if there were, we'd still need to address
the<br>
> threading issue.  If we use node devices, what changes to the<br>
> configuration schema would be needed to associate a macvtap interface<br>
> with the underlying node device?<br>
> <br>
> I'd appreciate input on item (4) as well (e.g. does it always make
sense<br>
> to ignore the missing host interface on the assumption that it could<br>
> show up later?).<br>
> <br>
> --Ed<br>
> <br>
> <br>
> --<br>
> libvir-list mailing list<br>
> libvir-list@redhat.com<br>
> </font></tt><a href="https://www.redhat.com/mailman/listinfo/libvir-list"><tt><font size=2>https://www.redhat.com/mailman/listinfo/libvir-list</font></tt></a><tt><font size=2><br>
</font></tt>