]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: re-add hostdev interfaces to hostdev array on libvirtd restart
authorLaine Stump <laine@laine.org>
Thu, 19 Dec 2013 12:44:03 +0000 (14:44 +0200)
committerLaine Stump <laine@laine.org>
Mon, 23 Dec 2013 11:16:57 +0000 (13:16 +0200)
This resolves:

   https://bugzilla.redhat.com/show_bug.cgi?id=1045002

If a domain has an <interface type='hostdev'> or an <interface
type='network'> where the network itself is a pool of hostdev devices,
then libvirt will internally keep that device on both the interface
list *and* the hostdev list for the domain. One of the places this
comes in handy is when a new device is being added and libvirt wants
to find a unique "alias" name for it - it just scans through the
hostdev array and makes sure it picks a name that doesn't match the
alias of any device in that array.

However, when libvirtd was restarted, if there was an <interface
type='network'> with the network being a hostdev pool, the device
would not be added to the reconstructed internal hostdev array, so its
alias would not be found during a scan of the hostdev array, thus
attempts to add a new hostdev (or <interface type='hostdev'> or
<interface type='network'>) would result in a message like this:

internal error: unable to execute QEMU command 'device_add':
                Duplicate ID 'hostdev0' for device

This patch simply fixes the existing code in the domain XML parser
that fixes up the hostdev array in the case of <interface
type='hostdev'> to do the same thing in the case of <interface
type='network'> with a hostdev network.

This bug has existed since the very first addition of hostdev networks
to libvirt (0.10.0).

src/conf/domain_conf.c

index 773c29d6ad50672b744e7d06d2a794ff8bff0651..80bc85fad8870588cc91d9ba8d4f85cfce4ea1aa 100644 (file)
@@ -12101,9 +12101,12 @@ virDomainDefParseXML(xmlDocPtr xml,
 
         def->nets[def->nnets++] = net;
 
-        /* <interface type='hostdev'> must also be in the hostdevs array */
-        if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
-            virDomainHostdevInsert(def, &net->data.hostdev.def) < 0) {
+        /* <interface type='hostdev'> (and <interface type='net'>
+         * where the actual network type is already known to be
+         * hostdev) must also be in the hostdevs array.
+         */
+        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+            virDomainHostdevInsert(def, virDomainNetGetActualHostdev(net)) < 0) {
             goto error;
         }
     }