[libvirt] [PATCH 2/5] First level of plumbing for virInterface*.

Daniel P. Berrange berrange at redhat.com
Wed May 20 12:01:43 UTC 2009


On Tue, May 19, 2009 at 12:51:24PM -0400, Laine Stump wrote:
> From: Laine Stump <laine at 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 :|




More information about the libvir-list mailing list