From b95ad92e058d3b25b9fc0a9f48cf21c57c29e0b5 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Mon, 17 Sep 2012 20:27:06 -0500 Subject: build: define WITH_INTERFACE for the driver 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 * 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. * libvirt.spec.in: Add RPM support for --with-interface --- configure.ac | 32 +- daemon/Makefile.am | 2 +- daemon/libvirtd.c | 8 +- libvirt.spec.in | 18 +- po/POTFILES.in | 2 +- src/Makefile.am | 24 +- src/interface/interface_backend_netcf.c | 811 ++++++++++++++++++++++++++++++++ src/interface/interface_driver.h | 29 ++ src/interface/netcf_driver.c | 811 -------------------------------- src/interface/netcf_driver.h | 29 -- tests/virdrivermoduletest.c | 2 +- tools/virsh.c | 5 +- 12 files changed, 912 insertions(+), 861 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 186f79e87..3e9067202 100644 --- a/configure.ac +++ b/configure.ac @@ -2787,6 +2787,36 @@ 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 libblkid is used by several storage drivers; therefore we probe dnl for it unconditionally. AC_ARG_WITH([libblkid], @@ -3018,7 +3048,7 @@ AC_MSG_NOTICE([ Test: $with_test]) 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 b45349c1b..3405c6718 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -151,7 +151,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 6973df646..1156bd636 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -78,8 +78,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" @@ -382,7 +382,7 @@ static void daemonInitialize(void) # ifdef WITH_NWFILTER virDriverLoadModule("nwfilter"); # endif -# ifdef WITH_NETCF +# ifdef WITH_INTERFACE virDriverLoadModule("interface"); # endif # ifdef WITH_XEN @@ -404,7 +404,7 @@ static void daemonInitialize(void) # ifdef WITH_NETWORK networkRegister(); # endif -# ifdef WITH_NETCF +# ifdef WITH_INTERFACE interfaceRegister(); # endif # ifdef WITH_STORAGE diff --git a/libvirt.spec.in b/libvirt.spec.in index 8c4c08dfc..119273914 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -70,6 +70,7 @@ %define with_parallels 0%{!?_without_parallels:1} # Then the secondary host drivers, which run inside libvirtd +%define with_interface 0%{!?_without_interface:%{server_drivers}} %define with_network 0%{!?_without_network:%{server_drivers}} %define with_storage_fs 0%{!?_without_storage_fs:%{server_drivers}} %define with_storage_lvm 0%{!?_without_storage_lvm:%{server_drivers}} @@ -207,6 +208,11 @@ %define with_hal 0%{!?_without_hal:%{server_drivers}} %endif +# interface requires netcf +%if ! 0%{?with_netcf} +%define with_interface 0 +%endif + # Enable yajl library for JSON mode with QEMU %if 0%{?fedora} >= 13 || 0%{?rhel} >= 6 %define with_yajl 0%{!?_without_yajl:%{server_drivers}} @@ -226,6 +232,7 @@ # Disable some drivers when building without libvirt daemon. # The logic is the same as in configure.ac %if ! %{with_libvirtd} +%define with_interface 0 %define with_network 0 %define with_qemu 0 %define with_lxc 0 @@ -281,12 +288,6 @@ %define with_nodedev 0 %endif -%if %{with_netcf} -%define with_interface 1 -%else -%define with_interface 0 -%endif - %if %{with_storage_fs} || %{with_storage_mpath} || %{with_storage_iscsi} || %{with_storage_lvm} || %{with_storage_disk} %define with_storage 1 %else @@ -1113,6 +1114,10 @@ of recent versions of Linux (and other OSes). %define _with_rhel5_api --with-rhel5-api %endif +%if ! %{with_interface} +%define _without_interface --without-interface +%endif + %if ! %{with_network} %define _without_network --without-network %endif @@ -1249,6 +1254,7 @@ autoreconf -if %{?_without_hyperv} \ %{?_without_vmware} \ %{?_without_parallels} \ + %{?_without_interface} \ %{?_without_network} \ %{?_with_rhel5_api} \ %{?_without_storage_fs} \ diff --git a/po/POTFILES.in b/po/POTFILES.in index 7a91eb4a9..12a2b25cd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -40,7 +40,7 @@ src/fdstream.c src/hyperv/hyperv_driver.c src/hyperv/hyperv_util.c src/hyperv/hyperv_wmi.c -src/interface/netcf_driver.c +src/interface/interface_backend_netcf.c src/internal.h src/libvirt.c src/libvirt-qemu.c diff --git a/src/Makefile.am b/src/Makefile.am index 9f27fcfa7..4ae741be2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -552,8 +552,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 @@ -1021,7 +1030,7 @@ endif EXTRA_DIST += network/default.xml -if WITH_NETCF +if WITH_INTERFACE if WITH_DRIVER_MODULES mod_LTLIBRARIES += libvirt_driver_interface.la else @@ -1029,10 +1038,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 000000000..3b4ee1144 --- /dev/null +++ b/src/interface/interface_backend_netcf.c @@ -0,0 +1,811 @@ +/* + * 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 + * . + * + * Author: Laine Stump + */ + +#include + +#include + +#include "virterror_internal.h" +#include "datatypes.h" +#include "interface_driver.h" +#include "interface_conf.h" +#include "memory.h" +#include "logging.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 int +interfaceListAllInterfaces(virConnectPtr conn, + virInterfacePtr **ifaces, + unsigned int flags) +{ + struct interface_driver *driver = conn->interfacePrivateData; + int count; + int i; + struct netcf_if *iface = NULL; + virInterfacePtr *tmp_iface_objs = NULL; + virInterfacePtr iface_obj = NULL; + unsigned int status; + int niface_objs = 0; + int ret = -1; + char **names = NULL; + + virCheckFlags(VIR_CONNECT_LIST_INTERFACES_ACTIVE | + VIR_CONNECT_LIST_INTERFACES_INACTIVE, -1); + + interfaceDriverLock(driver); + + /* List all interfaces, in case of we might support new filter flags + * except active|inactive in future. + */ + count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_ACTIVE | + 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 host interfaces: %s%s%s"), + errmsg, details ? " - " : "", + details ? details : ""); + ret = -1; + goto cleanup; + } + + if (count == 0) { + ret = 0; + goto cleanup; + } + + if (VIR_ALLOC_N(names, count) < 0) { + virReportOOMError(); + ret = -1; + goto cleanup; + } + + if ((count = ncf_list_interfaces(driver->netcf, count, names, + NETCF_IFACE_ACTIVE | + NETCF_IFACE_INACTIVE)) < 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 : ""); + goto cleanup; + } + + if (ifaces) { + if (VIR_ALLOC_N(tmp_iface_objs, count + 1) < 0) { + virReportOOMError(); + goto cleanup; + } + } + + for (i = 0; i < count; i++) { + iface = ncf_lookup_by_name(driver->netcf, names[i]); + 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"), + names[i], errmsg, + details ? " - " : "", details ? details : ""); + goto cleanup; + } else { + /* Ignore the NETCF_NOERROR, as the interface is very likely + * deleted by other management apps (e.g. virt-manager). + */ + VIR_WARN("couldn't find interface named '%s', might be " + "deleted by other process", names[i]); + continue; + } + } + + if (ncf_if_status(iface, &status) < 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"), + names[i], errmsg, details ? " - " : "", + details ? details : ""); + goto cleanup; + } + + /* XXX: Filter the result, need to be splitted once new filter flags + * except active|inactive are supported. + */ + if (((status & NETCF_IFACE_ACTIVE) && + (flags & VIR_CONNECT_LIST_INTERFACES_ACTIVE)) || + ((status & NETCF_IFACE_INACTIVE) && + (flags & VIR_CONNECT_LIST_INTERFACES_INACTIVE))) { + if (ifaces) { + iface_obj = virGetInterface(conn, ncf_if_name(iface), + ncf_if_mac_string(iface)); + tmp_iface_objs[niface_objs] = iface_obj; + } + niface_objs++; + } + + ncf_if_free(iface); + iface = NULL; + } + + if (tmp_iface_objs) { + /* trim the array to the final size */ + ignore_value(VIR_REALLOC_N(tmp_iface_objs, niface_objs + 1)); + *ifaces = tmp_iface_objs; + tmp_iface_objs = NULL; + } + + ret = niface_objs; + +cleanup: + ncf_if_free(iface); + + if (names) + for (i = 0; i < count; i++) + VIR_FREE(names[i]); + VIR_FREE(names); + + if (tmp_iface_objs) { + for (i = 0; i < niface_objs; i++) { + if (tmp_iface_objs[i]) + virInterfaceFree(tmp_iface_objs[i]); + } + } + + interfaceDriverUnlock(driver); + return ret; +} + + +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 */ + .listAllInterfaces = interfaceListAllInterfaces, /* 0.10.2 */ + .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 000000000..38fbc77eb --- /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 + * . + * + * Author: Laine Stump + */ + + +#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 6e429db68..000000000 --- a/src/interface/netcf_driver.c +++ /dev/null @@ -1,811 +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 - * . - * - * Author: Laine Stump - */ - -#include - -#include - -#include "virterror_internal.h" -#include "datatypes.h" -#include "netcf_driver.h" -#include "interface_conf.h" -#include "memory.h" -#include "logging.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 int -interfaceListAllInterfaces(virConnectPtr conn, - virInterfacePtr **ifaces, - unsigned int flags) -{ - struct interface_driver *driver = conn->interfacePrivateData; - int count; - int i; - struct netcf_if *iface = NULL; - virInterfacePtr *tmp_iface_objs = NULL; - virInterfacePtr iface_obj = NULL; - unsigned int status; - int niface_objs = 0; - int ret = -1; - char **names = NULL; - - virCheckFlags(VIR_CONNECT_LIST_INTERFACES_ACTIVE | - VIR_CONNECT_LIST_INTERFACES_INACTIVE, -1); - - interfaceDriverLock(driver); - - /* List all interfaces, in case of we might support new filter flags - * except active|inactive in future. - */ - count = ncf_num_of_interfaces(driver->netcf, NETCF_IFACE_ACTIVE | - 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 host interfaces: %s%s%s"), - errmsg, details ? " - " : "", - details ? details : ""); - ret = -1; - goto cleanup; - } - - if (count == 0) { - ret = 0; - goto cleanup; - } - - if (VIR_ALLOC_N(names, count) < 0) { - virReportOOMError(); - ret = -1; - goto cleanup; - } - - if ((count = ncf_list_interfaces(driver->netcf, count, names, - NETCF_IFACE_ACTIVE | - NETCF_IFACE_INACTIVE)) < 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 : ""); - goto cleanup; - } - - if (ifaces) { - if (VIR_ALLOC_N(tmp_iface_objs, count + 1) < 0) { - virReportOOMError(); - goto cleanup; - } - } - - for (i = 0; i < count; i++) { - iface = ncf_lookup_by_name(driver->netcf, names[i]); - 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"), - names[i], errmsg, - details ? " - " : "", details ? details : ""); - goto cleanup; - } else { - /* Ignore the NETCF_NOERROR, as the interface is very likely - * deleted by other management apps (e.g. virt-manager). - */ - VIR_WARN("couldn't find interface named '%s', might be " - "deleted by other process", names[i]); - continue; - } - } - - if (ncf_if_status(iface, &status) < 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"), - names[i], errmsg, details ? " - " : "", - details ? details : ""); - goto cleanup; - } - - /* XXX: Filter the result, need to be splitted once new filter flags - * except active|inactive are supported. - */ - if (((status & NETCF_IFACE_ACTIVE) && - (flags & VIR_CONNECT_LIST_INTERFACES_ACTIVE)) || - ((status & NETCF_IFACE_INACTIVE) && - (flags & VIR_CONNECT_LIST_INTERFACES_INACTIVE))) { - if (ifaces) { - iface_obj = virGetInterface(conn, ncf_if_name(iface), - ncf_if_mac_string(iface)); - tmp_iface_objs[niface_objs] = iface_obj; - } - niface_objs++; - } - - ncf_if_free(iface); - iface = NULL; - } - - if (tmp_iface_objs) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(tmp_iface_objs, niface_objs + 1)); - *ifaces = tmp_iface_objs; - tmp_iface_objs = NULL; - } - - ret = niface_objs; - -cleanup: - ncf_if_free(iface); - - if (names) - for (i = 0; i < count; i++) - VIR_FREE(names[i]); - VIR_FREE(names); - - if (tmp_iface_objs) { - for (i = 0; i < niface_objs; i++) { - if (tmp_iface_objs[i]) - virInterfaceFree(tmp_iface_objs[i]); - } - } - - interfaceDriverUnlock(driver); - return ret; -} - - -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 */ - .listAllInterfaces = interfaceListAllInterfaces, /* 0.10.2 */ - .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 38fbc77eb..000000000 --- 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 - * . - * - * Author: Laine Stump - */ - - -#ifndef __VIR_INTERFACE__DRIVER_H -# define __VIR_INTERFACE__DRIVER_H - -int interfaceRegister(void); - -#endif /* __VIR_INTERFACE__DRIVER_H */ diff --git a/tests/virdrivermoduletest.c b/tests/virdrivermoduletest.c index 4d6e91e61..8762de435 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 6a72412ba..5447376be 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2707,8 +2707,11 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_BRIDGE vshPrint(ctl, " Bridging"); #endif -#ifdef WITH_NETCF +#if defined(WITH_INTERFACE) vshPrint(ctl, " Interface"); +# if defined(WITH_NETCF) + vshPrint(ctl, " netcf"); +# endif #endif #ifdef WITH_NWFILTER vshPrint(ctl, " Nwfilter"); -- cgit v1.2.3-65-gdbad