From 2e3465d664c764032bd133c545905639f459efbc Mon Sep 17 00:00:00 2001 Message-Id: <2e3465d664c764032bd133c545905639f459efbc.1381871411.git.jdenemar@redhat.com> From: Laine Stump Date: Fri, 4 Oct 2013 01:53:09 -0600 Subject: [PATCH] qemu: check actual netdev type rather than config netdev type during init This resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1012824 (RHEL7) https://bugzilla.redhat.com/show_bug.cgi?id=1012834 (RHEL6) Note that a similar problem was reported in: https://bugzilla.redhat.com/show_bug.cgi?id=827519 but the fix only worked for , *not* for where the network itself was a pool of hostdevs. The symptom in both cases was this error message: internal error: Unable to determine device index for network device In both cases the cause was lack of proper handling for netdevs () of type='hostdev' when scanning the netdev list looking for alias names in qemuAssignDeviceNetAlias() - those that aren't type='hostdev' have an alias of the form "net%d", while those that are hostdev use "hostdev%d". This special handling was completely lacking prior to the fix for Bug 827519 which was: When searching for the highest alias index, libvirt looks at the alias for each netdev and if it is type='hostdev' it ignores the entry. If the type is not hostdev, then it expects the "net%d" form; if it doesn't find that, it fails and logs the above error message. That fix works except in the case of where the network uses hostdev (i.e. the network is a pool of VFs to be assigned to the guests via PCI passthrough). In this case, the check for type='hostdev' would fail because it was done as: def->net[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV (which compares what was written in the config) when it actually should have been: virDomainNetGetActualType(def->net[i]) == VIR_DOMAIN_NET_TYPE_HOSTDEV (which compares the type of netdev that was actually allocated from the network at runtime). Of course the latter wouldn't be of any use if the netdevs of type='network' hadn't already acquired their actual network connection yet, but manual examination of the code showed that this is never the case. While looking through qemu_command.c, two other places were found to directly compare the net[i]->type field rather than getting actualType: * qemuAssignDeviceAliases() - in this case, the incorrect comparison would cause us to create a "net%d" alias for a netdev with type='network' but actualType='hostdev'. This alias would be subsequently overwritten by the proper "hostdev%d" form, so everything would operate properly, but a string would be leaked. This patch also fixes this problem. * qemuAssignDevicePCISlots() - would defer assigning a PCI address to a netdev if it was type='hostdev', but not for type='network + actualType='hostdev'. In this case, the actual device usually hasn't been acquired yet anyway, and even in the case that it has, there is no practical difference between assigning a PCI address while traversing the netdev list or while traversing the hostdev list. Because changing it would be an effective NOP (but potentially cause some unexpected regression), this usage was left unchanged. (cherry picked from commit 9881bfed2541faa428372b4513518b4b9ae1ab15) Signed-off-by: Jiri Denemark --- src/qemu/qemu_command.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 47b488a..dcce432 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -787,7 +787,8 @@ qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx) for (i = 0; i < def->nnets; i++) { int thisidx; - if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { + if (virDomainNetGetActualType(def->nets[i]) + == VIR_DOMAIN_NET_TYPE_HOSTDEV) { /* type='hostdev' interfaces have a hostdev%d alias */ continue; } @@ -957,8 +958,9 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) /* type='hostdev' interfaces are also on the hostdevs list, * and will have their alias assigned with other hostdevs. */ - if ((def->nets[i]->type != VIR_DOMAIN_NET_TYPE_HOSTDEV) && - (qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0)) { + if (virDomainNetGetActualType(def->nets[i]) + != VIR_DOMAIN_NET_TYPE_HOSTDEV && + qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0) { return -1; } } -- 1.8.3.2