Comment 3 for bug 1764314

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

It is sometimes surprising what extra features libvirt all has - I haven't touched this for all the time working with it - Feature of 2009 it seems :-)

First of all yes, I also can't see anything on 18.04 boxes (not that on 16.04 I'd have got a lot, only "lo" actually).

There is nothing of the common issues:
- no appamor denie
- no error in a full-debug libvirtd log

Internally this goes through virshInterfaceListCollect -> virConnectListAllInterfaces -> conn->interfaceDriver->connectListAllInterfaces

That call to the libvirt daemon succeeds but returns:
(gdb) p *(virshInterfaceListPtr)ifaces
$15 = {ifaces = 0x55555580f370, nifaces = 0}

So that is an empty list from the daemon, check what happens over there.
The backend uses netcf through ncf_list_interfaces and gets a count of zero.

The implementation of this is in ncf.
It does a few checks and then goes to drv_list_interfaces which for us is is implemented in drv_debian.c.
This then calls list_interface_ids with arguments to fill the list (one can set arg 2/3 to 0 to just get a number).

This then uses list_interfaces to generate a list via uniq_device_names and checks against some filters.

But uniq_device_names already gets an argument with "how many" interfaces are to be expected and that is zero.

This number comes from:
  aug_fmt_match(ncf, &devs, "%s/iface", network_interfaces_path);

This implementation is based on ENI as network_interfaces_path is essentially
  static const char *const network_interfaces_path = "/files/etc/network/interfaces"

So I think we found a case of ENI -> (pure) networkd transition causing some issues.
That also explains why on my 16.04 I don't see all interfaces, I have not all (none but lo) configured via ENI in /etc/network/interfaces.

This is not so much a lbivirt, but much more a netcf issue.
IMHO this was all forgotten in the netplan change :-/ and needs implementation.
Maybe it needs more since it seems to just hang around for quite a while.

A testcase for now looks like that:
$ apt source netcf
$ sudo apt build-dep netcf
$ cd netcf-0.2.8
$ ./configure --with-driver=debian
$ make -j12
$ make check
$ cd tests
$ make test-debian
$ make check

That actually should have tested the function we found breaking - odd.
Instead one can for now use a very simplified netcfConnectListInterfacesImpl:

$ sudo apt install libnetcf1

$ cat >> test.c << EOF
#include <netcf.h>
#include <stdio.h>

int main()
{
   int count = 0;
   int status = NETCF_IFACE_ACTIVE | NETCF_IFACE_INACTIVE;
   struct netcf *netcf = NULL;

   if (ncf_init(&netcf, NULL) != 0) {
       printf("Init failed\n");
       return -1;
   }

   count = ncf_num_of_interfaces(netcf, status);
   printf("Count is %d\n", count);
   return 0;
}
EOF

$ gcc -Wall -o test test.c -lnetcf; ./test

That should return a number matching your /et/network/interfaces on 16.04, but due to lacking it nothing on 18.04

Only good thing for now, it seems only libvirt uses netcf and while iface list and such fail they are not strictly required (as we can see it only now shows up for virt-manager centric usage).
Never the less a big issue :-/

There is a udev backend, maybe we should consider switchign instead of implementing so much in netcf - both ways need a in -depth analysis.