[libvirt] [PATCH v5 02/24] conf: introduce virNetworkPortDefPtr struct and XML support
Daniel P. Berrangé
berrange at redhat.com
Wed May 22 10:29:37 UTC 2019
On Mon, May 20, 2019 at 09:44:04PM -0400, Laine Stump wrote:
> On 5/14/19 11:48 AM, Daniel P. Berrangé wrote:
> > Introduce a virNetworkPortDefPtr struct to represent the data associated
> > with a virtual network port. Add APIs for parsing/formatting XML docs
> > with the data.
> >
> > Signed-off-by: Daniel P. Berrangé<berrange at redhat.com>
> > ---
> > docs/docs.html.in | 1 +
> > docs/formatnetworkport.html.in | 212 ++++++++
> > docs/schemas/networkport.rng | 165 ++++++
> > src/conf/Makefile.inc.am | 2 +
> > src/conf/virnetworkportdef.c | 509 ++++++++++++++++++
> > src/conf/virnetworkportdef.h | 113 ++++
> > src/libvirt_private.syms | 10 +
> > tests/Makefile.am | 7 +
> > .../plug-bridge-mactbl.xml | 9 +
> > .../virnetworkportxml2xmldata/plug-bridge.xml | 15 +
> > .../virnetworkportxml2xmldata/plug-direct.xml | 12 +
> > .../plug-hostdev-pci.xml | 12 +
> > .../plug-network.xml | 16 +
> > tests/virnetworkportxml2xmldata/plug-none.xml | 8 +
> > tests/virnetworkportxml2xmltest.c | 104 ++++
> > tests/virschematest.c | 1 +
> > 16 files changed, 1196 insertions(+)
> > create mode 100644 docs/formatnetworkport.html.in
> > create mode 100644 docs/schemas/networkport.rng
> > create mode 100644 src/conf/virnetworkportdef.c
> > create mode 100644 src/conf/virnetworkportdef.h
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge.xml
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-direct.xml
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-network.xml
> > create mode 100644 tests/virnetworkportxml2xmldata/plug-none.xml
> > create mode 100644 tests/virnetworkportxml2xmltest.c
> >
> > diff --git a/docs/formatnetworkport.html.in b/docs/formatnetworkport.html.in
> > new file mode 100644
> > index 0000000000..0211518a6a
> > --- /dev/null
> > +++ b/docs/formatnetworkport.html.in
> > + <dl>
> > + <dt><code>bandwidth</code></dt>
> > + <dd>This part of the network port XML provides setting quality of service.
> > + Incoming and outgoing traffic can be shaped independently.
> > + The <code>bandwidth</code> element and its child elements are described
> > + in the <a href="formatnetwork.html#elementQoS">QoS</a> section of
> > + the Network XML. In addition the <code>classID</code> attribute may
> > + exist provide the ID of the traffic shaping class that is active.
> > + </dd>
> > + <dt><code>rxfilters</code></dt>
> > + <dd>The <code>rxfilters</code> element property
> > + <code>trustGuestRxFilters</code> provides the
>
>
> Earlier you referred to this as "trustGuest" (also looks like that's what
> the parser/formatter use)
Yes, copy & paste mistake
>
>
> > + capability for the host to detect and trust reports from the
> > + guest regarding changes to the interface mac address and receive
> > + filters by setting the attribute to <code>yes</code>. The default
> > + setting for the attribute is <code>no</code> for security
> > + reasons and support depends on the guest network device model as
> > + well as the type of connection on the host - currently it is
> > + only supported for the virtio device model and for macvtap
> > + connections on the host.
> > + </dd>
> > + <dt><code>virtualport</code></dt>
> > + <dd>The <code>virtualport</code> element describes metadata that
> > + needs to be provided to the underlying network subsystem. It
> > + is described in the domain XML
> > + <a href="formatdomain.html#elementsNICS">interface documentation</a>.
> > + </dd>
> > + </dl>
> > +
> > +
> > + <h3><a id="elementsPlug">Plugs</a></h3>
> > +
> > + <p>
> > + The <code>plug</code> element has varying content depending
> > + on the value of the <code>type</code> attribute.
> > + </p>
> > +
> > + <h4><a id="elementsPlugNetwork">Network</a></h4>
> > +
> > + <p>
> > + The <code>network</code> plug type refers to a managed virtual
> > + network plug that is based on a traditional software bridge
> > + device privately managed by libvirt.
> > + </p>
>
>
> Your patches essentially take the same items that are in the virActualNetDef
> and put them into virNetworkPortDef. I think this is the right way to
> approach the task of changing the infrastructure - makes it more
> straightforward to get all the same functionality working with the new
> intra-driver communication method. The one thing that bothers me, though, is
> that this ends up replicating design mistakes that we ("I" :-P - most of it
> was good, I just added in some things that were kind of screwed up...) made
> with the original. I'm hoping that there will also be a path to correcting
> those mistakes after the fact so that we don't have to live with them
> forever.
I don't see any viable alternative. We have to be able to convert
between the virActualNetDef & virNetworkPortDef in both directions
without loosing information. This inherantly means replicating the
same concepts.
> In particular, we've been using "type='network' to imply that the network
> supports a bandwidth floor setting (and who knows what else). Although we
> made this mistake with <interface> status, I would really prefer if we don't
> (permanently at least) propagate the mistake to networkport. What
> "type='network' really means is a tap device connected to a bridge that
> probably has a routed connection and supports bandwidth floor setting). But
> what if network port was instead something like:
>
>
> <plug type='tap' forward='route' bridge='virbr0'/>
>
> <plug type='tap' forward='bridge' bridge='br0'/>
>
> <plug type='direct' dev='ens3' mode='vepa'/>
>
> (maybe if we use "type='tap'", we should also use "type='macvtap'"?. Hmm,
> and of course if we're going to spell out "tap", then for container-ish
> connections that use a veth pair, we would have to say "type='veth'"...)
You raised this same point in an earlier review of this same series.
This is not desirable as it is refering to a specific implementation
choice of the QEMU backend. The LXC driver doesn't use tap devices
or macvtap devices, instead it uses veth devices and macvlan devices.
> Anyway, like I said, I think it *is* better to change the infrastructure
> without changing the attributes right now, but will we be able to change it
> in the future?
I don't believe we should change it, as the current concepts are
intentionally independant of a specific implementation choice.
> > diff --git a/docs/schemas/networkport.rng b/docs/schemas/networkport.rng
> > new file mode 100644
> > index 0000000000..8192f6efc4
> > --- /dev/null
> > +++ b/docs/schemas/networkport.rng
> > @@ -0,0 +1,165 @@
> > +<?xml version="1.0"?>
> > +<!-- A Relax NG schema for the libvirt network port XML format -->
> > +<grammar xmlns="http://relaxng.org/ns/structure/1.0"
> > + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
> > + <include href='basictypes.rng'/>
> > + <include href='networkcommon.rng'/>
> > +
> > + <start>
> > + <ref name="networkport"/>
> > + </start>
> > +
> > + <define name="networkport">
> > + <element name="networkport">
> > + <interleave>
> > + <element name="uuid">
> > + <ref name="UUID"/>
> > + </element>
> > + <ref name="owner"/>
> > + <ref name="mac"/>
> > + <optional>
> > + <ref name="group"/>
> > + </optional>
> > + <optional>
> > + <ref name="class"/>
> > + </optional>
>
>
>
> I thought in the previous patch you had integrated <class id='blah'/> into
> the bandwidth element as a classID attribute. Did you just forget to remove
> it from the rng?
Yeah, I forgot to update the schema.
> > + <define name="plughostdevpci">
> > + <attribute name="type">
> > + <value>hostdev-pci</value>
> > + </attribute>
> > + <optional>
> > + <attribute name="managed">
> > + <ref name="virYesNo"/>
> > + </attribute>
> > + </optional>
> > + <optional>
> > + <element name="driver">
> > + <attribute name="name">
> > + <choice>
> > + <value>kvm</value>
>
>
> We *really* need to get rid of <driver name='kvm'/> for hostdev - it's been
> deprecated for 5 years, and removing it would eliminate ugly code.
Regardless of whether the code uses it or not, it is in the domain schema
and for purposes of doing a bi-directional conversion, it better to have
it in the network port XML too. It isn't the network port XML parser's
job to decide if its used or not - that's upto the QEMU driver
> > +static virNetworkPortDefPtr
> > +virNetworkPortDefParseXML(xmlXPathContextPtr ctxt)
> > +{
> > + virNetworkPortDefPtr def;
> > + char *uuid = NULL;
> > + xmlNodePtr virtPortNode;
> > + xmlNodePtr vlanNode;
> > + xmlNodePtr bandwidthNode;
> > + xmlNodePtr addressNode;
> > + char *trustGuestRxFilters = NULL;
> > + char *mac = NULL;
> > + char *macmgr = NULL;
> > + char *mode = NULL;
> > + char *plugtype = NULL;
> > + char *managed = NULL;
> > + char *driver = NULL;
> > + char *class_id = NULL;
> > +
> > + if (VIR_ALLOC(def) < 0)
> > + return NULL;
> > +
> > + uuid = virXPathString("string(./uuid)", ctxt);
> > + if (!uuid) {
> > + virReportError(VIR_ERR_INTERNAL_ERROR,
> > + "%s", _("network port has no uuid"));
> > + goto error;
> > + }
> > + if (virUUIDParse(uuid, def->uuid) < 0) {
> > + virReportError(VIR_ERR_INTERNAL_ERROR,
> > + _("Unable to parse UUID '%s'"), uuid);
> > + goto error;
> > + }
> > +
> > + def->ownername = virXPathString("string(./owner/name)", ctxt);
> > + if (!def->ownername) {
> > + virReportError(VIR_ERR_INTERNAL_ERROR,
> > + "%s", _("network port has no owner name"));
> > + goto error;
> > + }
>
>
> I'm curious why you made name and uuid subelements of owner, rather than
> attributes. Just for consistency with the name element we use in other
> places? Or are you expecting it might need qualifying attributes? Or just
> because the <owner> line would be too long if they were attributes?
This mirrors what is done with the nwfilter binding XML schema.
> > + case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
> > + managed = virXPathString("string(./plug/@managed)", ctxt);
> > + if (managed &&
> > + (def->plug.hostdevpci.managed =
> > + virTristateBoolTypeFromString(managed)) < 0) {
> > + virReportError(VIR_ERR_XML_ERROR,
> > + _("Invalid managed setting '%s' in network port"), mode);
> > + goto error;
> > + }
> > + driver = virXPathString("string(./plug/driver/@name)", ctxt);
> > + if (driver &&
> > + (def->plug.hostdevpci.driver =
> > + virNetworkForwardDriverNameTypeFromString(driver)) <= 0) {
> > + virReportError(VIR_ERR_XML_ERROR, "%s",
> > + _("Missing network port driver name"));
> > + goto error;
> > + }
>
>
> Yeah, the more I think about this, the more I think it's unnecessary (and
> that we should also consider removing it from other places it's used, since
> non-VFIO device assignment hasn't worked in Linux since RHEL6 days).
Again, from XML parsing pov it is preferrable to have it present so that
conversion to/from the actual network def avoids any special cases. If
QEMU driver wants to reject it later that's fine
> > +int
> > +virNetworkPortDefSaveStatus(virNetworkPortDef *def,
> > + const char *dir)
> > +{
> > + char uuidstr[VIR_UUID_STRING_BUFLEN];
> > + char *path;
> > + char *xml = NULL;
> > + int ret = -1;
> > +
> > + virUUIDFormat(def->uuid, uuidstr);
> > +
> > + if (virFileMakePath(dir) < 0)
> > + goto cleanup;
> > +
> > + if (!(path = virNetworkPortDefConfigFile(dir, uuidstr)))
> > + goto cleanup;
> > +
> > + if (!(xml = virNetworkPortDefFormat(def)))
> > + goto cleanup;
> > +
> > + if (virXMLSaveFile(path, uuidstr, "net-port-create", xml) < 0)
> > + goto cleanup;
>
>
> For other objects, when they are saved to a "status" file, the xml is
> enclosed in a "<blahstatus>" element, e.g. <domstatus>, <networkstatus>,
> etc. I guess this is done in case there are other things about the state of
> the object that aren't contained directly in virBlahDef. Did you not do that
> here on purpose (maybe because the entire point of this object is to keep
> track of the state of a particular connection, so of course there is nothing
> extra?), or was it an oversite?
Essentially the network port XML is always a "status" file, since this
object only ever exists for a running VM. There shouldn't be any info
we record in the network port that isn't part of the public schema. Thus
there's no need to wrap it in a extra status XML schema. This is the same
as the nwfilter binding XML which is also a runtime only XML doc.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list