File libvirt.suse-netcontrol.patch of Package libvirt
From: Olaf Hering <olaf@aepfle.de>
Date: Wed, 21 Feb 2018 10:03:54 +0000
Subject: suse-netcontrol
---
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(-)
--- a/meson.build
+++ b/meson.build
@@ -1116,24 +1116,30 @@ libxml_dep = dependency('libxml-2.0', version: '>=' + libxml_version)
libm_dep = cc.find_library('m')
netcf_version = '0.1.8'
if not get_option('netcf').disabled()
netcf_dep = dependency('netcf', version: '>=' + netcf_version, required: get_option('netcf'))
if netcf_dep.found()
conf.set('WITH_NETCF', 1)
endif
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')
if not have_gettext
intl_dep = cc.find_library('intl', required: false)
have_gettext = intl_dep.found()
else
intl_dep = dependency('', required: false)
endif
if not have_gettext and get_option('nls').enabled()
error('gettext() is required to build libvirt')
endif
@@ -1477,28 +1483,28 @@ if not get_option('driver_esx').disabled() and curl_dep.found()
conf.set('WITH_ESX', 1)
conf.set('WITH_VMX', 1)
elif get_option('driver_esx').enabled()
error('Curl is required for the ESX driver')
endif
if not get_option('driver_hyperv').disabled() and openwsman_dep.found()
conf.set('WITH_HYPERV', 1)
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')
libxl_version = '4.9.0'
libxl_dep = dependency('xenlight', version: '>=' + libxl_version, required: get_option('driver_libxl'))
if libxl_dep.found()
libxl_firmware_dir = libxl_dep.get_variable(pkgconfig : 'xenfirmwaredir', default_value: '')
libxl_execbin = libxl_dep.get_variable(pkgconfig : 'libexec_bin', default_value: '')
if libxl_firmware_dir != ''
conf.set_quoted('LIBXL_FIRMWARE_DIR', libxl_firmware_dir)
endif
@@ -2254,24 +2260,25 @@ libs_summary = {
'json-c': json_c_dep,
'libbsd': libbsd_dep,
'libiscsi': libiscsi_dep,
'libkvm': libkvm_dep,
'libnbd': libnbd_dep,
'libnl': libnl_dep,
'libparted': libparted_dep,
'libpcap': libpcap_dep,
'libssh': libssh_dep,
'libssh2': libssh2_dep,
'libutil': libutil_dep,
'netcf': netcf_dep,
+ 'netcontrol': netcontrol_dep,
'NLS': have_gnu_gettext_tools,
'numactl': numactl_dep,
'openwsman': openwsman_dep,
'parallels-sdk': parallels_sdk_dep,
'pciaccess': pciaccess_dep,
'polkit': conf.has('WITH_POLKIT'),
'rbd': rbd_dep,
'readline': readline_dep,
'sanlock': sanlock_dep,
'sasl': sasl_dep,
'selinux': selinux_dep,
'udev': udev_dep,
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -26,24 +26,25 @@ option('bash_completion_dir', type: 'string', value: '', description: 'directory
option('blkid', type: 'feature', value: 'auto', description: 'blkid support')
option('capng', type: 'feature', value: 'auto', description: 'cap-ng support')
option('curl', type: 'feature', value: 'auto', description: 'curl support')
option('fuse', type: 'feature', value: 'auto', description: 'fuse support')
option('glusterfs', type: 'feature', value: 'auto', description: 'glusterfs support')
option('json_c', type: 'feature', value: 'auto', description: 'JSON-C support')
option('libiscsi', type: 'feature', value: 'auto', description: 'libiscsi support')
option('libnl', type: 'feature', value: 'auto', description: 'libnl support')
option('libpcap', type: 'feature', value: 'auto', description: 'libpcap support')
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')
option('pciaccess', type: 'feature', value: 'auto', description: 'pciaccess support')
option('polkit', type: 'feature', value: 'auto', description: 'use PolicyKit for UNIX socket access checks')
option('readline', type: 'feature', value: 'auto', description: 'readline support')
option('sanlock', type: 'feature', value: 'auto', description: 'sanlock support')
option('sasl', type: 'feature', value: 'auto', description: 'sasl support')
option('selinux', type: 'feature', value: 'auto', description: 'selinux support')
option('selinux_mount', type: 'string', value: '', description: 'set SELinux mount point')
option('sshconfdir', type: 'string', value: '', description: 'directory for SSH client configuration')
# dep:pciaccess
--- a/src/interface/interface_backend_netcf.c
+++ b/src/interface/interface_backend_netcf.c
@@ -12,25 +12,30 @@
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
-#include <netcf.h>
+#ifdef WITH_NETCONTROL
+# include <netcontrol/netcf.h>
+# include <netcontrol/logger.h>
+#else
+# include <netcf.h>
+#endif
#include "virerror.h"
#include "datatypes.h"
#include "interface_driver.h"
#include "interface_conf.h"
#include "viralloc.h"
#include "virlog.h"
#include "virpidfile.h"
#include "viraccessapicheck.h"
#include "virinterfaceobj.h"
#include "virutil.h"
@@ -61,24 +66,55 @@ static int
virNetcfDriverStateOnceInit(void)
{
if (!VIR_CLASS_NEW(virNetcfDriverState, virClassForObjectLockable()))
return -1;
return 0;
}
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)
{
virNetcfDriverStatePtr _driver = obj;
if (_driver->netcf)
ncf_close(_driver->netcf);
if (_driver->lockFD != -1)
virPidFileRelease(_driver->stateDir, "driver", _driver->lockFD);
@@ -117,24 +153,28 @@ netcfStateInitialize(bool privileged,
}
if (g_mkdir_with_parents(driver->stateDir, S_IRWXU) < 0) {
virReportSystemError(errno, _("cannot create state directory '%1$s'"),
driver->stateDir);
goto error;
}
if ((driver->lockFD =
virPidFileAcquire(driver->stateDir, "driver", 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",
_("failed to initialize netcf"));
goto error;
}
return VIR_DRV_STATE_INIT_COMPLETE;
error:
g_clear_pointer(&driver, virObjectUnref);
return VIR_DRV_STATE_INIT_ERROR;
}
@@ -1062,24 +1102,25 @@ static int netcfInterfaceIsActive(virInterfacePtr ifinfo)
goto cleanup;
if (netcfInterfaceObjIsActive(iface, &active) < 0)
goto cleanup;
ret = active ? 1 : 0;
cleanup:
ncf_if_free(iface);
return ret;
}
+#ifdef HAVE_NETCF_TRANSACTIONS
static int netcfInterfaceChangeBegin(virConnectPtr conn, unsigned int flags)
{
int ret = -1;
virCheckFlags(0, -1); /* currently flags must be 0 */
if (virInterfaceChangeBeginEnsureACL(conn) < 0)
return -1;
VIR_WITH_OBJECT_LOCK_GUARD(driver) {
ret = ncf_change_begin(driver->netcf, 0);
if (ret < 0) {
@@ -1133,43 +1174,46 @@ static int netcfInterfaceChangeRollback(virConnectPtr conn, unsigned int flags)
if (ret < 0) {
const char *errmsg, *details;
int errcode = ncf_error(driver->netcf, &errmsg, &details);
virReportError(netcf_to_vir_err(errcode),
_("failed to rollback transaction: %1$s%2$s%3$s"),
errmsg, details ? " - " : "",
NULLSTR_EMPTY(details));
}
}
return ret;
}
+#endif /* HAVE_NETCF_TRANSACTIONS */
static virInterfaceDriver interfaceDriver = {
.name = INTERFACE_DRIVER_NAME,
.connectNumOfInterfaces = netcfConnectNumOfInterfaces, /* 0.7.0 */
.connectListInterfaces = netcfConnectListInterfaces, /* 0.7.0 */
.connectNumOfDefinedInterfaces = netcfConnectNumOfDefinedInterfaces, /* 0.7.0 */
.connectListDefinedInterfaces = netcfConnectListDefinedInterfaces, /* 0.7.0 */
.connectListAllInterfaces = netcfConnectListAllInterfaces, /* 0.10.2 */
.interfaceLookupByName = netcfInterfaceLookupByName, /* 0.7.0 */
.interfaceLookupByMACString = netcfInterfaceLookupByMACString, /* 0.7.0 */
.interfaceGetXMLDesc = netcfInterfaceGetXMLDesc, /* 0.7.0 */
.interfaceDefineXML = netcfInterfaceDefineXML, /* 0.7.0 */
.interfaceUndefine = netcfInterfaceUndefine, /* 0.7.0 */
.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 */
};
static virHypervisorDriver interfaceHypervisorDriver = {
.name = "interface",
.connectOpen = netcfConnectOpen, /* 4.1.0 */
.connectClose = netcfConnectClose, /* 4.1.0 */
.connectIsEncrypted = netcfConnectIsEncrypted, /* 4.1.0 */
.connectIsSecure = netcfConnectIsSecure, /* 4.1.0 */
.connectIsAlive = netcfConnectIsAlive, /* 4.1.0 */
};
@@ -1182,20 +1226,33 @@ static virConnectDriver interfaceConnectDriver = {
};
static virStateDriver interfaceStateDriver = {
.name = INTERFACE_DRIVER_NAME,
.stateInitialize = netcfStateInitialize,
.stateCleanup = netcfStateCleanup,
.stateReload = netcfStateReload,
};
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_INFO("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)
return -1;
if (virRegisterStateDriver(&interfaceStateDriver) < 0)
return -1;
return 0;
}
--- a/src/interface/interface_driver.c
+++ b/src/interface/interface_driver.c
@@ -21,19 +21,26 @@
#include <config.h>
#include "interface_driver.h"
int
interfaceRegister(void)
{
#ifdef WITH_NETCF
/* Attempt to load the netcf based backend first */
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 */
return -1;
}
--- a/src/interface/meson.build
+++ b/src/interface/meson.build
@@ -1,37 +1,38 @@
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
if conf.has('WITH_UDEV')
interface_driver_sources += 'interface_backend_udev.c'
endif
driver_source_files += files(interface_driver_sources)
stateful_driver_source_files += files(interface_driver_sources)
if conf.has('WITH_INTERFACE')
virt_modules += {
'name': 'virt_driver_interface',
'sources': [
files(interface_driver_sources),
],
'deps': [
access_dep,
libnl_dep,
netcf_dep,
+ netcontrol_dep,
udev_dep,
],
'link_args': [
libvirt_no_undefined,
],
}
virt_daemons += {
'name': 'virtinterfaced',
'c_args': [
'-DDAEMON_NAME="virtinterfaced"',
'-DMODULE_NAME="interface"',
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -529,24 +529,26 @@ virshShowVersion(vshControl *ctl G_GNUC_UNUSED)
vshPrint(ctl, " Remote");
#endif
#ifdef WITH_NETWORK
vshPrint(ctl, " Network");
#endif
#ifdef WITH_BRIDGE
vshPrint(ctl, " Bridging");
#endif
#if defined(WITH_INTERFACE)
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
#endif
#ifdef WITH_NWFILTER
vshPrint(ctl, " Nwfilter");
#endif
vshPrint(ctl, "\n");
vshPrint(ctl, "%s", _(" Storage:"));
#ifdef WITH_STORAGE_DIR
vshPrint(ctl, " Dir");