提交 1a60d6bc 编写于 作者: D Daniel P. Berrange

Improve driver open URI handling

上级 e978774e
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.
......
......@@ -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,
};
......@@ -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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册