[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] PATCH: 7/12: Public API for node devices



This patch is the public API parts of the node device enumeration code.
No changes since David's last submission of this, except for some
Makefile tweaks

Daniel

diff -r 78738f80cf4c include/libvirt/libvirt.h
--- a/include/libvirt/libvirt.h	Wed Nov 12 21:05:32 2008 +0000
+++ b/include/libvirt/libvirt.h	Wed Nov 12 21:11:46 2008 +0000
@@ -995,6 +995,74 @@
                                                  unsigned int flags);
 
 /*
+ * Host device enumeration
+ */
+
+/**
+ * virNodeDevice:
+ *
+ * A virNodeDevice contains a node (host) device details.
+ */
+
+typedef struct _virNodeDevice virNodeDevice;
+
+/**
+ * virNodeDevicePtr:
+ *
+ * A virNodeDevicePtr is a pointer to a virNodeDevice structure.  Get
+ * one via virNodeDeviceLookupByKey, virNodeDeviceLookupByName, or
+ * virNodeDeviceCreate.  Be sure to Call virNodeDeviceFree when done
+ * using a virNodeDevicePtr obtained from any of the above functions to
+ * avoid leaking memory.
+ */
+
+typedef virNodeDevice *virNodeDevicePtr;
+
+
+int                     virNodeNumOfDevices     (virConnectPtr conn,
+                                                 unsigned int flags);
+
+int                     virNodeListDevices      (virConnectPtr conn,
+                                                 char **const names,
+                                                 int maxnames,
+                                                 unsigned int flags);
+
+int                     virNodeNumOfDevicesByCap (virConnectPtr conn,
+                                                  const char *cap,
+                                                  unsigned int flags);
+
+int                     virNodeListDevicesByCap (virConnectPtr conn,
+                                                 const char *cap,
+                                                 char **const names,
+                                                 int maxnames,
+                                                 unsigned int flags);
+
+virNodeDevicePtr        virNodeDeviceLookupByName (virConnectPtr conn,
+                                                   const char *name);
+
+const char *            virNodeDeviceGetName     (virNodeDevicePtr dev);
+
+const char *            virNodeDeviceGetParent   (virNodeDevicePtr dev);
+
+int                     virNodeDeviceNumOfCaps   (virNodeDevicePtr dev);
+
+int                     virNodeDeviceListCaps    (virNodeDevicePtr dev,
+                                                  char **const names,
+                                                  int maxnames);
+
+char *                  virNodeDeviceGetXMLDesc (virNodeDevicePtr dev,
+                                                 unsigned int flags);
+
+virNodeDevicePtr        virNodeDeviceCreate     (virConnectPtr conn,
+                                                 const char *xml,
+                                                 unsigned int flags);
+
+int                     virNodeDeviceDestroy    (virNodeDevicePtr dev,
+                                                 unsigned int flags);
+
+int                     virNodeDeviceFree       (virNodeDevicePtr dev);
+
+/*
  * Domain Event Notification
  */
 
diff -r 78738f80cf4c include/libvirt/libvirt.h.in
--- a/include/libvirt/libvirt.h.in	Wed Nov 12 21:05:32 2008 +0000
+++ b/include/libvirt/libvirt.h.in	Wed Nov 12 21:11:46 2008 +0000
@@ -995,6 +995,74 @@
                                                  unsigned int flags);
 
 /*
+ * Host device enumeration
+ */
+
+/**
+ * virNodeDevice:
+ *
+ * A virNodeDevice contains a node (host) device details.
+ */
+
+typedef struct _virNodeDevice virNodeDevice;
+
+/**
+ * virNodeDevicePtr:
+ *
+ * A virNodeDevicePtr is a pointer to a virNodeDevice structure.  Get
+ * one via virNodeDeviceLookupByKey, virNodeDeviceLookupByName, or
+ * virNodeDeviceCreate.  Be sure to Call virNodeDeviceFree when done
+ * using a virNodeDevicePtr obtained from any of the above functions to
+ * avoid leaking memory.
+ */
+
+typedef virNodeDevice *virNodeDevicePtr;
+
+
+int                     virNodeNumOfDevices     (virConnectPtr conn,
+                                                 unsigned int flags);
+
+int                     virNodeListDevices      (virConnectPtr conn,
+                                                 char **const names,
+                                                 int maxnames,
+                                                 unsigned int flags);
+
+int                     virNodeNumOfDevicesByCap (virConnectPtr conn,
+                                                  const char *cap,
+                                                  unsigned int flags);
+
+int                     virNodeListDevicesByCap (virConnectPtr conn,
+                                                 const char *cap,
+                                                 char **const names,
+                                                 int maxnames,
+                                                 unsigned int flags);
+
+virNodeDevicePtr        virNodeDeviceLookupByName (virConnectPtr conn,
+                                                   const char *name);
+
+const char *            virNodeDeviceGetName     (virNodeDevicePtr dev);
+
+const char *            virNodeDeviceGetParent   (virNodeDevicePtr dev);
+
+int                     virNodeDeviceNumOfCaps   (virNodeDevicePtr dev);
+
+int                     virNodeDeviceListCaps    (virNodeDevicePtr dev,
+                                                  char **const names,
+                                                  int maxnames);
+
+char *                  virNodeDeviceGetXMLDesc (virNodeDevicePtr dev,
+                                                 unsigned int flags);
+
+virNodeDevicePtr        virNodeDeviceCreate     (virConnectPtr conn,
+                                                 const char *xml,
+                                                 unsigned int flags);
+
+int                     virNodeDeviceDestroy    (virNodeDevicePtr dev,
+                                                 unsigned int flags);
+
+int                     virNodeDeviceFree       (virNodeDevicePtr dev);
+
+/*
  * Domain Event Notification
  */
 
diff -r 78738f80cf4c include/libvirt/virterror.h
--- a/include/libvirt/virterror.h	Wed Nov 12 21:05:32 2008 +0000
+++ b/include/libvirt/virterror.h	Wed Nov 12 21:11:46 2008 +0000
@@ -58,6 +58,7 @@
     VIR_FROM_STORAGE,   /* Error from storage driver */
     VIR_FROM_NETWORK,   /* Error from network config */
     VIR_FROM_DOMAIN,    /* Error from domain config */
+    VIR_FROM_DEVMONITOR,/* Error from node device monitor */
 } virErrorDomain;
 
 
@@ -148,6 +149,9 @@
     VIR_WAR_NO_STORAGE, /* failed to start storage */
     VIR_ERR_NO_STORAGE_POOL, /* storage pool not found */
     VIR_ERR_NO_STORAGE_VOL, /* storage pool not found */
+    VIR_WAR_NO_NODE, /* failed to start node driver */
+    VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
+    VIR_ERR_NO_NODE_DEVICE,/* node device not found */
 } virErrorNumber;
 
 /**
diff -r 78738f80cf4c src/datatypes.c
--- a/src/datatypes.c	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/datatypes.c	Wed Nov 12 21:11:46 2008 +0000
@@ -140,6 +140,9 @@
     ret->storageVols = virHashCreate(20);
     if (ret->storageVols == NULL)
         goto failed;
+    ret->nodeDevices = virHashCreate(256);
+    if (ret->nodeDevices == NULL)
+        goto failed;
 
     pthread_mutex_init(&ret->lock, NULL);
 
@@ -156,6 +159,8 @@
             virHashFree(ret->storagePools, (virHashDeallocator) virStoragePoolFreeName);
         if (ret->storageVols != NULL)
             virHashFree(ret->storageVols, (virHashDeallocator) virStorageVolFreeName);
+        if (ret->nodeDevices != NULL)
+            virHashFree(ret->nodeDevices, (virHashDeallocator) virNodeDeviceFree);
 
         pthread_mutex_destroy(&ret->lock);
         VIR_FREE(ret);
@@ -183,6 +188,8 @@
         virHashFree(conn->storagePools, (virHashDeallocator) virStoragePoolFreeName);
     if (conn->storageVols != NULL)
         virHashFree(conn->storageVols, (virHashDeallocator) virStorageVolFreeName);
+    if (conn->nodeDevices != NULL)
+        virHashFree(conn->nodeDevices, (virHashDeallocator) virNodeDeviceFree);
 
     virResetError(&conn->err);
     if (virLastErr.conn == conn)
@@ -771,3 +778,126 @@
     pthread_mutex_unlock(&vol->conn->lock);
     return (refs);
 }
+
+
+/**
+ * virGetNodeDevice:
+ * @conn: the hypervisor connection
+ * @name: device name (unique on node)
+ *
+ * Lookup if the device is already registered for that connection,
+ * if yes return a new pointer to it, if no allocate a new structure,
+ * and register it in the table. In any case a corresponding call to
+ * virFreeNodeDevice() is needed to not leak data.
+ *
+ * Returns a pointer to the node device, or NULL in case of failure
+ */
+virNodeDevicePtr
+virGetNodeDevice(virConnectPtr conn, const char *name)
+{
+    virNodeDevicePtr ret = NULL;
+
+    if ((!VIR_IS_CONNECT(conn)) || (name == NULL)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(NULL);
+    }
+    pthread_mutex_lock(&conn->lock);
+
+    ret = (virNodeDevicePtr) virHashLookup(conn->nodeDevices, name);
+    if (ret == NULL) {
+       if (VIR_ALLOC(ret) < 0) {
+            virLibConnError(conn, VIR_ERR_NO_MEMORY, _("allocating node dev"));
+            goto error;
+        }
+        ret->magic = VIR_NODE_DEVICE_MAGIC;
+        ret->conn = conn;
+        ret->name = strdup(name);
+        if (ret->name == NULL) {
+            virLibConnError(conn, VIR_ERR_NO_MEMORY, _("copying node dev name"));
+            goto error;
+        }
+
+        if (virHashAddEntry(conn->nodeDevices, name, ret) < 0) {
+            virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("failed to add node dev to conn hash table"));
+            goto error;
+        }
+        conn->refs++;
+    }
+    ret->refs++;
+    pthread_mutex_unlock(&conn->lock);
+    return(ret);
+
+error:
+    pthread_mutex_unlock(&conn->lock);
+    if (ret != NULL) {
+        VIR_FREE(ret->name);
+        VIR_FREE(ret);
+    }
+    return(NULL);
+}
+
+
+/**
+ * virReleaseNodeDevice:
+ * @dev: the dev to release
+ *
+ * Unconditionally release all memory associated with a dev.
+ * The conn.lock mutex must be held prior to calling this, and will
+ * be released prior to this returning. The dev obj must not
+ * be used once this method returns.
+ *
+ * It will also unreference the associated connection object,
+ * which may also be released if its ref count hits zero.
+ */
+static void
+virReleaseNodeDevice(virNodeDevicePtr dev) {
+    virConnectPtr conn = dev->conn;
+    DEBUG("release dev %p %s", dev, dev->name);
+
+    if (virHashRemoveEntry(conn->nodeDevices, dev->name, NULL) < 0)
+        virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("dev missing from connection hash table"));
+
+    dev->magic = -1;
+    VIR_FREE(dev->name);
+    VIR_FREE(dev);
+
+    DEBUG("unref connection %p %d", conn, conn->refs);
+    conn->refs--;
+    if (conn->refs == 0) {
+        virReleaseConnect(conn);
+        /* Already unlocked mutex */
+        return;
+    }
+
+    pthread_mutex_unlock(&conn->lock);
+}
+
+
+/**
+ * virUnrefNodeDevice:
+ * @dev: the dev to unreference
+ *
+ * Unreference the dev. If the use count drops to zero, the structure is
+ * actually freed.
+ *
+ * Returns the reference count or -1 in case of failure.
+ */
+int
+virUnrefNodeDevice(virNodeDevicePtr dev) {
+    int refs;
+
+    pthread_mutex_lock(&dev->conn->lock);
+    DEBUG("unref dev %p %s %d", dev, dev->name, dev->refs);
+    dev->refs--;
+    refs = dev->refs;
+    if (refs == 0) {
+        virReleaseNodeDevice(dev);
+        /* Already unlocked mutex */
+        return (0);
+    }
+
+    pthread_mutex_unlock(&dev->conn->lock);
+    return (refs);
+}
diff -r 78738f80cf4c src/datatypes.h
--- a/src/datatypes.h	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/datatypes.h	Wed Nov 12 21:11:46 2008 +0000
@@ -78,6 +78,16 @@
 #define VIR_IS_STORAGE_VOL(obj)		((obj) && (obj)->magic==VIR_STORAGE_VOL_MAGIC)
 #define VIR_IS_CONNECTED_STORAGE_VOL(obj)	(VIR_IS_STORAGE_VOL(obj) && VIR_IS_CONNECT((obj)->conn))
 
+/**
+ * VIR_NODE_DEVICE_MAGIC:
+ *
+ * magic value used to protect the API when pointers to storage vol structures
+ * are passed down by the users.
+ */
+#define VIR_NODE_DEVICE_MAGIC                   0xDEAD5679
+#define VIR_IS_NODE_DEVICE(obj)                 ((obj) && (obj)->magic==VIR_NODE_DEVICE_MAGIC)
+#define VIR_IS_CONNECTED_NODE_DEVICE(obj)       (VIR_IS_NODE_DEVICE(obj) && VIR_IS_CONNECT((obj)->conn))
+
 
 /**
  * _virConnect:
@@ -93,6 +103,7 @@
     virDriverPtr      driver;
     virNetworkDriverPtr networkDriver;
     virStorageDriverPtr storageDriver;
+    virDeviceMonitorPtr  deviceMonitor;
 
     /* Private data pointer which can be used by driver and
      * network driver as they wish.
@@ -101,6 +112,7 @@
     void *            privateData;
     void *            networkPrivateData;
     void *            storagePrivateData;
+    void *            devMonPrivateData;
 
     /* Per-connection error. */
     virError err;           /* the last error */
@@ -118,6 +130,7 @@
     virHashTablePtr networks; /* hash table for known domains */
     virHashTablePtr storagePools;/* hash table for known storage pools */
     virHashTablePtr storageVols;/* hash table for known storage vols */
+    virHashTablePtr nodeDevices; /* hash table for known node devices */
     int refs;                 /* reference count */
 };
 
@@ -176,6 +189,19 @@
     char key[PATH_MAX];                  /* unique key for storage vol */
 };
 
+/**
+ * _virNodeDevice:
+ *
+ * Internal structure associated with a node device
+ */
+struct _virNodeDevice {
+    unsigned int magic;                 /* specific value to check */
+    int refs;                           /* reference count */
+    virConnectPtr conn;                 /* pointer back to the connection */
+    char *name;                         /* device name (unique on node) */
+};
+
+
 /************************************************************************
  *									*
  *	API for domain/connections (de)allocations and lookups		*
@@ -203,4 +229,8 @@
                                     const char *key);
 int virUnrefStorageVol(virStorageVolPtr vol);
 
+virNodeDevicePtr virGetNodeDevice(virConnectPtr conn,
+                                  const char *name);
+int virUnrefNodeDevice(virNodeDevicePtr dev);
+
 #endif
diff -r 78738f80cf4c src/driver.h
--- a/src/driver.h	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/driver.h	Wed Nov 12 21:11:46 2008 +0000
@@ -604,6 +604,73 @@
 };
 #endif
 
+
+typedef struct _virDeviceMonitor virDeviceMonitor;
+typedef virDeviceMonitor *virDeviceMonitorPtr;
+
+typedef int (*virDevMonNumOfDevices)(virConnectPtr conn,
+                                     unsigned int flags);
+
+typedef int (*virDevMonListDevices)(virConnectPtr conn,
+                                    char **const names,
+                                    int maxnames,
+                                    unsigned int flags);
+
+typedef int (*virDevMonNumOfDevicesByCap)(virConnectPtr conn,
+                                          const char *cap,
+                                          unsigned int flags);
+
+typedef int (*virDevMonListDevicesByCap)(virConnectPtr conn,
+                                         const char *cap,
+                                         char **const names,
+                                         int maxnames,
+                                         unsigned int flags);
+
+typedef virNodeDevicePtr (*virDevMonDeviceLookupByName)(virConnectPtr conn,
+                                                        const char *name);
+
+typedef char * (*virDevMonDeviceDumpXML)(virNodeDevicePtr dev,
+                                         unsigned int flags);
+
+typedef char * (*virDevMonDeviceGetParent)(virNodeDevicePtr dev);
+
+typedef int (*virDevMonDeviceNumOfCaps)(virNodeDevicePtr dev);
+
+typedef int (*virDevMonDeviceListCaps)(virNodeDevicePtr dev,
+                                       char **const names,
+                                       int maxnames);
+
+typedef virNodeDevicePtr (*virDevMonDeviceCreate)(virConnectPtr conn,
+                                                  const char *xml,
+                                                  unsigned int flags);
+
+typedef int (*virDevMonDeviceDestroy)(virNodeDevicePtr dev,
+                                      unsigned int flags);
+
+/**
+ * _virDeviceMonitor:
+ *
+ * Structure associated with monitoring the devices
+ * on a virtualized node.
+ *
+ */
+struct _virDeviceMonitor {
+    const char * name;    /* the name of the driver */
+    virDrvOpen open;
+    virDrvClose close;
+    virDevMonNumOfDevices numOfDevices;
+    virDevMonListDevices listDevices;
+    virDevMonNumOfDevicesByCap numOfDevicesByCap;
+    virDevMonListDevicesByCap listDevicesByCap;
+    virDevMonDeviceLookupByName deviceLookupByName;
+    virDevMonDeviceDumpXML deviceDumpXML;
+    virDevMonDeviceGetParent deviceGetParent;
+    virDevMonDeviceNumOfCaps deviceNumOfCaps;
+    virDevMonDeviceListCaps deviceListCaps;
+    virDevMonDeviceCreate deviceCreate;
+    virDevMonDeviceDestroy deviceDestroy;
+};
+
 /*
  * Registration
  * TODO: also need ways to (des)activate a given driver
@@ -612,6 +679,7 @@
 int virRegisterDriver(virDriverPtr);
 int virRegisterNetworkDriver(virNetworkDriverPtr);
 int virRegisterStorageDriver(virStorageDriverPtr);
+int virRegisterDeviceMonitor(virDeviceMonitorPtr);
 #ifdef WITH_LIBVIRTD
 int virRegisterStateDriver(virStateDriverPtr);
 #endif
diff -r 78738f80cf4c src/libvirt.c
--- a/src/libvirt.c	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/libvirt.c	Wed Nov 12 21:11:46 2008 +0000
@@ -70,6 +70,8 @@
 static int virNetworkDriverTabCount = 0;
 static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS];
 static int virStorageDriverTabCount = 0;
+static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS];
+static int virDeviceMonitorTabCount = 0;
 #ifdef WITH_LIBVIRTD
 static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
 static int virStateDriverTabCount = 0;
@@ -449,6 +451,32 @@
 }
 
 /**
+ * virLibNodeDeviceError:
+ * @dev: the device if available
+ * @error: the error number
+ * @info: extra information string
+ *
+ * Handle an error at the node device level
+ */
+static void
+virLibNodeDeviceError(virNodeDevicePtr dev, 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_NODE_DEVICE)
+        conn = dev->conn;
+
+    virRaiseError(conn, NULL, NULL, VIR_FROM_DEVMONITOR, error, VIR_ERR_ERROR,
+                    errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
+/**
  * virRegisterNetworkDriver:
  * @driver: pointer to a network driver block
  *
@@ -508,6 +536,34 @@
 
     virStorageDriverTab[virStorageDriverTabCount] = driver;
     return virStorageDriverTabCount++;
+}
+
+/**
+ * virRegisterDeviceMonitor:
+ * @driver: pointer to a device monitor block
+ *
+ * Register a device monitor
+ *
+ * Returns the driver priority or -1 in case of error.
+ */
+int
+virRegisterDeviceMonitor(virDeviceMonitorPtr driver)
+{
+    if (virInitialize() < 0)
+      return -1;
+
+    if (driver == NULL) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    if (virDeviceMonitorTabCount >= MAX_DRIVERS) {
+        virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+
+    virDeviceMonitorTab[virDeviceMonitorTabCount] = driver;
+    return virDeviceMonitorTabCount++;
 }
 
 /**
@@ -806,6 +862,33 @@
         }
     }
 
+    /* Node driver (optional) */
+    for (i = 0; i < virDeviceMonitorTabCount; i++) {
+        res = virDeviceMonitorTab[i]->open (ret, auth, flags);
+        DEBUG("node driver %d %s returned %s",
+              i, virDeviceMonitorTab[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(virDeviceMonitorTab[i]->name, "remote")) {
+                virLibConnWarning (NULL, VIR_WAR_NO_NODE,
+                                   "Is the libvirtd daemon running ?");
+            } else {
+                char *msg;
+                if (asprintf(&msg, "Is the %s daemon running?",
+                             virDeviceMonitorTab[i]->name) > 0) {
+                    virLibConnWarning (NULL, VIR_WAR_NO_NODE, msg);
+                    VIR_FREE(msg);
+                }
+            }
+            break;
+        } else if (res == VIR_DRV_OPEN_SUCCESS) {
+            ret->deviceMonitor = virDeviceMonitorTab[i];
+            break;
+        }
+    }
+
     return ret;
 
 failed:
@@ -923,6 +1006,8 @@
         conn->networkDriver->close (conn);
     if (conn->storageDriver)
         conn->storageDriver->close (conn);
+    if (conn->deviceMonitor)
+        conn->deviceMonitor->close (conn);
     conn->driver->close (conn);
 
     if (virUnrefConnect(conn) < 0)
@@ -5263,6 +5348,383 @@
 
 
 
+
+/**
+ * virNodeNumOfDevices:
+ * @conn: pointer to the hypervisor connection
+ * @flags: flags (unused, pass 0)
+ *
+ * Provides the number of node devices.
+ *
+ * Returns the number of node devices or -1 in case of error
+ */
+int
+virNodeNumOfDevices(virConnectPtr conn, unsigned int flags)
+{
+    DEBUG("conn=%p, flags=%d", conn, flags);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+    if (flags != 0) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->numOfDevices)
+        return conn->deviceMonitor->numOfDevices (conn, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
+/**
+ * virNodeListDevices:
+ * @conn: pointer to the hypervisor connection
+ * @names: array to collect the list of node device names
+ * @maxnames: size of @names
+ * @flags: flags (unused, pass 0)
+ *
+ * Collect the list of node devices, and store their names in @names
+ *
+ * Returns the number of node devices found or -1 in case of error
+ */
+int
+virNodeListDevices(virConnectPtr conn, char **const names, int maxnames,
+                   unsigned int flags)
+{
+    DEBUG("conn=%p, names=%p, maxnames=%d, flags=%d",
+          conn, names, maxnames, flags);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+    if ((flags != 0) || (names == NULL) || (maxnames < 0)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->listDevices)
+        return conn->deviceMonitor->listDevices (conn, names, maxnames, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virNodeNumOfDevicesByCap:
+ * @conn: pointer to the hypervisor connection
+ * @cap: capability name
+ * @flags: flags (unused, pass 0)
+ *
+ * Provides the number of node devices with the given capability.
+ *
+ * Returns the number of node devices with the capability or -1 in case of error
+ */
+int
+virNodeNumOfDevicesByCap(virConnectPtr conn, const char *cap,
+                         unsigned int flags)
+{
+    DEBUG("conn=%p, cap=%p, flags=%d", conn, cap, flags);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if ((flags != 0) || (cap == NULL)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->numOfDevicesByCap)
+        return conn->deviceMonitor->numOfDevicesByCap (conn, cap, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
+/**
+ * virNodeListDevicesByCap:
+ * @conn: pointer to the hypervisor connection
+ * @cap: capability name
+ * @names: array to collect the list of node device names
+ * @maxnames: size of @names
+ * @flags: flags (unused, pass 0)
+ *
+ * Collect the list of node devices with the given capability, and store
+ * their names in @names
+ *
+ * Returns the number of node devices found with the capability or -1 in case of error
+ */
+int
+virNodeListDevicesByCap(virConnectPtr conn, const char *cap,
+                        char **const names, int maxnames,
+                        unsigned int flags)
+{
+    DEBUG("conn=%p, cap=%p, names=%p, maxnames=%d, flags=%d",
+          conn, cap, names, maxnames, flags);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return (-1);
+    }
+
+    if ((flags != 0) || (names == NULL) || (maxnames < 0) || (cap == NULL)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->listDevicesByCap)
+        return conn->deviceMonitor->listDevicesByCap (conn, cap, names, maxnames, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
+/**
+ * virNodeDeviceLookupByName:
+ * @conn: pointer to the hypervisor connection
+ * @name: unique device name
+ *
+ * Lookup a node device by its name.
+ *
+ * Returns a virNodeDevicePtr if found, NULL otherwise.
+ */
+virNodeDevicePtr virNodeDeviceLookupByName(virConnectPtr conn, const char *name)
+{
+    DEBUG("conn=%p, name=%p", conn, name);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return NULL;
+    }
+
+    if (name == NULL) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return NULL;
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->deviceLookupByName)
+        return conn->deviceMonitor->deviceLookupByName (conn, name);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
+}
+
+
+/**
+ * virNodeDeviceCreate:
+ * @conn: pointer to the hypervisor connection
+ * @xml: XML description for new device
+ * @flags: flags (unused, pass 0)
+ *
+ * Creates a new node device, as described by the XML.
+ * [Need to describe what kinds of devices can be created this way]
+ *
+ * Returns a pointer to the new device, or NULL for error.
+ */
+virNodeDevicePtr virNodeDeviceCreate(virConnectPtr conn, const char *xml,
+                                     unsigned int flags)
+{
+    DEBUG("conn=%p, xml=%p, flags=%d", conn, xml, flags);
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return NULL;
+    }
+
+    if ((flags != 0) || (xml == NULL)) {
+        virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return NULL;
+    }
+
+    if (conn->deviceMonitor && conn->deviceMonitor->deviceCreate)
+        return conn->deviceMonitor->deviceCreate (conn, xml, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
+}
+
+/**
+ * virNodeDeviceGetXMLDesc:
+ * @dev: pointer to the node device
+ * @flags: flags for XML generation (unused, pass 0)
+ *
+ * Fetch an XML document describing all aspects of
+ * the device.
+ *
+ * Return the XML document, or NULL on error
+ */
+char *virNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags)
+{
+    DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return NULL;
+    }
+
+    if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceDumpXML)
+        return dev->conn->deviceMonitor->deviceDumpXML (dev, flags);
+
+    virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
+}
+
+
+/**
+ * virNodeDeviceDestroy:
+ * @dev: pointer to the created device
+ * @flags: flags (unused, pass 0)
+ *
+ * Removes a device created by virNodeDeviceCreate.
+ *
+ * Returns 0 for success, <0 for failure.
+ */
+int virNodeDeviceDestroy(virNodeDevicePtr dev, unsigned int flags)
+{
+    DEBUG("dev=%p, conn=%p, flags=%d", dev, dev ? dev->conn : NULL, flags);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return (-1);
+    }
+
+    if (flags != 0) {
+        virLibConnError(dev->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return -1;
+    }
+
+    if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceDestroy)
+        return dev->conn->deviceMonitor->deviceDestroy (dev, flags);
+
+    virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
+/**
+ * virNodeDeviceGetName:
+ * @dev: the device
+ *
+ * Returns the device name.
+ */
+const char *virNodeDeviceGetName(virNodeDevicePtr dev)
+{
+    DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return NULL;
+    }
+
+    return dev->name;
+}
+
+/**
+ * virNodeDeviceGetParent:
+ * @dev: the device
+ *
+ * Returns the name of the device's parent, or NULL if the
+ * device has no parent.
+ */
+const char *virNodeDeviceGetParent(virNodeDevicePtr dev)
+{
+    DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return NULL;
+    }
+
+    if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceGetParent)
+        return dev->conn->deviceMonitor->deviceGetParent (dev);
+
+    virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
+}
+
+/**
+ * virNodeDeviceNumOfCaps:
+ * @dev: the device
+ *
+ * Returns the number of capabilities supported by the device.
+ */
+int virNodeDeviceNumOfCaps(virNodeDevicePtr dev)
+{
+    DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return -1;
+    }
+
+    if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceNumOfCaps)
+        return dev->conn->deviceMonitor->deviceNumOfCaps (dev);
+
+    virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virNodeDeviceListCaps:
+ * @dev: the device
+ * @names: array to collect the list of capability names
+ * @maxnames: size of @names
+ *
+ * Lists the names of the capabilities supported by the device.
+ *
+ * Returns the number of capability names listed in @names.
+ */
+int virNodeDeviceListCaps(virNodeDevicePtr dev,
+                          char **const names,
+                          int maxnames)
+{
+    DEBUG("dev=%p, conn=%p, names=%p, maxnames=%d",
+          dev, dev ? dev->conn : NULL, names, maxnames);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return -1;
+    }
+
+    if (dev->conn->deviceMonitor && dev->conn->deviceMonitor->deviceListCaps)
+        return dev->conn->deviceMonitor->deviceListCaps (dev, names, maxnames);
+
+    virLibConnError (dev->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
+/**
+ * virNodeDeviceFree:
+ * @dev: pointer to the node device
+ *
+ * Drops a reference to the node device, freeing it if
+ * this was the last reference.
+ *
+ * Returns the 0 for success, -1 for error.
+ */
+int virNodeDeviceFree(virNodeDevicePtr dev)
+{
+    DEBUG("dev=%p, conn=%p", dev, dev ? dev->conn : NULL);
+
+    if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+        virLibNodeDeviceError(NULL, VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+        return (-1);
+    }
+    if (virUnrefNodeDevice(dev) < 0)
+        return (-1);
+    return(0);
+}
+
+
 /*
  * Domain Event Notification
  */
diff -r 78738f80cf4c src/libvirt_sym.version.in
--- a/src/libvirt_sym.version.in	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/libvirt_sym.version.in	Wed Nov 12 21:11:46 2008 +0000
@@ -232,6 +232,21 @@
 	virEventRegisterImpl;
 	virConnectDomainEventRegister;
 	virConnectDomainEventDeregister;
+
+	virNodeNumOfDevices;
+	virNodeListDevices;
+	virNodeNumOfDevicesByCap;
+	virNodeListDevicesByCap;
+	virNodeDeviceLookupByName;
+	virNodeDeviceFree;
+	virNodeDeviceGetXMLDesc;
+	virNodeDeviceCreate;
+	virNodeDeviceDestroy;
+	virNodeDeviceGetName;
+	virNodeDeviceGetParent;
+	virNodeDeviceNumOfCaps;
+	virNodeDeviceListCaps;
+
 } LIBVIRT_0.4.5;
 
 /* .... define new API here using predicted next version number .... */
diff -r 78738f80cf4c src/virterror.c
--- a/src/virterror.c	Wed Nov 12 21:05:32 2008 +0000
+++ b/src/virterror.c	Wed Nov 12 21:11:46 2008 +0000
@@ -309,6 +309,9 @@
             break;
         case VIR_FROM_DOMAIN:
             dom = "Domain Config ";
+            break;
+        case VIR_FROM_DEVMONITOR:
+            dom = "Device Monitor ";
             break;
 
     }
@@ -719,6 +722,24 @@
                 else
                         errmsg = _("Failed to find a storage driver: %s");
                 break;
+        case VIR_WAR_NO_NODE:
+                if (info == NULL)
+                        errmsg = _("Failed to find a node driver");
+                else
+                        errmsg = _("Failed to find a node driver: %s");
+                break;
+        case VIR_ERR_INVALID_NODE_DEVICE:
+                if (info == NULL)
+                        errmsg = _("invalid node device pointer");
+                else
+                        errmsg = _("invalid node device pointer in %s");
+                break;
+        case VIR_ERR_NO_NODE_DEVICE:
+                if (info == NULL)
+                        errmsg = _("Node device not found");
+                else
+                        errmsg = _("Node device not found: %s");
+                break;
     }
     return (errmsg);
 }


-- 
|: 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 :|


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]