[libvirt] [PATCH 2/2] VirtualBox support (Resending by fixing a autodetection Bug)
Daniel P. Berrange
berrange at redhat.com
Tue Apr 14 12:36:16 UTC 2009
On Thu, Apr 09, 2009 at 11:25:08AM +0200, Pritesh Kothari wrote:
> Hi All,
>
> Resending the second patch [PATCH 2/2] after fixing the Bug mentioned by
> Florian on the list.
>
> Regards,
> Pritesh
>
> On Wednesday 08 April 2009 14:20:29 Pritesh Kothari wrote:
> > Hi All,
> >
> > I have attached a patch which when applied on the HEAD as of today would
> > allow virtualbox support in libvirt. It takes cares of all the stuff
> > mentioned on the list earlier. Still if I have missed anything, please do
> > tell me.
> >
> > The patch works very well with the VirtualBox OSE version and the 2.2
> > release.
> >
> > [PATCH 1/2] contains diff of files already in libvirt.
> > [PATCH 2/2] contains new files needed for VirtualBox support.
> diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c
> new file mode 100644
> index 0000000..8e0a771
> --- /dev/null
> +++ b/src/vbox/vbox_XPCOMCGlue.c
> @@ -0,0 +1,215 @@
> +/** @file vbox_XPCOMCGlue.c
> + * Glue code for dynamically linking to VBoxXPCOMC.
> + */
> +
> +/*******************************************************************************
> +* Global Variables *
> +*******************************************************************************/
> +/** The dlopen handle for VBoxXPCOMC. */
> +void *g_hVBoxXPCOMC = NULL;
> +/** The last load error. */
> +char g_szVBoxErrMsg[256];
> +/** Pointer to the VBoxXPCOMC function table. */
> +PCVBOXXPCOM g_pVBoxFuncs = NULL;
> +/** Pointer to VBoxGetXPCOMCFunctions for the loaded VBoxXPCOMC so/dylib/dll. */
> +PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions = NULL;
> +/** boolean for checking if the VBOX_APP_HOME is already set by the users */
> +int g_bVAHSet = 0;
I don't much like the static fixed size error message buffer
here. It only appears to be used in one function:
> + * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all
> + * the symbols we need.
> + *
> + * @returns 0 on success, -1 on failure.
> + * @param pszHome The director where to try load VBoxXPCOMC from. Can be NULL.
> + */
> +static int tryLoadOne(const char *pszHome)
> +{
> + size_t cchHome = pszHome ? strlen(pszHome) : 0;
> + size_t cbReq;
> + char szBuf[4096];
> + int rc = -1;
> +
> + /*
> + * Construct the full name.
> + */
> + cbReq = cchHome + sizeof("/" DYNLIB_NAME);
> + if (cbReq > sizeof(szBuf))
> + {
> + sprintf(g_szVBoxErrMsg, "path buffer too small: %u bytes required", (unsigned)cbReq);
> + return -1;
> + }
> + memcpy(szBuf, pszHome, cchHome);
> + szBuf[cchHome] = '/';
> + cchHome++;
> + memcpy(&szBuf[cchHome], DYNLIB_NAME, sizeof(DYNLIB_NAME));
> +
> + /*
> + * Try load it by that name, setting the VBOX_APP_HOME first (for now).
> + * Then resolve and call the function table getter.
> + */
> + if (!g_bVAHSet)
> + {
> + /* Override it as we know that user didn't set it
> + * and that we only did it in previous iteration
> + */
> + setenv("VBOX_APP_HOME", pszHome, 1);
> + }
> + g_hVBoxXPCOMC = dlopen(szBuf, RTLD_NOW | RTLD_LOCAL);
> + if (g_hVBoxXPCOMC)
> + {
> + PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions;
> + pfnGetFunctions = (PFNVBOXGETXPCOMCFUNCTIONS)
> + dlsym(g_hVBoxXPCOMC, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME);
> + if (pfnGetFunctions)
> + {
> + g_pVBoxFuncs = pfnGetFunctions(VBOX_XPCOMC_VERSION);
> + if (g_pVBoxFuncs)
> + {
> + g_pfnGetFunctions = pfnGetFunctions;
> + rc = 0;
> + }
> + else
> + sprintf(g_szVBoxErrMsg, "%.80s: pfnGetFunctions(%#x) failed",
> + szBuf, VBOX_XPCOMC_VERSION);
> + }
> + else
> + sprintf(g_szVBoxErrMsg, "dlsym(%.80s/%.32s): %128s",
> + szBuf, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, dlerror());
> + if (rc != 0)
> + {
> + dlclose(g_hVBoxXPCOMC);
> + g_hVBoxXPCOMC = NULL;
> + }
> + }
> + else
> + sprintf(g_szVBoxErrMsg, "dlopen(%.80s): %128s", szBuf, dlerror());
> + return rc;
> +}
And the caller of this function just calls the formal libvirt error
reporting function via vboxError():
> +static int vboxInitialize(virConnectPtr conn, vboxGlobalData *data) {
> +
> + if (VBoxCGlueInit() != 0) {
> + vboxError(conn, VIR_ERR_INTERNAL_ERROR,"%s\n", g_szVBoxErrMsg);
> + goto cleanup;
> + }
> +
> + if (g_pVBoxFuncs == NULL) {
> + vboxError(conn, VIR_ERR_INTERNAL_ERROR,"%s\n", g_szVBoxErrMsg);
> + goto cleanup;
> + }
> +
> + g_pVBoxFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession);
> + if (data->vboxObj == NULL)
> + goto cleanup;
> + if (data->vboxSession == NULL)
> + goto cleanup;
> +
> + return 0;
> +
> +cleanup:
> + return -1;
> +}
So, I think it'd be better to get rid of g_szVBoxErrMsg, and just have
tryLoadOne() call vboxError() (or virRaiseErrorHelper) directly.
> +
> +static virDrvOpenStatus vboxOpen(virConnectPtr conn,
> + virConnectAuthPtr auth ATTRIBUTE_UNUSED,
> + int flags ATTRIBUTE_UNUSED) {
> + vboxGlobalData *data;
> + uid_t uid = getuid();
> +
> + if (errorval == -1)
> + return VIR_DRV_OPEN_DECLINED;
> +
> + if (conn->uri == NULL) {
> + conn->uri = xmlParseURI(uid ? "vbox:///session" : "vbox:///system");
> + if (conn->uri == NULL) {
> + vboxError(conn, VIR_ERR_NO_DOMAIN, NULL);
> + return VIR_DRV_OPEN_ERROR;
Minor bug here, the VIR_ERR_NO_DOMAIN error isn't the correct code for an
URI parsing error :-)
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
More information about the libvir-list
mailing list