[libvirt] checkpoint patches of netcf integration for review/guidance

I've gone through the first two steps of danpb's "Guide to Adding New libvirt APIs", and thought this would be a good time to send a copy of my work to the list to make sure I'm going in the right direction. Now is (yet another) good time to tell me "You're doing it wrong!". Basically, I've defined the public api in libvirt.h (actually libvirt.h.in - it's a real pain to have generated files under source control - it almost led me to mistakenly lose my modifications a couple times after running autogen, until I actually looked in the directory containing the file and saw the *.in file), done all the toplevel functions in libvirt.c, and whatever ancillary definitions and small functions were needed by them. In a 3rd patch, I also added stuff to configure.in that detects the presence of libnetcf and 1) turns on WITH_NETCF in config.h and 2) adds -lnetcf to LDFLAGS. I noticed that some other similar items have been added to configure.in by peppering little changes in several spots throughout the file; I preferred adding all my stuff in one place to make it easier to follow (and less likely to cause merge conflicts). So far this has been a *lot* of cut-n-paste, which makes me a bit uneasy (both because of the lesser problem that it almost always leads to errors caused by missing bits and pieces that need modification after the paste, and the greater problem that using this method may indicate I'm operating mechanically, without having adequate understanding of what I'm trying to do).

From: Laine Stump <laine@redhat.com> --- include/libvirt/libvirt.h | 77 ++++++++++++++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 779ea72..f2e695a 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -854,6 +854,83 @@ int virNetworkGetAutostart (virNetworkPtr network, int virNetworkSetAutostart (virNetworkPtr network, int autostart); +/* + * Physical host interface configuration API + */ + +/** + * virInterface: + * + * a virInterface is a private structure representing a virtual interface. + */ +typedef struct _virInterface virInterface; + +/** + * virInterfacePtr: + * + * a virInterfacePtr is pointer to a virInterface private structure, this is the + * type used to reference a virtual interface in the API. + */ +typedef virInterface *virInterfacePtr; + +/* + * Get connection from interface. + */ +virConnectPtr virInterfaceGetConnect (virInterfacePtr interface); + +/* + * List defined interfaces + */ +int virConnectNumOfInterfaces (virConnectPtr conn); +int virConnectListInterfaces (virConnectPtr conn, + char **const names, + int maxnames); + +/* + * Lookup interface by name or MAC address + */ +virInterfacePtr virInterfaceLookupByName (virConnectPtr conn, + const char *name); +virInterfacePtr virInterfaceLookupByMAC (virConnectPtr conn, + const unsigned char *mac); +virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn, + const char *mac); + +/* + * Define interface (or modify existing interface configuration) + */ +virInterfacePtr virInterfaceDefineXML (virConnectPtr conn, + const char *xmlDesc, + int flags); + +/* + * Delete interface + */ +int virInterfaceUndefine (virInterfacePtr interface); + +/* + * Activate interface (ie call "ifup") + */ +int virInterfaceCreate (virInterfacePtr interface, + int flags); + +/* + * De-activate interface (call "ifdown") + */ +int virInterfaceDestroy (virInterfacePtr interface, + int flags); + +/* + * Interface information + */ +const char* virInterfaceGetName (virInterfacePtr interface); +int virInterfaceGetMAC (virInterfacePtr interface, + unsigned char *mac); +int virInterfaceGetMACString (virInterfacePtr interface, + char *mac); + +char * virInterfaceGetXMLDesc (virInterfacePtr interface, + int flags); /** * virStoragePool: diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a028b21..f2656a3 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -854,6 +854,83 @@ int virNetworkGetAutostart (virNetworkPtr network, int virNetworkSetAutostart (virNetworkPtr network, int autostart); +/* + * Physical host interface configuration API + */ + +/** + * virInterface: + * + * a virInterface is a private structure representing a virtual interface. + */ +typedef struct _virInterface virInterface; + +/** + * virInterfacePtr: + * + * a virInterfacePtr is pointer to a virInterface private structure, this is the + * type used to reference a virtual interface in the API. + */ +typedef virInterface *virInterfacePtr; + +/* + * Get connection from interface. + */ +virConnectPtr virInterfaceGetConnect (virInterfacePtr interface); + +/* + * List defined interfaces + */ +int virConnectNumOfInterfaces (virConnectPtr conn); +int virConnectListInterfaces (virConnectPtr conn, + char **const names, + int maxnames); + +/* + * Lookup interface by name or MAC address + */ +virInterfacePtr virInterfaceLookupByName (virConnectPtr conn, + const char *name); +virInterfacePtr virInterfaceLookupByMAC (virConnectPtr conn, + const unsigned char *mac); +virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn, + const char *mac); + +/* + * Define interface (or modify existing interface configuration) + */ +virInterfacePtr virInterfaceDefineXML (virConnectPtr conn, + const char *xmlDesc, + int flags); + +/* + * Delete interface + */ +int virInterfaceUndefine (virInterfacePtr interface); + +/* + * Activate interface (ie call "ifup") + */ +int virInterfaceCreate (virInterfacePtr interface, + int flags); + +/* + * De-activate interface (call "ifdown") + */ +int virInterfaceDestroy (virInterfacePtr interface, + int flags); + +/* + * Interface information + */ +const char* virInterfaceGetName (virInterfacePtr interface); +int virInterfaceGetMAC (virInterfacePtr interface, + unsigned char *mac); +int virInterfaceGetMACString (virInterfacePtr interface, + char *mac); + +char * virInterfaceGetXMLDesc (virInterfacePtr interface, + int flags); /** * virStoragePool: -- 1.6.0.6

On Thu, Apr 02, 2009 at 02:18:38PM -0400, laine@laine.org wrote:
From: Laine Stump <laine@redhat.com>
ACK, we've discussed this public API enough now :-) Will wait till we have a driver using it before re-reviewing it agian. Daniel
diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 779ea72..f2e695a 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -854,6 +854,83 @@ int virNetworkGetAutostart (virNetworkPtr network, int virNetworkSetAutostart (virNetworkPtr network, int autostart);
+/* + * Physical host interface configuration API + */ + +/** + * virInterface: + * + * a virInterface is a private structure representing a virtual interface. + */ +typedef struct _virInterface virInterface; + +/** + * virInterfacePtr: + * + * a virInterfacePtr is pointer to a virInterface private structure, this is the + * type used to reference a virtual interface in the API. + */ +typedef virInterface *virInterfacePtr; + +/* + * Get connection from interface. + */ +virConnectPtr virInterfaceGetConnect (virInterfacePtr interface); + +/* + * List defined interfaces + */ +int virConnectNumOfInterfaces (virConnectPtr conn); +int virConnectListInterfaces (virConnectPtr conn, + char **const names, + int maxnames); + +/* + * Lookup interface by name or MAC address + */ +virInterfacePtr virInterfaceLookupByName (virConnectPtr conn, + const char *name); +virInterfacePtr virInterfaceLookupByMAC (virConnectPtr conn, + const unsigned char *mac); +virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn, + const char *mac); + +/* + * Define interface (or modify existing interface configuration) + */ +virInterfacePtr virInterfaceDefineXML (virConnectPtr conn, + const char *xmlDesc, + int flags); + +/* + * Delete interface + */ +int virInterfaceUndefine (virInterfacePtr interface); + +/* + * Activate interface (ie call "ifup") + */ +int virInterfaceCreate (virInterfacePtr interface, + int flags); + +/* + * De-activate interface (call "ifdown") + */ +int virInterfaceDestroy (virInterfacePtr interface, + int flags); + +/* + * Interface information + */ +const char* virInterfaceGetName (virInterfacePtr interface); +int virInterfaceGetMAC (virInterfacePtr interface, + unsigned char *mac); +int virInterfaceGetMACString (virInterfacePtr interface, + char *mac); + +char * virInterfaceGetXMLDesc (virInterfacePtr interface, + int flags);
/** * virStoragePool: diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a028b21..f2656a3 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -854,6 +854,83 @@ int virNetworkGetAutostart (virNetworkPtr network, int virNetworkSetAutostart (virNetworkPtr network, int autostart);
+/* + * Physical host interface configuration API + */ + +/** + * virInterface: + * + * a virInterface is a private structure representing a virtual interface. + */ +typedef struct _virInterface virInterface; + +/** + * virInterfacePtr: + * + * a virInterfacePtr is pointer to a virInterface private structure, this is the + * type used to reference a virtual interface in the API. + */ +typedef virInterface *virInterfacePtr; + +/* + * Get connection from interface. + */ +virConnectPtr virInterfaceGetConnect (virInterfacePtr interface); + +/* + * List defined interfaces + */ +int virConnectNumOfInterfaces (virConnectPtr conn); +int virConnectListInterfaces (virConnectPtr conn, + char **const names, + int maxnames); + +/* + * Lookup interface by name or MAC address + */ +virInterfacePtr virInterfaceLookupByName (virConnectPtr conn, + const char *name); +virInterfacePtr virInterfaceLookupByMAC (virConnectPtr conn, + const unsigned char *mac); +virInterfacePtr virInterfaceLookupByMACString (virConnectPtr conn, + const char *mac); + +/* + * Define interface (or modify existing interface configuration) + */ +virInterfacePtr virInterfaceDefineXML (virConnectPtr conn, + const char *xmlDesc, + int flags); + +/* + * Delete interface + */ +int virInterfaceUndefine (virInterfacePtr interface); + +/* + * Activate interface (ie call "ifup") + */ +int virInterfaceCreate (virInterfacePtr interface, + int flags); + +/* + * De-activate interface (call "ifdown") + */ +int virInterfaceDestroy (virInterfacePtr interface, + int flags); + +/* + * Interface information + */ +const char* virInterfaceGetName (virInterfacePtr interface); +int virInterfaceGetMAC (virInterfacePtr interface, + unsigned char *mac); +int virInterfaceGetMACString (virInterfacePtr interface, + char *mac); + +char * virInterfaceGetXMLDesc (virInterfacePtr interface, + int flags);
/** * virStoragePool: -- 1.6.0.6
-- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- |: 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 :|

From: Laine Stump <laine@redhat.com> --- include/libvirt/libvirt.h | 18 ++ include/libvirt/libvirt.h.in | 18 ++ include/libvirt/virterror.h | 4 + src/datatypes.h | 25 ++ src/driver.h | 73 +++++ src/libvirt.c | 628 ++++++++++++++++++++++++++++++++++++++++++ src/util.h | 2 - src/virterror.c | 3 + 8 files changed, 769 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index f2e695a..886c400 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 f2656a3..77b00b3 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 2c3777d..b8a9cad 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -62,6 +62,7 @@ typedef enum { VIR_FROM_NODEDEV, /* Error from node device monitor */ VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */ VIR_FROM_SECURITY, /* Error from security framework */ + VIR_FROM_INTERFACE, /* Error when operating on an interface */ } virErrorDomain; @@ -156,6 +157,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 88c2b0a..50c9b64 100644 --- a/src/driver.h +++ b/src/driver.h @@ -487,6 +487,78 @@ 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 virInterfacePtr + (*virDrvInterfaceLookupByMACString) (virConnectPtr conn, + const char *mac); +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 const char* + (*virDrvInterfaceGetName) (virInterfacePtr interface); +typedef int + (*virDrvInterfaceGetMAC) (virInterfacePtr interface, + unsigned char *mac); +typedef int + (*virDrvInterfaceGetMACString) (virInterfacePtr interface, + char *mac); +typedef char * + (*virDrvInterfaceGetXMLDesc) (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; + virDrvInterfaceLookupByMACString interfaceLookupByMACString; + virDrvInterfaceDefineXML interfaceDefineXML; + virDrvInterfaceUndefine interfaceUndefine; + virDrvInterfaceCreate interfaceCreate; + virDrvInterfaceDestroy interfaceDestroy; + virDrvInterfaceGetName interfaceGetName; + virDrvInterfaceGetMAC interfaceGetMAC; + virDrvInterfaceGetMACString interfaceGetMACString; + virDrvInterfaceGetXMLDesc interfaceGetXMLDesc; +}; + typedef int (*virDrvConnectNumOfStoragePools) (virConnectPtr conn); @@ -710,6 +782,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 d6de773..af46c31 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -71,6 +71,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]; @@ -455,6 +457,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 @@ -564,6 +592,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 * @@ -955,6 +1014,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++) { @@ -1115,6 +1192,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) @@ -5258,6 +5337,555 @@ 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; +} + +/** + * 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; +} + +/** + * 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; +} /** * virStoragePoolGetConnect: diff --git a/src/util.h b/src/util.h index 6fe03b6..99327cd 100644 --- a/src/util.h +++ b/src/util.h @@ -142,9 +142,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 d2514db..e7a0acf 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -154,6 +154,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { case VIR_FROM_SECURITY: dom = "Security Labeling "; break; + case VIR_FROM_INTERFACE: + dom = "Interface "; + break; } return(dom); } -- 1.6.0.6

On Thu, Apr 02, 2009 at 02:18:39PM -0400, laine@laine.org wrote:
From: Laine Stump <laine@redhat.com>
--- include/libvirt/libvirt.h | 18 ++ include/libvirt/libvirt.h.in | 18 ++ include/libvirt/virterror.h | 4 + src/datatypes.h | 25 ++ src/driver.h | 73 +++++ src/libvirt.c | 628 ++++++++++++++++++++++++++++++++++++++++++ src/util.h | 2 - src/virterror.c | 3 + 8 files changed, 769 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index f2e695a..886c400 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)
We might need to make this a little longer to be safe to cope with devices that a non-Ethernet based. eg wmaster0 and tun0 (Vpn) have hardware addresses that are 16 bytes long [snip] The rest of this plumbing all looks fine to me - its pretty standard stuff and all just derives from the public API defintions. 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 :|

From: Laine Stump <laine@redhat.com> --- configure.in | 22 ++++++++++++++++++++++ src/Makefile.am | 2 +- 2 files changed, 23 insertions(+), 1 deletions(-) diff --git a/configure.in b/configure.in index 392f2b9..6fba66d 100644 --- a/configure.in +++ b/configure.in @@ -783,6 +783,27 @@ fi AM_CONDITIONAL([WITH_BRIDGE], [test "$with_bridge" = "yes"]) dnl +dnl Is the netcf library available and desired? +dnl +AC_ARG_WITH([netcf], +[ --with-netcf add libnetcf support (on)],[],[with_netcf=yes]) +if test "$with_netcf" = "yes" ; then + AC_CHECK_LIB([netcf], [ncf_init], + [AC_CHECK_HEADER([netcf.h], + [LIB_NETCF=-lnetcf], + [AC_MSG_WARN([header netcf.h was not found, support for libnetcf will not be built])] + [with_netcf=no] + )], + [AC_MSG_WARN([libnetcf library was not found or not usable, support for libnetcf will not be built])] + [with_netcf=no]) + AC_SUBST([LIB_NETCF]) +fi +if test "$with_netcf" = "yes" ; then + AC_DEFINE_UNQUOTED([WITH_NETCF], 1, [whether host interface config via libnetcf is enabled]) +fi +AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"]) + +dnl dnl Storage driver checks dnl @@ -1367,6 +1388,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([]) AC_MSG_NOTICE([Storage Drivers]) AC_MSG_NOTICE([]) diff --git a/src/Makefile.am b/src/Makefile.am index 60b2d46..39766ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -207,7 +207,7 @@ libvirt_driver_la_SOURCES = \ $(NODE_DEVICE_CONF_SOURCES) libvirt_driver_la_CFLAGS = $(XEN_CFLAGS) $(NUMACTL_CFLAGS) -libvirt_driver_la_LDFLAGS = $(XEN_LIBS) $(NUMACTL_LIBS) +libvirt_driver_la_LDFLAGS = $(XEN_LIBS) $(NUMACTL_LIBS) $(LIB_NETCF) USED_SYM_FILES = libvirt_private.syms -- 1.6.0.6

On Thu, Apr 02, 2009 at 02:18:40PM -0400, laine@laine.org wrote:
dnl +dnl Is the netcf library available and desired? +dnl +AC_ARG_WITH([netcf], +[ --with-netcf add libnetcf support (on)],[],[with_netcf=yes]) +if test "$with_netcf" = "yes" ; then + AC_CHECK_LIB([netcf], [ncf_init], + [AC_CHECK_HEADER([netcf.h], + [LIB_NETCF=-lnetcf], + [AC_MSG_WARN([header netcf.h was not found, support for libnetcf will not be built])] + [with_netcf=no] + )], + [AC_MSG_WARN([libnetcf library was not found or not usable, support for libnetcf will not be built])] + [with_netcf=no])
I'm fairly sure netcf has support for pkg-config, so this CHECK_LIB/HEADER bit can be simplified. Take a look at te AVAHI check for a good example usage of pkg-config.
+ AC_SUBST([LIB_NETCF]) +fi +if test "$with_netcf" = "yes" ; then + AC_DEFINE_UNQUOTED([WITH_NETCF], 1, [whether host interface config via libnetcf is enabled]) +fi +AM_CONDITIONAL([WITH_NETCF], [test "$with_netcf" = "yes"])
+ +dnl dnl Storage driver checks dnl
@@ -1367,6 +1388,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([]) AC_MSG_NOTICE([Storage Drivers]) AC_MSG_NOTICE([]) diff --git a/src/Makefile.am b/src/Makefile.am index 60b2d46..39766ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -207,7 +207,7 @@ libvirt_driver_la_SOURCES = \ $(NODE_DEVICE_CONF_SOURCES)
libvirt_driver_la_CFLAGS = $(XEN_CFLAGS) $(NUMACTL_CFLAGS) -libvirt_driver_la_LDFLAGS = $(XEN_LIBS) $(NUMACTL_LIBS) +libvirt_driver_la_LDFLAGS = $(XEN_LIBS) $(NUMACTL_LIBS) $(LIB_NETCF)
The 'netcf' stuff I imagine will only need to be used by the 'interface', so I expect you'd end up with a libvirt_driver_interface_la... which would have the NETCF_LIBS & NETCF_CFLAGS settings 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 :|
participants (2)
-
Daniel P. Berrange
-
laine@laine.org