[libvirt] [PATCH] Add XML config switch to enable/disable vhost-net support

Laine Stump laine at laine.org
Fri Jan 14 16:24:05 UTC 2011


On 01/14/2011 08:22 AM, Daniel P. Berrange wrote:
> On Thu, Jan 13, 2011 at 01:45:28AM -0500, Laine Stump wrote:
>> This patch is in response to
>>
>>    https://bugzilla.redhat.com/show_bug.cgi?id=643050
>>
>> The existing libvirt support for the vhost-net backend to the virtio
>> network driver happens automatically - if the vhost-net device is
>> available, it is always enabled, otherwise the standard userland
>> virtio backend is used.
>>
>> This patch makes it possible to force whether or not vhost-net is used
>> with a bit of XML. Adding a<driver>  element to the interface XML, eg:
>>
>>       <interface type="network">
>>         <model type="virtio"/>
>>         <driver name="vhost"/>
>>
>> will force use of vhost-net (if it's not available, the domain will
>> fail to start). if driver name="qemu", vhost-net will not be used even
>> if it is available.
>>
>> If there is no<driver name='xxx'/>  in the config, libvirt will revert
>> to the pre-existing automatic behavior - use vhost-net if it's
>> available, and userland backend if vhost-net isn't available.
>> ---
>>
>> Note that I don't really like the "name='vhost|qemu'" nomenclature,
>> but am including it here just to get the patches on the list. I could
>> live with it this way, or with any of the following (anyone have a
>> strong opinion?) (note that in all cases, nothing specified means "try
>> to use vhost, but fallback to userland if necessary")
>>
>>     vhost='on|off'
>>     vhost='required|disabled'
>>     mode='vhost|qemu'
>>     mode='kernel|user'
>>     backend='kernel|user'
> I wanted 'name=' becasue that matches<driver>  usage in<disk>.
> This rules out the first options completely, since we can just
> play with attribute values. kernel|user is nice, except when
> QEMU invent  vhost2, and now 'kernel' is no longer unique :-(
> Also we used 'name=qemu' already in<disk>  to refer to the
> in-QEMU disk backend, and there's likely to be a 'vhost' backend
> for disks too in the future. So in summary I think 'name=vhost|qemu'
> is the best optionl.


Okay, I'm convinced! :-)


>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index b4df38c..04ed502 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -184,6 +184,10 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
>>                 "internal",
>>                 "direct")
>>
>> +VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
>> +              "qemu",
>> +              "vhost")
>> +
>>   VIR_ENUM_IMPL(virDomainChrChannelTarget,
>>                 VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST,
>>                 "guestfwd",
>> @@ -2289,6 +2293,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
>>       char *address = NULL;
>>       char *port = NULL;
>>       char *model = NULL;
>> +    char *backend = NULL;
>>       char *filter = NULL;
>>       char *internal = NULL;
>>       char *devaddr = NULL;
>> @@ -2371,6 +2376,8 @@ virDomainNetDefParseXML(virCapsPtr caps,
>>                   script = virXMLPropString(cur, "path");
>>               } else if (xmlStrEqual (cur->name, BAD_CAST "model")) {
>>                   model = virXMLPropString(cur, "type");
>> +            } else if (xmlStrEqual (cur->name, BAD_CAST "driver")) {
>> +                backend = virXMLPropString(cur, "name");
>>               } else if (xmlStrEqual (cur->name, BAD_CAST "filterref")) {
>>                   filter = virXMLPropString(cur, "filter");
>>                   VIR_FREE(filterparams);
>> @@ -2558,6 +2565,18 @@ virDomainNetDefParseXML(virCapsPtr caps,
>>           model = NULL;
>>       }
>>
>> +    if ((backend != NULL)&&
>> +        (def->model&&  STREQ(def->model, "virtio"))) {
>> +        int b;
>> +        if ((b = virDomainNetBackendTypeFromString(backend))<  0) {
>> +            virDomainReportError(VIR_ERR_INTERNAL_ERROR,
>> +                                 _("Unkown interface<driver name='%s'>  has been specified"),
>> +                                 backend);
>> +            goto error;
>> +        }
>> +        def->backend = b;
>> +        def->backend_specified = 1;
>> +    }
>>       if (filter != NULL) {
>>           switch (def->type) {
>>           case VIR_DOMAIN_NET_TYPE_ETHERNET:
>> @@ -2584,6 +2603,7 @@ cleanup:
>>       VIR_FREE(script);
>>       VIR_FREE(bridge);
>>       VIR_FREE(model);
>> +    VIR_FREE(backend);
>>       VIR_FREE(filter);
>>       VIR_FREE(type);
>>       VIR_FREE(internal);
>> @@ -6275,9 +6295,14 @@ virDomainNetDefFormat(virBufferPtr buf,
>>       if (def->ifname)
>>           virBufferEscapeString(buf, "<target dev='%s'/>\n",
>>                                 def->ifname);
>> -    if (def->model)
>> +    if (def->model) {
>>           virBufferEscapeString(buf, "<model type='%s'/>\n",
>>                                 def->model);
>> +        if (STREQ(def->model, "virtio")&&  def->backend_specified) {
>> +            virBufferVSprintf(buf, "<driver name='%s'/>\n",
>> +                              virDomainNetBackendTypeToString(def->backend));
>> +        }
>> +    }
>>       if (def->filter) {
>>           virBufferEscapeString(buf, "<filterref filter='%s'",
>>                                 def->filter);
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index a459a22..451ccad 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -292,6 +292,13 @@ enum virDomainNetType {
>>       VIR_DOMAIN_NET_TYPE_LAST,
>>   };
>>
>> +/* the backend driver used for virtio interfaces */
>> +enum virDomainNetBackendType {
>> +    VIR_DOMAIN_NET_BACKEND_TYPE_QEMU,         /* userland */
>> +    VIR_DOMAIN_NET_BACKEND_TYPE_VHOST,        /* kernel */
>> +
>> +    VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
>> +};
>>
>>   /* the mode type for macvtap devices */
>>   enum virDomainNetdevMacvtapType {
>> @@ -310,6 +317,8 @@ struct _virDomainNetDef {
>>       enum virDomainNetType type;
>>       unsigned char mac[VIR_MAC_BUFLEN];
>>       char *model;
>> +    enum virDomainNetBackendType backend;
>> +    int backend_specified : 1;
> I don't really like this pattern since it is at odds with the way
> we handle defaults elsewhere which is to include the default as
> the first enum value, eg
>
>    enum virDomainNetBackendType {
>      VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT,      /* Try best available */
>      VIR_DOMAIN_NET_BACKEND_TYPE_QEMU,         /* userland */
>      VIR_DOMAIN_NET_BACKEND_TYPE_VHOST,        /* kernel */
>
>      VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
>    };
>
> And then we do
>
>    if (def->backend)
>       ...print XML...
>
> when formatting the XML, so that the 'name=default' never
> actually appears in the XML output.

Right. What I didn't like was that, using the VIR_ENUM_IMPL() macro, we 
would end up giving the user the ability to put <driver name='default'/> 
into the XML, which would then disappear. In his review, Eric pointed 
out the elegant solution of simply generating an error during parse if 
they try to enter that value; everything else will already do what we 
want. So that's what I'm doing in V2.




More information about the libvir-list mailing list