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(a)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