[libvirt] [PATCH 2/3] qemu: Use nodedev callback mechanism to to get a nodedev data

John Ferlan jferlan at redhat.com
Thu Feb 9 03:34:03 UTC 2017


Using the nodedev driver callback mechanism - allow qemu to be
notified whenever a nodedev is added/removed.

Keep track of the node devices in a hash table rather than requiring
a connection in order to get specific information about a node device
that qemu would eventually like to keep track of.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/qemu/qemu_conf.c   | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_conf.h   | 14 ++++++++++++++
 src/qemu/qemu_driver.c | 31 +++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 6613d59..f88c7f3 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1598,3 +1598,51 @@ qemuGetDomainHupageMemPath(const virDomainDef *def,
 
     return 0;
 }
+
+
+/**
+ * @driver: qemu driver pointer
+ * @def: Node device definition
+ * @enumeration: boolean for emumeration indication
+ *
+ * Taking the @def from the node device driver, add the device to
+ * the qemu node device hash table. The @enumeration is true when
+ * this callback is called from the node device enumeration and false
+ * when called when the @def was added to the node device.
+ *
+ * Returns -1 on failure, 0 on adding device name, 1 on already added name
+ */
+int
+qemuNodeDeviceEntryAdd(virQEMUDriverPtr driver,
+                       virNodeDeviceDefPtr def,
+                       bool enumerate)
+{
+    VIR_DEBUG("Attempt to add name='%s', parent='%s' enumerate=%d",
+              def->name, def->parent, enumerate);
+
+    if (!virHashLookup(driver->nodeDevices, def->name)) {
+        if (virHashAddEntry(driver->nodeDevices, def->name, NULL) < 0)
+            return -1;
+        return 0;
+    }
+    return 1;
+}
+
+
+/**
+ * @driver: qemu driver pointer
+ * @def: node device definition
+ *
+ * Remove the definition from qemu's node device hash table.
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+qemuNodeDeviceEntryRemove(virQEMUDriverPtr driver,
+                          virNodeDeviceDefPtr def)
+{
+    VIR_DEBUG("Attempt to remove name='%s' parent='%s'",
+              def->name, def->parent);
+
+    return virHashRemoveEntry(driver->nodeDevices, def->name);
+}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 92a7a50..7d514a9 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -32,6 +32,7 @@
 # include "network_conf.h"
 # include "domain_conf.h"
 # include "snapshot_conf.h"
+# include "node_device_conf.h"
 # include "domain_event.h"
 # include "virthread.h"
 # include "security/security_manager.h"
@@ -253,6 +254,9 @@ struct _virQEMUDriver {
     virHashTablePtr sharedDevices;
 
     /* Immutable pointer, self-locking APIs */
+    virHashTablePtr nodeDevices;
+
+    /* Immutable pointer, self-locking APIs */
     virPortAllocatorPtr remotePorts;
 
     /* Immutable pointer, self-locking APIs */
@@ -348,4 +352,14 @@ int qemuGetDomainHupageMemPath(const virDomainDef *def,
                                virQEMUDriverConfigPtr cfg,
                                unsigned long long pagesize,
                                char **memPath);
+
+void qemuNodeDeviceEntryFree(void *payload, const void *name);
+
+int qemuNodeDeviceEntryAdd(virQEMUDriverPtr driver,
+                           virNodeDeviceDefPtr def,
+                           bool enumerate);
+
+int qemuNodeDeviceEntryRemove(virQEMUDriverPtr driver,
+                              virNodeDeviceDefPtr def);
+
 #endif /* __QEMUD_CONF_H */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 89bc833..758a7f5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -197,6 +197,28 @@ static virNWFilterCallbackDriver qemuCallbackDriver = {
 };
 
 
+static int
+qemuNodeDeviceAdd(virNodeDeviceDefPtr def,
+                  bool enumerate)
+{
+    return qemuNodeDeviceEntryAdd(qemu_driver, def, enumerate);
+}
+
+
+static int
+qemuNodeDeviceRemove(virNodeDeviceDefPtr def)
+{
+    return qemuNodeDeviceEntryRemove(qemu_driver, def);
+}
+
+
+static virNodeDeviceCallbackDriver qemuNodedevCallbackDriver = {
+    .name = QEMU_DRIVER_NAME,
+    .nodeDeviceAdd = qemuNodeDeviceAdd,
+    .nodeDeviceRemove = qemuNodeDeviceRemove,
+};
+
+
 struct qemuAutostartData {
     virQEMUDriverPtr driver;
     virConnectPtr conn;
@@ -776,6 +798,15 @@ qemuStateInitialize(bool privileged,
     if (!(qemu_driver->sharedDevices = virHashCreate(30, qemuSharedDeviceEntryFree)))
         goto error;
 
+    /* Create a hash table to keep track of node device's by name */
+    if (!(qemu_driver->nodeDevices = virHashCreate(100, NULL)))
+        goto error;
+
+    /* Set up a callback mechanism with the node device conf code to get
+     * called whenever a node device is added or removed. */
+    if (virNodeDeviceRegisterCallbackDriver(&qemuNodedevCallbackDriver) < 0)
+        goto error;
+
     if (qemuMigrationErrorInit(qemu_driver) < 0)
         goto error;
 
-- 
2.7.4




More information about the libvir-list mailing list