From: Laine Stump <laine@xxxxxxxxxx> --- include/libvirt/libvirt.h | 18 ++ include/libvirt/libvirt.h.in | 18 ++ include/libvirt/virterror.h | 4 + src/datatypes.h | 25 ++ src/driver.h | 60 ++++ src/libvirt.c | 695 ++++++++++++++++++++++++++++++++++++++++++ src/util.h | 2 - src/virterror.c | 21 ++ 8 files changed, 841 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 91af6fd..b0d93a2 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -433,6 +433,24 @@ extern virConnectAuthPtr virConnectAuthPtrDefault; #define VIR_UUID_STRING_BUFLEN (36+1) +/** + * VIR_MAC_BUFLEN: + * + * This macro provides the length of the buffer required + * for an interface MAC address + */ + +#define VIR_MAC_BUFLEN (6) + +/** + * VIR_MAC_STRING_BUFLEN: + * + * This macro provides the length of the buffer required + * for virInterfaceGetMACString() + */ + +#define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3) + /* library versioning */ /** diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index cee3d94..fbaf212 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -433,6 +433,24 @@ extern virConnectAuthPtr virConnectAuthPtrDefault; #define VIR_UUID_STRING_BUFLEN (36+1) +/** + * VIR_MAC_BUFLEN: + * + * This macro provides the length of the buffer required + * for an interface MAC address + */ + +#define VIR_MAC_BUFLEN (6) + +/** + * VIR_MAC_STRING_BUFLEN: + * + * This macro provides the length of the buffer required + * for virInterfaceGetMACString() + */ + +#define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3) + /* library versioning */ /** diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index faf3f61..766cbad 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; @@ -157,6 +158,9 @@ typedef enum { VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */ VIR_ERR_NO_NODE_DEVICE,/* node device not found */ VIR_ERR_NO_SECURITY_MODEL, /* security model not found */ + 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..deac9df 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 */ + unsigned char mac[VIR_MAC_BUFLEN]; /* the interface MAC address */ +}; + +/** * _virStoragePool: * * Internal structure associated to a storage pool diff --git a/src/driver.h b/src/driver.h index c357b76..30905c0 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 + (*virDrvInterfaceLookupByMAC) (virConnectPtr conn, + const unsigned char *mac); + +typedef char * + (*virDrvInterfaceGetXMLDesc) (virInterfacePtr interface, + int flags); + +typedef virInterfacePtr + (*virDrvInterfaceDefineXML) (virConnectPtr conn, + const char *xmlDesc, + int flags); +typedef int + (*virDrvInterfaceUndefine) (virInterfacePtr interface); +typedef int + (*virDrvInterfaceCreate) (virInterfacePtr interface, + int flags); +typedef int + (*virDrvInterfaceDestroy) (virInterfacePtr interface, + 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; + virDrvInterfaceLookupByMAC interfaceLookupByMAC; + virDrvInterfaceGetXMLDesc interfaceGetXMLDesc; + virDrvInterfaceDefineXML interfaceDefineXML; + virDrvInterfaceUndefine interfaceUndefine; + virDrvInterfaceCreate interfaceCreate; + virDrvInterfaceDestroy interfaceDestroy; +}; + typedef int (*virDrvConnectNumOfStoragePools) (virConnectPtr conn); @@ -718,6 +777,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 ded18a7..4bd85a7 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,622 @@ 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; +} + +/** + * virInterfaceLookupByMAC: + * @conn: pointer to the hypervisor connection + * @mac: the raw MAC for the interface + * + * 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 +virInterfaceLookupByMAC(virConnectPtr conn, const unsigned char *mac) +{ + DEBUG("conn=%p, mac=%02X:%02X:%02X:%02X:%02X:%02X", conn, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (NULL); + } + if (mac == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->interfaceDriver && conn->interfaceDriver->interfaceLookupByMAC){ + virInterfacePtr ret; + ret = conn->interfaceDriver->interfaceLookupByMAC (conn, mac); + 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 string MAC for the interface + * + * 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) +{ + unsigned char mac[VIR_MAC_BUFLEN]; + int ret; + 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; + } + + ret = virParseMacAddr (macstr, mac); + if (ret == -1) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + return virInterfaceLookupByMAC(conn, &mac[0]); + +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); +} + +/** + * virInterfaceGetMAC: + * @interface: a interface object + * @mac: pointer to a VIR_MAC_BUFLEN bytes array + * + * Get the MAC for a interface + * + * Returns -1 in case of error, 0 in case of success + */ +int +virInterfaceGetMAC(virInterfacePtr interface, unsigned char *mac) +{ + DEBUG("interface=%p, mac=%p", interface, mac); + + virResetLastError(); + + if (!VIR_IS_INTERFACE(interface)) { + virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__); + return (-1); + } + if (mac == NULL) { + virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + memcpy(mac, &interface->mac[0], VIR_MAC_BUFLEN); + + return (0); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(interface->conn); + return -1; +} + +/** + * virInterfaceGetMACString: + * @interface: a interface object + * @buf: pointer to a VIR_MAC_STRING_BUFLEN bytes array + * + * Get the MAC for a interface as string. For more information about + * MAC see RFC4122. + * + * Returns -1 in case of error, 0 in case of success + */ +int +virInterfaceGetMACString(virInterfacePtr interface, char *buf) +{ + unsigned char mac[VIR_MAC_BUFLEN]; + DEBUG("interface=%p, buf=%p", interface, buf); + + virResetLastError(); + + if (!VIR_IS_INTERFACE(interface)) { + virLibInterfaceError(NULL, VIR_ERR_INVALID_INTERFACE, __FUNCTION__); + return (-1); + } + if (buf == NULL) { + virLibInterfaceError(interface, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (virInterfaceGetMAC(interface, &mac[0])) + return (-1); + + virFormatMacAddr(mac, buf); + return (0); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(interface->conn); + return -1; +} + +/** + * 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 relaunch 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, 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 + * + * 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, 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 + * + * 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 + * + * Activate an interface (ie call "ifup") + * + * Returns 0 in case of success, -1 in case of error + */ +int +virInterfaceCreate(virInterfacePtr interface, 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 + * + * Destroy the interface object. The running instance is shutdown if not down + * already and all resources used by it are given back to the hypervisor. This + * does not free the associated virInterfacePtr object. + * This function may require privileged access + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virInterfaceDestroy(virInterfacePtr interface, 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 running instance is kept alive. + * 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/util.h b/src/util.h index 4bed077..2bb45bf 100644 --- a/src/util.h +++ b/src/util.h @@ -146,9 +146,7 @@ int virParseNumber(const char **str); int virAsprintf(char **strp, const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 2, 3); -#define VIR_MAC_BUFLEN 6 #define VIR_MAC_PREFIX_BUFLEN 3 -#define VIR_MAC_STRING_BUFLEN VIR_MAC_BUFLEN * 3 int virParseMacAddr(const char* str, unsigned char *addr); diff --git a/src/virterror.c b/src/virterror.c index c9db91f..0f4a9eb 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); } @@ -1018,6 +1021,24 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("Security model not found: %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); } -- 1.6.0.6 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list