]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Improve driver open URI handling
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 12 May 2009 15:35:18 +0000 (15:35 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 12 May 2009 15:35:18 +0000 (15:35 +0000)
ChangeLog
src/vbox/vbox_driver.c
src/vbox/vbox_tmpl.c

index 673f36e4c93b2e62550e59ae1e8b06a02241778b..d57c391c9f91cc1a28c2ef47ca10e89333e1bb9d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue May 12 16:35:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       Improve driver open URI handling
+       * src/vbox/vbox_driver.c: Register dummy no-op driver if
+       the virtualbox libraries are not avialable
+       * src/vbox/vbox_tmpl.c: Return fatal error if open fails
+       for a URI we expect to handle
+
 Tue May 12 17:25:52 CEST 2009 Daniel Veillard <veillard@redhat.com>
 
        * src/network_driver.c: enable bridges which are not up, i.e.
index 7db437c63dea8ff27d344b4a498f59e177087c11..76632e71a43191181cab7919eb560821a3e1e6ad 100644 (file)
@@ -34,6 +34,7 @@
 #include "logging.h"
 #include "vbox_driver.h"
 #include "vbox_XPCOMCGlue.h"
+#include "virterror_internal.h"
 
 #define VIR_FROM_THIS VIR_FROM_VBOX
 
@@ -43,15 +44,25 @@ extern virDriver vbox22Driver;
 extern virDriver vbox25Driver;
 #endif
 
+static virDriver vboxDriverDummy;
+
+#define VIR_FROM_THIS VIR_FROM_VBOX
+
+#define vboxError(conn, code, fmt...) \
+        virReportErrorHelper(conn, VIR_FROM_VBOX, code, __FILE__, \
+                            __FUNCTION__, __LINE__, fmt)
 
 int vboxRegister(void) {
     virDriverPtr        driver;
     uint32_t            uVersion;
 
-    /* vboxRegister() shouldn't fail as that will render libvirt unless.
-     * So, we use the v2.2 driver as a fallback/dummy.
+    /*
+     * If the glue layer does not initialize, we register a driver
+     * with a dummy open method, so we can report nicer errors
+     * if the user requests a vbox:// URI which we know will
+     * never work
      */
-    driver        = &vbox22Driver;
+    driver        = &vboxDriverDummy;
 
     /* Init the glue and get the API version. */
     if (VBoxCGlueInit() == 0) {
@@ -79,7 +90,7 @@ int vboxRegister(void) {
         }
 
     } else {
-        DEBUG0("VBoxCGlueInit failed");
+        DEBUG0("VBoxCGlueInit failed, using dummy driver");
     }
 
     if (virRegisterDriver(driver) < 0)
@@ -87,3 +98,46 @@ int vboxRegister(void) {
 
     return 0;
 }
+
+static virDrvOpenStatus vboxOpenDummy(virConnectPtr conn,
+                                      virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                      int flags ATTRIBUTE_UNUSED) {
+    uid_t uid = getuid();
+
+    if (conn->uri == NULL ||
+        conn->uri->scheme == NULL ||
+        STRNEQ (conn->uri->scheme, "vbox") ||
+        conn->uri->server != NULL)
+        return VIR_DRV_OPEN_DECLINED;
+
+    if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
+        vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                  _("no VirtualBox driver path specified (try vbox:///session)"));
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    if (uid != 0) {
+        if (STRNEQ (conn->uri->path, "/session")) {
+            vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+                      _("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
+            return VIR_DRV_OPEN_ERROR;
+        }
+    } else { /* root */
+        if (STRNEQ (conn->uri->path, "/system") &&
+            STRNEQ (conn->uri->path, "/session")) {
+            vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+                      _("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
+            return VIR_DRV_OPEN_ERROR;
+        }
+    }
+
+    vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+              _("unable to initialize VirtualBox driver API"));
+    return VIR_DRV_OPEN_ERROR;
+}
+
+static virDriver vboxDriverDummy = {
+    VIR_DRV_VBOX,
+    "VBOX",
+    .open = vboxOpenDummy,
+};
index a27eada67f847f197d35d1668f192da5387b3584..a4061ce70964d882bd0295949d2c3a2afd86454d 100644 (file)
@@ -216,16 +216,6 @@ no_memory:
 }
 
 static int vboxInitialize(virConnectPtr conn, vboxGlobalData *data) {
-
-    if (VBoxCGlueInit() != 0) {
-        vboxError(conn, VIR_ERR_INTERNAL_ERROR, "Can't Initialize VirtualBox, VBoxCGlueInit failed.");
-        goto cleanup;
-    }
-
-    /* This is for when glue init failed and we're serving as dummy driver. */
-    if (g_pfnGetFunctions == NULL)
-        goto cleanup;
-
     /* Get the API table for out version, g_pVBoxFuncs is for the oldest
        version of the API that we support so we cannot use that. */
     data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
@@ -291,13 +281,13 @@ static int vboxExtractVersion(virConnectPtr conn, vboxGlobalData *data) {
 }
 
 static void vboxUninitialize(vboxGlobalData *data) {
+    if (!data)
+        return;
+
     if (data->pFuncs)
         data->pFuncs->pfnComUninitialize();
     VBoxCGlueTerm();
 
-    if (!data)
-        return;
-
     virDomainObjListFree(&data->domains);
     virCapabilitiesFree(data->caps);
     VIR_FREE(data);
@@ -306,52 +296,62 @@ static void vboxUninitialize(vboxGlobalData *data) {
 static virDrvOpenStatus vboxOpen(virConnectPtr conn,
                                  virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                                  int flags ATTRIBUTE_UNUSED) {
-    vboxGlobalData *data;
+    vboxGlobalData *data = NULL;
     uid_t uid = getuid();
 
     if (conn->uri == NULL) {
         conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
         if (conn->uri == NULL) {
+            virReportOOMError(conn);
             return VIR_DRV_OPEN_ERROR;
         }
-    } else if (conn->uri->scheme == NULL ||
-               conn->uri->path == NULL ) {
-        return VIR_DRV_OPEN_DECLINED;
     }
 
-    if (STRNEQ (conn->uri->scheme, "vbox"))
+    if (conn->uri->scheme == NULL ||
+        STRNEQ (conn->uri->scheme, "vbox"))
+        return VIR_DRV_OPEN_DECLINED;
+
+    /* Leave for remote driver */
+    if (conn->uri->server != NULL)
         return VIR_DRV_OPEN_DECLINED;
 
+    if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
+        vboxError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                  _("no VirtualBox driver path specified (try vbox:///session)"));
+        return VIR_DRV_OPEN_ERROR;
+    }
+
     if (uid != 0) {
-        if (STRNEQ (conn->uri->path, "/session"))
-            return VIR_DRV_OPEN_DECLINED;
+        if (STRNEQ (conn->uri->path, "/session")) {
+            vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+                      _("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
+            return VIR_DRV_OPEN_ERROR;
+        }
     } else { /* root */
         if (STRNEQ (conn->uri->path, "/system") &&
-            STRNEQ (conn->uri->path, "/session"))
-            return VIR_DRV_OPEN_DECLINED;
+            STRNEQ (conn->uri->path, "/session")) {
+            vboxError(conn, VIR_ERR_INTERNAL_ERROR,
+                      _("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
+            return VIR_DRV_OPEN_ERROR;
+        }
     }
 
     if (VIR_ALLOC(data) < 0) {
         virReportOOMError(conn);
-        goto cleanup;
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    if (!(data->caps = vboxCapsInit()))
-        goto cleanup;
-
-    if (vboxInitialize(conn, data) < 0)
-        goto cleanup;
-
-    if (vboxExtractVersion(conn, data) < 0)
-        goto cleanup;
+    if (!(data->caps = vboxCapsInit()) ||
+        vboxInitialize(conn, data) < 0 ||
+        vboxExtractVersion(conn, data) < 0) {
+        vboxUninitialize(data);
+        return VIR_DRV_OPEN_ERROR;
+    }
 
     conn->privateData = data;
     DEBUG0("in vboxOpen");
 
     return VIR_DRV_OPEN_SUCCESS;
-cleanup:
-    vboxUninitialize(data);
-    return VIR_DRV_OPEN_DECLINED;
 }
 
 static int vboxClose(virConnectPtr conn) {