RFC: deprecating/obsoleting netcf package and libvirt virInterface*() APIs

Jim Fehlig jfehlig at suse.com
Thu Dec 3 04:33:13 UTC 2020


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




More information about the libvir-list mailing list