On 26.06.2014 15:51, Taowei wrote:
In vbox_common.c:
vboxInitialize and vboxDomainSave are rewrited with vboxUniformedAPI.
In vbox_common.h
Some common definitions in vbox_CAPI_v*.h are directly extracted to
this file. Some other incompatible defintions are simplified here. So we
can write common code with it.
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/vbox/vbox_common.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++
src/vbox/vbox_common.h | 151 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 303 insertions(+)
create mode 100644 src/vbox/vbox_common.c
create mode 100644 src/vbox/vbox_common.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 31a8381..8c1b712 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -213,6 +213,7 @@ src/util/virxml.c
src/vbox/vbox_MSCOMGlue.c
src/vbox/vbox_XPCOMCGlue.c
src/vbox/vbox_driver.c
+src/vbox/vbox_common.c
src/vbox/vbox_snapshot_conf.c
src/vbox/vbox_tmpl.c
src/vmware/vmware_conf.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c1e3f45..7a935e5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -674,6 +674,7 @@ VBOX_DRIVER_SOURCES = \
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_4.c vbox/vbox_CAPI_v4_3_4.h \
+ vbox/vbox_common.c vbox/vbox_common.h \
vbox/vbox_uniformed_api.h
VBOX_DRIVER_EXTRA_DIST = \
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
new file mode 100644
index 0000000..27211a0
--- /dev/null
+++ b/src/vbox/vbox_common.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2014, Taowei Luo (uaedante(a)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 "vbox_common.h"
+#include "vbox_uniformed_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 RC_SUCCEEDED(rc) NS_SUCCEEDED(rc.resultCode)
+#define RC_FAILED(rc) NS_FAILED(rc.resultCode)
+
+#define VBOX_RELEASE(arg) \
+ do { \
+ if (arg) { \
+ pVBoxAPI->nsisupportsRelease((void *)arg); \
+ (arg) = NULL; \
+ } \
+ } while (0)
+
+#define VBOX_OBJECT_CHECK(conn, type, value) \
+vboxGlobalData *data = conn->privateData;\
+type ret = value;\
+if (!data->vboxObj) {\
+ return ret;\
+}
+
+static vboxUniformedAPI *pVBoxAPI;
+
+void vboxRegisterUniformedAPI(vboxUniformedAPI *vboxAPI)
+{
+ VIR_DEBUG("VirtualBox Uniformed API has been registered");
+ pVBoxAPI = vboxAPI;
+}
+
+int vboxInitialize(vboxGlobalData *data)
+{
+ if (pVBoxAPI->pfnInitialize(data) != 0)
+ goto cleanup;
+
+ if (pVBoxAPI->fWatchNeedInitialize && pVBoxAPI->initializeFWatch(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;
+}
+
+int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED)
+{
+ VBOX_OBJECT_CHECK(dom->conn, int, -1);
+ IConsole *console = NULL;
+ vboxIIDUnion iid;
+ IMachine *machine = NULL;
+ nsresult rc;
+
+ pVBoxAPI->initializeVboxIID(&iid);
+ /* VirtualBox currently doesn't support saving to a file
+ * at a location other then the machine folder and thus
+ * setting path to ATTRIBUTE_UNUSED for now, will change
+ * this behaviour once get the VirtualBox API in right
+ * shape to do this
+ */
+
This down here ..
+ /* Open a Session for the machine */
+ pVBoxAPI->vboxIIDFromUUID(data, &iid, dom->uuid);
+ if (pVBoxAPI->getMachineForSession) {
+ /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
+ rc = pVBoxAPI->objectGetMachine(data, &iid, &machine);
+ if (NS_FAILED(rc)) {
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return -1;
+ }
+ }
.. I guess is going to be used fairly frequently, so maybe it can be
turned into a separate function.
+
+ rc = pVBoxAPI->sessionOpenExisting(data, &iid, machine);
+ if (NS_SUCCEEDED(rc)) {
+ rc = pVBoxAPI->sessionGetConsole(data->vboxSession, &console);
+ if (NS_SUCCEEDED(rc) && console) {
+ IProgress *progress = NULL;
+
+ pVBoxAPI->consoleSaveState(console, &progress);
+
+ if (progress) {
+ resultCodeUnion resultCode;
+
+ pVBoxAPI->progressWaitForCompletion(progress, -1);
+ pVBoxAPI->progressGetResultCode(progress, &resultCode);
+ if (RC_SUCCEEDED(resultCode)) {
+ ret = 0;
+ }
+ VBOX_RELEASE(progress);
+ }
+ VBOX_RELEASE(console);
+ }
+ pVBoxAPI->sessionClose(data->vboxSession);
+ }
I find this still distant to the rest of our code. I mean, we use this
pattern:
if (func() < 0)
goto cleanup;
rc = func2();
if (rc < 0)
goto cleanup;
So maybe we can use the same here:
rc = pVBoxAPI->sessionOpenExisting(data, &iid, machine);
if (NS_FAILED(rc) < 0)
goto cleanup;
rc = pVBoxAPI->sessionGetConsole(data->vboxSession, &console);
if (NS_FAILED(rc) < 0)
goto cleanup;
...
ret = 0;
cleanup:
VBOX_RELEASE(progress);
VBOX_RELEASE(console);
pVBoxAPI->sessionClose(data->vboxSession);
...
return ret;
+
+ pVBoxAPI->DEBUGIID("UUID of machine being saved:", &iid);
+
+ VBOX_RELEASE(machine);
+ pVBoxAPI->vboxIIDUnalloc(data, &iid);
+ return ret;
+}
diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h
new file mode 100644
index 0000000..bf0d106
--- /dev/null
+++ b/src/vbox/vbox_common.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2014, Taowei Luo (uaedante(a)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
Are these really necessary? I know we already have them, I'm just asking.
+
+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)))
Wow, I didn't know we are using likely and unlikely in libvirt.
+
+/**
+ * An "interface id" which can be used to uniquely identify a given
+ * interface.
+ * A "unique identifier". This is modeled after OSF DCE UUIDs.
+ */
+
+struct nsID {
+ PRUint32 m0;
+ PRUint16 m1;
+ PRUint16 m2;
+ PRUint8 m3[8];
+};
+
+typedef struct nsID nsID;
+typedef nsID nsIID;
+
+/* Simplied definitions in vbox_CAPI_*.h */
+
+typedef void const *PCVBOXXPCOM;
+typedef void IVirtualBox;
+typedef void ISession;
+typedef void IVirtualBoxCallback;
+typedef void nsIEventQueue;
+typedef void IConsole;
+typedef void IMachine;
+typedef void IProgress;
+
+#endif /* VBOX_COMMON_H */