From a2a8fd82918b5d3e8ac5c8fd6f2f97be1d4bdf11 Mon Sep 17 00:00:00 2001 From: Jim Fehlig Date: Tue, 5 Jul 2022 11:58:35 -0600 Subject: libnetcontrol patch for libvirt Originally authored by mt@suse.de --- meson.build | 11 ++++- meson_options.txt | 1 + src/interface/interface_backend_netcf.c | 59 ++++++++++++++++++++++++- src/interface/interface_driver.c | 9 +++- src/interface/meson.build | 3 +- tools/virsh.c | 2 + 6 files changed, 80 insertions(+), 5 deletions(-) Index: libvirt-9.0.0/meson.build =================================================================== --- libvirt-9.0.0.orig/meson.build +++ libvirt-9.0.0/meson.build @@ -1017,6 +1017,12 @@ else netcf_dep = dependency('', required: false) endif +netcontrol_version = '0.2.0' +netcontrol_dep = dependency('netcontrol', version: '>=' + netcontrol_version, required: get_option('netcontrol')) +if netcontrol_dep.found() + conf.set('WITH_NETCONTROL', 1) +endif + have_gnu_gettext_tools = false if not get_option('nls').disabled() have_gettext = cc.has_function('gettext') @@ -1427,10 +1433,10 @@ elif get_option('driver_hyperv').enabled error('openwsman is required for the Hyper-V driver') endif -if not get_option('driver_interface').disabled() and conf.has('WITH_LIBVIRTD') and (udev_dep.found() or conf.has('WITH_NETCF')) +if not get_option('driver_interface').disabled() and conf.has('WITH_LIBVIRTD') and (udev_dep.found() or conf.has('WITH_NETCF') or netcontrol_dep.found()) conf.set('WITH_INTERFACE', 1) elif get_option('driver_interface').enabled() - error('Requested the Interface driver without netcf or udev and libvirtd support') + error('Requested the Interface driver without netcf, netcontrol or udev and libvirtd support') endif if not get_option('driver_libxl').disabled() and conf.has('WITH_LIBVIRTD') @@ -2200,6 +2206,7 @@ libs_summary = { 'libssh2': libssh2_dep.found(), 'libutil': libutil_dep.found(), 'netcf': conf.has('WITH_NETCF'), + 'netcontrol': netcontrol_dep.found(), 'NLS': have_gnu_gettext_tools, 'numactl': numactl_dep.found(), 'openwsman': openwsman_dep.found(), Index: libvirt-9.0.0/meson_options.txt =================================================================== --- libvirt-9.0.0.orig/meson_options.txt +++ libvirt-9.0.0/meson_options.txt @@ -29,6 +29,7 @@ option('libpcap', type: 'feature', value option('libssh', type: 'feature', value: 'auto', description: 'libssh support') option('libssh2', type: 'feature', value: 'auto', description: 'libssh2 support') option('netcf', type: 'feature', value: 'auto', description: 'netcf support') +option('netcontrol', type: 'feature', value: 'auto', description: 'netcontrol support') option('nls', type: 'feature', value: 'auto', description: 'nls support') option('numactl', type: 'feature', value: 'auto', description: 'numactl support') option('openwsman', type: 'feature', value: 'auto', description: 'openwsman support') Index: libvirt-9.0.0/src/interface/interface_backend_netcf.c =================================================================== --- libvirt-9.0.0.orig/src/interface/interface_backend_netcf.c +++ libvirt-9.0.0/src/interface/interface_backend_netcf.c @@ -21,7 +21,12 @@ #include -#include +#ifdef WITH_NETCONTROL +# include +# include +#else +# include +#endif #include "virerror.h" #include "datatypes.h" @@ -70,6 +75,37 @@ VIR_ONCE_GLOBAL_INIT(virNetcfDriverState static virNetcfDriverStatePtr driver; +#ifdef WITH_NETCONTROL +static void +interface_nc_log_driver(const char *category ATTRIBUTE_UNUSED, + int priority, + const char *func, + const char *file, + long long line, + const char *msg, + size_t len ATTRIBUTE_UNUSED) +{ + int vp; + + switch (priority) { + case NC_LOG_FATAL: + case NC_LOG_ERROR: + vp = VIR_LOG_ERROR; + break; + case NC_LOG_WARN: + vp = VIR_LOG_WARN; + break; + case NC_LOG_INFO: + vp = VIR_LOG_INFO; + break; + case NC_LOG_DEBUG: + default: + vp = VIR_LOG_DEBUG; + break; + } + virLogMessage(&virLogSelf, vp, file, line, func, 0, "%s", msg); +} +#endif static void virNetcfDriverStateDispose(void *obj) @@ -126,6 +162,10 @@ netcfStateInitialize(bool privileged, virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto error; +#ifdef WITH_NETCONTROL + nc_logger_redirect_to(interface_nc_log_driver); +#endif + /* open netcf */ if (ncf_init(&driver->netcf, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1071,6 +1111,7 @@ static int netcfInterfaceIsActive(virInt return ret; } +#ifdef HAVE_NETCF_TRANSACTIONS static int netcfInterfaceChangeBegin(virConnectPtr conn, unsigned int flags) { int ret = -1; @@ -1142,6 +1183,7 @@ static int netcfInterfaceChangeRollback( return ret; } +#endif /* HAVE_NETCF_TRANSACTIONS */ static virInterfaceDriver interfaceDriver = { .name = INTERFACE_DRIVER_NAME, @@ -1158,9 +1200,11 @@ static virInterfaceDriver interfaceDrive .interfaceCreate = netcfInterfaceCreate, /* 0.7.0 */ .interfaceDestroy = netcfInterfaceDestroy, /* 0.7.0 */ .interfaceIsActive = netcfInterfaceIsActive, /* 0.7.3 */ +#ifdef HAVE_NETCF_TRANSACTIONS .interfaceChangeBegin = netcfInterfaceChangeBegin, /* 0.9.2 */ .interfaceChangeCommit = netcfInterfaceChangeCommit, /* 0.9.2 */ .interfaceChangeRollback = netcfInterfaceChangeRollback, /* 0.9.2 */ +#endif /* HAVE_NETCF_TRANSACTIONS */ }; @@ -1191,6 +1235,19 @@ static virStateDriver interfaceStateDriv int netcfIfaceRegister(void) { + struct netcf *netcf; + + /* Initialization of libnetcontrol will fail if NetworkManager is enabled. + * Skip registration if ncf_init fails. + * TODO: finer-grained check? E.g. is_nm_enabled() + */ + if (ncf_init(&netcf, NULL) != 0) { + VIR_WARN("Failed to initialize libnetcontrol. Management of interface devices is disabled"); + return 0; + } + + ncf_close(netcf); + if (virRegisterConnectDriver(&interfaceConnectDriver, false) < 0) return -1; if (virSetSharedInterfaceDriver(&interfaceDriver) < 0) Index: libvirt-9.0.0/src/interface/interface_driver.c =================================================================== --- libvirt-9.0.0.orig/src/interface/interface_driver.c +++ libvirt-9.0.0/src/interface/interface_driver.c @@ -30,8 +30,15 @@ interfaceRegister(void) if (netcfIfaceRegister() == 0) return 0; #endif /* WITH_NETCF */ +#ifdef WITH_NETCONTROL + /* Attempt to load the netcontrol based backend, which is a slightly + patched netcf backend */ + if (netcfIfaceRegister() == 0) + return 0; +#endif /* WITH_NETCONTROL */ #if WITH_UDEV - /* If there's no netcf or it failed to load, register the udev backend */ + /* If there's no netcf or netcontrol, or it failed to load, register the + udev backend */ if (udevIfaceRegister() == 0) return 0; #endif /* WITH_UDEV */ Index: libvirt-9.0.0/src/interface/meson.build =================================================================== --- libvirt-9.0.0.orig/src/interface/meson.build +++ libvirt-9.0.0/src/interface/meson.build @@ -2,7 +2,7 @@ interface_driver_sources = [ 'interface_driver.c', ] -if conf.has('WITH_NETCF') +if conf.has('WITH_NETCF') or conf.has('WITH_NETCONTROL') interface_driver_sources += 'interface_backend_netcf.c' endif @@ -23,6 +23,7 @@ if conf.has('WITH_INTERFACE') access_dep, libnl_dep, netcf_dep, + netcontrol_dep, udev_dep, ], 'link_args': [ Index: libvirt-9.0.0/tools/virsh.c =================================================================== --- libvirt-9.0.0.orig/tools/virsh.c +++ libvirt-9.0.0/tools/virsh.c @@ -545,6 +545,8 @@ virshShowVersion(vshControl *ctl G_GNUC_ vshPrint(ctl, " Interface"); # if defined(WITH_NETCF) vshPrint(ctl, " netcf"); +# elif defined(WITH_NETCONTROL) + vshPrint(ctl, " netcontrol"); # elif defined(WITH_UDEV) vshPrint(ctl, " udev"); # endif