mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
vbox: Begin to rewrite, vboxConnectOpen
Introduce vbox_uniformed_api to deal with version conflicts. Use vbox_install_api to register the currect vboxUniformedAPI with vbox version. vboxConnectOpen has been rewritten.
This commit is contained in:
parent
7809615056
commit
7f0f415b87
@ -217,6 +217,7 @@ src/util/virxml.c
|
|||||||
src/vbox/vbox_MSCOMGlue.c
|
src/vbox/vbox_MSCOMGlue.c
|
||||||
src/vbox/vbox_XPCOMCGlue.c
|
src/vbox/vbox_XPCOMCGlue.c
|
||||||
src/vbox/vbox_driver.c
|
src/vbox/vbox_driver.c
|
||||||
|
src/vbox/vbox_common.c
|
||||||
src/vbox/vbox_snapshot_conf.c
|
src/vbox/vbox_snapshot_conf.c
|
||||||
src/vbox/vbox_tmpl.c
|
src/vbox/vbox_tmpl.c
|
||||||
src/vmware/vmware_conf.c
|
src/vmware/vmware_conf.c
|
||||||
|
@ -675,7 +675,10 @@ VBOX_DRIVER_SOURCES = \
|
|||||||
vbox/vbox_V4_2.c vbox/vbox_CAPI_v4_2.h \
|
vbox/vbox_V4_2.c vbox/vbox_CAPI_v4_2.h \
|
||||||
vbox/vbox_V4_2_20.c vbox/vbox_CAPI_v4_2_20.h \
|
vbox/vbox_V4_2_20.c vbox/vbox_CAPI_v4_2_20.h \
|
||||||
vbox/vbox_V4_3.c vbox/vbox_CAPI_v4_3.h \
|
vbox/vbox_V4_3.c vbox/vbox_CAPI_v4_3.h \
|
||||||
vbox/vbox_V4_3_4.c vbox/vbox_CAPI_v4_3_4.h
|
vbox/vbox_V4_3_4.c vbox/vbox_CAPI_v4_3_4.h \
|
||||||
|
vbox/vbox_common.c vbox/vbox_common.h \
|
||||||
|
vbox/vbox_uniformed_api.h \
|
||||||
|
vbox/vbox_install_api.h
|
||||||
|
|
||||||
VBOX_DRIVER_EXTRA_DIST = \
|
VBOX_DRIVER_EXTRA_DIST = \
|
||||||
vbox/vbox_tmpl.c vbox/README \
|
vbox/vbox_tmpl.c vbox/README \
|
||||||
|
291
src/vbox/vbox_common.c
Normal file
291
src/vbox/vbox_common.c
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Taowei Luo (uaedante@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
#include "datatypes.h"
|
||||||
|
#include "domain_conf.h"
|
||||||
|
#include "domain_event.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
#include "viralloc.h"
|
||||||
|
#include "nodeinfo.h"
|
||||||
|
|
||||||
|
#include "vbox_common.h"
|
||||||
|
#include "vbox_uniformed_api.h"
|
||||||
|
#include "vbox_install_api.h"
|
||||||
|
|
||||||
|
/* Common codes for vbox driver. With the definitions in vbox_common.h,
|
||||||
|
* it treats vbox structs as a void*. Though vboxUniformedAPI
|
||||||
|
* it call vbox functions. This file is a high level implement about
|
||||||
|
* the vbox driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_VBOX
|
||||||
|
|
||||||
|
VIR_LOG_INIT("vbox.vbox_common");
|
||||||
|
|
||||||
|
#define VBOX_UTF16_FREE(arg) \
|
||||||
|
do { \
|
||||||
|
if (arg) { \
|
||||||
|
gVBoxAPI.UPFN.Utf16Free(data->pFuncs, arg); \
|
||||||
|
(arg) = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define VBOX_UTF8_FREE(arg) \
|
||||||
|
do { \
|
||||||
|
if (arg) { \
|
||||||
|
gVBoxAPI.UPFN.Utf8Free(data->pFuncs, arg); \
|
||||||
|
(arg) = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define VBOX_COM_UNALLOC_MEM(arg) \
|
||||||
|
do { \
|
||||||
|
if (arg) { \
|
||||||
|
gVBoxAPI.UPFN.ComUnallocMem(data->pFuncs, arg); \
|
||||||
|
(arg) = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define VBOX_UTF16_TO_UTF8(arg1, arg2) gVBoxAPI.UPFN.Utf16ToUtf8(data->pFuncs, arg1, arg2)
|
||||||
|
#define VBOX_UTF8_TO_UTF16(arg1, arg2) gVBoxAPI.UPFN.Utf8ToUtf16(data->pFuncs, arg1, arg2)
|
||||||
|
|
||||||
|
/* global vbox API, used for all common codes. */
|
||||||
|
static vboxUniformedAPI gVBoxAPI;
|
||||||
|
|
||||||
|
int vboxRegisterUniformedAPI(uint32_t uVersion)
|
||||||
|
{
|
||||||
|
/* Install gVBoxAPI according to the vbox API version.
|
||||||
|
* Return -1 for unsupported version.
|
||||||
|
*/
|
||||||
|
if (uVersion >= 2001052 && uVersion < 2002051) {
|
||||||
|
vbox22InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 2002051 && uVersion < 3000051) {
|
||||||
|
vbox30InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 3000051 && uVersion < 3001051) {
|
||||||
|
vbox31InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 3001051 && uVersion < 3002051) {
|
||||||
|
vbox32InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 3002051 && uVersion < 4000051) {
|
||||||
|
vbox40InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 4000051 && uVersion < 4001051) {
|
||||||
|
vbox41InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 4001051 && uVersion < 4002020) {
|
||||||
|
vbox42InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 4002020 && uVersion < 4002051) {
|
||||||
|
vbox42_20InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 4002051 && uVersion < 4003004) {
|
||||||
|
vbox43InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else if (uVersion >= 4003004 && uVersion < 4003051) {
|
||||||
|
vbox43_4InstallUniformedAPI(&gVBoxAPI);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virDomainDefParserConfig vboxDomainDefParserConfig = {
|
||||||
|
.macPrefix = { 0x08, 0x00, 0x27 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static virDomainXMLOptionPtr
|
||||||
|
vboxXMLConfInit(void)
|
||||||
|
{
|
||||||
|
return virDomainXMLOptionNew(&vboxDomainDefParserConfig,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxInitialize(vboxGlobalData *data)
|
||||||
|
{
|
||||||
|
if (gVBoxAPI.UPFN.Initialize(data) != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (gVBoxAPI.domainEventCallbacks && gVBoxAPI.initializeDomainEvent(data) != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (data->vboxObj == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("IVirtualBox object is null"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->vboxSession == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("ISession object is null"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virCapsPtr vboxCapsInit(void)
|
||||||
|
{
|
||||||
|
virCapsPtr caps;
|
||||||
|
virCapsGuestPtr guest;
|
||||||
|
|
||||||
|
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
||||||
|
false, false)) == NULL)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (nodeCapsInitNUMA(caps) < 0)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if ((guest = virCapabilitiesAddGuest(caps,
|
||||||
|
"hvm",
|
||||||
|
caps->host.arch,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL)) == NULL)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
if (virCapabilitiesAddGuestDomain(guest,
|
||||||
|
"vbox",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL) == NULL)
|
||||||
|
goto no_memory;
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
no_memory:
|
||||||
|
virObjectUnref(caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vboxExtractVersion(vboxGlobalData *data)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
PRUnichar *versionUtf16 = NULL;
|
||||||
|
char *vboxVersion = NULL;
|
||||||
|
nsresult rc;
|
||||||
|
|
||||||
|
if (data->version > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = gVBoxAPI.UIVirtualBox.GetVersion(data->vboxObj, &versionUtf16);
|
||||||
|
if (NS_FAILED(rc))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
|
||||||
|
|
||||||
|
if (virParseVersionString(vboxVersion, &data->version, false) >= 0)
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
VBOX_UTF8_FREE(vboxVersion);
|
||||||
|
VBOX_COM_UNALLOC_MEM(versionUtf16);
|
||||||
|
failed:
|
||||||
|
if (ret != 0)
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Could not extract VirtualBox version"));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vboxUninitialize(vboxGlobalData *data)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gVBoxAPI.UPFN.Uninitialize(data);
|
||||||
|
|
||||||
|
virObjectUnref(data->caps);
|
||||||
|
virObjectUnref(data->xmlopt);
|
||||||
|
if (gVBoxAPI.domainEventCallbacks)
|
||||||
|
virObjectEventStateFree(data->domainEvents);
|
||||||
|
VIR_FREE(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
||||||
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
vboxGlobalData *data = NULL;
|
||||||
|
uid_t uid = geteuid();
|
||||||
|
|
||||||
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
||||||
|
|
||||||
|
if (conn->uri == NULL &&
|
||||||
|
!(conn->uri = virURIParse(uid ? "vbox:///session" : "vbox:///system")))
|
||||||
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
|
||||||
|
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, "")) {
|
||||||
|
virReportError(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")) {
|
||||||
|
virReportError(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")) {
|
||||||
|
virReportError(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)
|
||||||
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
|
||||||
|
if (!(data->caps = vboxCapsInit()) ||
|
||||||
|
vboxInitialize(data) < 0 ||
|
||||||
|
vboxExtractVersion(data) < 0 ||
|
||||||
|
!(data->xmlopt = vboxXMLConfInit())) {
|
||||||
|
vboxUninitialize(data);
|
||||||
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVBoxAPI.domainEventCallbacks) {
|
||||||
|
if (!(data->domainEvents = virObjectEventStateNew())) {
|
||||||
|
vboxUninitialize(data);
|
||||||
|
return VIR_DRV_OPEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->conn = conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gVBoxAPI.hasStaticGlobalData)
|
||||||
|
gVBoxAPI.registerGlobalData(data);
|
||||||
|
|
||||||
|
conn->privateData = data;
|
||||||
|
VIR_DEBUG("in vboxOpen");
|
||||||
|
|
||||||
|
return VIR_DRV_OPEN_SUCCESS;
|
||||||
|
}
|
130
src/vbox/vbox_common.h
Normal file
130
src/vbox/vbox_common.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Taowei Luo (uaedante@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VBOX_COMMON_H
|
||||||
|
# define VBOX_COMMON_H
|
||||||
|
|
||||||
|
# ifdef ___VirtualBox_CXPCOM_h
|
||||||
|
# error this file should not be included after vbox_CAPI_v*.h
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
# include <stddef.h>
|
||||||
|
# include "wchar.h"
|
||||||
|
|
||||||
|
/* This file extracts some symbols defined in
|
||||||
|
* vbox_CAPI_v*.h. It tells the vbox_common.c
|
||||||
|
* how to treat with this symbols. This file
|
||||||
|
* can't be included with files such as
|
||||||
|
* vbox_CAPI_v*.h, or it would casue multiple
|
||||||
|
* definitions.
|
||||||
|
*
|
||||||
|
* You can see the more informations in vbox_api.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copied definitions from vbox_CAPI_*.h.
|
||||||
|
* We must MAKE SURE these codes are compatible. */
|
||||||
|
|
||||||
|
typedef unsigned char PRUint8;
|
||||||
|
# if (defined(HPUX) && defined(__cplusplus) \
|
||||||
|
&& !defined(__GNUC__) && __cplusplus < 199707L) \
|
||||||
|
|| (defined(SCO) && defined(__cplusplus) \
|
||||||
|
&& !defined(__GNUC__) && __cplusplus == 1L)
|
||||||
|
typedef char PRInt8;
|
||||||
|
# else
|
||||||
|
typedef signed char PRInt8;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define PR_INT8_MAX 127
|
||||||
|
# define PR_INT8_MIN (-128)
|
||||||
|
# define PR_UINT8_MAX 255U
|
||||||
|
|
||||||
|
typedef unsigned short PRUint16;
|
||||||
|
typedef short PRInt16;
|
||||||
|
|
||||||
|
# define PR_INT16_MAX 32767
|
||||||
|
# define PR_INT16_MIN (-32768)
|
||||||
|
# define PR_UINT16_MAX 65535U
|
||||||
|
|
||||||
|
typedef unsigned int PRUint32;
|
||||||
|
typedef int PRInt32;
|
||||||
|
# define PR_INT32(x) x
|
||||||
|
# define PR_UINT32(x) x ## U
|
||||||
|
|
||||||
|
# define PR_INT32_MAX PR_INT32(2147483647)
|
||||||
|
# define PR_INT32_MIN (-PR_INT32_MAX - 1)
|
||||||
|
# define PR_UINT32_MAX PR_UINT32(4294967295)
|
||||||
|
|
||||||
|
typedef long PRInt64;
|
||||||
|
typedef unsigned long PRUint64;
|
||||||
|
typedef int PRIntn;
|
||||||
|
typedef unsigned int PRUintn;
|
||||||
|
|
||||||
|
typedef double PRFloat64;
|
||||||
|
typedef size_t PRSize;
|
||||||
|
|
||||||
|
typedef ptrdiff_t PRPtrdiff;
|
||||||
|
|
||||||
|
typedef unsigned long PRUptrdiff;
|
||||||
|
|
||||||
|
typedef PRIntn PRBool;
|
||||||
|
|
||||||
|
# define PR_TRUE 1
|
||||||
|
# define PR_FALSE 0
|
||||||
|
|
||||||
|
typedef PRUint8 PRPackedBool;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Status code used by some routines that have a single point of failure or
|
||||||
|
** special status return.
|
||||||
|
*/
|
||||||
|
typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
|
||||||
|
|
||||||
|
# ifndef __PRUNICHAR__
|
||||||
|
# define __PRUNICHAR__
|
||||||
|
# if defined(WIN32) || defined(XP_MAC)
|
||||||
|
typedef wchar_t PRUnichar;
|
||||||
|
# else
|
||||||
|
typedef PRUint16 PRUnichar;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
typedef long PRWord;
|
||||||
|
typedef unsigned long PRUword;
|
||||||
|
|
||||||
|
# define nsnull 0
|
||||||
|
typedef PRUint32 nsresult;
|
||||||
|
|
||||||
|
# if defined(__GNUC__) && (__GNUC__ > 2)
|
||||||
|
# define NS_LIKELY(x) (__builtin_expect((x), 1))
|
||||||
|
# define NS_UNLIKELY(x) (__builtin_expect((x), 0))
|
||||||
|
# else
|
||||||
|
# define NS_LIKELY(x) (x)
|
||||||
|
# define NS_UNLIKELY(x) (x)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000))
|
||||||
|
# define NS_SUCCEEDED(_nsresult) (NS_LIKELY(!((_nsresult) & 0x80000000)))
|
||||||
|
|
||||||
|
/* Simplied definitions in vbox_CAPI_*.h */
|
||||||
|
|
||||||
|
typedef void const *PCVBOXXPCOM;
|
||||||
|
typedef void IVirtualBox;
|
||||||
|
typedef void ISession;
|
||||||
|
|
||||||
|
#endif /* VBOX_COMMON_H */
|
@ -39,6 +39,10 @@
|
|||||||
#include "vbox_glue.h"
|
#include "vbox_glue.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
|
#include "domain_event.h"
|
||||||
|
#include "domain_conf.h"
|
||||||
|
|
||||||
|
#include "vbox_install_api.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_VBOX
|
#define VIR_FROM_THIS VIR_FROM_VBOX
|
||||||
|
|
||||||
@ -161,6 +165,8 @@ int vboxRegister(void)
|
|||||||
} else {
|
} else {
|
||||||
VIR_DEBUG("Unsupported VirtualBox API version: %u", uVersion);
|
VIR_DEBUG("Unsupported VirtualBox API version: %u", uVersion);
|
||||||
}
|
}
|
||||||
|
/* Register vboxUniformedAPI. */
|
||||||
|
vboxRegisterUniformedAPI(uVersion);
|
||||||
} else {
|
} else {
|
||||||
VIR_DEBUG("VBoxCGlueInit failed, using dummy driver");
|
VIR_DEBUG("VBoxCGlueInit failed, using dummy driver");
|
||||||
}
|
}
|
||||||
@ -175,9 +181,9 @@ int vboxRegister(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
static virDrvOpenStatus dummyConnectOpen(virConnectPtr conn,
|
||||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
uid_t uid = geteuid();
|
uid_t uid = geteuid();
|
||||||
|
|
||||||
@ -218,5 +224,5 @@ static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
|||||||
static virDriver vboxDriverDummy = {
|
static virDriver vboxDriverDummy = {
|
||||||
VIR_DRV_VBOX,
|
VIR_DRV_VBOX,
|
||||||
"VBOX",
|
"VBOX",
|
||||||
.connectOpen = vboxConnectOpen,
|
.connectOpen = dummyConnectOpen,
|
||||||
};
|
};
|
||||||
|
26
src/vbox/vbox_install_api.h
Normal file
26
src/vbox/vbox_install_api.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Taowei Luo (uaedante@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VBOX_INSTALL_API_H
|
||||||
|
# define VBOX_INSTALL_API_H
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
|
||||||
|
int vboxRegisterUniformedAPI(uint32_t uVersion);
|
||||||
|
|
||||||
|
#endif /* VBOX_INSTALL_API_H */
|
@ -89,12 +89,15 @@
|
|||||||
|
|
||||||
/* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */
|
/* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */
|
||||||
#include "vbox_glue.h"
|
#include "vbox_glue.h"
|
||||||
|
#include "vbox_uniformed_api.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_VBOX
|
#define VIR_FROM_THIS VIR_FROM_VBOX
|
||||||
|
|
||||||
VIR_LOG_INIT("vbox.vbox_tmpl");
|
VIR_LOG_INIT("vbox.vbox_tmpl");
|
||||||
|
|
||||||
|
#define vboxUnsupported() \
|
||||||
|
VIR_WARN("No %s in current vbox version %d.", __FUNCTION__, VBOX_API_VERSION);
|
||||||
|
|
||||||
#define VBOX_UTF16_FREE(arg) \
|
#define VBOX_UTF16_FREE(arg) \
|
||||||
do { \
|
do { \
|
||||||
if (arg) { \
|
if (arg) { \
|
||||||
@ -203,41 +206,7 @@ if (strUtf16) {\
|
|||||||
(unsigned)(iid)->m3[7]);\
|
(unsigned)(iid)->m3[7]);\
|
||||||
}\
|
}\
|
||||||
|
|
||||||
typedef struct {
|
#if VBOX_API_VERSION > 2002000
|
||||||
virMutex lock;
|
|
||||||
unsigned long version;
|
|
||||||
|
|
||||||
virCapsPtr caps;
|
|
||||||
virDomainXMLOptionPtr xmlopt;
|
|
||||||
|
|
||||||
IVirtualBox *vboxObj;
|
|
||||||
ISession *vboxSession;
|
|
||||||
|
|
||||||
/** Our version specific API table pointer. */
|
|
||||||
PCVBOXXPCOM pFuncs;
|
|
||||||
|
|
||||||
#if VBOX_API_VERSION == 2002000
|
|
||||||
|
|
||||||
} vboxGlobalData;
|
|
||||||
|
|
||||||
#else /* !(VBOX_API_VERSION == 2002000) */
|
|
||||||
|
|
||||||
/* Async event handling */
|
|
||||||
virObjectEventStatePtr domainEvents;
|
|
||||||
int fdWatch;
|
|
||||||
|
|
||||||
# if VBOX_API_VERSION <= 3002000
|
|
||||||
/* IVirtualBoxCallback is used in VirtualBox 3.x only */
|
|
||||||
IVirtualBoxCallback *vboxCallback;
|
|
||||||
# endif /* VBOX_API_VERSION <= 3002000 */
|
|
||||||
|
|
||||||
nsIEventQueue *vboxQueue;
|
|
||||||
int volatile vboxCallBackRefCount;
|
|
||||||
|
|
||||||
/* pointer back to the connection */
|
|
||||||
virConnectPtr conn;
|
|
||||||
|
|
||||||
} vboxGlobalData;
|
|
||||||
|
|
||||||
/* g_pVBoxGlobalData has to be global variable,
|
/* g_pVBoxGlobalData has to be global variable,
|
||||||
* there is no other way to make the callbacks
|
* there is no other way to make the callbacks
|
||||||
@ -865,137 +834,6 @@ vboxSocketParseAddrUtf16(vboxGlobalData *data, const PRUnichar *utf16,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static virDomainDefParserConfig vboxDomainDefParserConfig = {
|
|
||||||
.macPrefix = { 0x08, 0x00, 0x27 },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static virDomainXMLOptionPtr
|
|
||||||
vboxXMLConfInit(void)
|
|
||||||
{
|
|
||||||
return virDomainXMLOptionNew(&vboxDomainDefParserConfig,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static virCapsPtr vboxCapsInit(void)
|
|
||||||
{
|
|
||||||
virCapsPtr caps;
|
|
||||||
virCapsGuestPtr guest;
|
|
||||||
|
|
||||||
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
|
||||||
false, false)) == NULL)
|
|
||||||
goto no_memory;
|
|
||||||
|
|
||||||
if (nodeCapsInitNUMA(caps) < 0)
|
|
||||||
goto no_memory;
|
|
||||||
|
|
||||||
if ((guest = virCapabilitiesAddGuest(caps,
|
|
||||||
"hvm",
|
|
||||||
caps->host.arch,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL)) == NULL)
|
|
||||||
goto no_memory;
|
|
||||||
|
|
||||||
if (virCapabilitiesAddGuestDomain(guest,
|
|
||||||
"vbox",
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL) == NULL)
|
|
||||||
goto no_memory;
|
|
||||||
|
|
||||||
return caps;
|
|
||||||
|
|
||||||
no_memory:
|
|
||||||
virObjectUnref(caps);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
vboxInitialize(vboxGlobalData *data)
|
|
||||||
{
|
|
||||||
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
|
|
||||||
|
|
||||||
if (data->pFuncs == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
#if VBOX_XPCOMC_VERSION == 0x00010000U
|
|
||||||
data->pFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession);
|
|
||||||
#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
|
||||||
data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
|
|
||||||
ISESSION_IID_STR, &data->vboxSession);
|
|
||||||
|
|
||||||
# if VBOX_API_VERSION == 2002000
|
|
||||||
|
|
||||||
/* No event queue functionality in 2.2.* as of now */
|
|
||||||
|
|
||||||
# else /* !(VBOX_API_VERSION == 2002000) */
|
|
||||||
|
|
||||||
/* Initial the fWatch needed for Event Callbacks */
|
|
||||||
data->fdWatch = -1;
|
|
||||||
|
|
||||||
data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
|
|
||||||
|
|
||||||
if (data->vboxQueue == NULL) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("nsIEventQueue object is null"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
# endif /* !(VBOX_API_VERSION == 2002000) */
|
|
||||||
#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
|
||||||
|
|
||||||
if (data->vboxObj == NULL) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("IVirtualBox object is null"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->vboxSession == NULL) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("ISession object is null"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vboxExtractVersion(vboxGlobalData *data)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
PRUnichar *versionUtf16 = NULL;
|
|
||||||
nsresult rc;
|
|
||||||
|
|
||||||
if (data->version > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
rc = data->vboxObj->vtbl->GetVersion(data->vboxObj, &versionUtf16);
|
|
||||||
if (NS_SUCCEEDED(rc)) {
|
|
||||||
char *vboxVersion = NULL;
|
|
||||||
|
|
||||||
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
|
|
||||||
|
|
||||||
if (virParseVersionString(vboxVersion, &data->version, false) >= 0)
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
VBOX_UTF8_FREE(vboxVersion);
|
|
||||||
VBOX_COM_UNALLOC_MEM(versionUtf16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != 0)
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Could not extract VirtualBox version"));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vboxUninitialize(vboxGlobalData *data)
|
static void vboxUninitialize(vboxGlobalData *data)
|
||||||
{
|
{
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -1014,82 +852,6 @@ static void vboxUninitialize(vboxGlobalData *data)
|
|||||||
VIR_FREE(data);
|
VIR_FREE(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
|
||||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
||||||
unsigned int flags)
|
|
||||||
{
|
|
||||||
vboxGlobalData *data = NULL;
|
|
||||||
uid_t uid = geteuid();
|
|
||||||
|
|
||||||
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
||||||
|
|
||||||
if (conn->uri == NULL &&
|
|
||||||
!(conn->uri = virURIParse(uid ? "vbox:///session" : "vbox:///system")))
|
|
||||||
return VIR_DRV_OPEN_ERROR;
|
|
||||||
|
|
||||||
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, "")) {
|
|
||||||
virReportError(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")) {
|
|
||||||
virReportError(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")) {
|
|
||||||
virReportError(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)
|
|
||||||
return VIR_DRV_OPEN_ERROR;
|
|
||||||
|
|
||||||
if (!(data->caps = vboxCapsInit()) ||
|
|
||||||
vboxInitialize(data) < 0 ||
|
|
||||||
vboxExtractVersion(data) < 0 ||
|
|
||||||
!(data->xmlopt = vboxXMLConfInit())) {
|
|
||||||
vboxUninitialize(data);
|
|
||||||
return VIR_DRV_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if VBOX_API_VERSION == 2002000
|
|
||||||
|
|
||||||
/* No domainEventCallbacks in 2.2.* version */
|
|
||||||
|
|
||||||
#else /* !(VBOX_API_VERSION == 2002000) */
|
|
||||||
|
|
||||||
if (!(data->domainEvents = virObjectEventStateNew())) {
|
|
||||||
vboxUninitialize(data);
|
|
||||||
return VIR_DRV_OPEN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->conn = conn;
|
|
||||||
g_pVBoxGlobalData = data;
|
|
||||||
|
|
||||||
#endif /* !(VBOX_API_VERSION == 2002000) */
|
|
||||||
|
|
||||||
conn->privateData = data;
|
|
||||||
VIR_DEBUG("in vboxOpen");
|
|
||||||
|
|
||||||
return VIR_DRV_OPEN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vboxConnectClose(virConnectPtr conn)
|
static int vboxConnectClose(virConnectPtr conn)
|
||||||
{
|
{
|
||||||
vboxGlobalData *data = conn->privateData;
|
vboxGlobalData *data = conn->privateData;
|
||||||
@ -11497,6 +11259,121 @@ vboxNodeGetFreePages(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
return nodeGetFreePages(npages, pages, startCell, cellCount, counts);
|
return nodeGetFreePages(npages, pages, startCell, cellCount, counts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _pfnInitialize(vboxGlobalData *data)
|
||||||
|
{
|
||||||
|
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
|
||||||
|
if (data->pFuncs == NULL)
|
||||||
|
return -1;
|
||||||
|
#if VBOX_XPCOMC_VERSION == 0x00010000U
|
||||||
|
data->pFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession);
|
||||||
|
#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
||||||
|
data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj, ISESSION_IID_STR, &data->vboxSession);
|
||||||
|
#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_initializeDomainEvent(vboxGlobalData *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
|
||||||
|
/* No event queue functionality in 2.2.* and 4.* as of now */
|
||||||
|
vboxUnsupported();
|
||||||
|
#else /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
|
||||||
|
/* Initialize the fWatch needed for Event Callbacks */
|
||||||
|
data->fdWatch = -1;
|
||||||
|
data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
|
||||||
|
if (data->vboxQueue == NULL) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("nsIEventQueue object is null"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void _registerGlobalData(vboxGlobalData *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
#if VBOX_API_VERSION == 2002000
|
||||||
|
vboxUnsupported();
|
||||||
|
#else /* VBOX_API_VERSION != 2002000 */
|
||||||
|
g_pVBoxGlobalData = data;
|
||||||
|
#endif /* VBOX_API_VERSION != 2002000 */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pfnUninitialize(vboxGlobalData *data)
|
||||||
|
{
|
||||||
|
if (data->pFuncs)
|
||||||
|
data->pFuncs->pfnComUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pfnComUnallocMem(PCVBOXXPCOM pFuncs, void *pv)
|
||||||
|
{
|
||||||
|
pFuncs->pfnComUnallocMem(pv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pfnUtf16Free(PCVBOXXPCOM pFuncs, PRUnichar *pwszString)
|
||||||
|
{
|
||||||
|
pFuncs->pfnUtf16Free(pwszString);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pfnUtf8Free(PCVBOXXPCOM pFuncs, char *pszString)
|
||||||
|
{
|
||||||
|
pFuncs->pfnUtf8Free(pszString);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _pfnUtf16ToUtf8(PCVBOXXPCOM pFuncs, const PRUnichar *pwszString, char **ppszString)
|
||||||
|
{
|
||||||
|
return pFuncs->pfnUtf16ToUtf8(pwszString, ppszString);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar **ppwszString)
|
||||||
|
{
|
||||||
|
return pFuncs->pfnUtf8ToUtf16(pszString, ppwszString);
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
_virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16)
|
||||||
|
{
|
||||||
|
return vboxObj->vtbl->GetVersion(vboxObj, versionUtf16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static vboxUniformedPFN _UPFN = {
|
||||||
|
.Initialize = _pfnInitialize,
|
||||||
|
.Uninitialize = _pfnUninitialize,
|
||||||
|
.ComUnallocMem = _pfnComUnallocMem,
|
||||||
|
.Utf16Free = _pfnUtf16Free,
|
||||||
|
.Utf8Free = _pfnUtf8Free,
|
||||||
|
.Utf16ToUtf8 = _pfnUtf16ToUtf8,
|
||||||
|
.Utf8ToUtf16 = _pfnUtf8ToUtf16,
|
||||||
|
};
|
||||||
|
|
||||||
|
static vboxUniformedIVirtualBox _UIVirtualBox = {
|
||||||
|
.GetVersion = _virtualboxGetVersion,
|
||||||
|
};
|
||||||
|
|
||||||
|
void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
|
||||||
|
{
|
||||||
|
pVBoxAPI->APIVersion = VBOX_API_VERSION;
|
||||||
|
pVBoxAPI->XPCOMCVersion = VBOX_XPCOMC_VERSION;
|
||||||
|
pVBoxAPI->initializeDomainEvent = _initializeDomainEvent;
|
||||||
|
pVBoxAPI->registerGlobalData = _registerGlobalData;
|
||||||
|
pVBoxAPI->UPFN = _UPFN;
|
||||||
|
pVBoxAPI->UIVirtualBox = _UIVirtualBox;
|
||||||
|
|
||||||
|
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
|
||||||
|
pVBoxAPI->domainEventCallbacks = 0;
|
||||||
|
#else /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
|
||||||
|
pVBoxAPI->domainEventCallbacks = 1;
|
||||||
|
#endif /* VBOX_API_VERSION > 2002000 || VBOX_API_VERSION < 4000000 */
|
||||||
|
|
||||||
|
#if VBOX_API_VERSION == 2002000
|
||||||
|
pVBoxAPI->hasStaticGlobalData = 0;
|
||||||
|
#else /* VBOX_API_VERSION > 2002000 */
|
||||||
|
pVBoxAPI->hasStaticGlobalData = 1;
|
||||||
|
#endif /* VBOX_API_VERSION > 2002000 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Tables
|
* Function Tables
|
||||||
|
153
src/vbox/vbox_uniformed_api.h
Normal file
153
src/vbox/vbox_uniformed_api.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Taowei Luo (uaedante@gmail.com)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VBOX_UNIFORMED_API_H
|
||||||
|
# define VBOX_UNIFORMED_API_H
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
|
||||||
|
/* This file may be used in three place. That is vbox_tmpl.c,
|
||||||
|
* vbox_common.c and vbox_driver.c. The vboxUniformedAPI and some
|
||||||
|
* types used for vboxUniformedAPI is defined here.
|
||||||
|
*
|
||||||
|
* The vbox_tmpl.c is the only place where the driver knows the inside
|
||||||
|
* architecture of those vbox structs(vboxObj, vboxSession,
|
||||||
|
* pFuncs, vboxCallback and vboxQueue). The file should be included
|
||||||
|
* after the currect vbox_CAPI_v*.h, then we can use the vbox structs
|
||||||
|
* in vboxGlobalData. The vbox_tmpl.c should implement functions
|
||||||
|
* defined in vboxUniformedAPI.
|
||||||
|
*
|
||||||
|
* In vbox_driver.c, it is used to define the struct vboxUniformedAPI.
|
||||||
|
* The vbox_driver.c collects vboxUniformedAPI for all versions.
|
||||||
|
* Then vboxRegister calls the vboxRegisterUniformedAPI to register.
|
||||||
|
* Note: In vbox_driver.c, the vbox structs in vboxGlobalData is
|
||||||
|
* defined by vbox_CAPI_v2.2.h.
|
||||||
|
*
|
||||||
|
* The vbox_common.c, it is used to generate common codes for all vbox
|
||||||
|
* versions. Bacause the same member varible's offset in a vbox struct
|
||||||
|
* may change between different vbox versions. The vbox_common.c
|
||||||
|
* shouldn't directly use struct's member varibles defined in
|
||||||
|
* vbox_CAPI_v*.h. To make things safety, we include the
|
||||||
|
* vbox_common.h in vbox_common.c. In this case, we treat structs
|
||||||
|
* defined by vbox as a void*. The common codes don't concern about
|
||||||
|
* the inside of this structs(actually, we can't, in the common level).
|
||||||
|
* With the help of vboxUniformed API, we call VirtualBox's API and
|
||||||
|
* implement the vbox driver in a high level.
|
||||||
|
*
|
||||||
|
* In conclusion:
|
||||||
|
* * In vbox_tmpl.c, this file is included after vbox_CAPI_v*.h
|
||||||
|
* * In vbox_driver.c, this file is included after vbox_glue.h
|
||||||
|
* * In vbox_common.c, this file is included after vbox_common.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
virMutex lock;
|
||||||
|
unsigned long version;
|
||||||
|
|
||||||
|
virCapsPtr caps;
|
||||||
|
virDomainXMLOptionPtr xmlopt;
|
||||||
|
|
||||||
|
IVirtualBox *vboxObj;
|
||||||
|
ISession *vboxSession;
|
||||||
|
|
||||||
|
/** Our version specific API table pointer. */
|
||||||
|
PCVBOXXPCOM pFuncs;
|
||||||
|
|
||||||
|
/* The next is used for domainEvent */
|
||||||
|
# if defined(VBOX_API_VERSION) && VBOX_API_VERSION > 2002000 && VBOX_API_VERSION < 4000000
|
||||||
|
|
||||||
|
/* Async event handling */
|
||||||
|
virObjectEventStatePtr domainEvents;
|
||||||
|
int fdWatch;
|
||||||
|
IVirtualBoxCallback *vboxCallback;
|
||||||
|
nsIEventQueue *vboxQueue;
|
||||||
|
|
||||||
|
int volatile vboxCallBackRefCount;
|
||||||
|
|
||||||
|
/* pointer back to the connection */
|
||||||
|
virConnectPtr conn;
|
||||||
|
|
||||||
|
# else /* VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000 || VBOX_API_VERSION undefined */
|
||||||
|
|
||||||
|
virObjectEventStatePtr domainEvents;
|
||||||
|
int fdWatch;
|
||||||
|
void *vboxCallback;
|
||||||
|
void *vboxQueue;
|
||||||
|
int volatile vboxCallBackRefCount;
|
||||||
|
virConnectPtr conn;
|
||||||
|
|
||||||
|
# endif /* VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000 || VBOX_API_VERSION undefined */
|
||||||
|
|
||||||
|
} vboxGlobalData;
|
||||||
|
|
||||||
|
/* vboxUniformedAPI gives vbox_common.c a uniformed layer to see
|
||||||
|
* vbox API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Functions for pFuncs */
|
||||||
|
typedef struct {
|
||||||
|
int (*Initialize)(vboxGlobalData *data);
|
||||||
|
void (*Uninitialize)(vboxGlobalData *data);
|
||||||
|
void (*ComUnallocMem)(PCVBOXXPCOM pFuncs, void *pv);
|
||||||
|
void (*Utf16Free)(PCVBOXXPCOM pFuncs, PRUnichar *pwszString);
|
||||||
|
void (*Utf8Free)(PCVBOXXPCOM pFuncs, char *pszString);
|
||||||
|
int (*Utf16ToUtf8)(PCVBOXXPCOM pFuncs, const PRUnichar *pwszString, char **ppszString);
|
||||||
|
int (*Utf8ToUtf16)(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar **ppwszString);
|
||||||
|
} vboxUniformedPFN;
|
||||||
|
|
||||||
|
/* Functions for IVirtualBox */
|
||||||
|
typedef struct {
|
||||||
|
nsresult (*GetVersion)(IVirtualBox *vboxObj, PRUnichar **versionUtf16);
|
||||||
|
} vboxUniformedIVirtualBox;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* vbox API version */
|
||||||
|
uint32_t APIVersion;
|
||||||
|
uint32_t XPCOMCVersion;
|
||||||
|
/* vbox APIs */
|
||||||
|
int (*initializeDomainEvent)(vboxGlobalData *data);
|
||||||
|
void (*registerGlobalData)(vboxGlobalData *data);
|
||||||
|
vboxUniformedPFN UPFN;
|
||||||
|
vboxUniformedIVirtualBox UIVirtualBox;
|
||||||
|
/* vbox API features */
|
||||||
|
bool domainEventCallbacks;
|
||||||
|
bool hasStaticGlobalData;
|
||||||
|
} vboxUniformedAPI;
|
||||||
|
|
||||||
|
/* libvirt API
|
||||||
|
* These API would be removed after we generate the
|
||||||
|
* vboxDriver in common code.
|
||||||
|
*/
|
||||||
|
virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
||||||
|
virConnectAuthPtr auth,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
/* Version specified functions for installing uniformed API */
|
||||||
|
void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox30InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox31InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox32InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox40InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox41InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox42InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox42_20InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox43InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
void vbox43_4InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
|
||||||
|
|
||||||
|
#endif /* VBOX_UNIFORMED_API_H */
|
Loading…
x
Reference in New Issue
Block a user