[libvirt] [PATCH RFC 1/2] conf: add net device prefix to capabilities
Joao Martins
joao.m.martins at oracle.com
Wed Feb 3 21:45:06 UTC 2016
On 01/22/2016 03:46 PM, Joao Martins wrote:
>
>
> On 01/22/2016 02:50 PM, Daniel P. Berrange wrote:
>> On Wed, Jan 20, 2016 at 11:41:26PM +0000, Joao Martins wrote:
>>> In the reverted commit d2e5538b1, the libxl driver was changed to copy
>>> interface names autogenerated by libxl to the corresponding network def
>>> in the domain's virDomainDef object. The copied name is freed when the
>>> domain transitions to the shutoff state. But when migrating a domain,
>>> the autogenerated name is included in the XML sent to the destination
>>> host. It is possible an interface with the same name already exists on
>>> the destination host, causing migration to fail.
>>>
>>> This patch defines a new capability for setting the network device
>>> prefix that will be used in the driver. This prefix will be then copied
>>> when domain is created as def->netprefix, which will be then used by
>>> virDomainNetDefFormat(). Valid prefixes are VIR_NET_GENERATED_PREFIX or
>>> the one announced by the driver.
>>>
>>> Signed-off-by: Joao Martins <joao.m.martins at oracle.com>
>>> ---
>>> src/conf/capabilities.c | 21 +++++++++++++++++++++
>>> src/conf/capabilities.h | 4 ++++
>>> src/conf/domain_conf.c | 20 +++++++++++++++-----
>>> src/conf/domain_conf.h | 2 ++
>>> src/libvirt_private.syms | 1 +
>>> src/network/bridge_driver.c | 2 +-
>>> 6 files changed, 44 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
>>> index 86ea212..eafa7a9 100644
>>> --- a/src/conf/capabilities.c
>>> +++ b/src/conf/capabilities.c
>>> @@ -269,6 +269,23 @@ virCapabilitiesAddHostMigrateTransport(virCapsPtr caps,
>>> return 0;
>>> }
>>>
>>> +/**
>>> + * virCapabilitiesSetNetPrefix:
>>> + * @caps: capabilities to extend
>>> + * @name: prefix for host generated network interfaces
>>> + *
>>> + * Registers the prefix that is used for generated network interfaces
>>> + */
>>> +int
>>> +virCapabilitiesSetNetPrefix(virCapsPtr caps,
>>> + const char *prefix)
>>> +{
>>> + if (VIR_STRDUP(caps->host.netprefix, prefix) < 0)
>>> + return -1;
>>> +
>>> + return 0;
>>> +}
>>
>> You'll need to update virCapabilitiesDispose to free this string
>> too.
>>
> OK.
>
>>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>>> index a9706b0..70d5556 100644
>>> --- a/src/conf/domain_conf.c
>>> +++ b/src/conf/domain_conf.c
>>> @@ -8403,6 +8403,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
>>> xmlNodePtr node,
>>> xmlXPathContextPtr ctxt,
>>> virHashTablePtr bootHash,
>>> + char *prefix,
>>> unsigned int flags)
>>> {
>>> virDomainNetDefPtr def;
>>> @@ -8569,7 +8570,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
>>> ifname = virXMLPropString(cur, "dev");
>>> if (ifname &&
>>> (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
>>> - STRPREFIX(ifname, VIR_NET_GENERATED_PREFIX)) {
>>> + (STRPREFIX(ifname, VIR_NET_GENERATED_PREFIX) ||
>>> + (prefix && STRPREFIX(ifname, prefix)))) {
>>> /* An auto-generated target name, blank it out */
>>> VIR_FREE(ifname);
>>> }
>>> @@ -12525,6 +12527,7 @@ virDomainDeviceDefParse(const char *xmlStr,
>>> xmlNodePtr node;
>>> xmlXPathContextPtr ctxt = NULL;
>>> virDomainDeviceDefPtr dev = NULL;
>>> + char *prefix;
>>>
>>> if (!(xml = virXMLParseStringCtxt(xmlStr, _("(device_definition)"), &ctxt)))
>>> goto error;
>>> @@ -12567,8 +12570,9 @@ virDomainDeviceDefParse(const char *xmlStr,
>>> goto error;
>>> break;
>>> case VIR_DOMAIN_DEVICE_NET:
>>> + prefix = caps->host.netprefix;
>>> if (!(dev->data.net = virDomainNetDefParseXML(xmlopt, node, ctxt,
>>> - NULL, flags)))
>>> + NULL, prefix, flags)))
>>> goto error;
>>> break;
>>> case VIR_DOMAIN_DEVICE_INPUT:
>>> @@ -15885,11 +15889,15 @@ virDomainDefParseXML(xmlDocPtr xml,
>>> goto error;
>>> if (n && VIR_ALLOC_N(def->nets, n) < 0)
>>> goto error;
>>> + if (caps->host.netprefix &&
>>> + VIR_STRDUP(def->netprefix, caps->host.netprefix) < 0)
>>> + goto error;
>>> for (i = 0; i < n; i++) {
>>> virDomainNetDefPtr net = virDomainNetDefParseXML(xmlopt,
>>> nodes[i],
>>> ctxt,
>>> bootHash,
>>> + def->netprefix,
>>> flags);
>>> if (!net)
>>> goto error;
>>> @@ -19880,6 +19888,7 @@ virDomainVirtioNetDriverFormat(char **outstr,
>>> int
>>> virDomainNetDefFormat(virBufferPtr buf,
>>> virDomainNetDefPtr def,
>>> + char *prefix,
>>> unsigned int flags)
>>> {
>>> unsigned int actualType = virDomainNetGetActualType(def);
>>> @@ -20057,7 +20066,8 @@ virDomainNetDefFormat(virBufferPtr buf,
>>> virBufferEscapeString(buf, "<backenddomain name='%s'/>\n", def->domain_name);
>>> if (def->ifname &&
>>> !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) &&
>>> - (STRPREFIX(def->ifname, VIR_NET_GENERATED_PREFIX)))) {
>>> + (STRPREFIX(def->ifname, VIR_NET_GENERATED_PREFIX) ||
>>> + (prefix && STRPREFIX(def->ifname, prefix))))) {
>>> /* Skip auto-generated target names for inactive config. */
>>> virBufferEscapeString(buf, "<target dev='%s'/>\n", def->ifname);
>>> }
>>> @@ -22310,7 +22320,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>>> goto error;
>>>
>>> for (n = 0; n < def->nnets; n++)
>>> - if (virDomainNetDefFormat(buf, def->nets[n], flags) < 0)
>>> + if (virDomainNetDefFormat(buf, def->nets[n], def->netprefix, flags) < 0)
>>> goto error;
>>>
>>> for (n = 0; n < def->nsmartcards; n++)
>>> @@ -23535,7 +23545,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
>>> rc = virDomainFSDefFormat(&buf, src->data.fs, flags);
>>> break;
>>> case VIR_DOMAIN_DEVICE_NET:
>>> - rc = virDomainNetDefFormat(&buf, src->data.net, flags);
>>> + rc = virDomainNetDefFormat(&buf, src->data.net, def->netprefix, flags);
>>> break;
>>> case VIR_DOMAIN_DEVICE_INPUT:
>>> rc = virDomainInputDefFormat(&buf, src->data.input, flags);
>>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>>> index 0141009..9e085a7 100644
>>> --- a/src/conf/domain_conf.h
>>> +++ b/src/conf/domain_conf.h
>>> @@ -2254,6 +2254,7 @@ struct _virDomainDef {
>>>
>>> virDomainOSDef os;
>>> char *emulator;
>>> + char *netprefix;
>>> /* These three options are of type virTristateSwitch,
>>> * except VIR_DOMAIN_FEATURE_CAPABILITIES that is of type
>>> * virDomainCapabilitiesPolicy */
>>> @@ -2748,6 +2749,7 @@ int virDomainDiskSourceFormat(virBufferPtr buf,
>>>
>>> int virDomainNetDefFormat(virBufferPtr buf,
>>> virDomainNetDefPtr def,
>>> + char *prefix,
>>> unsigned int flags);
>>
>> It will result in a ripple effect across the drivers, but rather than
>> storing 'netprefix' in virDomainDef, I think we should probably change
>> virDomainDefFormat to pass in the virCapsPtr object, so we can directly
>> access the canonical source for this data.
>>
>> It is probably best to add virCapsPtr to virDomainDefFormat as a separate
>> patch to this one to keep it clean
>>
Iit looks like the ripple effect is rather big: there are a couple of other
functions in which this requires interfaces to be changed such as
virDomainSaveConfig, virSnapshotDefFormat. Caching netprefix in the virDomainDef
makes the changes significantly smaller, which makes it a bit more attractive
(but perhaps less correct?). I have submitted it as "RFC v2" [0], and kept
driver changes together in the relevant patches to help bisectability.
Thanks!
[0] https://www.redhat.com/archives/libvir-list/2016-February/msg00187.html
> Got it.
>
> Thanks for the review!
>
>> Regards,
>> Daniel
>>
More information about the libvir-list
mailing list