Allow the possibility of opening a connection to only the nodedev
driver, by defining nodedev:///system and nodedev:///session URIs
and registering a fake hypervisor driver that supports them.
The hypervisor drivers can now directly open a nodedev driver
connection at time of need, instead of having to pass around a
virConnectPtr through many functions. This will facilitate the later
change to support separate daemons for each driver.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/node_device/node_device_driver.c | 73 +++++++++++++++++++++++++++++++++++-
src/node_device/node_device_driver.h | 9 +++++
src/node_device/node_device_hal.c | 18 +++++++++
src/node_device/node_device_udev.c | 19 ++++++++++
4 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index 6216a69773..efbe898249 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -47,6 +47,78 @@
virNodeDeviceDriverStatePtr driver;
+virDrvOpenStatus nodeConnectOpen(virConnectPtr conn,
+ virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+ virConfPtr conf ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
+
+ /* Verify uri was specified */
+ if (conn->uri == NULL) {
+ /* Only hypervisor drivers are permitted to auto-open on NULL uri */
+ return VIR_DRV_OPEN_DECLINED;
+ } else {
+ if (STRNEQ_NULLABLE(conn->uri->scheme, "nodedev"))
+ return VIR_DRV_OPEN_DECLINED;
+
+ /* Leave for remote driver */
+ if (conn->uri->server != NULL)
+ return VIR_DRV_OPEN_DECLINED;
+
+ if (driver == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("nodedev state driver is not active"));
+ return VIR_DRV_OPEN_ERROR;
+ }
+
+ if (driver->privileged) {
+ if (STRNEQ(conn->uri->path, "/system")) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected nodedev URI path '%s', try
nodedev:///system"),
+ conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
+ } else {
+ if (STRNEQ(conn->uri->path, "/session")) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected nodedev URI path '%s', try
nodedev:///session"),
+ conn->uri->path);
+ return VIR_DRV_OPEN_ERROR;
+ }
+ }
+ }
+
+ if (virConnectOpenEnsureACL(conn) < 0)
+ return VIR_DRV_OPEN_ERROR;
+
+ return VIR_DRV_OPEN_SUCCESS;
+}
+
+int nodeConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+int nodeConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ /* Trivially secure, since always inside the daemon */
+ return 1;
+}
+
+
+int nodeConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ /* Not encrypted, but remote driver takes care of that */
+ return 0;
+}
+
+
+int nodeConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
static int
nodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
@@ -661,7 +733,6 @@ nodeConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
return ret;
}
-
int
nodedevRegister(void)
{
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 109c717815..83a9449139 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -51,6 +51,15 @@ extern virNodeDeviceDriverStatePtr driver;
int
nodedevRegister(void);
+virDrvOpenStatus nodeConnectOpen(virConnectPtr conn,
+ virConnectAuthPtr auth,
+ virConfPtr conf,
+ unsigned int flags);
+int nodeConnectClose(virConnectPtr conn);
+int nodeConnectIsSecure(virConnectPtr conn);
+int nodeConnectIsEncrypted(virConnectPtr conn);
+int nodeConnectIsAlive(virConnectPtr conn);
+
int
nodeNumOfDevices(virConnectPtr conn,
const char *cap,
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index c19e327c96..9cd5bb3eec 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -773,6 +773,22 @@ static virNodeDeviceDriver halNodeDeviceDriver = {
};
+static virHypervisorDriver halHypervisorDriver = {
+ .name = "nodedev",
+ .connectOpen = nodeConnectOpen, /* 4.1.0 */
+ .connectClose = nodeConnectClose, /* 4.1.0 */
+ .connectIsEncrypted = nodeConnectIsEncrypted, /* 4.1.0 */
+ .connectIsSecure = nodeConnectIsSecure, /* 4.1.0 */
+ .connectIsAlive = nodeConnectIsAlive, /* 4.1.0 */
+};
+
+
+static virConnectDriver halConnectDriver = {
+ .hypervisorDriver = &halHypervisorDriver,
+ .nodeDeviceDriver = &halNodeDeviceDriver,
+};
+
+
static virStateDriver halStateDriver = {
.name = "HAL",
.stateInitialize = nodeStateInitialize, /* 0.5.0 */
@@ -783,6 +799,8 @@ static virStateDriver halStateDriver = {
int
halNodeRegister(void)
{
+ if (virRegisterConnectDriver(&halConnectDriver, false) < 0)
+ return -1;
if (virSetSharedNodeDeviceDriver(&halNodeDeviceDriver) < 0)
return -1;
return virRegisterStateDriver(&halStateDriver);
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index e0fca6159e..f7645b6876 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2065,6 +2065,23 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
.nodeDeviceDestroy = nodeDeviceDestroy, /* 0.7.3 */
};
+
+static virHypervisorDriver udevHypervisorDriver = {
+ .name = "nodedev",
+ .connectOpen = nodeConnectOpen, /* 4.1.0 */
+ .connectClose = nodeConnectClose, /* 4.1.0 */
+ .connectIsEncrypted = nodeConnectIsEncrypted, /* 4.1.0 */
+ .connectIsSecure = nodeConnectIsSecure, /* 4.1.0 */
+ .connectIsAlive = nodeConnectIsAlive, /* 4.1.0 */
+};
+
+
+static virConnectDriver udevConnectDriver = {
+ .hypervisorDriver = &udevHypervisorDriver,
+ .nodeDeviceDriver = &udevNodeDeviceDriver,
+};
+
+
static virStateDriver udevStateDriver = {
.name = "udev",
.stateInitialize = nodeStateInitialize, /* 0.7.3 */
@@ -2078,6 +2095,8 @@ udevNodeRegister(void)
{
VIR_DEBUG("Registering udev node device backend");
+ if (virRegisterConnectDriver(&udevConnectDriver, false) < 0)
+ return -1;
if (virSetSharedNodeDeviceDriver(&udevNodeDeviceDriver) < 0)
return -1;
--
2.14.3