mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
conf: properly clear out autogenerated macvtap names when formatting/parsing
Back when macvtap support was added in commit315baab944
in Feb. 2010 (libvirt-0.7.7), it was setup to autogenerate a name for the device if one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"), similar to the way an unspecified standard tap device name will lead to an autogenerated "vnet%d". As a matter of fact, in commitca1b7cc8e4
added in May 2010, the code was changed to *always* ignore a supplied device name for macvtap interfaces by deleting *any* name immediately during the <interface> parsing (this was intended to prevent one domain which had failed to completely start from deleting the macvtap device of another domain which had subsequently been provided the same device name (this will seem mildly ironic later). This was later fixed to only clear the device name when inactive XML was being parsed. HOWEVER - this was only done if the xml was <interface type='direct'> - autogenerated names were not cleared for <interface type='network'> (which could also result in a macvtap device). Although the names of "vnetX" tap devices had always been automatically cleared when parsing <interface> (see commitd1304583d
from July 2008 (!)), at the time macvtap support was added, both vnetX and macvtapX device names were always included when formatting the XML. Then in commita8be259d0c
(July 2011, libvirt-0.9.4), <interface> formatting was changed to also clear out "vnetX" device names during XML formatting as well. However the same treatment wasn't given to "macvtapX". Now in 2020, there has been a report that a failed migration leads to the macvtap device of some other unrelated guest on the destination host losing its network connectivity. It was determined that this was due to the domain XML in the migration containing a macvtap device name, e.g. "macvtap0", that was already in use by the other guest on the destination. Normally this wouldn't be a problem, because libvirt would see that the device was already in use, and then find a different unused name. But in this case, other external problems were causing the migration to fail prior to selecting a macvtap device and successfully opening it, and during error recovery, qemuProcessStop() was called, which went through all def->nets objects and (if they were macvtap) deleted the device specified in net->ifname; since libvirt hadn't gotten to the point of replacing the incoming "macvtap0" with the name of a device it actually created for this guest, that meant that "macvtap0" was deleted, *even though it was currently in use by a different guest*! Whew! So, it turns out that when formatting "migratable" XML, "vnetX" devices are omitted, just as when formatting "inactive" XML. By making the code in both interface parsing and formatting consistent for "vnetX", "macvtapX", and "macvlanX", we can thus make sure that the autogenerated (and unneeded / completely *not* wanted) macvtap device name will not be sent with the migration XML. This way when a migration fails, net->ifname will be NULL, and libvirt won't have any device to try and (erroneously) delete. Signed-off-by: Laine Stump <laine@redhat.com> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
5cad64ec03
commit
282d135ddb
@ -12428,14 +12428,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||
}
|
||||
|
||||
def->data.direct.linkdev = g_steal_pointer(&dev);
|
||||
|
||||
if (ifname &&
|
||||
flags & VIR_DOMAIN_DEF_PARSE_INACTIVE &&
|
||||
(STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
|
||||
STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) {
|
||||
VIR_FREE(ifname);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
|
||||
@ -12481,6 +12473,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||
if (def->managed_tap != VIR_TRISTATE_BOOL_NO && ifname &&
|
||||
(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
|
||||
(STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) ||
|
||||
STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
|
||||
STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) ||
|
||||
(prefix && STRPREFIX(ifname, prefix)))) {
|
||||
/* An auto-generated target name, blank it out */
|
||||
VIR_FREE(ifname);
|
||||
@ -26796,6 +26790,8 @@ virDomainNetDefFormat(virBufferPtr buf,
|
||||
(def->managed_tap == VIR_TRISTATE_BOOL_NO ||
|
||||
!((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) &&
|
||||
(STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) ||
|
||||
STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
|
||||
STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) ||
|
||||
(prefix && STRPREFIX(def->ifname, prefix)))))) {
|
||||
/* Skip auto-generated target names for inactive config. */
|
||||
virBufferEscapeString(&attrBuf, " dev='%s'", def->ifname);
|
||||
|
Loading…
Reference in New Issue
Block a user