On Tue, May 19, 2009 at 12:51:24PM -0400, Laine Stump wrote:
From: Laine Stump <laine(a)redhat.com>
---
include/libvirt/virterror.h | 4 +
src/datatypes.h | 25 ++
src/driver.h | 60 +++++
src/libvirt.c | 607 +++++++++++++++++++++++++++++++++++++++++++
src/virterror.c | 21 ++
5 files changed, 717 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 4677ebc..3613ac2 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -63,6 +63,7 @@ typedef enum {
VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */
VIR_FROM_SECURITY, /* Error from security framework */
VIR_FROM_VBOX, /* Error from VirtualBox driver */
+ VIR_FROM_INTERFACE, /* Error when operating on an interface */
} virErrorDomain;
@@ -158,6 +159,9 @@ typedef enum {
VIR_ERR_NO_NODE_DEVICE,/* node device not found */
VIR_ERR_NO_SECURITY_MODEL, /* security model not found */
VIR_ERR_OPERATION_INVALID, /* operation is not applicable at this time */
+ VIR_WAR_NO_INTERFACE, /* failed to start interface driver */
+ VIR_ERR_NO_INTERFACE, /* interface driver not running */
+ VIR_ERR_INVALID_INTERFACE, /* invalid interface object */
} virErrorNumber;
/**
diff --git a/src/datatypes.h b/src/datatypes.h
index 5956c5d..756e0a5 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -59,6 +59,16 @@
#define VIR_IS_CONNECTED_NETWORK(obj) (VIR_IS_NETWORK(obj) &&
VIR_IS_CONNECT((obj)->conn))
/**
+ * VIR_INTERFACE_MAGIC:
+ *
+ * magic value used to protect the API when pointers to interface structures
+ * are passed down by the users.
+ */
+#define VIR_INTERFACE_MAGIC 0xDEAD5309
+#define VIR_IS_INTERFACE(obj) ((obj) && (obj)->magic==VIR_INTERFACE_MAGIC)
+#define VIR_IS_CONNECTED_INTERFACE(obj) (VIR_IS_INTERFACE(obj) &&
VIR_IS_CONNECT((obj)->conn))
+
+/**
* VIR_STORAGE_POOL_MAGIC:
*
* magic value used to protect the API when pointers to storage pool structures
@@ -106,6 +116,7 @@ struct _virConnect {
/* The underlying hypervisor driver and network driver. */
virDriverPtr driver;
virNetworkDriverPtr networkDriver;
+ virInterfaceDriverPtr interfaceDriver;
virStorageDriverPtr storageDriver;
virDeviceMonitorPtr deviceMonitor;
@@ -115,6 +126,7 @@ struct _virConnect {
*/
void * privateData;
void * networkPrivateData;
+ void * interfacePrivateData;
void * storagePrivateData;
void * devMonPrivateData;
@@ -167,6 +179,19 @@ struct _virNetwork {
};
/**
+* _virInterface:
+*
+* Internal structure associated to a physical host interface
+*/
+struct _virInterface {
+ unsigned int magic; /* specific value to check */
+ int refs; /* reference count */
+ virConnectPtr conn; /* pointer back to the connection */
+ char *name; /* the network external name */
+ char *mac; /* the interface MAC address */
+};
+
+/**
* _virStoragePool:
*
* Internal structure associated to a storage pool
diff --git a/src/driver.h b/src/driver.h
index b8e0a04..01758a9 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -488,6 +488,65 @@ struct _virNetworkDriver {
virDrvNetworkSetAutostart networkSetAutostart;
};
+/*-------*/
+typedef int
+ (*virDrvNumOfInterfaces) (virConnectPtr conn);
+typedef int
+ (*virDrvListInterfaces) (virConnectPtr conn,
+ char **const names,
+ int maxnames);
+typedef virInterfacePtr
+ (*virDrvInterfaceLookupByName) (virConnectPtr conn,
+ const char *name);
+typedef virInterfacePtr
+ (*virDrvInterfaceLookupByMACString) (virConnectPtr conn,
+ const char *mac);
+
+typedef char *
+ (*virDrvInterfaceGetXMLDesc) (virInterfacePtr interface,
+ unsigned int flags);
+
+typedef virInterfacePtr
+ (*virDrvInterfaceDefineXML) (virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags);
+typedef int
+ (*virDrvInterfaceUndefine) (virInterfacePtr interface);
+typedef int
+ (*virDrvInterfaceCreate) (virInterfacePtr interface,
+ unsigned int flags);
+typedef int
+ (*virDrvInterfaceDestroy) (virInterfacePtr interface,
+ unsigned int flags);
+
+typedef struct _virInterfaceDriver virInterfaceDriver;
+typedef virInterfaceDriver *virInterfaceDriverPtr;
+
+/**
+ * _virInterfaceDriver:
+ *
+ * Structure associated to a network virtualization driver, defining the various
+ * entry points for it.
+ *
+ * All drivers must support the following fields/methods:
+ * - open
+ * - close
+ */
+struct _virInterfaceDriver {
+ const char *name; /* the name of the driver */
+ virDrvOpen open;
+ virDrvClose close;
+ virDrvNumOfInterfaces numOfInterfaces;
+ virDrvListInterfaces listInterfaces;
+ virDrvInterfaceLookupByName interfaceLookupByName;
+ virDrvInterfaceLookupByMACString interfaceLookupByMACString;
+ virDrvInterfaceGetXMLDesc interfaceGetXMLDesc;
+ virDrvInterfaceDefineXML interfaceDefineXML;
+ virDrvInterfaceUndefine interfaceUndefine;
+ virDrvInterfaceCreate interfaceCreate;
+ virDrvInterfaceDestroy interfaceDestroy;
+};
+
typedef int
(*virDrvConnectNumOfStoragePools) (virConnectPtr conn);
@@ -724,6 +783,7 @@ struct _virDeviceMonitor {
*/
int virRegisterDriver(virDriverPtr);
int virRegisterNetworkDriver(virNetworkDriverPtr);
+int virRegisterInterfaceDriver(virInterfaceDriverPtr);
int virRegisterStorageDriver(virStorageDriverPtr);
int virRegisterDeviceMonitor(virDeviceMonitorPtr);
#ifdef WITH_LIBVIRTD
diff --git a/src/libvirt.c b/src/libvirt.c
index f1f81b3..f63a47b 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -74,6 +74,8 @@ static virDriverPtr virDriverTab[MAX_DRIVERS];
static int virDriverTabCount = 0;
static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
static int virNetworkDriverTabCount = 0;
+static virInterfaceDriverPtr virInterfaceDriverTab[MAX_DRIVERS];
+static int virInterfaceDriverTabCount = 0;
static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
static int virStorageDriverTabCount = 0;
static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS];
@@ -462,6 +464,32 @@ virLibNetworkError(virNetworkPtr network, virErrorNumber error,
}
/**
+ * virLibInterfaceError:
+ * @conn: the connection if available
+ * @error: the error number
+ * @info: extra information string
+ *
+ * Handle an error at the connection level
+ */
+static void
+virLibInterfaceError(virInterfacePtr interface, virErrorNumber error,
+ const char *info)
+{
+ virConnectPtr conn = NULL;
+ const char *errmsg;
+
+ if (error == VIR_ERR_OK)
+ return;
+
+ errmsg = virErrorMsg(error, info);
+ if (error != VIR_ERR_INVALID_INTERFACE) {
+ conn = interface->conn;
+ }
+ virRaiseError(conn, NULL, NULL, VIR_FROM_INTERFACE, error, VIR_ERR_ERROR,
+ errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
+/**
* virLibStoragePoolError:
* @conn: the connection if available
* @error: the error number
@@ -571,6 +599,37 @@ virRegisterNetworkDriver(virNetworkDriverPtr driver)
}
/**
+ * virRegisterInterfaceDriver:
+ * @driver: pointer to a interface driver block
+ *
+ * Register a interface virtualization driver
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
+{
+ if (virInitialize() < 0)
+ return -1;
+
+ if (driver == NULL) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ if (virInterfaceDriverTabCount >= MAX_DRIVERS) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+
+ DEBUG ("registering %s as interface driver %d",
+ driver->name, virInterfaceDriverTabCount);
+
+ virInterfaceDriverTab[virInterfaceDriverTabCount] = driver;
+ return virInterfaceDriverTabCount++;
+}
+
+/**
* virRegisterStorageDriver:
* @driver: pointer to a storage driver block
*
@@ -966,6 +1025,24 @@ do_open (const char *name,
}
}
+ for (i = 0; i < virInterfaceDriverTabCount; i++) {
+ res = virInterfaceDriverTab[i]->open (ret, auth, flags);
+ DEBUG("interface driver %d %s returned %s",
+ i, virInterfaceDriverTab[i]->name,
+ res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" :
+ (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" :
+ (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown
status")));
+ if (res == VIR_DRV_OPEN_ERROR) {
+ if (STREQ(virInterfaceDriverTab[i]->name, "remote")) {
+ virLibConnWarning (NULL, VIR_WAR_NO_INTERFACE,
+ "Is the daemon running ?");
+ }
+ break;
+ } else if (res == VIR_DRV_OPEN_SUCCESS) {
+ ret->interfaceDriver = virInterfaceDriverTab[i];
+ break;
+ }
+ }
/* Secondary driver for storage. Optional */
for (i = 0; i < virStorageDriverTabCount; i++) {
@@ -1126,6 +1203,8 @@ virConnectClose(virConnectPtr conn)
if (conn->networkDriver)
conn->networkDriver->close (conn);
+ if (conn->interfaceDriver)
+ conn->interfaceDriver->close (conn);
if (conn->storageDriver)
conn->storageDriver->close (conn);
if (conn->deviceMonitor)
@@ -5278,6 +5357,534 @@ error:
return -1;
}
+/**
+ * virInterfaceGetConnect:
+ * @net: pointer to a interface
+ *
+ * Provides the connection pointer associated with an interface. The
+ * reference counter on the connection is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do
+ * not use this function. Instead, store the connection and
+ * the interface object together.
+ *
+ * Returns the virConnectPtr or NULL in case of failure.
+ */
+virConnectPtr
+virInterfaceGetConnect (virInterfacePtr interface)
+{
+ DEBUG("interface=%p", interface);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE (interface)) {
+ virLibInterfaceError (NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return NULL;
+ }
+ return interface->conn;
+}
+
+/**
+ * virConnectNumOfInterfaces:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Provides the number of interfaces on the physical host.
+ *
+ * Returns the number of interface found or -1 in case of error
+ */
+int
+virConnectNumOfInterfaces(virConnectPtr conn)
+{
+ DEBUG("conn=%p", conn);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->numOfInterfaces) {
+ int ret;
+ ret = conn->interfaceDriver->numOfInterfaces (conn);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return -1;
+}
+
+/**
+ * virConnectListInterfaces:
+ * @conn: pointer to the hypervisor connection
+ * @names: array to collect the list of names of interfaces
+ * @maxnames: size of @names
+ *
+ * Collect the list of physical host interfaces, and store their names in @names
+ *
+ * Returns the number of interfaces found or -1 in case of error
+ */
+int
+virConnectListInterfaces(virConnectPtr conn, char **const names, int maxnames)
+{
+ DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (-1);
+ }
+
+ if ((names == NULL) || (maxnames < 0)) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver && conn->interfaceDriver->listInterfaces)
{
+ int ret;
+ ret = conn->interfaceDriver->listInterfaces (conn, names, maxnames);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return -1;
+}
+
+/**
+ * virInterfaceLookupByName:
+ * @conn: pointer to the hypervisor connection
+ * @name: name for the interface
+ *
+ * Try to lookup an interface on the given hypervisor based on its name.
+ *
+ * Returns a new interface object or NULL in case of failure. If the
+ * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
+ */
+virInterfacePtr
+virInterfaceLookupByName(virConnectPtr conn, const char *name)
+{
+ DEBUG("conn=%p, name=%s", conn, name);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (name == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceLookupByName) {
+ virInterfacePtr ret;
+ ret = conn->interfaceDriver->interfaceLookupByName (conn, name);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+/**
+ * virInterfaceLookupByMACString:
+ * @conn: pointer to the hypervisor connection
+ * @macstr: the MAC for the interface (null-terminated ASCII format)
+ *
+ * Try to lookup an interface on the given hypervisor based on its MAC.
+ *
+ * Returns a new interface object or NULL in case of failure. If the
+ * interface cannot be found, then VIR_ERR_NO_INTERFACE error is raised.
+ */
+virInterfacePtr
+virInterfaceLookupByMACString(virConnectPtr conn, const char *macstr)
+{
+ DEBUG("conn=%p, macstr=%s", conn, macstr);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (macstr == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceLookupByMACString) {
+ virInterfacePtr ret;
+ ret = conn->interfaceDriver->interfaceLookupByMACString (conn, macstr);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+/**
+ * virInterfaceGetName:
+ * @interface: a interface object
+ *
+ * Get the public name for that interface
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * its lifetime will be the same as the interface object.
+ */
+const char *
+virInterfaceGetName(virInterfacePtr interface)
+{
+ DEBUG("interface=%p", interface);
+
+ virResetLastError();
+
+ if (!VIR_IS_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (NULL);
+ }
+ return (interface->name);
+}
+
+/**
+ * virInterfaceGetMACString:
+ * @interface: a interface object
+ *
+ * Get the MAC for a interface as string. For more information about
+ * MAC see RFC4122.
+ *
+ * Returns a pointer to the MAC address (in null-terminated ASCII
+ * format) or NULL, the string need not be deallocated its lifetime
+ * will be the same as the interface object.
+ */
+const char *
+virInterfaceGetMACString(virInterfacePtr interface)
+{
+ DEBUG("interface=%p", interface);
+
+ virResetLastError();
+
+ if (!VIR_IS_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (NULL);
+ }
+ return (interface->mac);
+}
+
+/**
+ * virInterfaceGetXMLDesc:
+ * @interface: a interface object
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * Provide an XML description of the interface. The description may be reused
+ * later to recreate the interface with virInterfaceCreateXML().
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *
+virInterfaceGetXMLDesc(virInterfacePtr interface, unsigned int flags)
+{
+ virConnectPtr conn;
+ DEBUG("interface=%p, flags=%d", interface, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (NULL);
+ }
+ if (flags != 0) {
+ virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ conn = interface->conn;
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceGetXMLDesc) {
+ char *ret;
+ ret = conn->interfaceDriver->interfaceGetXMLDesc (interface, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(interface->conn);
+ return NULL;
+}
+
+/**
+ * virInterfaceDefineXML:
+ * @conn: pointer to the hypervisor connection
+ * @xml: the XML description for the interface, preferably in UTF-8
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * Define an interface (or modify existing interface configuration)
+ *
+ * Returns NULL in case of error, a pointer to the interface otherwise
+ */
+virInterfacePtr
+virInterfaceDefineXML(virConnectPtr conn, const char *xml, unsigned int flags)
+{
+ DEBUG("conn=%p, xml=%s, flags=%d", conn, xml, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+ if (xml == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceDefineXML) {
+ virInterfacePtr ret;
+ ret = conn->interfaceDriver->interfaceDefineXML (conn, xml, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+/**
+ * virInterfaceUndefine:
+ * @interface: pointer to a defined interface
+ *
+ * Undefine an interface, ie remove it from the config.
+ * This does not free the associated virInterfacePtr object.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virInterfaceUndefine(virInterfacePtr interface) {
+ virConnectPtr conn;
+ DEBUG("interface=%p", interface);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (-1);
+ }
+ conn = interface->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceUndefine) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceUndefine (interface);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(interface->conn);
+ return -1;
+}
+
+/**
+ * virInterfaceCreate:
+ * @interface: pointer to a defined interface
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * Activate an interface (ie call "ifup")
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virInterfaceCreate(virInterfacePtr interface, unsigned int flags)
+{
+ virConnectPtr conn;
+ DEBUG("interface=%p, flags=%d", interface, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (-1);
+ }
+ conn = interface->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceCreate) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceCreate (interface, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(interface->conn);
+ return -1;
+}
+
+/**
+ * virInterfaceDestroy:
+ * @interface: an interface object
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * deactivate an interface (ie call "ifdown")
+ * This does not remove the interface from the config, and
+ * does not free the associated virInterfacePtr object.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceDestroy(virInterfacePtr interface, unsigned int flags)
+{
+ virConnectPtr conn;
+ DEBUG("interface=%p, flags=%d", interface, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (-1);
+ }
+
+ conn = interface->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibInterfaceError(interface, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->interfaceDriver &&
conn->interfaceDriver->interfaceDestroy) {
+ int ret;
+ ret = conn->interfaceDriver->interfaceDestroy (interface, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(interface->conn);
+ return -1;
+}
+
+/**
+ * virInterfaceRef:
+ * @interface: the interface to hold a reference on
+ *
+ * Increment the reference count on the interface. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virInterfaceFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * This method is typically useful for applications where multiple
+ * threads are using a connection, and it is required that the
+ * connection remain open until all threads have finished using
+ * it. ie, each new thread using a interface would increment
+ * the reference count.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virInterfaceRef(virInterfacePtr interface)
+{
+ if ((!VIR_IS_CONNECTED_INTERFACE(interface))) {
+ virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return(-1);
+ }
+ virMutexLock(&interface->conn->lock);
+ DEBUG("interface=%p refs=%d", interface, interface->refs);
+ interface->refs++;
+ virMutexUnlock(&interface->conn->lock);
+ return 0;
+}
+
+/**
+ * virInterfaceFree:
+ * @interface: a interface object
+ *
+ * Free the interface object. The interface itself is unaltered.
+ * The data structure is freed and should not be used thereafter.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virInterfaceFree(virInterfacePtr interface)
+{
+ DEBUG("interface=%p", interface);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_INTERFACE(interface)) {
+ virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__);
+ return (-1);
+ }
+#if 0
+ /*
+ * FIXME: This needs to be uncommented when the stubs are replaced
+ * with actual functionality.
+ */
+
+ if (virUnrefInterface(interface) < 0)
+ return (-1);
+#else
+ interface->refs--;
+#endif
+
+ return(0);
+}
+
/**
* virStoragePoolGetConnect:
diff --git a/src/virterror.c b/src/virterror.c
index e12608d..3af6544 100644
--- a/src/virterror.c
+++ b/src/virterror.c
@@ -157,6 +157,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_VBOX:
dom = "VBOX ";
break;
+ case VIR_FROM_INTERFACE:
+ dom = "Interface ";
+ break;
}
return(dom);
}
@@ -1024,6 +1027,24 @@ virErrorMsg(virErrorNumber error, const char *info)
else
errmsg = _("Requested operation is not valid: %s");
break;
+ case VIR_WAR_NO_INTERFACE:
+ if (info == NULL)
+ errmsg = _("Failed to find the interface");
+ else
+ errmsg = _("Failed to find the interface: %s");
+ break;
+ case VIR_ERR_NO_INTERFACE:
+ if (info == NULL)
+ errmsg = _("Interface not found");
+ else
+ errmsg = _("Interface not found: %s");
+ break;
+ case VIR_ERR_INVALID_INTERFACE:
+ if (info == NULL)
+ errmsg = _("invalid interface pointer in");
+ else
+ errmsg = _("invalid interface pointer in %s");
+ break;
}
return (errmsg);
}
--
ACK, looks fine now
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|