mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Improve driver open URI handling
This commit is contained in:
parent
e978774ec6
commit
1a60d6bcd6
@ -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>
|
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.
|
* src/network_driver.c: enable bridges which are not up, i.e.
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "vbox_driver.h"
|
#include "vbox_driver.h"
|
||||||
#include "vbox_XPCOMCGlue.h"
|
#include "vbox_XPCOMCGlue.h"
|
||||||
|
#include "virterror_internal.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_VBOX
|
#define VIR_FROM_THIS VIR_FROM_VBOX
|
||||||
|
|
||||||
@ -43,15 +44,25 @@ extern virDriver vbox22Driver;
|
|||||||
extern virDriver vbox25Driver;
|
extern virDriver vbox25Driver;
|
||||||
#endif
|
#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) {
|
int vboxRegister(void) {
|
||||||
virDriverPtr driver;
|
virDriverPtr driver;
|
||||||
uint32_t uVersion;
|
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. */
|
/* Init the glue and get the API version. */
|
||||||
if (VBoxCGlueInit() == 0) {
|
if (VBoxCGlueInit() == 0) {
|
||||||
@ -79,7 +90,7 @@ int vboxRegister(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG0("VBoxCGlueInit failed");
|
DEBUG0("VBoxCGlueInit failed, using dummy driver");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virRegisterDriver(driver) < 0)
|
if (virRegisterDriver(driver) < 0)
|
||||||
@ -87,3 +98,46 @@ int vboxRegister(void) {
|
|||||||
|
|
||||||
return 0;
|
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) {
|
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
|
/* 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. */
|
version of the API that we support so we cannot use that. */
|
||||||
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
|
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
|
||||||
@ -291,13 +281,13 @@ static int vboxExtractVersion(virConnectPtr conn, vboxGlobalData *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void vboxUninitialize(vboxGlobalData *data) {
|
static void vboxUninitialize(vboxGlobalData *data) {
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
if (data->pFuncs)
|
if (data->pFuncs)
|
||||||
data->pFuncs->pfnComUninitialize();
|
data->pFuncs->pfnComUninitialize();
|
||||||
VBoxCGlueTerm();
|
VBoxCGlueTerm();
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
virDomainObjListFree(&data->domains);
|
virDomainObjListFree(&data->domains);
|
||||||
virCapabilitiesFree(data->caps);
|
virCapabilitiesFree(data->caps);
|
||||||
VIR_FREE(data);
|
VIR_FREE(data);
|
||||||
@ -306,52 +296,62 @@ static void vboxUninitialize(vboxGlobalData *data) {
|
|||||||
static virDrvOpenStatus vboxOpen(virConnectPtr conn,
|
static virDrvOpenStatus vboxOpen(virConnectPtr conn,
|
||||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||||
int flags ATTRIBUTE_UNUSED) {
|
int flags ATTRIBUTE_UNUSED) {
|
||||||
vboxGlobalData *data;
|
vboxGlobalData *data = NULL;
|
||||||
uid_t uid = getuid();
|
uid_t uid = getuid();
|
||||||
|
|
||||||
if (conn->uri == NULL) {
|
if (conn->uri == NULL) {
|
||||||
conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
|
conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
|
||||||
if (conn->uri == NULL) {
|
if (conn->uri == NULL) {
|
||||||
|
virReportOOMError(conn);
|
||||||
return VIR_DRV_OPEN_ERROR;
|
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;
|
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 (uid != 0) {
|
||||||
if (STRNEQ (conn->uri->path, "/session"))
|
if (STRNEQ (conn->uri->path, "/session")) {
|
||||||
return VIR_DRV_OPEN_DECLINED;
|
vboxError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
|
||||||
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
}
|
||||||
} else { /* root */
|
} else { /* root */
|
||||||
if (STRNEQ (conn->uri->path, "/system") &&
|
if (STRNEQ (conn->uri->path, "/system") &&
|
||||||
STRNEQ (conn->uri->path, "/session"))
|
STRNEQ (conn->uri->path, "/session")) {
|
||||||
return VIR_DRV_OPEN_DECLINED;
|
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) {
|
if (VIR_ALLOC(data) < 0) {
|
||||||
virReportOOMError(conn);
|
virReportOOMError(conn);
|
||||||
goto cleanup;
|
return VIR_DRV_OPEN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(data->caps = vboxCapsInit()))
|
if (!(data->caps = vboxCapsInit()) ||
|
||||||
goto cleanup;
|
vboxInitialize(conn, data) < 0 ||
|
||||||
|
vboxExtractVersion(conn, data) < 0) {
|
||||||
if (vboxInitialize(conn, data) < 0)
|
vboxUninitialize(data);
|
||||||
goto cleanup;
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
}
|
||||||
if (vboxExtractVersion(conn, data) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
conn->privateData = data;
|
conn->privateData = data;
|
||||||
DEBUG0("in vboxOpen");
|
DEBUG0("in vboxOpen");
|
||||||
|
|
||||||
return VIR_DRV_OPEN_SUCCESS;
|
return VIR_DRV_OPEN_SUCCESS;
|
||||||
cleanup:
|
|
||||||
vboxUninitialize(data);
|
|
||||||
return VIR_DRV_OPEN_DECLINED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vboxClose(virConnectPtr conn) {
|
static int vboxClose(virConnectPtr conn) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user