[libvirt] [PATCH] build: define WITH_INTERFACE for the driver

<not part of the commit> Really just looking for feedback if this an acceptable update to the previous work. My plan is to add a 'udev' backend that will provide just some basic read-only host interface information. Basically I've been seeing postings to libvirt-users and virt-tools where people are on distros that don't support netcf and are noticing that virt-manager uses HAL or they use libvir APIs and can configure everything for the virtual machine respecting the host except for the network. </not part of the commit> Based exclusively on work by Eric Blake in a patch posted with the same subject. However some modifications related to comments and my plans to add another backend. Added WITH_INTERFACE as the only automake variable deciding whether to build the driver and using WITH_NETCF to identify that we're wanting to use the netcf library as the backend. * configure.ac: Added with_interface and enhanced with_netcf to respect with_interface. * src/interface/netcf_driver.c: Renamed.. * src/interface/interface_backend_netcf.c: ..to this to match storage. * src/interface/netcf_driver.h: Renamed.. * src/interface/interface_driver.h: ..to this. * daemon/Makefile.am: Respect WITH_INTERFACE and WITH_NETCF. --- configure.ac | 44 ++- daemon/Makefile.am | 2 +- daemon/libvirtd.c | 8 +- src/Makefile.am | 24 +- src/interface/interface_backend_netcf.c | 663 +++++++++++++++++++++++++++++++ src/interface/interface_driver.h | 29 ++ src/interface/netcf_driver.c | 663 ------------------------------- src/interface/netcf_driver.h | 29 -- src/util/util.c | 21 +- tests/virdrivermoduletest.c | 2 +- tools/virsh.c | 4 +- 11 files changed, 776 insertions(+), 713 deletions(-) create mode 100644 src/interface/interface_backend_netcf.c create mode 100644 src/interface/interface_driver.h delete mode 100644 src/interface/netcf_driver.c delete mode 100644 src/interface/netcf_driver.h diff --git a/configure.ac b/configure.ac index df39df2..2d7a55e 100644 --- a/configure.ac +++ b/configure.ac @@ -1963,9 +1963,6 @@ if test "$with_netcf" = "yes" || test "$with_netcf" = "check"; then fi fi fi -AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"]) -AC_SUBST([NETCF_CFLAGS]) -AC_SUBST([NETCF_LIBS]) AC_ARG_WITH([secrets], @@ -2806,6 +2803,46 @@ if test "$with_nwfilter" = "yes" ; then fi AM_CONDITIONAL([WITH_NWFILTER], [test "$with_nwfilter" = "yes"]) +dnl check if the interface driver should be compiled +AC_ARG_WITH([interface], + AC_HELP_STRING([--with-interface], + [with host interface driver @<:@default=check@:>@]), [], + [with_interface=check]) + +dnl Don't compile the interface driver without libvirtd +if test "$with_libvirtd" = "no" ; then + with_interface=no +fi + +dnl The interface driver depends on the netcf library +if test "$with_interface:$with_netcf" = "check:yes" ; then + with_interface=yes +fi + +if test "$with_interface:$with_netcf" = "check:no" ; then + with_interface=no +fi + +if test "$with_interface:$with_netcf" = "yes:no" ; then + AC_MSG_ERROR([Requested the Interface driver without netcf support]) +fi + +if test "$with_interface" = "yes" ; then + AC_DEFINE_UNQUOTED([WITH_INTERFACE], [1], + [whether the interface driver is enabled]) +fi +AM_CONDITIONAL([WITH_INTERFACE], [test "$with_interface" = "yes"]) + +dnl If the interface driver is off disable netcf +if test "$with_interface" = "no" ; then + with_netcf=no +fi + +dnl We only use netcf for the interface driver so only enable it then +AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"]) +AC_SUBST([NETCF_CFLAGS]) +AC_SUBST([NETCF_LIBS]) + dnl libblkid is used by several storage drivers; therefore we probe dnl for it unconditionally. AC_ARG_WITH([libblkid], @@ -3018,6 +3055,7 @@ AC_MSG_NOTICE([ Remote: $with_remote]) AC_MSG_NOTICE([ Network: $with_network]) AC_MSG_NOTICE([ Libvirtd: $with_libvirtd]) AC_MSG_NOTICE([ netcf: $with_netcf]) +AC_MSG_NOTICE([Interface: $with_interface]) AC_MSG_NOTICE([ macvtap: $with_macvtap]) AC_MSG_NOTICE([ virtport: $with_virtualport]) AC_MSG_NOTICE([]) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index b00fc13..fbd5a5e 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -147,7 +147,7 @@ if WITH_NETWORK libvirtd_LDADD += ../src/libvirt_driver_network.la endif -if WITH_NETCF +if WITH_INTERFACE libvirtd_LDADD += ../src/libvirt_driver_interface.la endif diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 19dd26b..c2923d5 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -75,8 +75,8 @@ # ifdef WITH_NETWORK # include "network/bridge_driver.h" # endif -# ifdef WITH_NETCF -# include "interface/netcf_driver.h" +# ifdef WITH_INTERFACE +# include "interface/interface_driver.h" # endif # ifdef WITH_STORAGE # include "storage/storage_driver.h" @@ -379,7 +379,7 @@ static void daemonInitialize(void) # ifdef WITH_NWFILTER virDriverLoadModule("nwfilter"); # endif -# ifdef WITH_NETCF +# ifdef WITH_INTERFACE virDriverLoadModule("interface"); # endif # ifdef WITH_QEMU @@ -401,7 +401,7 @@ static void daemonInitialize(void) # ifdef WITH_NETWORK networkRegister(); # endif -# ifdef WITH_NETCF +# ifdef WITH_INTERFACE interfaceRegister(); # endif # ifdef WITH_STORAGE diff --git a/src/Makefile.am b/src/Makefile.am index 95e1bea..72c4d6c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -548,8 +548,17 @@ PARALLELS_DRIVER_SOURCES = \ NETWORK_DRIVER_SOURCES = \ network/bridge_driver.h network/bridge_driver.c -INTERFACE_DRIVER_SOURCES = \ - interface/netcf_driver.h interface/netcf_driver.c +INTERFACE_DRIVER_SOURCES = + +if WITH_INTERFACE +INTERFACE_DRIVER_SOURCES += \ + interface/interface_driver.h +endif + +if WITH_NETCF +INTERFACE_DRIVER_SOURCES += \ + interface/interface_backend_netcf.c +endif SECRET_DRIVER_SOURCES = \ secret/secret_driver.h secret/secret_driver.c @@ -1017,7 +1026,7 @@ endif EXTRA_DIST += network/default.xml -if WITH_NETCF +if WITH_INTERFACE if WITH_DRIVER_MODULES mod_LTLIBRARIES += libvirt_driver_interface.la else @@ -1025,10 +1034,13 @@ noinst_LTLIBRARIES += libvirt_driver_interface.la # Stateful, so linked to daemon instead #libvirt_la_BUILT_LIBADD += libvirt_driver_interface.la endif -libvirt_driver_interface_la_CFLAGS = $(NETCF_CFLAGS) \ - -I$(top_srcdir)/src/conf $(AM_CFLAGS) +libvirt_driver_interface_la_CFLAGS = -I$(top_srcdir)/src/conf $(AM_CFLAGS) libvirt_driver_interface_la_LDFLAGS = $(AM_LDFLAGS) -libvirt_driver_interface_la_LIBADD = $(NETCF_LIBS) +libvirt_driver_interface_la_LIBADD = +if WITH_NETCF +libvirt_driver_interface_la_CFLAGS += $(NETCF_CFLAGS) +libvirt_driver_interface_la_LIBADD += $(NETCF_LIBS) +endif if WITH_DRIVER_MODULES libvirt_driver_interface_la_LIBADD += ../gnulib/lib/libgnu.la libvirt_driver_interface_la_LDFLAGS += -module -avoid-version diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c new file mode 100644 index 0000000..9285b08 --- /dev/null +++ b/src/interface/interface_backend_netcf.c @@ -0,0 +1,663 @@ +/* + * interface_driver.c: backend driver methods to handle physical + * interface configuration using the netcf library. + * + * Copyright (C) 2006-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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/>. + * + * Author: Laine Stump <laine@redhat.com> + */ + +#include <config.h> + +#include <netcf.h> + +#include "virterror_internal.h" +#include "datatypes.h" +#include "interface_driver.h" +#include "interface_conf.h" +#include "memory.h" + +#define VIR_FROM_THIS VIR_FROM_INTERFACE + +/* Main driver state */ +struct interface_driver +{ + virMutex lock; + struct netcf *netcf; +}; + + +static void interfaceDriverLock(struct interface_driver *driver) +{ + virMutexLock(&driver->lock); +} + +static void interfaceDriverUnlock(struct interface_driver *driver) +{ + virMutexUnlock(&driver->lock); +} + +static int netcf_to_vir_err(int netcf_errcode) +{ + switch (netcf_errcode) + { + case NETCF_NOERROR: + /* no error, everything ok */ + return VIR_ERR_OK; + case NETCF_EINTERNAL: + /* internal error, aka bug */ + return VIR_ERR_INTERNAL_ERROR; + case NETCF_EOTHER: + /* other error, copout for being more specific */ + return VIR_ERR_INTERNAL_ERROR; + case NETCF_ENOMEM: + /* + * allocation failed return VIR ERR NO MEMORY + * though it should not be used now. + */ + return 2; + case NETCF_EXMLPARSER: + /* XML parser choked */ + return VIR_ERR_XML_ERROR; + case NETCF_EXMLINVALID: + /* XML invalid in some form */ + return VIR_ERR_XML_ERROR; + case NETCF_ENOENT: + /* Required entry in a tree is missing */ + return VIR_ERR_INTERNAL_ERROR; + case NETCF_EEXEC: + /* external program execution failed or returned non-0 */ + return VIR_ERR_INTERNAL_ERROR; +#ifdef NETCF_EINVALIDOP + case NETCF_EINVALIDOP: + /* attempted operation is invalid while the system is in the current state. */ + return VIR_ERR_OPERATION_INVALID; +#endif + default: + return VIR_ERR_INTERNAL_ERROR; + } +} + +static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfacePtr ifinfo) +{ + /* 1) caller already has lock, + * 2) caller cleans up iface on return + */ + struct netcf_if *iface = ncf_lookup_by_name(ncf, ifinfo->name); + if (!iface) { + const char *errmsg, *details; + int errcode = ncf_error(ncf, &errmsg, &details); + if (errcode != NETCF_NOERROR) { + virReportError(netcf_to_vir_err(errcode), + _("couldn't find interface named '%s': %s%s%s"), + ifinfo->name, errmsg, details ? " - " : "", + details ? details : ""); + } else { + virReportError(VIR_ERR_NO_INTERFACE, + _("couldn't find interface named '%s'"), + ifinfo->name); + } + } + return iface; +} + +static virDrvOpenStatus interfaceOpenInterface(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + unsigned int flags) +{ + struct interface_driver *driverState; + + virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); + + if (VIR_ALLOC(driverState) < 0) + { + virReportOOMError(); + goto alloc_error; + } + + /* initialize non-0 stuff in driverState */ + if (virMutexInit(&driverState->lock) < 0) + { + /* what error to report? */ + goto mutex_error; + } + + /* open netcf */ + if (ncf_init(&driverState->netcf, NULL) != 0) + { + /* what error to report? */ + goto netcf_error; + } + + conn->interfacePrivateData = driverState; + return VIR_DRV_OPEN_SUCCESS; + +netcf_error: + if (driverState->netcf) + { + ncf_close(driverState->netcf); + } + virMutexDestroy (&driverState->lock); +mutex_error: + VIR_FREE(driverState); +alloc_error: + return VIR_DRV_OPEN_ERROR; +} + +static int interfaceCloseInterface(virConnectPtr conn) +{ + + if (conn->interfacePrivateData != NULL) + { + struct interface_driver *driver = conn->interfacePrivateData; + + /* close netcf instance */ + ncf_close(driver->netcf); + /* destroy lock */ + virMutexDestroy(&driver->lock); + /* free driver state */ + VIR_FREE(driver); + } + conn->interfacePrivateData = NULL; + return 0; +} + +static int interfaceNumOfInterfaces(virConnectPtr conn) +{ + int count; + struct interface_driver *driver = conn->interfacePrivateData; + + interfaceDriverLock(driver); + count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_ACTIVE); + if (count < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to get number of interfaces on host: %s%s%s"), + errmsg, details ? " - " : "", details ? details : ""); + } + + interfaceDriverUnlock(driver); + return count; +} + +static int interfaceListInterfaces(virConnectPtr conn, char **const names, int nnames) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int count; + + interfaceDriverLock(driver); + + count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_ACTIVE); + if (count < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to list host interfaces: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return count; + +} + +static int interfaceNumOfDefinedInterfaces(virConnectPtr conn) +{ + int count; + struct interface_driver *driver = conn->interfacePrivateData; + + interfaceDriverLock(driver); + count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_INACTIVE); + if (count < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to get number of defined interfaces on host: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return count; +} + +static int interfaceListDefinedInterfaces(virConnectPtr conn, char **const names, int nnames) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int count; + + interfaceDriverLock(driver); + + count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_INACTIVE); + if (count < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to list host defined interfaces: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return count; + +} + +static virInterfacePtr interfaceLookupByName(virConnectPtr conn, + const char *name) +{ + struct interface_driver *driver = conn->interfacePrivateData; + struct netcf_if *iface; + virInterfacePtr ret = NULL; + + interfaceDriverLock(driver); + iface = ncf_lookup_by_name(driver->netcf, name); + if (!iface) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + if (errcode != NETCF_NOERROR) { + virReportError(netcf_to_vir_err(errcode), + _("couldn't find interface named '%s': %s%s%s"), + name, errmsg, + details ? " - " : "", details ? details : ""); + } else { + virReportError(VIR_ERR_NO_INTERFACE, + _("couldn't find interface named '%s'"), name); + } + goto cleanup; + } + + ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +static virInterfacePtr interfaceLookupByMACString(virConnectPtr conn, + const char *macstr) +{ + struct interface_driver *driver = conn->interfacePrivateData; + struct netcf_if *iface; + int niface; + virInterfacePtr ret = NULL; + + interfaceDriverLock(driver); + niface = ncf_lookup_by_mac_string(driver->netcf, macstr, 1, &iface); + + if (niface < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("couldn't find interface with MAC address '%s': %s%s%s"), + macstr, errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + if (niface == 0) { + virReportError(VIR_ERR_NO_INTERFACE, + _("couldn't find interface with MAC address '%s'"), + macstr); + goto cleanup; + } + if (niface > 1) { + virReportError(VIR_ERR_MULTIPLE_INTERFACES, + "%s", _("multiple interfaces with matching MAC address")); + goto cleanup; + } + + ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +static char *interfaceGetXMLDesc(virInterfacePtr ifinfo, + unsigned int flags) +{ + struct interface_driver *driver = ifinfo->conn->interfacePrivateData; + struct netcf_if *iface = NULL; + char *xmlstr = NULL; + virInterfaceDefPtr ifacedef = NULL; + char *ret = NULL; + + virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL); + + interfaceDriverLock(driver); + + iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); + if (!iface) { + /* helper already reported error */ + goto cleanup; + } + + if ((flags & VIR_INTERFACE_XML_INACTIVE)) { + xmlstr = ncf_if_xml_desc(iface); + } else { + xmlstr = ncf_if_xml_state(iface); + } + if (!xmlstr) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("could not get interface XML description: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + + ifacedef = virInterfaceDefParseString(xmlstr); + if (!ifacedef) { + /* error was already reported */ + goto cleanup; + } + + ret = virInterfaceDefFormat(ifacedef); + if (!ret) { + /* error was already reported */ + goto cleanup; + } + +cleanup: + ncf_if_free(iface); + VIR_FREE(xmlstr); + virInterfaceDefFree(ifacedef); + interfaceDriverUnlock(driver); + return ret; +} + +static virInterfacePtr interfaceDefineXML(virConnectPtr conn, + const char *xml, + unsigned int flags) +{ + struct interface_driver *driver = conn->interfacePrivateData; + struct netcf_if *iface = NULL; + char *xmlstr = NULL; + virInterfaceDefPtr ifacedef = NULL; + virInterfacePtr ret = NULL; + + virCheckFlags(0, NULL); + + interfaceDriverLock(driver); + + ifacedef = virInterfaceDefParseString(xml); + if (!ifacedef) { + /* error was already reported */ + goto cleanup; + } + + xmlstr = virInterfaceDefFormat(ifacedef); + if (!xmlstr) { + /* error was already reported */ + goto cleanup; + } + + iface = ncf_define(driver->netcf, xmlstr); + if (!iface) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("could not get interface XML description: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + + ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); + +cleanup: + ncf_if_free(iface); + VIR_FREE(xmlstr); + virInterfaceDefFree(ifacedef); + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceUndefine(virInterfacePtr ifinfo) { + struct interface_driver *driver = ifinfo->conn->interfacePrivateData; + struct netcf_if *iface = NULL; + int ret = -1; + + interfaceDriverLock(driver); + + iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); + if (!iface) { + /* helper already reported error */ + goto cleanup; + } + + ret = ncf_if_undefine(iface); + if (ret < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to undefine interface %s: %s%s%s"), + ifinfo->name, errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceCreate(virInterfacePtr ifinfo, + unsigned int flags) +{ + struct interface_driver *driver = ifinfo->conn->interfacePrivateData; + struct netcf_if *iface = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + interfaceDriverLock(driver); + + iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); + if (!iface) { + /* helper already reported error */ + goto cleanup; + } + + ret = ncf_if_up(iface); + if (ret < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to create (start) interface %s: %s%s%s"), + ifinfo->name, errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceDestroy(virInterfacePtr ifinfo, + unsigned int flags) +{ + struct interface_driver *driver = ifinfo->conn->interfacePrivateData; + struct netcf_if *iface = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + interfaceDriverLock(driver); + + iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); + if (!iface) { + /* helper already reported error */ + goto cleanup; + } + + ret = ncf_if_down(iface); + if (ret < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to destroy (stop) interface %s: %s%s%s"), + ifinfo->name, errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceIsActive(virInterfacePtr ifinfo) +{ + struct interface_driver *driver = ifinfo->conn->interfacePrivateData; + struct netcf_if *iface = NULL; + unsigned int flags = 0; + int ret = -1; + + interfaceDriverLock(driver); + + iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); + if (!iface) { + /* helper already reported error */ + goto cleanup; + } + + if (ncf_if_status(iface, &flags) < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to get status of interface %s: %s%s%s"), + ifinfo->name, errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + + ret = flags & NETCF_IFACE_ACTIVE ? 1 : 0; + +cleanup: + ncf_if_free(iface); + interfaceDriverUnlock(driver); + return ret; +} + +#ifdef HAVE_NETCF_TRANSACTIONS +static int interfaceChangeBegin(virConnectPtr conn, unsigned int flags) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int ret; + + virCheckFlags(0, -1); /* currently flags must be 0 */ + + interfaceDriverLock(driver); + + ret = ncf_change_begin(driver->netcf, 0); + if (ret < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to begin transaction: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceChangeCommit(virConnectPtr conn, unsigned int flags) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int ret; + + virCheckFlags(0, -1); /* currently flags must be 0 */ + + interfaceDriverLock(driver); + + ret = ncf_change_commit(driver->netcf, 0); + if (ret < 0) { + const char *errmsg, *details; + int errcode = ncf_error(driver->netcf, &errmsg, &details); + virReportError(netcf_to_vir_err(errcode), + _("failed to commit transaction: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return ret; +} + +static int interfaceChangeRollback(virConnectPtr conn, unsigned int flags) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int ret; + + virCheckFlags(0, -1); /* currently flags must be 0 */ + + interfaceDriverLock(driver); + + ret = ncf_change_rollback(driver->netcf, 0); + 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: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + } + + interfaceDriverUnlock(driver); + return ret; +} +#endif /* HAVE_NETCF_TRANSACTIONS */ + +static virInterfaceDriver interfaceDriver = { + "Interface", + .open = interfaceOpenInterface, /* 0.7.0 */ + .close = interfaceCloseInterface, /* 0.7.0 */ + .numOfInterfaces = interfaceNumOfInterfaces, /* 0.7.0 */ + .listInterfaces = interfaceListInterfaces, /* 0.7.0 */ + .numOfDefinedInterfaces = interfaceNumOfDefinedInterfaces, /* 0.7.0 */ + .listDefinedInterfaces = interfaceListDefinedInterfaces, /* 0.7.0 */ + .interfaceLookupByName = interfaceLookupByName, /* 0.7.0 */ + .interfaceLookupByMACString = interfaceLookupByMACString, /* 0.7.0 */ + .interfaceGetXMLDesc = interfaceGetXMLDesc, /* 0.7.0 */ + .interfaceDefineXML = interfaceDefineXML, /* 0.7.0 */ + .interfaceUndefine = interfaceUndefine, /* 0.7.0 */ + .interfaceCreate = interfaceCreate, /* 0.7.0 */ + .interfaceDestroy = interfaceDestroy, /* 0.7.0 */ + .interfaceIsActive = interfaceIsActive, /* 0.7.3 */ +#ifdef HAVE_NETCF_TRANSACTIONS + .interfaceChangeBegin = interfaceChangeBegin, /* 0.9.2 */ + .interfaceChangeCommit = interfaceChangeCommit, /* 0.9.2 */ + .interfaceChangeRollback = interfaceChangeRollback, /* 0.9.2 */ +#endif /* HAVE_NETCF_TRANSACTIONS */ +}; + +int interfaceRegister(void) { + virRegisterInterfaceDriver(&interfaceDriver); + return 0; +} diff --git a/src/interface/interface_driver.h b/src/interface/interface_driver.h new file mode 100644 index 0000000..38fbc77 --- /dev/null +++ b/src/interface/interface_driver.h @@ -0,0 +1,29 @@ +/* + * interface_driver.h: core driver methods for managing physical host interfaces + * + * Copyright (C) 2006, 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * 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/>. + * + * Author: Laine Stump <laine@redhat.com> + */ + + +#ifndef __VIR_INTERFACE__DRIVER_H +# define __VIR_INTERFACE__DRIVER_H + +int interfaceRegister(void); + +#endif /* __VIR_INTERFACE__DRIVER_H */ diff --git a/src/interface/netcf_driver.c b/src/interface/netcf_driver.c deleted file mode 100644 index 935be66..0000000 --- a/src/interface/netcf_driver.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * interface_driver.c: backend driver methods to handle physical - * interface configuration using the netcf library. - * - * Copyright (C) 2006-2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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/>. - * - * Author: Laine Stump <laine@redhat.com> - */ - -#include <config.h> - -#include <netcf.h> - -#include "virterror_internal.h" -#include "datatypes.h" -#include "netcf_driver.h" -#include "interface_conf.h" -#include "memory.h" - -#define VIR_FROM_THIS VIR_FROM_INTERFACE - -/* Main driver state */ -struct interface_driver -{ - virMutex lock; - struct netcf *netcf; -}; - - -static void interfaceDriverLock(struct interface_driver *driver) -{ - virMutexLock(&driver->lock); -} - -static void interfaceDriverUnlock(struct interface_driver *driver) -{ - virMutexUnlock(&driver->lock); -} - -static int netcf_to_vir_err(int netcf_errcode) -{ - switch (netcf_errcode) - { - case NETCF_NOERROR: - /* no error, everything ok */ - return VIR_ERR_OK; - case NETCF_EINTERNAL: - /* internal error, aka bug */ - return VIR_ERR_INTERNAL_ERROR; - case NETCF_EOTHER: - /* other error, copout for being more specific */ - return VIR_ERR_INTERNAL_ERROR; - case NETCF_ENOMEM: - /* - * allocation failed return VIR ERR NO MEMORY - * though it should not be used now. - */ - return 2; - case NETCF_EXMLPARSER: - /* XML parser choked */ - return VIR_ERR_XML_ERROR; - case NETCF_EXMLINVALID: - /* XML invalid in some form */ - return VIR_ERR_XML_ERROR; - case NETCF_ENOENT: - /* Required entry in a tree is missing */ - return VIR_ERR_INTERNAL_ERROR; - case NETCF_EEXEC: - /* external program execution failed or returned non-0 */ - return VIR_ERR_INTERNAL_ERROR; -#ifdef NETCF_EINVALIDOP - case NETCF_EINVALIDOP: - /* attempted operation is invalid while the system is in the current state. */ - return VIR_ERR_OPERATION_INVALID; -#endif - default: - return VIR_ERR_INTERNAL_ERROR; - } -} - -static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfacePtr ifinfo) -{ - /* 1) caller already has lock, - * 2) caller cleans up iface on return - */ - struct netcf_if *iface = ncf_lookup_by_name(ncf, ifinfo->name); - if (!iface) { - const char *errmsg, *details; - int errcode = ncf_error(ncf, &errmsg, &details); - if (errcode != NETCF_NOERROR) { - virReportError(netcf_to_vir_err(errcode), - _("couldn't find interface named '%s': %s%s%s"), - ifinfo->name, errmsg, details ? " - " : "", - details ? details : ""); - } else { - virReportError(VIR_ERR_NO_INTERFACE, - _("couldn't find interface named '%s'"), - ifinfo->name); - } - } - return iface; -} - -static virDrvOpenStatus interfaceOpenInterface(virConnectPtr conn, - virConnectAuthPtr auth ATTRIBUTE_UNUSED, - unsigned int flags) -{ - struct interface_driver *driverState; - - virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); - - if (VIR_ALLOC(driverState) < 0) - { - virReportOOMError(); - goto alloc_error; - } - - /* initialize non-0 stuff in driverState */ - if (virMutexInit(&driverState->lock) < 0) - { - /* what error to report? */ - goto mutex_error; - } - - /* open netcf */ - if (ncf_init(&driverState->netcf, NULL) != 0) - { - /* what error to report? */ - goto netcf_error; - } - - conn->interfacePrivateData = driverState; - return VIR_DRV_OPEN_SUCCESS; - -netcf_error: - if (driverState->netcf) - { - ncf_close(driverState->netcf); - } - virMutexDestroy (&driverState->lock); -mutex_error: - VIR_FREE(driverState); -alloc_error: - return VIR_DRV_OPEN_ERROR; -} - -static int interfaceCloseInterface(virConnectPtr conn) -{ - - if (conn->interfacePrivateData != NULL) - { - struct interface_driver *driver = conn->interfacePrivateData; - - /* close netcf instance */ - ncf_close(driver->netcf); - /* destroy lock */ - virMutexDestroy(&driver->lock); - /* free driver state */ - VIR_FREE(driver); - } - conn->interfacePrivateData = NULL; - return 0; -} - -static int interfaceNumOfInterfaces(virConnectPtr conn) -{ - int count; - struct interface_driver *driver = conn->interfacePrivateData; - - interfaceDriverLock(driver); - count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_ACTIVE); - if (count < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to get number of interfaces on host: %s%s%s"), - errmsg, details ? " - " : "", details ? details : ""); - } - - interfaceDriverUnlock(driver); - return count; -} - -static int interfaceListInterfaces(virConnectPtr conn, char **const names, int nnames) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int count; - - interfaceDriverLock(driver); - - count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_ACTIVE); - if (count < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to list host interfaces: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return count; - -} - -static int interfaceNumOfDefinedInterfaces(virConnectPtr conn) -{ - int count; - struct interface_driver *driver = conn->interfacePrivateData; - - interfaceDriverLock(driver); - count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_INACTIVE); - if (count < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to get number of defined interfaces on host: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return count; -} - -static int interfaceListDefinedInterfaces(virConnectPtr conn, char **const names, int nnames) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int count; - - interfaceDriverLock(driver); - - count = ncf_list_interfaces(driver->netcf, nnames, names, NETCF_IFACE_INACTIVE); - if (count < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to list host defined interfaces: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return count; - -} - -static virInterfacePtr interfaceLookupByName(virConnectPtr conn, - const char *name) -{ - struct interface_driver *driver = conn->interfacePrivateData; - struct netcf_if *iface; - virInterfacePtr ret = NULL; - - interfaceDriverLock(driver); - iface = ncf_lookup_by_name(driver->netcf, name); - if (!iface) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - if (errcode != NETCF_NOERROR) { - virReportError(netcf_to_vir_err(errcode), - _("couldn't find interface named '%s': %s%s%s"), - name, errmsg, - details ? " - " : "", details ? details : ""); - } else { - virReportError(VIR_ERR_NO_INTERFACE, - _("couldn't find interface named '%s'"), name); - } - goto cleanup; - } - - ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -static virInterfacePtr interfaceLookupByMACString(virConnectPtr conn, - const char *macstr) -{ - struct interface_driver *driver = conn->interfacePrivateData; - struct netcf_if *iface; - int niface; - virInterfacePtr ret = NULL; - - interfaceDriverLock(driver); - niface = ncf_lookup_by_mac_string(driver->netcf, macstr, 1, &iface); - - if (niface < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("couldn't find interface with MAC address '%s': %s%s%s"), - macstr, errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - if (niface == 0) { - virReportError(VIR_ERR_NO_INTERFACE, - _("couldn't find interface with MAC address '%s'"), - macstr); - goto cleanup; - } - if (niface > 1) { - virReportError(VIR_ERR_MULTIPLE_INTERFACES, - "%s", _("multiple interfaces with matching MAC address")); - goto cleanup; - } - - ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -static char *interfaceGetXMLDesc(virInterfacePtr ifinfo, - unsigned int flags) -{ - struct interface_driver *driver = ifinfo->conn->interfacePrivateData; - struct netcf_if *iface = NULL; - char *xmlstr = NULL; - virInterfaceDefPtr ifacedef = NULL; - char *ret = NULL; - - virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL); - - interfaceDriverLock(driver); - - iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); - if (!iface) { - /* helper already reported error */ - goto cleanup; - } - - if ((flags & VIR_INTERFACE_XML_INACTIVE)) { - xmlstr = ncf_if_xml_desc(iface); - } else { - xmlstr = ncf_if_xml_state(iface); - } - if (!xmlstr) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("could not get interface XML description: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - - ifacedef = virInterfaceDefParseString(xmlstr); - if (!ifacedef) { - /* error was already reported */ - goto cleanup; - } - - ret = virInterfaceDefFormat(ifacedef); - if (!ret) { - /* error was already reported */ - goto cleanup; - } - -cleanup: - ncf_if_free(iface); - VIR_FREE(xmlstr); - virInterfaceDefFree(ifacedef); - interfaceDriverUnlock(driver); - return ret; -} - -static virInterfacePtr interfaceDefineXML(virConnectPtr conn, - const char *xml, - unsigned int flags) -{ - struct interface_driver *driver = conn->interfacePrivateData; - struct netcf_if *iface = NULL; - char *xmlstr = NULL; - virInterfaceDefPtr ifacedef = NULL; - virInterfacePtr ret = NULL; - - virCheckFlags(0, NULL); - - interfaceDriverLock(driver); - - ifacedef = virInterfaceDefParseString(xml); - if (!ifacedef) { - /* error was already reported */ - goto cleanup; - } - - xmlstr = virInterfaceDefFormat(ifacedef); - if (!xmlstr) { - /* error was already reported */ - goto cleanup; - } - - iface = ncf_define(driver->netcf, xmlstr); - if (!iface) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("could not get interface XML description: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - - ret = virGetInterface(conn, ncf_if_name(iface), ncf_if_mac_string(iface)); - -cleanup: - ncf_if_free(iface); - VIR_FREE(xmlstr); - virInterfaceDefFree(ifacedef); - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceUndefine(virInterfacePtr ifinfo) { - struct interface_driver *driver = ifinfo->conn->interfacePrivateData; - struct netcf_if *iface = NULL; - int ret = -1; - - interfaceDriverLock(driver); - - iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); - if (!iface) { - /* helper already reported error */ - goto cleanup; - } - - ret = ncf_if_undefine(iface); - if (ret < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to undefine interface %s: %s%s%s"), - ifinfo->name, errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceCreate(virInterfacePtr ifinfo, - unsigned int flags) -{ - struct interface_driver *driver = ifinfo->conn->interfacePrivateData; - struct netcf_if *iface = NULL; - int ret = -1; - - virCheckFlags(0, -1); - - interfaceDriverLock(driver); - - iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); - if (!iface) { - /* helper already reported error */ - goto cleanup; - } - - ret = ncf_if_up(iface); - if (ret < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to create (start) interface %s: %s%s%s"), - ifinfo->name, errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceDestroy(virInterfacePtr ifinfo, - unsigned int flags) -{ - struct interface_driver *driver = ifinfo->conn->interfacePrivateData; - struct netcf_if *iface = NULL; - int ret = -1; - - virCheckFlags(0, -1); - - interfaceDriverLock(driver); - - iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); - if (!iface) { - /* helper already reported error */ - goto cleanup; - } - - ret = ncf_if_down(iface); - if (ret < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to destroy (stop) interface %s: %s%s%s"), - ifinfo->name, errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceIsActive(virInterfacePtr ifinfo) -{ - struct interface_driver *driver = ifinfo->conn->interfacePrivateData; - struct netcf_if *iface = NULL; - unsigned int flags = 0; - int ret = -1; - - interfaceDriverLock(driver); - - iface = interfaceDriverGetNetcfIF(driver->netcf, ifinfo); - if (!iface) { - /* helper already reported error */ - goto cleanup; - } - - if (ncf_if_status(iface, &flags) < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to get status of interface %s: %s%s%s"), - ifinfo->name, errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - - ret = flags & NETCF_IFACE_ACTIVE ? 1 : 0; - -cleanup: - ncf_if_free(iface); - interfaceDriverUnlock(driver); - return ret; -} - -#ifdef HAVE_NETCF_TRANSACTIONS -static int interfaceChangeBegin(virConnectPtr conn, unsigned int flags) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int ret; - - virCheckFlags(0, -1); /* currently flags must be 0 */ - - interfaceDriverLock(driver); - - ret = ncf_change_begin(driver->netcf, 0); - if (ret < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to begin transaction: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceChangeCommit(virConnectPtr conn, unsigned int flags) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int ret; - - virCheckFlags(0, -1); /* currently flags must be 0 */ - - interfaceDriverLock(driver); - - ret = ncf_change_commit(driver->netcf, 0); - if (ret < 0) { - const char *errmsg, *details; - int errcode = ncf_error(driver->netcf, &errmsg, &details); - virReportError(netcf_to_vir_err(errcode), - _("failed to commit transaction: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return ret; -} - -static int interfaceChangeRollback(virConnectPtr conn, unsigned int flags) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int ret; - - virCheckFlags(0, -1); /* currently flags must be 0 */ - - interfaceDriverLock(driver); - - ret = ncf_change_rollback(driver->netcf, 0); - 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: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - } - - interfaceDriverUnlock(driver); - return ret; -} -#endif /* HAVE_NETCF_TRANSACTIONS */ - -static virInterfaceDriver interfaceDriver = { - "Interface", - .open = interfaceOpenInterface, /* 0.7.0 */ - .close = interfaceCloseInterface, /* 0.7.0 */ - .numOfInterfaces = interfaceNumOfInterfaces, /* 0.7.0 */ - .listInterfaces = interfaceListInterfaces, /* 0.7.0 */ - .numOfDefinedInterfaces = interfaceNumOfDefinedInterfaces, /* 0.7.0 */ - .listDefinedInterfaces = interfaceListDefinedInterfaces, /* 0.7.0 */ - .interfaceLookupByName = interfaceLookupByName, /* 0.7.0 */ - .interfaceLookupByMACString = interfaceLookupByMACString, /* 0.7.0 */ - .interfaceGetXMLDesc = interfaceGetXMLDesc, /* 0.7.0 */ - .interfaceDefineXML = interfaceDefineXML, /* 0.7.0 */ - .interfaceUndefine = interfaceUndefine, /* 0.7.0 */ - .interfaceCreate = interfaceCreate, /* 0.7.0 */ - .interfaceDestroy = interfaceDestroy, /* 0.7.0 */ - .interfaceIsActive = interfaceIsActive, /* 0.7.3 */ -#ifdef HAVE_NETCF_TRANSACTIONS - .interfaceChangeBegin = interfaceChangeBegin, /* 0.9.2 */ - .interfaceChangeCommit = interfaceChangeCommit, /* 0.9.2 */ - .interfaceChangeRollback = interfaceChangeRollback, /* 0.9.2 */ -#endif /* HAVE_NETCF_TRANSACTIONS */ -}; - -int interfaceRegister(void) { - virRegisterInterfaceDriver(&interfaceDriver); - return 0; -} diff --git a/src/interface/netcf_driver.h b/src/interface/netcf_driver.h deleted file mode 100644 index 38fbc77..0000000 --- a/src/interface/netcf_driver.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * interface_driver.h: core driver methods for managing physical host interfaces - * - * Copyright (C) 2006, 2007 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * 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/>. - * - * Author: Laine Stump <laine@redhat.com> - */ - - -#ifndef __VIR_INTERFACE__DRIVER_H -# define __VIR_INTERFACE__DRIVER_H - -int interfaceRegister(void); - -#endif /* __VIR_INTERFACE__DRIVER_H */ diff --git a/src/util/util.c b/src/util/util.c index 9068e0f..793f803 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1251,39 +1251,52 @@ int virDirCreate(const char *path ATTRIBUTE_UNUSED, } #endif /* WIN32 */ +#define here fprintf(stderr, "%s:%d %s\n", __func__, __LINE__, path) + static int virFileMakePathHelper(char *path, mode_t mode) { struct stat st; char *p; if (stat(path, &st) >= 0) { - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st.st_mode)) { + here; return 0; + } errno = ENOTDIR; + here; return -1; } - if (errno != ENOENT) + if (errno != ENOENT) { + here; return -1; + } if ((p = strrchr(path, '/')) == NULL) { errno = EINVAL; + here; return -1; } if (p != path) { *p = '\0'; - if (virFileMakePathHelper(path, mode) < 0) + if (virFileMakePathHelper(path, mode) < 0) { + here; return -1; + } *p = '/'; } - if (mkdir(path, mode) < 0 && errno != EEXIST) + if (mkdir(path, mode) < 0 && errno != EEXIST) { + here; return -1; + } + here; return 0; } diff --git a/tests/virdrivermoduletest.c b/tests/virdrivermoduletest.c index 4d6e91e..8762de4 100644 --- a/tests/virdrivermoduletest.c +++ b/tests/virdrivermoduletest.c @@ -79,7 +79,7 @@ mymain(void) #ifdef WITH_NWFILTER TEST("nwfilter", NULL); #endif -#ifdef WITH_NETCF +#ifdef WITH_INTERFACE TEST("interface", NULL); #endif #ifdef WITH_QEMU diff --git a/tools/virsh.c b/tools/virsh.c index 7a5b92c..b8ec663 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2643,8 +2643,8 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_BRIDGE vshPrint(ctl, " Bridging"); #endif -#ifdef WITH_NETCF - vshPrint(ctl, " Interface"); +#if defined(WITH_INTERFACE) && defined(WITH_NETCF) + vshPrint(ctl, " Interface (netcf)"); #endif #ifdef WITH_NWFILTER vshPrint(ctl, " Nwfilter"); -- 1.7.8.6

On 08/28/2012 09:17 PM, Doug Goldstein wrote:
<not part of the commit> Really just looking for feedback if this an acceptable update to the previous work. My plan is to add a 'udev' backend that will provide just some basic read-only host interface information. Basically I've been seeing postings to libvirt-users and virt-tools where people are on distros that don't support netcf and are noticing that virt-manager uses HAL or they use libvir APIs and can configure everything for the virtual machine respecting the host except for the network. </not part of the commit>
It's best to stick comments like this...
Based exclusively on work by Eric Blake in a patch posted with the same subject. However some modifications related to comments and my plans to add another backend.
Thanks for picking up work on my old attempt.
Added WITH_INTERFACE as the only automake variable deciding whether to build the driver and using WITH_NETCF to identify that we're wanting to use the netcf library as the backend.
* configure.ac: Added with_interface and enhanced with_netcf to respect with_interface.
This sounds backwards. If I recall the discussion back on my old attempt, the consensus moved towards wanting all library checks first, and all driver checks last. But I'll have to look at the actual configure changes to see if they make sense.
* src/interface/netcf_driver.c: Renamed.. * src/interface/interface_backend_netcf.c: ..to this to match storage. * src/interface/netcf_driver.h: Renamed.. * src/interface/interface_driver.h: ..to this. * daemon/Makefile.am: Respect WITH_INTERFACE and WITH_NETCF. ---
...here, after the '---' marker. Then 'git am' will automatically discard them, while they will still be available as a review hint to the reader.
src/Makefile.am | 24 +- src/interface/interface_backend_netcf.c | 663 +++++++++++++++++++++++++++++++ src/interface/interface_driver.h | 29 ++ src/interface/netcf_driver.c | 663 ------------------------------- src/interface/netcf_driver.h | 29 --
'git config diff.renames true', then this will output a MUCH more compact patch.
+++ b/configure.ac @@ -1963,9 +1963,6 @@ if test "$with_netcf" = "yes" || test "$with_netcf" = "check"; then fi fi fi -AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"]) -AC_SUBST([NETCF_CFLAGS]) -AC_SUBST([NETCF_LIBS])
This delays the netcf probe...
AC_ARG_WITH([secrets], @@ -2806,6 +2803,46 @@ if test "$with_nwfilter" = "yes" ; then fi AM_CONDITIONAL([WITH_NWFILTER], [test "$with_nwfilter" = "yes"])
+dnl check if the interface driver should be compiled +AC_ARG_WITH([interface], + AC_HELP_STRING([--with-interface], + [with host interface driver @<:@default=check@:>@]), [], + [with_interface=check]) + +dnl Don't compile the interface driver without libvirtd +if test "$with_libvirtd" = "no" ; then + with_interface=no +fi + +dnl The interface driver depends on the netcf library +if test "$with_interface:$with_netcf" = "check:yes" ; then + with_interface=yes +fi
...but this tries to make decisions based on the probe...
+ +if test "$with_interface:$with_netcf" = "check:no" ; then + with_interface=no +fi + +if test "$with_interface:$with_netcf" = "yes:no" ; then + AC_MSG_ERROR([Requested the Interface driver without netcf support]) +fi + +if test "$with_interface" = "yes" ; then + AC_DEFINE_UNQUOTED([WITH_INTERFACE], [1], + [whether the interface driver is enabled]) +fi +AM_CONDITIONAL([WITH_INTERFACE], [test "$with_interface" = "yes"]) + +dnl If the interface driver is off disable netcf +if test "$with_interface" = "no" ; then + with_netcf=no +fi + +dnl We only use netcf for the interface driver so only enable it then +AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"]) +AC_SUBST([NETCF_CFLAGS]) +AC_SUBST([NETCF_LIBS])
...that doesn't occur until here. So this logic needs to be rewritten. I think the correct order is to check netcf first, (add in your new backend check at this point), and _finally_ check with_interface, using: if test $with_interface = yes; then require at least one backend (for now, netcf) is also yes, or fail else if test $with_interface = check; then if at least one backend is yes, then set yes fi
@@ -3018,6 +3055,7 @@ AC_MSG_NOTICE([ Remote: $with_remote]) AC_MSG_NOTICE([ Network: $with_network]) AC_MSG_NOTICE([ Libvirtd: $with_libvirtd]) AC_MSG_NOTICE([ netcf: $with_netcf]) +AC_MSG_NOTICE([Interface: $with_interface]) AC_MSG_NOTICE([ macvtap: $with_macvtap]) AC_MSG_NOTICE([ virtport: $with_virtualport]) AC_MSG_NOTICE([])
I think there's still more data we should be outputting in this section, as well as some re-ordering. with_netcf should be output in the libraries section, not the drivers section.
+++ b/src/util/util.c @@ -1251,39 +1251,52 @@ int virDirCreate(const char *path ATTRIBUTE_UNUSED, } #endif /* WIN32 */
+#define here fprintf(stderr, "%s:%d %s\n", __func__, __LINE__, path)
leftover debugging?
+ static int virFileMakePathHelper(char *path, mode_t mode) { struct stat st; char *p;
if (stat(path, &st) >= 0) { - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st.st_mode)) { + here; return 0; + }
errno = ENOTDIR; + here; return -1; ...
Kill this hunk. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Doug Goldstein
-
Eric Blake