On 12/2/20 12:47 PM, Laine Stump wrote:
netcf (the backend of libvirt's virInterface*() APIs) hasn't been modified in over 2 years, and the last time there was a change significant enough for an upstream release was in 2015 (!). It has never been possible to reliably translate back and forth between native and netcf/libvirt XML config for interfaces without losing some information, and impossible to keep up with new functionality being added to host network configuration in NetworkManager (especially since the modelling was slightly different - netcf is based on the idea of each physical interface having one configuration, while NetworkManager has potentially several different "Connections" for any given hardware interface, and at most one of these connections can be active at a time for the interface. Or something like that.)

The libvirt virInterface*() API (and netcf behind it) originally arose out of a request from the oVirt project that we (libvirt) provide a way to provision the networking config on a compute node (I *think* this is the case - I started working on libvirt when they were in the middle of these discussions; netcf was originally implemented mostly by David Lutterkort, and then handed off to me when he moved on to other pastures). oVirt network provisioning usually meant adding a bridge, assigning it an IP address, and attaching an ethernet (or two via a bond) to that bridge. They wanted libvirt to provide this functionality because (I guess?) they wanted to have a single connection to the node that could perform all the setup they needed.

Although netcf could do that, in the end it didn't provide exactly what they needed, so they "rolled their own" host network interface config and didn't use netcf. In the meantime, the idea of using a virtualization API to configure host network interfaces never took off (Who'da thunk?).

netcf was designed so that a single C API + XML frontend could be compiled with multiple different backends, for different network configuration paradigms. A few other drivers were (partially) written (e.g. SuSE and Windows), but in the real world, the only backends that have been used have been the one that uses ifcfg files in Fedora/RHEL/CentOS, and the one that uses the /etc/network/interfaces file on debian/ubuntu.

I could never get the SUSE network folks onboard, primarily due to resource constraints. There was some early effort to make the interface APIs work with a small shim library that looked and smelled like netcf, but there was never any followup to make that a proper netcf backend. It was long ago and I had little experience with downstream patch maintenance. Regretfully I accepted a non-upstreamable patch in the downstream libvirt package that has caused much pain and irritation over the many years since

https://build.opensuse.org/package/view_file/Virtualization/libvirt/libvirt-suse-netcontrol.patch?expand=1

In both cases, the backend understands a subset of what is possible in those files, so some information from the config doesn't show up in the XML, and thus won't be preserved if netcf is used to modify (i.e. redefine) the interface. In addition, since a functionally identical configuration can be represented in multiple ways in both those formats, sometimes a config file is deemed unreadable by netcf, or it is read and interpreted correctly, but the modified config is written back using the "other" method.

Since ovirt chose not to use it, the only users of its interface configuration capabilities that I've ever noticed in the wild were the occasional user wanting to use the "virsh iface-bridge" command to put a bridge behind their ethernet - certainly none of the higher level virtualization management applications (that I'm aware of) use any of the libvirt APIs that call to netcf (that means "anything starting with "virInterface").

The small part of the virInterface APIs that have been used with some regularity are just the functions that list current interfaces and get their current live status (i.e. based on sending/receiving netlink messages, not on the contents of the host network config files). Even on that front, the one commonly used example that I know know of is virt-manager, which had used virInterface*() to get a list of bridges/ethernets available for guest network connections, but that functionality was removed from virt-manager-3.0, which was released in September of this year.

In spite of this sporadic use, there are occasional netcf BZes that get filed complaining about certain device options missing, or erroneous config resulting in a confusing error message. These are usually filed by Red Hat virt QE, simply because it's a part of their test plan (i.e. these reports generally don't reflect a failure on a production system). Because the "fix" wouldn't provide any gain in the real world, these BZes just sit in the queue and server only to make me (the netcf maintainer) feel like even more of a procrastinator that I actually am.

I received a recent report (sorry the details are not public) about 'virsh iface-list' taking longer on libvirt 6.0.0 (5m26.713s) vs 5.1.0 (3m49.949s) with a large number (>200) of interfaces. I provided the customer with a small test app that uses libnetcontrol directly, which took only 2m28.172s to list the interfaces. I haven't had time to investigate, but it's obvious libvirt is adding considerable time.

(A sidebar: netcf was originally made into a separate library, rather than just a few files within libvirt itself, because there was at least shrugging verbal agreement that it would be used in places other than libvirt (and thus there would be a community benefit in eliminated duplicate code in the multiple projects); this also never materialized, so in the end, it is a separate library that is only consumed by libvirt, but because it's a separate library the "barrier to entry" for anyone to make any changes to it is very high, and so it (effectively) never sees any contributions from the outside.)

Likely another reason the SUSE network folks lost interest. They couldn't rationalize the effort for a single consumer.

Because of all the above, I've thought for quite awhile that we should deprecate netcf itself, along with all of libvirt's virInterface APIs *except* the one that lists interfaces (virConnectListAllInterfaces) and the one that outputs an XML dump of the current status of interfaces (virInterfaceGetXMLDesc). Since netcf is only used by libvirt anyway, the part of functionality that performs those two tasks could be moved into one or two C files within libvirt, removing the dependency on netcf and making updates easier and more accessible to 3rd parties. As a followup to this, we might provide another backend that would use NetworkManager APIs to retrieve all this information rather than netlink messages (which is what netcf currently does).

Alternately, Cole suggested in a separate email that since libvirt's node device driver already reports various status information about devices on the host, we could just beef up the output of virNodeDeviceGetXMLDesc() for net_* devices to include more of the info that's visible in "ip link" and "ip addr".

Or, we could just decide that it's okay for a management application (the main consumer of libvirt) to need to use other APIs to get that information (especially since that's what they already do anyway!)

So, that's my piece to speak. I'm looking for opinions and ideas on a few different fronts:

1) Does this generally sound like a good direction? Or is there something I'm ignoring that renders my points moot?

If you haven't already guessed, I would be in favor of deprecating the virInterface APIs :-).

2) If we are going to do it, how should we proceed?

AFAIK, APIs have never been deprecated in libvirt, so it will be interesting to see how we proceed.

We obviously can't simply *remove* the virInterface API from libvirt (since that would destroy backward compatibility guarantees), but could immediately begin logging some sort of "this API is deprecated" message when any of the functions are called, and then in a later release change the APIs to return an error (while simultaneously removing netcf from the build and dependency lists).

Without much thought, this proposal sounds fine.

At the same time, we would need to decide if the "interface status" functionality needs to be maintained within appropriate virInterface*() APIs, reproduced in virNodeDeviceGetXMLDesc(), or just dropped altogether.

On the netcf side, there are several small patches that have been sitting in git for a few years without being in any official release; it would probably be nice to make one final release before closing up shop. The mailing list could then be closed down, and some final message put in a README in the git repo (on pagure.io) before putting it into some archival state.

After those things are done, the various distros could be notified of the newfound irrelevance of netcf, and given the opportunity to remove the package from their releases.

I look forward to the day! :-)

Regards,
Jim

Reply via email to