2009-04-17 16:09:07 +00:00
|
|
|
/** @file vbox_tmpl.c
|
|
|
|
* Template File to support multiple versions of VirtualBox
|
|
|
|
* at runtime :).
|
|
|
|
*
|
|
|
|
* IMPORTANT:
|
|
|
|
* Please dont include this file in the src/Makefile.am, it
|
|
|
|
* is automatically include by other files.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
* Copyright (C) 2010-2014 Red Hat, Inc.
|
2009-04-17 16:09:07 +00:00
|
|
|
* Copyright (C) 2008-2009 Sun Microsystems, Inc.
|
|
|
|
*
|
|
|
|
* This file is part of a free software library; you can redistribute
|
|
|
|
* it and/or modify it under the terms of the GNU Lesser General
|
|
|
|
* Public License version 2.1 as published by the Free Software
|
2013-05-15 20:30:23 +00:00
|
|
|
* Foundation and shipped in the "COPYING.LESSER" file with this library.
|
2009-04-17 16:09:07 +00:00
|
|
|
* The library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY of any kind.
|
|
|
|
*
|
|
|
|
* Sun LGPL Disclaimer: For the avoidance of doubt, except that if
|
|
|
|
* any license choice other than GPL or LGPL is available it will
|
|
|
|
* apply instead, Sun elects to use only the Lesser General Public
|
|
|
|
* License version 2.1 (LGPLv2) at this time for any software where
|
|
|
|
* a choice of LGPL license versions is made available with the
|
|
|
|
* language indicating that LGPLv2 or any later version may be used,
|
|
|
|
* or where a choice of which version of the LGPL is applied is
|
|
|
|
* otherwise unspecified.
|
|
|
|
*
|
|
|
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
|
|
|
* Clara, CA 95054 USA or visit http://www.sun.com if you need
|
|
|
|
* additional information or have any questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2010-12-14 22:07:57 +00:00
|
|
|
#include <unistd.h>
|
2011-04-01 13:34:23 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include "datatypes.h"
|
|
|
|
#include "domain_conf.h"
|
2012-08-14 00:09:12 +00:00
|
|
|
#include "snapshot_conf.h"
|
2009-05-06 13:51:19 +00:00
|
|
|
#include "network_conf.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2009-07-24 16:12:16 +00:00
|
|
|
#include "domain_event.h"
|
2009-09-04 14:28:52 +00:00
|
|
|
#include "storage_conf.h"
|
2012-12-13 15:25:48 +00:00
|
|
|
#include "virstoragefile.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2009-04-17 16:09:07 +00:00
|
|
|
#include "nodeinfo.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2009-04-17 16:09:07 +00:00
|
|
|
#include "vbox_driver.h"
|
2011-04-01 13:34:23 +00:00
|
|
|
#include "configmake.h"
|
2011-07-19 18:32:58 +00:00
|
|
|
#include "virfile.h"
|
2011-04-01 13:34:23 +00:00
|
|
|
#include "fdstream.h"
|
2012-02-24 18:48:55 +00:00
|
|
|
#include "viruri.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
/* This one changes from version to version. */
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-04-17 16:09:07 +00:00
|
|
|
# include "vbox_CAPI_v2_2.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 3000000
|
2009-07-24 16:12:16 +00:00
|
|
|
# include "vbox_CAPI_v3_0.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
# include "vbox_CAPI_v3_1.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 3002000
|
2010-05-26 11:54:16 +00:00
|
|
|
# include "vbox_CAPI_v3_2.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
# include "vbox_CAPI_v4_0.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
# include "vbox_CAPI_v4_1.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 4002000
|
2012-10-02 09:00:54 +00:00
|
|
|
# include "vbox_CAPI_v4_2.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 4002020
|
|
|
|
# include "vbox_CAPI_v4_2_20.h"
|
|
|
|
#elif VBOX_API_VERSION == 4003000
|
2013-11-21 14:41:07 +00:00
|
|
|
# include "vbox_CAPI_v4_3.h"
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 4003004
|
|
|
|
# include "vbox_CAPI_v4_3_4.h"
|
2009-07-24 16:12:16 +00:00
|
|
|
#else
|
|
|
|
# error "Unsupport VBOX_API_VERSION"
|
2009-04-17 16:09:07 +00:00
|
|
|
#endif
|
|
|
|
|
2009-05-06 13:51:19 +00:00
|
|
|
/* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */
|
2010-12-14 22:07:57 +00:00
|
|
|
#include "vbox_glue.h"
|
2009-05-06 13:51:19 +00:00
|
|
|
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_VBOX
|
2013-01-24 00:34:48 +00:00
|
|
|
#define VBOX_UTF16_FREE(arg) \
|
|
|
|
do { \
|
|
|
|
if (arg) { \
|
|
|
|
data->pFuncs->pfnUtf16Free(arg); \
|
|
|
|
(arg) = NULL; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define VBOX_UTF8_FREE(arg) \
|
|
|
|
do { \
|
|
|
|
if (arg) { \
|
|
|
|
data->pFuncs->pfnUtf8Free(arg); \
|
|
|
|
(arg) = NULL; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define VBOX_COM_UNALLOC_MEM(arg) \
|
|
|
|
do { \
|
|
|
|
if (arg) { \
|
|
|
|
data->pFuncs->pfnComUnallocMem(arg); \
|
|
|
|
(arg) = NULL; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
#define VBOX_UTF16_TO_UTF8(arg1, arg2) data->pFuncs->pfnUtf16ToUtf8(arg1, arg2)
|
|
|
|
#define VBOX_UTF8_TO_UTF16(arg1, arg2) data->pFuncs->pfnUtf8ToUtf16(arg1, arg2)
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
#define VBOX_ADDREF(arg) (arg)->vtbl->nsisupports.AddRef((nsISupports *)(arg))
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
#define VBOX_RELEASE(arg) \
|
|
|
|
do { \
|
|
|
|
if (arg) { \
|
|
|
|
(arg)->vtbl->nsisupports.Release((nsISupports *)(arg)); \
|
|
|
|
(arg) = NULL; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
#define VBOX_OBJECT_CHECK(conn, type, value) \
|
|
|
|
vboxGlobalData *data = conn->privateData;\
|
|
|
|
type ret = value;\
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!data->vboxObj) {\
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;\
|
|
|
|
}
|
|
|
|
|
|
|
|
#define VBOX_OBJECT_HOST_CHECK(conn, type, value) \
|
|
|
|
vboxGlobalData *data = conn->privateData;\
|
|
|
|
type ret = value;\
|
|
|
|
IHost *host = NULL;\
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!data->vboxObj) {\
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;\
|
|
|
|
}\
|
|
|
|
data->vboxObj->vtbl->GetHost(data->vboxObj, &host);\
|
|
|
|
if (!host) {\
|
|
|
|
return ret;\
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-03-09 18:22:22 +00:00
|
|
|
# define VBOX_MEDIUM_RELEASE(arg) \
|
2012-10-17 09:23:12 +00:00
|
|
|
if (arg)\
|
2009-12-04 13:49:45 +00:00
|
|
|
(arg)->vtbl->imedium.nsisupports.Release((nsISupports *)(arg))
|
2010-03-09 18:22:22 +00:00
|
|
|
# define VBOX_MEDIUM_FUNC_ARG1(object, func, arg1) \
|
2009-12-04 13:49:45 +00:00
|
|
|
(object)->vtbl->imedium.func((IMedium *)(object), arg1)
|
2010-03-09 18:22:22 +00:00
|
|
|
# define VBOX_MEDIUM_FUNC_ARG2(object, func, arg1, arg2) \
|
2009-12-04 13:49:45 +00:00
|
|
|
(object)->vtbl->imedium.func((IMedium *)(object), arg1, arg2)
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
typedef IMedium IHardDisk;
|
|
|
|
typedef IMediumAttachment IHardDiskAttachment;
|
2010-03-09 18:22:22 +00:00
|
|
|
# define MediaState_Inaccessible MediumState_Inaccessible
|
|
|
|
# define HardDiskVariant_Standard MediumVariant_Standard
|
|
|
|
# define HardDiskVariant_Fixed MediumVariant_Fixed
|
|
|
|
# define VBOX_MEDIUM_RELEASE(arg) VBOX_RELEASE(arg)
|
|
|
|
# define VBOX_MEDIUM_FUNC_ARG1(object, func, arg1) \
|
2009-12-04 13:49:45 +00:00
|
|
|
(object)->vtbl->func(object, arg1)
|
2010-03-09 18:22:22 +00:00
|
|
|
# define VBOX_MEDIUM_FUNC_ARG2(object, func, arg1, arg2) \
|
2009-12-04 13:49:45 +00:00
|
|
|
(object)->vtbl->func(object, arg1, arg2)
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-07-24 16:12:16 +00:00
|
|
|
#define DEBUGPRUnichar(msg, strUtf16) \
|
|
|
|
if (strUtf16) {\
|
|
|
|
char *strUtf8 = NULL;\
|
|
|
|
\
|
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(strUtf16, &strUtf8);\
|
|
|
|
if (strUtf8) {\
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("%s: %s", msg, strUtf8);\
|
2009-07-24 16:12:16 +00:00
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf8Free(strUtf8);\
|
|
|
|
}\
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DEBUGUUID(msg, iid) \
|
|
|
|
{\
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_DEBUG(msg ": {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",\
|
2009-07-24 16:12:16 +00:00
|
|
|
(unsigned)(iid)->m0,\
|
|
|
|
(unsigned)(iid)->m1,\
|
|
|
|
(unsigned)(iid)->m2,\
|
|
|
|
(unsigned)(iid)->m3[0],\
|
|
|
|
(unsigned)(iid)->m3[1],\
|
|
|
|
(unsigned)(iid)->m3[2],\
|
|
|
|
(unsigned)(iid)->m3[3],\
|
|
|
|
(unsigned)(iid)->m3[4],\
|
|
|
|
(unsigned)(iid)->m3[5],\
|
|
|
|
(unsigned)(iid)->m3[6],\
|
|
|
|
(unsigned)(iid)->m3[7]);\
|
|
|
|
}\
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
typedef struct {
|
|
|
|
virMutex lock;
|
2010-03-30 14:15:13 +00:00
|
|
|
unsigned long version;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
virCapsPtr caps;
|
2013-03-31 18:03:42 +00:00
|
|
|
virDomainXMLOptionPtr xmlopt;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
IVirtualBox *vboxObj;
|
|
|
|
ISession *vboxSession;
|
2009-05-06 13:51:19 +00:00
|
|
|
|
|
|
|
/** Our version specific API table pointer. */
|
|
|
|
PCVBOXXPCOM pFuncs;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
} vboxGlobalData;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
/* Async event handling */
|
2013-11-21 10:43:10 +00:00
|
|
|
virObjectEventStatePtr domainEvents;
|
2009-07-24 16:12:16 +00:00
|
|
|
int fdWatch;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION <= 3002000
|
2010-12-27 22:35:30 +00:00
|
|
|
/* IVirtualBoxCallback is used in VirtualBox 3.x only */
|
2009-07-24 16:12:16 +00:00
|
|
|
IVirtualBoxCallback *vboxCallback;
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION <= 3002000 */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
nsIEventQueue *vboxQueue;
|
|
|
|
int volatile vboxCallBackRefCount;
|
|
|
|
|
|
|
|
/* pointer back to the connection */
|
|
|
|
virConnectPtr conn;
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
} vboxGlobalData;
|
|
|
|
|
2009-07-24 16:12:16 +00:00
|
|
|
/* g_pVBoxGlobalData has to be global variable,
|
|
|
|
* there is no other way to make the callbacks
|
|
|
|
* work other then having g_pVBoxGlobalData as
|
|
|
|
* global, because the functions namely AddRef,
|
|
|
|
* Release, etc consider it as global and you
|
|
|
|
* can't change the function definition as it
|
|
|
|
* is XPCOM nsISupport::* function and it expects
|
|
|
|
* them that way
|
|
|
|
*/
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
static vboxGlobalData *g_pVBoxGlobalData = NULL;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* !(VBOX_API_VERSION == 2002000) */
|
2009-05-06 13:51:19 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
|
|
|
|
# define VBOX_OBJECT_GET_MACHINE(/* in */ iid_value, /* out */ machine) \
|
|
|
|
data->vboxObj->vtbl->GetMachine(data->vboxObj, iid_value, machine)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_OPEN(/* in */ iid_value, /* unused */ machine) \
|
|
|
|
data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid_value)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_OPEN_EXISTING(/* in */ iid_value, /* unused */ machine) \
|
|
|
|
data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid_value)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_CLOSE() \
|
|
|
|
data->vboxSession->vtbl->Close(data->vboxSession)
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
|
|
|
|
# define VBOX_OBJECT_GET_MACHINE(/* in */ iid_value, /* out */ machine) \
|
|
|
|
data->vboxObj->vtbl->FindMachine(data->vboxObj, iid_value, machine)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_OPEN(/* unused */ iid_value, /* in */ machine) \
|
|
|
|
machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Write)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_OPEN_EXISTING(/* unused */ iid_value, /* in */ machine) \
|
|
|
|
machine->vtbl->LockMachine(machine, data->vboxSession, LockType_Shared)
|
|
|
|
|
|
|
|
# define VBOX_SESSION_CLOSE() \
|
|
|
|
data->vboxSession->vtbl->UnlockMachine(data->vboxSession)
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml);
|
|
|
|
static int vboxDomainCreate(virDomainPtr dom);
|
2011-08-11 21:44:05 +00:00
|
|
|
static int vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-07-24 16:12:16 +00:00
|
|
|
static void vboxDriverLock(vboxGlobalData *data) {
|
|
|
|
virMutexLock(&data->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vboxDriverUnlock(vboxGlobalData *data) {
|
|
|
|
virMutexUnlock(&data->lock);
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-05-06 13:51:19 +00:00
|
|
|
static void nsIDtoChar(unsigned char *uuid, const nsID *iid) {
|
2009-04-17 16:09:07 +00:00
|
|
|
char uuidstrsrc[VIR_UUID_STRING_BUFLEN];
|
|
|
|
char uuidstrdst[VIR_UUID_STRING_BUFLEN];
|
|
|
|
unsigned char uuidinterim[VIR_UUID_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
memcpy(uuidinterim, iid, VIR_UUID_BUFLEN);
|
|
|
|
virUUIDFormat(uuidinterim, uuidstrsrc);
|
|
|
|
|
|
|
|
uuidstrdst[0] = uuidstrsrc[6];
|
|
|
|
uuidstrdst[1] = uuidstrsrc[7];
|
|
|
|
uuidstrdst[2] = uuidstrsrc[4];
|
|
|
|
uuidstrdst[3] = uuidstrsrc[5];
|
|
|
|
uuidstrdst[4] = uuidstrsrc[2];
|
|
|
|
uuidstrdst[5] = uuidstrsrc[3];
|
|
|
|
uuidstrdst[6] = uuidstrsrc[0];
|
|
|
|
uuidstrdst[7] = uuidstrsrc[1];
|
|
|
|
|
|
|
|
uuidstrdst[8] = uuidstrsrc[8];
|
|
|
|
|
|
|
|
uuidstrdst[9] = uuidstrsrc[11];
|
|
|
|
uuidstrdst[10] = uuidstrsrc[12];
|
|
|
|
uuidstrdst[11] = uuidstrsrc[9];
|
|
|
|
uuidstrdst[12] = uuidstrsrc[10];
|
|
|
|
|
|
|
|
uuidstrdst[13] = uuidstrsrc[13];
|
|
|
|
|
|
|
|
uuidstrdst[14] = uuidstrsrc[16];
|
|
|
|
uuidstrdst[15] = uuidstrsrc[17];
|
|
|
|
uuidstrdst[16] = uuidstrsrc[14];
|
|
|
|
uuidstrdst[17] = uuidstrsrc[15];
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
for (i = 18; i < VIR_UUID_STRING_BUFLEN; i++) {
|
2009-04-17 16:09:07 +00:00
|
|
|
uuidstrdst[i] = uuidstrsrc[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
uuidstrdst[VIR_UUID_STRING_BUFLEN-1] = '\0';
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(uuidstrdst, uuid));
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-05-06 13:51:19 +00:00
|
|
|
static void nsIDFromChar(nsID *iid, const unsigned char *uuid) {
|
2009-04-17 16:09:07 +00:00
|
|
|
char uuidstrsrc[VIR_UUID_STRING_BUFLEN];
|
|
|
|
char uuidstrdst[VIR_UUID_STRING_BUFLEN];
|
|
|
|
unsigned char uuidinterim[VIR_UUID_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
virUUIDFormat(uuid, uuidstrsrc);
|
|
|
|
|
|
|
|
uuidstrdst[0] = uuidstrsrc[6];
|
|
|
|
uuidstrdst[1] = uuidstrsrc[7];
|
|
|
|
uuidstrdst[2] = uuidstrsrc[4];
|
|
|
|
uuidstrdst[3] = uuidstrsrc[5];
|
|
|
|
uuidstrdst[4] = uuidstrsrc[2];
|
|
|
|
uuidstrdst[5] = uuidstrsrc[3];
|
|
|
|
uuidstrdst[6] = uuidstrsrc[0];
|
|
|
|
uuidstrdst[7] = uuidstrsrc[1];
|
|
|
|
|
|
|
|
uuidstrdst[8] = uuidstrsrc[8];
|
|
|
|
|
|
|
|
uuidstrdst[9] = uuidstrsrc[11];
|
|
|
|
uuidstrdst[10] = uuidstrsrc[12];
|
|
|
|
uuidstrdst[11] = uuidstrsrc[9];
|
|
|
|
uuidstrdst[12] = uuidstrsrc[10];
|
|
|
|
|
|
|
|
uuidstrdst[13] = uuidstrsrc[13];
|
|
|
|
|
|
|
|
uuidstrdst[14] = uuidstrsrc[16];
|
|
|
|
uuidstrdst[15] = uuidstrsrc[17];
|
|
|
|
uuidstrdst[16] = uuidstrsrc[14];
|
|
|
|
uuidstrdst[17] = uuidstrsrc[15];
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
for (i = 18; i < VIR_UUID_STRING_BUFLEN; i++) {
|
2009-04-17 16:09:07 +00:00
|
|
|
uuidstrdst[i] = uuidstrsrc[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
uuidstrdst[VIR_UUID_STRING_BUFLEN-1] = '\0';
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(uuidstrdst, uuidinterim));
|
2009-04-17 16:09:07 +00:00
|
|
|
memcpy(iid, uuidinterim, VIR_UUID_BUFLEN);
|
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
# ifdef WIN32
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
typedef struct _vboxIID_v2_x_WIN32 vboxIID;
|
|
|
|
typedef struct _vboxIID_v2_x_WIN32 vboxIID_v2_x_WIN32;
|
|
|
|
|
|
|
|
struct _vboxIID_v2_x_WIN32 {
|
|
|
|
/* IID is represented by a GUID value. */
|
|
|
|
GUID value;
|
|
|
|
};
|
|
|
|
|
|
|
|
# define VBOX_IID_INITIALIZER { { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
|
|
|
|
vboxIID_v2_x_WIN32 *iid ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
/* Nothing to free */
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDToUUID_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid, unsigned char *uuid)
|
|
|
|
{
|
|
|
|
nsIDtoChar(uuid, (nsID *)&iid->value);
|
|
|
|
}
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
|
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
|
|
|
vboxIIDUnalloc_v2_x_WIN32(data, iid);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
nsIDFromChar((nsID *)&iid->value, uuid);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static bool
|
|
|
|
vboxIIDIsEqual_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid1, vboxIID_v2_x_WIN32 *iid2)
|
|
|
|
{
|
2012-03-29 09:52:04 +00:00
|
|
|
return memcmp(&iid1->value, &iid2->value, sizeof(GUID)) == 0;
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
|
|
|
|
vboxArray *array, int idx)
|
|
|
|
{
|
|
|
|
GUID *items = (GUID *)array->items;
|
|
|
|
|
|
|
|
vboxIIDUnalloc_v2_x_WIN32(data, iid);
|
|
|
|
|
2012-03-29 09:52:04 +00:00
|
|
|
memcpy(&iid->value, &items[idx], sizeof(GUID));
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x_WIN32(data, iid)
|
|
|
|
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x_WIN32(iid, uuid)
|
|
|
|
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x_WIN32(data, iid, uuid)
|
|
|
|
# define vboxIIDIsEqual(iid1, iid2) vboxIIDIsEqual_v2_x_WIN32(iid1, iid2)
|
|
|
|
# define vboxIIDFromArrayItem(iid, array, idx) \
|
|
|
|
vboxIIDFromArrayItem_v2_x_WIN32(data, iid, array, idx)
|
|
|
|
# define DEBUGIID(msg, iid) DEBUGUUID(msg, (nsID *)&(iid))
|
|
|
|
|
|
|
|
# else /* !WIN32 */
|
|
|
|
|
|
|
|
typedef struct _vboxIID_v2_x vboxIID;
|
|
|
|
typedef struct _vboxIID_v2_x vboxIID_v2_x;
|
|
|
|
|
|
|
|
struct _vboxIID_v2_x {
|
|
|
|
/* IID is represented by a pointer to a nsID. */
|
|
|
|
nsID *value;
|
|
|
|
|
|
|
|
/* backing is used in cases where we need to create or copy an IID.
|
|
|
|
* We cannot allocate memory that can be freed by ComUnallocMem.
|
|
|
|
* Therefore, we use this stack allocated nsID instead. */
|
|
|
|
nsID backing;
|
|
|
|
};
|
|
|
|
|
|
|
|
# define VBOX_IID_INITIALIZER { NULL, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
|
|
|
|
{
|
|
|
|
if (iid->value == NULL) {
|
2009-09-04 14:28:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (iid->value != &iid->backing) {
|
|
|
|
data->pFuncs->pfnComUnallocMem(iid->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
iid->value = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDToUUID_v2_x(vboxIID_v2_x *iid, unsigned char *uuid)
|
|
|
|
{
|
|
|
|
nsIDtoChar(uuid, iid->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
|
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
|
|
|
vboxIIDUnalloc_v2_x(data, iid);
|
|
|
|
|
|
|
|
iid->value = &iid->backing;
|
|
|
|
|
2013-01-24 00:34:47 +00:00
|
|
|
sa_assert(iid->value);
|
2010-12-23 16:25:56 +00:00
|
|
|
nsIDFromChar(iid->value, uuid);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static bool
|
|
|
|
vboxIIDIsEqual_v2_x(vboxIID_v2_x *iid1, vboxIID_v2_x *iid2)
|
|
|
|
{
|
2012-03-29 09:52:04 +00:00
|
|
|
return memcmp(iid1->value, iid2->value, sizeof(nsID)) == 0;
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
|
|
|
|
vboxArray *array, int idx)
|
|
|
|
{
|
|
|
|
vboxIIDUnalloc_v2_x(data, iid);
|
|
|
|
|
|
|
|
iid->value = &iid->backing;
|
|
|
|
|
2012-03-29 09:52:04 +00:00
|
|
|
memcpy(iid->value, array->items[idx], sizeof(nsID));
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x(data, iid)
|
|
|
|
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x(iid, uuid)
|
|
|
|
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x(data, iid, uuid)
|
|
|
|
# define vboxIIDIsEqual(iid1, iid2) vboxIIDIsEqual_v2_x(iid1, iid2)
|
|
|
|
# define vboxIIDFromArrayItem(iid, array, idx) \
|
|
|
|
vboxIIDFromArrayItem_v2_x(data, iid, array, idx)
|
|
|
|
# define DEBUGIID(msg, iid) DEBUGUUID(msg, iid)
|
|
|
|
|
|
|
|
# endif /* !WIN32 */
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION != 2002000 */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
typedef struct _vboxIID_v3_x vboxIID;
|
|
|
|
typedef struct _vboxIID_v3_x vboxIID_v3_x;
|
|
|
|
|
|
|
|
struct _vboxIID_v3_x {
|
|
|
|
/* IID is represented by a UTF-16 encoded UUID in string form. */
|
|
|
|
PRUnichar *value;
|
|
|
|
|
|
|
|
/* owner indicates if we own the value and need to free it. */
|
|
|
|
bool owner;
|
|
|
|
};
|
|
|
|
|
|
|
|
# define VBOX_IID_INITIALIZER { NULL, true }
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
|
|
|
|
{
|
|
|
|
if (iid->value != NULL && iid->owner) {
|
|
|
|
data->pFuncs->pfnUtf16Free(iid->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
iid->value = NULL;
|
|
|
|
iid->owner = true;
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
|
|
|
|
unsigned char *uuid)
|
|
|
|
{
|
|
|
|
char *utf8 = NULL;
|
|
|
|
|
|
|
|
data->pFuncs->pfnUtf16ToUtf8(iid->value, &utf8);
|
|
|
|
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(utf8, uuid));
|
2010-12-23 16:25:56 +00:00
|
|
|
|
|
|
|
data->pFuncs->pfnUtf8Free(utf8);
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
|
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
|
|
|
char utf8[VIR_UUID_STRING_BUFLEN];
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc_v3_x(data, iid);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
virUUIDFormat(uuid, utf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
data->pFuncs->pfnUtf8ToUtf16(utf8, &iid->value);
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static bool
|
|
|
|
vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
|
|
|
|
vboxIID_v3_x *iid2)
|
|
|
|
{
|
|
|
|
unsigned char uuid1[VIR_UUID_BUFLEN];
|
|
|
|
unsigned char uuid2[VIR_UUID_BUFLEN];
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
/* Note: we can't directly compare the utf8 strings here
|
2011-10-10 20:02:06 +00:00
|
|
|
* cause the two UUID's may have separators as space or '-'
|
2009-09-04 14:28:52 +00:00
|
|
|
* or mixture of both and we don't want to fail here by
|
|
|
|
* using direct string comparison. Here virUUIDParse() takes
|
2010-12-23 16:25:56 +00:00
|
|
|
* care of these cases. */
|
|
|
|
vboxIIDToUUID_v3_x(data, iid1, uuid1);
|
|
|
|
vboxIIDToUUID_v3_x(data, iid2, uuid2);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
return memcmp(uuid1, uuid2, VIR_UUID_BUFLEN) == 0;
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static void
|
|
|
|
vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
|
|
|
|
vboxArray *array, int idx)
|
|
|
|
{
|
|
|
|
vboxIIDUnalloc_v3_x(data, iid);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
iid->value = array->items[idx];
|
|
|
|
iid->owner = false;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
|
|
|
|
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v3_x(data, iid)
|
|
|
|
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v3_x(data, iid, uuid)
|
|
|
|
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v3_x(data, iid, uuid)
|
|
|
|
# define vboxIIDIsEqual(iid1, iid2) vboxIIDIsEqual_v3_x(data, iid1, iid2)
|
|
|
|
# define vboxIIDFromArrayItem(iid, array, idx) \
|
|
|
|
vboxIIDFromArrayItem_v3_x(data, iid, array, idx)
|
|
|
|
# define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION >= 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* function to generate the name for medium,
|
|
|
|
* for e.g: hda, sda, etc
|
|
|
|
*
|
|
|
|
* @returns null terminated string with device name or NULL
|
|
|
|
* for failures
|
|
|
|
* @param conn Input Connection Pointer
|
|
|
|
* @param storageBus Input storage bus type
|
|
|
|
* @param deviceInst Input device instance number
|
|
|
|
* @param devicePort Input port number
|
|
|
|
* @param deviceSlot Input slot number
|
|
|
|
* @param aMaxPortPerInst Input array of max port per device instance
|
|
|
|
* @param aMaxSlotPerPort Input array of max slot per device port
|
|
|
|
*
|
|
|
|
*/
|
2009-12-04 14:18:45 +00:00
|
|
|
static char *vboxGenerateMediumName(PRUint32 storageBus,
|
2009-12-04 13:49:45 +00:00
|
|
|
PRInt32 deviceInst,
|
|
|
|
PRInt32 devicePort,
|
|
|
|
PRInt32 deviceSlot,
|
|
|
|
PRUint32 *aMaxPortPerInst,
|
|
|
|
PRUint32 *aMaxSlotPerPort) {
|
2009-12-04 14:18:45 +00:00
|
|
|
const char *prefix = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
char *name = NULL;
|
|
|
|
int total = 0;
|
|
|
|
PRUint32 maxPortPerInst = 0;
|
|
|
|
PRUint32 maxSlotPerPort = 0;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!aMaxPortPerInst ||
|
|
|
|
!aMaxSlotPerPort)
|
2009-12-04 13:49:45 +00:00
|
|
|
return NULL;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((storageBus < StorageBus_IDE) ||
|
|
|
|
(storageBus > StorageBus_Floppy))
|
2009-12-04 13:49:45 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
maxPortPerInst = aMaxPortPerInst[storageBus];
|
|
|
|
maxSlotPerPort = aMaxSlotPerPort[storageBus];
|
|
|
|
total = (deviceInst * maxPortPerInst * maxSlotPerPort)
|
|
|
|
+ (devicePort * maxSlotPerPort)
|
|
|
|
+ deviceSlot;
|
|
|
|
|
|
|
|
if (storageBus == StorageBus_IDE) {
|
2009-12-04 14:18:45 +00:00
|
|
|
prefix = "hd";
|
2012-10-17 09:23:12 +00:00
|
|
|
} else if ((storageBus == StorageBus_SATA) ||
|
|
|
|
(storageBus == StorageBus_SCSI)) {
|
2009-12-04 14:18:45 +00:00
|
|
|
prefix = "sd";
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (storageBus == StorageBus_Floppy) {
|
2009-12-04 14:18:45 +00:00
|
|
|
prefix = "fd";
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 14:18:45 +00:00
|
|
|
name = virIndexToDiskName(total, prefix);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("name=%s, total=%d, storageBus=%u, deviceInst=%d, "
|
2009-12-04 13:49:45 +00:00
|
|
|
"devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u",
|
2009-12-04 14:18:45 +00:00
|
|
|
NULLSTR(name), total, storageBus, deviceInst, devicePort,
|
2009-12-04 13:49:45 +00:00
|
|
|
deviceSlot, maxPortPerInst, maxSlotPerPort);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* function to get the StorageBus, Port number
|
|
|
|
* and Device number for the given devicename
|
|
|
|
* e.g: hda has StorageBus = IDE, port = 0,
|
|
|
|
* device = 0
|
|
|
|
*
|
|
|
|
* @returns true on Success, false on failure.
|
|
|
|
* @param deviceName Input device name
|
|
|
|
* @param aMaxPortPerInst Input array of max port per device instance
|
|
|
|
* @param aMaxSlotPerPort Input array of max slot per device port
|
|
|
|
* @param storageBus Input storage bus type
|
|
|
|
* @param deviceInst Output device instance number
|
|
|
|
* @param devicePort Output port number
|
|
|
|
* @param deviceSlot Output slot number
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static bool vboxGetDeviceDetails(const char *deviceName,
|
|
|
|
PRUint32 *aMaxPortPerInst,
|
|
|
|
PRUint32 *aMaxSlotPerPort,
|
|
|
|
PRUint32 storageBus,
|
|
|
|
PRInt32 *deviceInst,
|
|
|
|
PRInt32 *devicePort,
|
|
|
|
PRInt32 *deviceSlot) {
|
|
|
|
int total = 0;
|
|
|
|
PRUint32 maxPortPerInst = 0;
|
|
|
|
PRUint32 maxSlotPerPort = 0;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!deviceName ||
|
|
|
|
!deviceInst ||
|
|
|
|
!devicePort ||
|
|
|
|
!deviceSlot ||
|
|
|
|
!aMaxPortPerInst ||
|
|
|
|
!aMaxSlotPerPort)
|
2009-12-04 13:49:45 +00:00
|
|
|
return false;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((storageBus < StorageBus_IDE) ||
|
|
|
|
(storageBus > StorageBus_Floppy))
|
2009-12-04 13:49:45 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
total = virDiskNameToIndex(deviceName);
|
|
|
|
|
|
|
|
maxPortPerInst = aMaxPortPerInst[storageBus];
|
|
|
|
maxSlotPerPort = aMaxSlotPerPort[storageBus];
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!maxPortPerInst ||
|
|
|
|
!maxSlotPerPort ||
|
|
|
|
(total < 0))
|
2009-12-04 13:49:45 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
*deviceInst = total / (maxPortPerInst * maxSlotPerPort);
|
|
|
|
*devicePort = (total % (maxPortPerInst * maxSlotPerPort)) / maxSlotPerPort;
|
|
|
|
*deviceSlot = (total % (maxPortPerInst * maxSlotPerPort)) % maxSlotPerPort;
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("name=%s, total=%d, storageBus=%u, deviceInst=%d, "
|
2009-12-04 13:49:45 +00:00
|
|
|
"devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u",
|
|
|
|
deviceName, total, storageBus, *deviceInst, *devicePort,
|
|
|
|
*deviceSlot, maxPortPerInst, maxSlotPerPort);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* function to get the values for max port per
|
|
|
|
* instance and max slots per port for the devices
|
|
|
|
*
|
|
|
|
* @returns true on Success, false on failure.
|
|
|
|
* @param vbox Input IVirtualBox pointer
|
|
|
|
* @param maxPortPerInst Output array of max port per instance
|
|
|
|
* @param maxSlotPerPort Output array of max slot per port
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static bool vboxGetMaxPortSlotValues(IVirtualBox *vbox,
|
|
|
|
PRUint32 *maxPortPerInst,
|
|
|
|
PRUint32 *maxSlotPerPort) {
|
|
|
|
ISystemProperties *sysProps = NULL;
|
|
|
|
|
|
|
|
if (!vbox)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
vbox->vtbl->GetSystemProperties(vbox, &sysProps);
|
|
|
|
|
|
|
|
if (!sysProps)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
sysProps->vtbl->GetMaxPortCountForStorageBus(sysProps,
|
|
|
|
StorageBus_IDE,
|
|
|
|
&maxPortPerInst[StorageBus_IDE]);
|
|
|
|
sysProps->vtbl->GetMaxPortCountForStorageBus(sysProps,
|
|
|
|
StorageBus_SATA,
|
|
|
|
&maxPortPerInst[StorageBus_SATA]);
|
|
|
|
sysProps->vtbl->GetMaxPortCountForStorageBus(sysProps,
|
|
|
|
StorageBus_SCSI,
|
|
|
|
&maxPortPerInst[StorageBus_SCSI]);
|
|
|
|
sysProps->vtbl->GetMaxPortCountForStorageBus(sysProps,
|
|
|
|
StorageBus_Floppy,
|
|
|
|
&maxPortPerInst[StorageBus_Floppy]);
|
|
|
|
|
|
|
|
sysProps->vtbl->GetMaxDevicesPerPortForStorageBus(sysProps,
|
|
|
|
StorageBus_IDE,
|
|
|
|
&maxSlotPerPort[StorageBus_IDE]);
|
|
|
|
sysProps->vtbl->GetMaxDevicesPerPortForStorageBus(sysProps,
|
|
|
|
StorageBus_SATA,
|
|
|
|
&maxSlotPerPort[StorageBus_SATA]);
|
|
|
|
sysProps->vtbl->GetMaxDevicesPerPortForStorageBus(sysProps,
|
|
|
|
StorageBus_SCSI,
|
|
|
|
&maxSlotPerPort[StorageBus_SCSI]);
|
|
|
|
sysProps->vtbl->GetMaxDevicesPerPortForStorageBus(sysProps,
|
|
|
|
StorageBus_Floppy,
|
|
|
|
&maxSlotPerPort[StorageBus_Floppy]);
|
|
|
|
|
|
|
|
VBOX_RELEASE(sysProps);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts Utf-16 string to int
|
|
|
|
*/
|
|
|
|
static int PRUnicharToInt(PRUnichar *strUtf16) {
|
|
|
|
char *strUtf8 = NULL;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
if (!strUtf16)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(strUtf16, &strUtf8);
|
|
|
|
if (!strUtf8)
|
|
|
|
return -1;
|
|
|
|
|
2010-03-30 14:27:20 +00:00
|
|
|
if (virStrToLong_i(strUtf8, NULL, 10, &ret) < 0)
|
|
|
|
ret = -1;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf8Free(strUtf8);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts int to Utf-16 string
|
|
|
|
*/
|
|
|
|
static PRUnichar *PRUnicharFromInt(int n) {
|
|
|
|
PRUnichar *strUtf16 = NULL;
|
|
|
|
char s[24];
|
|
|
|
|
|
|
|
snprintf(s, sizeof(s), "%d", n);
|
|
|
|
|
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf8ToUtf16(s, &strUtf16);
|
|
|
|
|
|
|
|
return strUtf16;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-10-22 12:21:31 +00:00
|
|
|
static PRUnichar *
|
|
|
|
vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr)
|
|
|
|
{
|
|
|
|
char *utf8 = NULL;
|
|
|
|
PRUnichar *utf16 = NULL;
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
utf8 = virSocketAddrFormat(addr);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (utf8 == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(utf8, &utf16);
|
|
|
|
VIR_FREE(utf8);
|
|
|
|
|
|
|
|
return utf16;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxSocketParseAddrUtf16(vboxGlobalData *data, const PRUnichar *utf16,
|
|
|
|
virSocketAddrPtr addr)
|
|
|
|
{
|
|
|
|
int result = -1;
|
|
|
|
char *utf8 = NULL;
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(utf16, &utf8);
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(addr, utf8, AF_UNSPEC) < 0) {
|
2010-10-22 12:21:31 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_UTF8_FREE(utf8);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
Fix default console type setting
The default console type may vary based on the OS type. ie a Xen
paravirt guests wants a 'xen' console, while a fullvirt guests
wants a 'serial' console.
A plain integer default console type in the capabilities does
not suffice. Instead introduce a callback that is passed the
OS type.
* src/conf/capabilities.h: Use a callback for default console
type
* src/conf/domain_conf.c, src/conf/domain_conf.h: Use callback
for default console type. Add missing LXC/OpenVZ console types.
* src/esx/esx_driver.c, src/libxl/libxl_conf.c,
src/lxc/lxc_conf.c, src/openvz/openvz_conf.c,
src/phyp/phyp_driver.c, src/qemu/qemu_capabilities.c,
src/uml/uml_conf.c, src/vbox/vbox_tmpl.c,
src/vmware/vmware_conf.c, src/xen/xen_hypervisor.c,
src/xenapi/xenapi_driver.c: Set default console type callback
2011-10-20 13:56:20 +00:00
|
|
|
|
2013-03-15 14:44:12 +00:00
|
|
|
static virDomainDefParserConfig vboxDomainDefParserConfig = {
|
|
|
|
.macPrefix = { 0x08, 0x00, 0x27 },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-03-31 18:03:42 +00:00
|
|
|
static virDomainXMLOptionPtr
|
2013-03-05 15:17:24 +00:00
|
|
|
vboxXMLConfInit(void)
|
|
|
|
{
|
2013-03-15 14:44:12 +00:00
|
|
|
return virDomainXMLOptionNew(&vboxDomainDefParserConfig,
|
|
|
|
NULL, NULL);
|
2013-03-05 15:17:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-10 22:28:09 +00:00
|
|
|
static virCapsPtr vboxCapsInit(void)
|
|
|
|
{
|
2009-04-17 16:09:07 +00:00
|
|
|
virCapsPtr caps;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
2012-12-10 22:28:09 +00:00
|
|
|
if ((caps = virCapabilitiesNew(virArchFromHost(),
|
2009-04-17 16:09:07 +00:00
|
|
|
0, 0)) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
2009-06-03 13:28:02 +00:00
|
|
|
if (nodeCapsInitNUMA(caps) < 0)
|
2009-04-17 16:09:07 +00:00
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
if ((guest = virCapabilitiesAddGuest(caps,
|
|
|
|
"hvm",
|
2012-12-10 22:28:09 +00:00
|
|
|
caps->host.arch,
|
2009-04-17 16:09:07 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL)) == NULL)
|
|
|
|
goto no_memory;
|
|
|
|
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"vbox",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
goto no_memory;
|
Fix default console type setting
The default console type may vary based on the OS type. ie a Xen
paravirt guests wants a 'xen' console, while a fullvirt guests
wants a 'serial' console.
A plain integer default console type in the capabilities does
not suffice. Instead introduce a callback that is passed the
OS type.
* src/conf/capabilities.h: Use a callback for default console
type
* src/conf/domain_conf.c, src/conf/domain_conf.h: Use callback
for default console type. Add missing LXC/OpenVZ console types.
* src/esx/esx_driver.c, src/libxl/libxl_conf.c,
src/lxc/lxc_conf.c, src/openvz/openvz_conf.c,
src/phyp/phyp_driver.c, src/qemu/qemu_capabilities.c,
src/uml/uml_conf.c, src/vbox/vbox_tmpl.c,
src/vmware/vmware_conf.c, src/xen/xen_hypervisor.c,
src/xenapi/xenapi_driver.c: Set default console type callback
2011-10-20 13:56:20 +00:00
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
return caps;
|
|
|
|
|
|
|
|
no_memory:
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(caps);
|
2009-04-17 16:09:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-14 22:07:57 +00:00
|
|
|
static int
|
|
|
|
vboxInitialize(vboxGlobalData *data)
|
|
|
|
{
|
2009-05-06 13:51:19 +00:00
|
|
|
data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
|
|
|
|
|
|
|
|
if (data->pFuncs == NULL)
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
2009-05-06 13:51:19 +00:00
|
|
|
|
|
|
|
#if VBOX_XPCOMC_VERSION == 0x00010000U
|
|
|
|
data->pFuncs->pfnComInitialize(&data->vboxObj, &data->vboxSession);
|
2009-07-24 16:12:16 +00:00
|
|
|
#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
2009-05-06 13:51:19 +00:00
|
|
|
data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
|
|
|
|
ISESSION_IID_STR, &data->vboxSession);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION == 2002000
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* No event queue functionality in 2.2.* as of now */
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* Initial the fWatch needed for Event Callbacks */
|
|
|
|
data->fdWatch = -1;
|
|
|
|
|
|
|
|
data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
|
|
|
|
|
|
|
|
if (data->vboxQueue == NULL) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("nsIEventQueue object is null"));
|
2009-07-24 16:12:16 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
|
2009-05-06 13:51:19 +00:00
|
|
|
|
|
|
|
if (data->vboxObj == NULL) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("IVirtualBox object is null"));
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
2009-05-06 13:51:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (data->vboxSession == NULL) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("ISession object is null"));
|
2009-05-06 13:51:19 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-04-02 22:38:57 +00:00
|
|
|
static int vboxExtractVersion(vboxGlobalData *data) {
|
2010-03-30 14:15:13 +00:00
|
|
|
int ret = -1;
|
2009-04-17 16:09:07 +00:00
|
|
|
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;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-07-01 13:23:02 +00:00
|
|
|
if (virParseVersionString(vboxVersion, &data->version, false) >= 0)
|
2009-04-17 16:09:07 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(vboxVersion);
|
|
|
|
VBOX_COM_UNALLOC_MEM(versionUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ret != 0)
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Could not extract VirtualBox version"));
|
2010-03-30 14:15:13 +00:00
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vboxUninitialize(vboxGlobalData *data) {
|
2009-05-12 15:35:18 +00:00
|
|
|
if (!data)
|
|
|
|
return;
|
|
|
|
|
2009-05-08 10:14:30 +00:00
|
|
|
if (data->pFuncs)
|
|
|
|
data->pFuncs->pfnComUninitialize();
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(data->caps);
|
2013-03-31 18:03:42 +00:00
|
|
|
virObjectUnref(data->xmlopt);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-07-24 16:12:16 +00:00
|
|
|
/* No domainEventCallbacks in 2.2.* version */
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* !(VBOX_API_VERSION == 2002000) */
|
2013-11-21 10:43:10 +00:00
|
|
|
virObjectEventStateFree(data->domainEvents);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* !(VBOX_API_VERSION == 2002000) */
|
2009-04-17 16:09:07 +00:00
|
|
|
VIR_FREE(data);
|
|
|
|
}
|
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int flags)
|
2011-07-06 23:06:11 +00:00
|
|
|
{
|
2009-05-12 15:35:18 +00:00
|
|
|
vboxGlobalData *data = NULL;
|
2013-10-09 11:13:45 +00:00
|
|
|
uid_t uid = geteuid();
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
Centralize error reporting for URI parsing/formatting problems
Move error reporting out of the callers, into virURIParse
and virURIFormat, to get consistency.
* include/libvirt/virterror.h, src/util/virterror.c: Add VIR_FROM_URI
* src/util/viruri.c, src/util/viruri.h: Add error reporting
* src/esx/esx_driver.c, src/libvirt.c, src/libxl/libxl_driver.c,
src/lxc/lxc_driver.c, src/openvz/openvz_driver.c,
src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xen/xen_driver.c,
src/xen/xend_internal.c, tests/viruritest.c: Remove error
reporting
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-03-20 12:16:54 +00:00
|
|
|
if (conn->uri == NULL &&
|
|
|
|
!(conn->uri = virURIParse(uid ? "vbox:///session" : "vbox:///system")))
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-05-12 15:35:18 +00:00
|
|
|
if (conn->uri->scheme == NULL ||
|
2012-10-17 09:23:12 +00:00
|
|
|
STRNEQ(conn->uri->scheme, "vbox"))
|
2009-05-12 15:35:18 +00:00
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
|
|
|
/* Leave for remote driver */
|
|
|
|
if (conn->uri->server != NULL)
|
2009-04-17 16:09:07 +00:00
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
2009-05-12 15:35:18 +00:00
|
|
|
if (conn->uri->path == NULL || STREQ(conn->uri->path, "")) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("no VirtualBox driver path specified (try vbox:///session)"));
|
2009-05-12 15:35:18 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
if (uid != 0) {
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STRNEQ(conn->uri->path, "/session")) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown driver path '%s' specified (try vbox:///session)"), conn->uri->path);
|
2009-05-12 15:35:18 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
} else { /* root */
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STRNEQ(conn->uri->path, "/system") &&
|
|
|
|
STRNEQ(conn->uri->path, "/session")) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unknown driver path '%s' specified (try vbox:///system)"), conn->uri->path);
|
2009-05-12 15:35:18 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(data) < 0)
|
2009-05-12 15:35:18 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-05-12 15:35:18 +00:00
|
|
|
if (!(data->caps = vboxCapsInit()) ||
|
2010-04-02 22:38:57 +00:00
|
|
|
vboxInitialize(data) < 0 ||
|
2013-03-05 15:17:24 +00:00
|
|
|
vboxExtractVersion(data) < 0 ||
|
2013-03-31 18:03:42 +00:00
|
|
|
!(data->xmlopt = vboxXMLConfInit())) {
|
2009-05-12 15:35:18 +00:00
|
|
|
vboxUninitialize(data);
|
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* No domainEventCallbacks in 2.2.* version */
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2013-11-21 10:43:10 +00:00
|
|
|
if (!(data->domainEvents = virObjectEventStateNew())) {
|
2011-12-13 10:39:17 +00:00
|
|
|
vboxUninitialize(data);
|
2009-07-24 16:12:16 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->conn = conn;
|
|
|
|
g_pVBoxGlobalData = data;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* !(VBOX_API_VERSION == 2002000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
conn->privateData = data;
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("in vboxOpen");
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectClose(virConnectPtr conn) {
|
2009-04-17 16:09:07 +00:00
|
|
|
vboxGlobalData *data = conn->privateData;
|
2013-11-19 23:35:10 +00:00
|
|
|
VIR_DEBUG("%s: in vboxClose", conn->driver->name);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
vboxUninitialize(data);
|
|
|
|
conn->privateData = NULL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectGetVersion(virConnectPtr conn, unsigned long *version) {
|
2009-04-17 16:09:07 +00:00
|
|
|
vboxGlobalData *data = conn->privateData;
|
2013-11-19 23:35:10 +00:00
|
|
|
VIR_DEBUG("%s: in vboxGetVersion", conn->driver->name);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
vboxDriverLock(data);
|
|
|
|
*version = data->version;
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-26 16:39:11 +00:00
|
|
|
|
|
|
|
static char *vboxConnectGetHostname(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
return virGetHostname();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
/* Driver is using local, non-network based transport */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
/* No encryption is needed, or used on the local transport*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
|
2011-09-23 06:56:13 +00:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 maxCPUCount = 0;
|
|
|
|
|
|
|
|
/* VirtualBox Supports only hvm and thus the type passed to it
|
|
|
|
* has no meaning, setting it to ATTRIBUTE_UNUSED
|
|
|
|
*/
|
2009-12-04 13:49:45 +00:00
|
|
|
ISystemProperties *systemProperties = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetMaxGuestCPUCount(systemProperties, &maxCPUCount);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (maxCPUCount > 0)
|
|
|
|
ret = maxCPUCount;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static char *vboxConnectGetCapabilities(virConnectPtr conn) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, char *, NULL);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
vboxDriverLock(data);
|
|
|
|
ret = virCapabilitiesFormatXML(data->caps);
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectListDomains(virConnectPtr conn, int *ids, int nids) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2013-11-19 23:35:10 +00:00
|
|
|
_("Could not get list of Domains, rc=%08x"),
|
|
|
|
(unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = 0;
|
|
|
|
for (i = 0, j = 0; (i < machines.count) && (j < nids); ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (machine) {
|
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
|
|
|
ids[j++] = i + 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectNumOfDomains(virConnectPtr conn) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get number of Domains, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = 0;
|
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (machine) {
|
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline))
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr vboxDomainCreateXML(virConnectPtr conn, const char *xml,
|
2010-05-25 17:13:13 +00:00
|
|
|
unsigned int flags) {
|
2009-04-17 16:09:07 +00:00
|
|
|
/* VirtualBox currently doesn't have support for running
|
|
|
|
* virtual machines without actually defining them and thus
|
|
|
|
* for time being just define new machine and start it.
|
|
|
|
*
|
|
|
|
* TODO: After the appropriate API's are added in VirtualBox
|
|
|
|
* change this behaviour to the expected one.
|
|
|
|
*/
|
|
|
|
|
2010-05-25 17:13:13 +00:00
|
|
|
virDomainPtr dom;
|
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
|
|
|
dom = vboxDomainDefineXML(conn, xml);
|
2009-12-16 12:56:57 +00:00
|
|
|
if (dom == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (vboxDomainCreate(dom) < 0) {
|
2011-08-11 21:44:05 +00:00
|
|
|
vboxDomainUndefineFlags(dom, 0);
|
Convert public datatypes to inherit from virObject
This converts the following public API datatypes to use the
virObject infrastructure:
virConnectPtr
virDomainPtr
virDomainSnapshotPtr
virInterfacePtr
virNetworkPtr
virNodeDevicePtr
virNWFilterPtr
virSecretPtr
virStreamPtr
virStorageVolPtr
virStoragePoolPtr
The code is significantly simplified, since the mutex in the
virConnectPtr object now only needs to be held when accessing
the per-connection virError object instance. All other operations
are completely lock free.
* src/datatypes.c, src/datatypes.h, src/libvirt.c: Convert
public datatypes to use virObject
* src/conf/domain_event.c, src/phyp/phyp_driver.c,
src/qemu/qemu_command.c, src/qemu/qemu_migration.c,
src/qemu/qemu_process.c, src/storage/storage_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xend_internal.c,
tests/qemuxml2argvtest.c, tests/qemuxmlnstest.c,
tests/sexpr2xmltest.c, tests/xmconfigtest.c: Convert
to use virObjectUnref/virObjectRef
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-07-31 16:55:36 +00:00
|
|
|
virObjectUnref(dom);
|
2009-12-16 12:56:57 +00:00
|
|
|
return NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return dom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr vboxDomainLookupByID(virConnectPtr conn, int id) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-04-21 19:13:23 +00:00
|
|
|
/* Internal vbox IDs start from 0, the public libvirt ID
|
|
|
|
* starts from 1, so refuse id==0, and adjust the rest*/
|
|
|
|
if (id == 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), id);
|
2009-04-21 19:13:23 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
id = id - 1;
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
if (id < machines.count) {
|
|
|
|
IMachine *machine = machines.items[id];
|
|
|
|
|
|
|
|
if (machine) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2010-12-16 22:05:48 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (isAccessible) {
|
2010-12-16 22:05:48 +00:00
|
|
|
machine->vtbl->GetState(machine, &state);
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
|
|
|
char *machineNameUtf8 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
vboxIIDToUUID(&iid, uuid);
|
|
|
|
vboxIIDUnalloc(&iid);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* get a new domain pointer from virGetDomain, if it fails
|
|
|
|
* then no need to assign the id, else assign the id, cause
|
|
|
|
* it is -1 by default. rest is taken care by virGetDomain
|
|
|
|
* itself, so need not worry.
|
|
|
|
*/
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
ret = virGetDomain(conn, machineNameUtf8, uuid);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (ret)
|
|
|
|
ret->id = id + 1;
|
|
|
|
|
|
|
|
/* Cleanup all the XPCOM allocated stuff here */
|
|
|
|
VBOX_UTF8_FREE(machineNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(machineNameUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
return ret;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr vboxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-07-24 16:12:16 +00:00
|
|
|
char *machineNameUtf8 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char iid_as_uuid[VIR_UUID_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int matched = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
continue;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
if (NS_FAILED(rc))
|
2009-12-04 13:49:45 +00:00
|
|
|
continue;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDToUUID(&iid, iid_as_uuid);
|
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (memcmp(uuid, iid_as_uuid, VIR_UUID_BUFLEN) == 0) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 state;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
matched = 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* get a new domain pointer from virGetDomain, if it fails
|
|
|
|
* then no need to assign the id, else assign the id, cause
|
|
|
|
* it is -1 by default. rest is taken care by virGetDomain
|
|
|
|
* itself, so need not worry.
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
ret = virGetDomain(conn, machineNameUtf8, iid_as_uuid);
|
2012-10-17 09:23:12 +00:00
|
|
|
if (ret &&
|
|
|
|
(state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline))
|
2009-12-04 13:49:45 +00:00
|
|
|
ret->id = i + 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (matched == 1)
|
|
|
|
break;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Do the cleanup and take care you dont leak any memory */
|
|
|
|
VBOX_UTF8_FREE(machineNameUtf8);
|
|
|
|
VBOX_COM_UNALLOC_MEM(machineNameUtf16);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
return ret;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainPtr vboxDomainLookupByName(virConnectPtr conn, const char *name) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-07-24 16:12:16 +00:00
|
|
|
char *machineNameUtf8 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int matched = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
continue;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (STREQ(name, machineNameUtf8)) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 state;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
matched = 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
vboxIIDToUUID(&iid, uuid);
|
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* get a new domain pointer from virGetDomain, if it fails
|
|
|
|
* then no need to assign the id, else assign the id, cause
|
|
|
|
* it is -1 by default. rest is taken care by virGetDomain
|
|
|
|
* itself, so need not worry.
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
ret = virGetDomain(conn, machineNameUtf8, uuid);
|
2012-10-17 09:23:12 +00:00
|
|
|
if (ret &&
|
|
|
|
(state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline))
|
2009-12-04 13:49:45 +00:00
|
|
|
ret->id = i + 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(machineNameUtf8);
|
|
|
|
VBOX_COM_UNALLOC_MEM(machineNameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (matched == 1)
|
|
|
|
break;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
return ret;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
|
|
|
static int vboxDomainIsActive(virDomainPtr dom) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
char *machineNameUtf8 = NULL;
|
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
|
|
|
int matched = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
|
|
|
|
if (!machine)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
if (NS_FAILED(rc))
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
continue;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDToUUID(&iid, uuid);
|
|
|
|
vboxIIDUnalloc(&iid);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (memcmp(dom->uuid, uuid, VIR_UUID_BUFLEN) == 0) {
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 state;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
matched = 1;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetState(machine, &state);
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state >= MachineState_FirstOnline) &&
|
|
|
|
(state <= MachineState_LastOnline))
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (matched == 1)
|
|
|
|
break;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Do the cleanup and take care you dont leak any memory */
|
|
|
|
VBOX_UTF8_FREE(machineNameUtf8);
|
|
|
|
VBOX_COM_UNALLOC_MEM(machineNameUtf16);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-25 02:28:54 +00:00
|
|
|
static int vboxDomainIsPersistent(virDomainPtr dom ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
/* All domains are persistent. However, we do want to check for
|
|
|
|
* existence. */
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
Implmentation of new APIs to checking state/persistence of objects
This implements the virConnectIsSecure, virConnectIsEncrypted,
virDomainIsPersistent, virDomainIsActive, virNetworkIsActive,
virNetworkIsPersistent, virStoragePoolIsActive,
virStoragePoolIsPersistent, virInterfaceIsActive APIs in
(nearly) all drivers. Exceptions are:
phyp: missing domainIsActive/Persistent
esx: missing domainIsPersistent
opennebula: missing domainIsActive/Persistent
* src/remote/remote_protocol.x: Define remote wire ABI for newly
added APIs.
* daemon/remote_dispatch*.h: Re-generated from remote_protocol.x
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/network/bridge_driver.c,
src/opennebula/one_driver.c, src/openvz/openvz_conf.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/remote/remote_driver.c, src/storage/storage_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c, src/xen/xen_driver.h, src/xen/xen_inotify.c,
src/xen/xen_inotify.h: Implement all the new APIs where possible
2009-10-20 14:12:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-24 07:43:15 +00:00
|
|
|
static int vboxDomainIsUpdated(virDomainPtr dom ATTRIBUTE_UNUSED) {
|
2012-05-25 02:28:54 +00:00
|
|
|
/* VBox domains never have a persistent state that differs from
|
|
|
|
* current state. However, we do want to check for existence. */
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
2010-11-24 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
static int vboxDomainSuspend(virDomainPtr dom) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (state == MachineState_Running) {
|
2010-12-27 22:35:30 +00:00
|
|
|
/* set state pause */
|
|
|
|
VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (console) {
|
|
|
|
console->vtbl->Pause(console);
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("error while suspending the domain"));
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine not in running state to suspend it"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxDomainResume(virDomainPtr dom) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
|
|
|
|
|
|
|
if (state == MachineState_Paused) {
|
2010-12-27 22:35:30 +00:00
|
|
|
/* resume the machine here */
|
|
|
|
VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (console) {
|
|
|
|
console->vtbl->Resume(console);
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("error while resuming the domain"));
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine not paused, so can't resume it"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-05 17:31:55 +00:00
|
|
|
static int vboxDomainShutdownFlags(virDomainPtr dom,
|
|
|
|
unsigned int flags) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-10-05 17:31:55 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (state == MachineState_Paused) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine paused, so can't power it down"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else if (state == MachineState_PoweredOff) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine already powered down"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (console) {
|
|
|
|
console->vtbl->PowerButton(console);
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-10-05 17:31:55 +00:00
|
|
|
static int vboxDomainShutdown(virDomainPtr dom) {
|
|
|
|
return vboxDomainShutdownFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
static int vboxDomainReboot(virDomainPtr dom, unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (state == MachineState_Running) {
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (console) {
|
|
|
|
console->vtbl->Reset(console);
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine not running, so can't reboot it"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-21 07:59:16 +00:00
|
|
|
static int
|
|
|
|
vboxDomainDestroyFlags(virDomainPtr dom,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-07-21 07:59:16 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (state == MachineState_PoweredOff) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("machine already powered down"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (console) {
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-12-04 13:49:45 +00:00
|
|
|
console->vtbl->PowerDown(console);
|
2009-07-24 16:12:16 +00:00
|
|
|
#else
|
2010-03-31 08:39:48 +00:00
|
|
|
IProgress *progress = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
console->vtbl->PowerDown(console, &progress);
|
|
|
|
if (progress) {
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
VBOX_RELEASE(progress);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
#endif
|
|
|
|
VBOX_RELEASE(console);
|
2010-07-30 17:50:12 +00:00
|
|
|
dom->id = -1;
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-21 07:59:16 +00:00
|
|
|
static int
|
|
|
|
vboxDomainDestroy(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return vboxDomainDestroyFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
2010-02-04 18:19:08 +00:00
|
|
|
static char *vboxDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
|
2009-04-17 16:09:07 +00:00
|
|
|
/* Returning "hvm" always as suggested on list, cause
|
|
|
|
* this functions seems to be badly named and it
|
|
|
|
* is supposed to pass the ABI name and not the domain
|
|
|
|
* operating system driver as I had imagined ;)
|
|
|
|
*/
|
2013-05-03 12:50:19 +00:00
|
|
|
char *osType;
|
2009-11-08 21:08:54 +00:00
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(osType, "hvm"));
|
2009-11-08 21:08:54 +00:00
|
|
|
return osType;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxDomainSetMemory(virDomainPtr dom, unsigned long memory) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (state != MachineState_PoweredOff) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("memory size can't be changed unless domain is powered down"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (NS_SUCCEEDED(rc) && machine) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-01-28 21:03:24 +00:00
|
|
|
rc = machine->vtbl->SetMemorySize(machine,
|
|
|
|
VIR_DIV_UP(memory, 1024));
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
machine->vtbl->SaveSettings(machine);
|
|
|
|
ret = 0;
|
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not set the memory size of the "
|
|
|
|
"domain to: %lu Kb, rc=%08x"),
|
|
|
|
memory, (unsigned)rc);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-10-14 16:19:41 +00:00
|
|
|
static virDomainState vboxConvertState(enum MachineState state) {
|
|
|
|
switch (state) {
|
|
|
|
case MachineState_Running:
|
|
|
|
return VIR_DOMAIN_RUNNING;
|
|
|
|
case MachineState_Stuck:
|
|
|
|
return VIR_DOMAIN_BLOCKED;
|
|
|
|
case MachineState_Paused:
|
|
|
|
return VIR_DOMAIN_PAUSED;
|
|
|
|
case MachineState_Stopping:
|
|
|
|
return VIR_DOMAIN_SHUTDOWN;
|
|
|
|
case MachineState_PoweredOff:
|
2013-10-14 16:19:42 +00:00
|
|
|
case MachineState_Saved:
|
2013-10-14 16:19:41 +00:00
|
|
|
return VIR_DOMAIN_SHUTOFF;
|
|
|
|
case MachineState_Aborted:
|
|
|
|
return VIR_DOMAIN_CRASHED;
|
|
|
|
case MachineState_Null:
|
|
|
|
default:
|
|
|
|
return VIR_DOMAIN_NOSTATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
static int vboxDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
char *machineName = NULL;
|
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
info->nrVirtCpu = 0;
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
continue;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineName);
|
|
|
|
|
|
|
|
if (STREQ(dom->name, machineName)) {
|
|
|
|
/* Get the Machine State (also match it with
|
|
|
|
* virDomainState). Get the Machine memory and
|
2010-10-12 14:43:39 +00:00
|
|
|
* for time being set max_balloon and cur_balloon to same
|
2009-12-04 13:49:45 +00:00
|
|
|
* Also since there is no direct way of checking
|
|
|
|
* the cputime required (one condition being the
|
|
|
|
* VM is remote), return zero for cputime. Get the
|
|
|
|
* number of CPU.
|
|
|
|
*/
|
|
|
|
PRUint32 CPUCount = 0;
|
|
|
|
PRUint32 memorySize = 0;
|
|
|
|
PRUint32 state = MachineState_Null;
|
|
|
|
PRUint32 maxMemorySize = 4 * 1024;
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
|
|
|
|
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetMaxGuestRAM(systemProperties, &maxMemorySize);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetCPUCount(machine, &CPUCount);
|
|
|
|
machine->vtbl->GetMemorySize(machine, &memorySize);
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
|
|
|
|
|
|
|
info->cpuTime = 0;
|
|
|
|
info->nrVirtCpu = CPUCount;
|
2010-10-12 19:24:11 +00:00
|
|
|
info->memory = memorySize * 1024;
|
|
|
|
info->maxMem = maxMemorySize * 1024;
|
2013-10-14 16:19:41 +00:00
|
|
|
info->state = vboxConvertState(state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(machineName);
|
|
|
|
VBOX_COM_UNALLOC_MEM(machineNameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (info->nrVirtCpu)
|
|
|
|
break;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-05-02 09:35:29 +00:00
|
|
|
static int
|
|
|
|
vboxDomainGetState(virDomainPtr dom,
|
|
|
|
int *state,
|
|
|
|
int *reason,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
PRUint32 mstate = MachineState_Null;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&domiid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2011-05-02 09:35:29 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
machine->vtbl->GetState(machine, &mstate);
|
|
|
|
|
2013-10-14 16:19:41 +00:00
|
|
|
*state = vboxConvertState(mstate);
|
2011-05-02 09:35:29 +00:00
|
|
|
|
|
|
|
if (reason)
|
|
|
|
*reason = 0;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
vboxIIDUnalloc(&domiid);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IConsole *console = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-12-27 22:35:30 +00:00
|
|
|
IMachine *machine = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
/* 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
|
|
|
|
*/
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Open a Session for the machine */
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
/* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2010-12-27 22:35:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (NS_SUCCEEDED(rc) && console) {
|
|
|
|
IProgress *progress = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
console->vtbl->SaveState(console, &progress);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (progress) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult resultCode;
|
2009-07-24 16:12:16 +00:00
|
|
|
#else
|
2009-12-04 13:49:45 +00:00
|
|
|
PRInt32 resultCode;
|
2009-07-24 16:12:16 +00:00
|
|
|
#endif
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
progress->vtbl->GetResultCode(progress, &resultCode);
|
|
|
|
if (NS_SUCCEEDED(resultCode)) {
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(progress);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(console);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("UUID of machine being saved:", iid.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
static int
|
|
|
|
vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-09-02 14:08:14 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-09-02 14:08:14 +00:00
|
|
|
PRUint32 CPUCount = nvcpus;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-09-02 14:08:14 +00:00
|
|
|
|
2011-06-08 06:33:33 +00:00
|
|
|
if (flags != VIR_DOMAIN_AFFECT_LIVE) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
/* Get machine for the call to VBOX_SESSION_OPEN */
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2010-12-27 22:35:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
rc = VBOX_SESSION_OPEN(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (machine) {
|
|
|
|
rc = machine->vtbl->SetCPUCount(machine, CPUCount);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
machine->vtbl->SaveSettings(machine);
|
|
|
|
ret = 0;
|
2009-09-02 14:08:14 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not set the number of cpus of the domain "
|
|
|
|
"to: %u, rc=%08x"),
|
|
|
|
CPUCount, (unsigned)rc);
|
2009-09-02 14:08:14 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2009-09-02 14:08:14 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("no domain with matching id %d"), dom->id);
|
2009-09-02 14:08:14 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN,
|
|
|
|
_("can't open session to the domain with id %d"), dom->id);
|
2009-09-02 14:08:14 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-09-02 14:08:14 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-09-02 14:08:14 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
static int
|
|
|
|
vboxDomainSetVcpus(virDomainPtr dom, unsigned int nvcpus)
|
|
|
|
{
|
2011-06-08 06:33:33 +00:00
|
|
|
return vboxDomainSetVcpusFlags(dom, nvcpus, VIR_DOMAIN_AFFECT_LIVE);
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
2009-09-02 14:08:14 +00:00
|
|
|
PRUint32 maxCPUCount = 0;
|
|
|
|
|
2011-06-08 06:33:33 +00:00
|
|
|
if (flags != (VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-09-02 14:08:14 +00:00
|
|
|
/* Currently every domain supports the same number of max cpus
|
|
|
|
* as that supported by vbox and thus take it directly from
|
|
|
|
* the systemproperties.
|
|
|
|
*/
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetMaxGuestCPUCount(systemProperties, &maxCPUCount);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
2009-09-02 14:08:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (maxCPUCount > 0)
|
|
|
|
ret = maxCPUCount;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
static int
|
|
|
|
vboxDomainGetMaxVcpus(virDomainPtr dom)
|
|
|
|
{
|
2011-06-08 06:33:33 +00:00
|
|
|
return vboxDomainGetVcpusFlags(dom, (VIR_DOMAIN_AFFECT_LIVE |
|
vcpu: make old API trivially wrap to new API
Note - this wrapping is completely mechanical; the old API will
function identically, since the new API validates that the exact
same flags are provided by the old API. On a per-driver basis,
it may make sense to have the old API pass a different set of flags,
but that should be done in the per-driver patch that implements
the full range of flag support in the new API.
* src/esx/esx_driver.c (esxDomainSetVcpus, escDomainGetMaxVpcus):
Move guts...
(esxDomainSetVcpusFlags, esxDomainGetVcpusFlags): ...to new
functions.
(esxDriver): Trivially support the new API.
* src/openvz/openvz_driver.c (openvzDomainSetVcpus)
(openvzDomainSetVcpusFlags, openvzDomainGetMaxVcpus)
(openvzDomainGetVcpusFlags, openvzDriver): Likewise.
* src/phyp/phyp_driver.c (phypDomainSetCPU)
(phypDomainSetVcpusFlags, phypGetLparCPUMAX)
(phypDomainGetVcpusFlags, phypDriver): Likewise.
* src/qemu/qemu_driver.c (qemudDomainSetVcpus)
(qemudDomainSetVcpusFlags, qemudDomainGetMaxVcpus)
(qemudDomainGetVcpusFlags, qemuDriver): Likewise.
* src/test/test_driver.c (testSetVcpus, testDomainSetVcpusFlags)
(testDomainGetMaxVcpus, testDomainGetVcpusFlags, testDriver):
Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainSetVcpus)
(vboxDomainSetVcpusFlags, virDomainGetMaxVcpus)
(virDomainGetVcpusFlags, virDriver): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainSetVcpus)
(xenUnifiedDomainSetVcpusFlags, xenUnifiedDomainGetMaxVcpus)
(xenUnifiedDomainGetVcpusFlags, xenUnifiedDriver): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainSetVcpus)
(xenapiDomainSetVcpusFlags, xenapiDomainGetMaxVcpus)
(xenapiDomainGetVcpusFlags, xenapiDriver): Likewise.
(xenapiError): New helper macro.
2010-09-27 22:37:53 +00:00
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM));
|
|
|
|
}
|
|
|
|
|
2013-11-21 14:41:05 +00:00
|
|
|
static void vboxHostDeviceGetXMLDesc(vboxGlobalData *data, virDomainDefPtr def, IMachine *machine)
|
|
|
|
{
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:05 +00:00
|
|
|
IUSBController *USBController = NULL;
|
|
|
|
PRBool enabled = PR_FALSE;
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
IUSBDeviceFilters *USBDeviceFilters = NULL;
|
|
|
|
#endif
|
2013-11-21 14:41:05 +00:00
|
|
|
vboxArray deviceFilters = VBOX_ARRAY_INITIALIZER;
|
|
|
|
size_t i;
|
|
|
|
PRUint32 USBFilterCount = 0;
|
|
|
|
|
|
|
|
def->nhostdevs = 0;
|
2013-11-21 14:41:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:05 +00:00
|
|
|
machine->vtbl->GetUSBController(machine, &USBController);
|
|
|
|
|
|
|
|
if (!USBController)
|
|
|
|
return;
|
|
|
|
|
|
|
|
USBController->vtbl->GetEnabled(USBController, &enabled);
|
|
|
|
if (!enabled)
|
|
|
|
goto release_controller;
|
|
|
|
|
|
|
|
vboxArrayGet(&deviceFilters, USBController,
|
|
|
|
USBController->vtbl->GetDeviceFilters);
|
|
|
|
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
machine->vtbl->GetUSBDeviceFilters(machine, &USBDeviceFilters);
|
|
|
|
|
|
|
|
if (!USBDeviceFilters)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vboxArrayGet(&deviceFilters, USBDeviceFilters,
|
|
|
|
USBDeviceFilters->vtbl->GetDeviceFilters);
|
|
|
|
#endif
|
|
|
|
|
2013-11-21 14:41:05 +00:00
|
|
|
if (deviceFilters.count <= 0)
|
|
|
|
goto release_filters;
|
|
|
|
|
|
|
|
/* check if the filters are active and then only
|
|
|
|
* alloc mem and set def->nhostdevs
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = 0; i < deviceFilters.count; i++) {
|
|
|
|
PRBool active = PR_FALSE;
|
|
|
|
IUSBDeviceFilter *deviceFilter = deviceFilters.items[i];
|
|
|
|
|
|
|
|
deviceFilter->vtbl->GetActive(deviceFilter, &active);
|
|
|
|
if (active) {
|
|
|
|
def->nhostdevs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->nhostdevs == 0)
|
|
|
|
goto release_filters;
|
|
|
|
|
|
|
|
/* Alloc mem needed for the filters now */
|
|
|
|
if (VIR_ALLOC_N(def->hostdevs, def->nhostdevs) < 0)
|
|
|
|
goto release_filters;
|
|
|
|
|
2013-12-01 14:46:06 +00:00
|
|
|
for (i = 0; i < def->nhostdevs; i++) {
|
|
|
|
def->hostdevs[i] = virDomainHostdevDefAlloc();
|
|
|
|
if (!def->hostdevs[i])
|
|
|
|
goto release_hostdevs;
|
|
|
|
}
|
|
|
|
|
2013-12-01 14:46:05 +00:00
|
|
|
for (i = 0; i < deviceFilters.count; i++) {
|
2013-11-21 14:41:05 +00:00
|
|
|
PRBool active = PR_FALSE;
|
|
|
|
IUSBDeviceFilter *deviceFilter = deviceFilters.items[i];
|
|
|
|
PRUnichar *vendorIdUtf16 = NULL;
|
|
|
|
char *vendorIdUtf8 = NULL;
|
|
|
|
unsigned vendorId = 0;
|
|
|
|
PRUnichar *productIdUtf16 = NULL;
|
|
|
|
char *productIdUtf8 = NULL;
|
|
|
|
unsigned productId = 0;
|
|
|
|
char *endptr = NULL;
|
|
|
|
|
|
|
|
deviceFilter->vtbl->GetActive(deviceFilter, &active);
|
|
|
|
if (!active)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
def->hostdevs[USBFilterCount]->mode =
|
|
|
|
VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
|
|
|
|
def->hostdevs[USBFilterCount]->source.subsys.type =
|
|
|
|
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
|
|
|
|
|
|
|
|
deviceFilter->vtbl->GetVendorId(deviceFilter, &vendorIdUtf16);
|
|
|
|
deviceFilter->vtbl->GetProductId(deviceFilter, &productIdUtf16);
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(vendorIdUtf16, &vendorIdUtf8);
|
|
|
|
VBOX_UTF16_TO_UTF8(productIdUtf16, &productIdUtf8);
|
|
|
|
|
|
|
|
vendorId = strtol(vendorIdUtf8, &endptr, 16);
|
|
|
|
productId = strtol(productIdUtf8, &endptr, 16);
|
|
|
|
|
|
|
|
def->hostdevs[USBFilterCount]->source.subsys.u.usb.vendor = vendorId;
|
|
|
|
def->hostdevs[USBFilterCount]->source.subsys.u.usb.product = productId;
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(vendorIdUtf16);
|
|
|
|
VBOX_UTF8_FREE(vendorIdUtf8);
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(productIdUtf16);
|
|
|
|
VBOX_UTF8_FREE(productIdUtf8);
|
|
|
|
|
|
|
|
USBFilterCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
release_filters:
|
|
|
|
vboxArrayRelease(&deviceFilters);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:05 +00:00
|
|
|
release_controller:
|
|
|
|
VBOX_RELEASE(USBController);
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
VBOX_RELEASE(USBDeviceFilters);
|
|
|
|
#endif
|
2013-12-01 14:46:06 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
release_hostdevs:
|
|
|
|
for (i = 0; i < def->nhostdevs; i++)
|
|
|
|
virDomainHostdevDefFree(def->hostdevs[i]);
|
|
|
|
VIR_FREE(def->hostdevs);
|
|
|
|
|
|
|
|
goto release_filters;
|
2013-11-21 14:41:05 +00:00
|
|
|
}
|
|
|
|
|
2011-07-06 20:40:19 +00:00
|
|
|
static char *vboxDomainGetXMLDesc(virDomainPtr dom, unsigned int flags) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefPtr def = NULL;
|
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
int gotAllABoutDef = -1;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-07-13 22:24:38 +00:00
|
|
|
/* Flags checked by virDomainDefFormat */
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool accessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &accessible);
|
|
|
|
if (accessible) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool PAEEnabled = PR_FALSE;
|
|
|
|
PRBool ACPIEnabled = PR_FALSE;
|
|
|
|
PRBool IOAPICEnabled = PR_FALSE;
|
2010-12-27 22:35:30 +00:00
|
|
|
PRBool VRDxEnabled = PR_FALSE;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 CPUCount = 0;
|
|
|
|
PRUint32 memorySize = 0;
|
|
|
|
PRUint32 netAdpCnt = 0;
|
|
|
|
PRUint32 netAdpIncCnt = 0;
|
|
|
|
PRUint32 maxMemorySize = 4 * 1024;
|
|
|
|
PRUint32 maxBootPosition = 0;
|
|
|
|
PRUint32 serialPortCount = 0;
|
|
|
|
PRUint32 serialPortIncCount = 0;
|
|
|
|
PRUint32 parallelPortCount = 0;
|
|
|
|
PRUint32 parallelPortIncCount = 0;
|
|
|
|
IBIOSSettings *bios = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
PRInt32 hddNum = 0;
|
|
|
|
IDVDDrive *dvdDrive = NULL;
|
|
|
|
IHardDisk *hardDiskPM = NULL;
|
|
|
|
IHardDisk *hardDiskPS = NULL;
|
|
|
|
IHardDisk *hardDiskSS = NULL;
|
|
|
|
const char *hddBus = "IDE";
|
|
|
|
PRUnichar *hddBusUtf16 = NULL;
|
|
|
|
IFloppyDrive *floppyDrive = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
IVRDPServer *VRDxServer = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
IVRDEServer *VRDxServer = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
IAudioAdapter *audioAdapter = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
PRUint32 chipsetType = ChipsetType_Null;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
ISystemProperties *systemProperties = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->virtType = VIR_DOMAIN_VIRT_VBOX;
|
|
|
|
def->id = dom->id;
|
|
|
|
memcpy(def->uuid, dom->uuid, VIR_UUID_BUFLEN);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->name, dom->name) < 0)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetMemorySize(machine, &memorySize);
|
2010-10-12 14:43:39 +00:00
|
|
|
def->mem.cur_balloon = memorySize * 1024;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
machine->vtbl->GetChipsetType(machine, &chipsetType);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetMaxGuestRAM(systemProperties, &maxMemorySize);
|
|
|
|
systemProperties->vtbl->GetMaxBootPosition(systemProperties, &maxBootPosition);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2009-12-04 13:49:45 +00:00
|
|
|
systemProperties->vtbl->GetNetworkAdapterCount(systemProperties, &netAdpCnt);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties, chipsetType, &netAdpCnt);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
systemProperties->vtbl->GetSerialPortCount(systemProperties, &serialPortCount);
|
|
|
|
systemProperties->vtbl->GetParallelPortCount(systemProperties, ¶llelPortCount);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
|
|
|
}
|
|
|
|
/* Currently setting memory and maxMemory as same, cause
|
|
|
|
* the notation here seems to be inconsistent while
|
|
|
|
* reading and while dumping xml
|
|
|
|
*/
|
2010-10-12 14:43:39 +00:00
|
|
|
/* def->mem.max_balloon = maxMemorySize * 1024; */
|
|
|
|
def->mem.max_balloon = memorySize * 1024;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
machine->vtbl->GetCPUCount(machine, &CPUCount);
|
2010-09-29 16:20:07 +00:00
|
|
|
def->maxvcpus = def->vcpus = CPUCount;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* Skip cpumasklen, cpumask, onReboot, onPoweroff, onCrash */
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->os.type, "hvm") < 0)
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2012-12-10 22:28:09 +00:00
|
|
|
def->os.arch = virArchFromHost();
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
def->os.nBootDevs = 0;
|
|
|
|
for (i = 0; (i < VIR_DOMAIN_BOOT_LAST) && (i < maxBootPosition); i++) {
|
|
|
|
PRUint32 device = DeviceType_Null;
|
|
|
|
|
|
|
|
machine->vtbl->GetBootOrder(machine, i+1, &device);
|
|
|
|
|
|
|
|
if (device == DeviceType_Floppy) {
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_FLOPPY;
|
|
|
|
def->os.nBootDevs++;
|
|
|
|
} else if (device == DeviceType_DVD) {
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_CDROM;
|
|
|
|
def->os.nBootDevs++;
|
|
|
|
} else if (device == DeviceType_HardDisk) {
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_DISK;
|
|
|
|
def->os.nBootDevs++;
|
|
|
|
} else if (device == DeviceType_Network) {
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_NET;
|
|
|
|
def->os.nBootDevs++;
|
|
|
|
} else if (device == DeviceType_USB) {
|
|
|
|
/* Not supported by libvirt yet */
|
|
|
|
} else if (device == DeviceType_SharedFolder) {
|
|
|
|
/* Not supported by libvirt yet */
|
2011-06-07 11:29:34 +00:00
|
|
|
/* Can VirtualBox really boot from a shared folder? */
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetPAEEnabled(machine, &PAEEnabled);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetCpuProperty(machine, CpuPropertyType_PAE, &PAEEnabled);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 3002000
|
2010-05-26 11:54:16 +00:00
|
|
|
machine->vtbl->GetCPUProperty(machine, CPUPropertyType_PAE, &PAEEnabled);
|
|
|
|
#endif
|
2013-09-23 13:02:38 +00:00
|
|
|
if (PAEEnabled)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetBIOSSettings(machine, &bios);
|
|
|
|
if (bios) {
|
|
|
|
bios->vtbl->GetACPIEnabled(bios, &ACPIEnabled);
|
2013-09-23 13:02:38 +00:00
|
|
|
if (ACPIEnabled)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
bios->vtbl->GetIOAPICEnabled(bios, &IOAPICEnabled);
|
2013-09-23 13:02:38 +00:00
|
|
|
if (IOAPICEnabled)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_DOMAIN_FEATURE_STATE_ON;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(bios);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Currently VirtualBox always uses locatime
|
|
|
|
* so locatime is always true here */
|
2010-02-02 17:22:03 +00:00
|
|
|
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* dump video options vram/2d/3d/directx/etc. */
|
|
|
|
{
|
|
|
|
/* Currently supports only one graphics card */
|
|
|
|
def->nvideos = 1;
|
|
|
|
if (VIR_ALLOC_N(def->videos, def->nvideos) >= 0) {
|
|
|
|
if (VIR_ALLOC(def->videos[0]) >= 0) {
|
|
|
|
/* the default is: vram is 8MB, One monitor, 3dAccel Off */
|
2010-12-30 14:18:27 +00:00
|
|
|
PRUint32 VRAMSize = 8;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 monitorCount = 1;
|
|
|
|
PRBool accelerate3DEnabled = PR_FALSE;
|
|
|
|
PRBool accelerate2DEnabled = PR_FALSE;
|
|
|
|
|
|
|
|
machine->vtbl->GetVRAMSize(machine, &VRAMSize);
|
|
|
|
machine->vtbl->GetMonitorCount(machine, &monitorCount);
|
|
|
|
machine->vtbl->GetAccelerate3DEnabled(machine, &accelerate3DEnabled);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccelerate2DVideoEnabled(machine, &accelerate2DEnabled);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
def->videos[0]->type = VIR_DOMAIN_VIDEO_TYPE_VBOX;
|
2010-12-30 14:18:27 +00:00
|
|
|
def->videos[0]->vram = VRAMSize * 1024;
|
2009-12-04 13:49:45 +00:00
|
|
|
def->videos[0]->heads = monitorCount;
|
|
|
|
if (VIR_ALLOC(def->videos[0]->accel) >= 0) {
|
|
|
|
def->videos[0]->accel->support3d = accelerate3DEnabled;
|
|
|
|
def->videos[0]->accel->support2d = accelerate2DEnabled;
|
2013-07-04 10:17:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-09-03 08:36:44 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump display options vrdp/gui/sdl */
|
|
|
|
{
|
|
|
|
int vrdpPresent = 0;
|
|
|
|
int sdlPresent = 0;
|
|
|
|
int guiPresent = 0;
|
|
|
|
int totalPresent = 0;
|
|
|
|
char *guiDisplay = NULL;
|
|
|
|
char *sdlDisplay = NULL;
|
|
|
|
PRUnichar *keyTypeUtf16 = NULL;
|
|
|
|
PRUnichar *valueTypeUtf16 = NULL;
|
|
|
|
char *valueTypeUtf8 = NULL;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->ngraphics = 0;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
|
|
|
|
machine->vtbl->GetExtraData(machine, keyTypeUtf16, &valueTypeUtf16);
|
|
|
|
VBOX_UTF16_FREE(keyTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (valueTypeUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(valueTypeUtf16, &valueTypeUtf8);
|
|
|
|
VBOX_UTF16_FREE(valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STREQ(valueTypeUtf8, "sdl") || STREQ(valueTypeUtf8, "gui")) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *keyDislpayUtf16 = NULL;
|
|
|
|
PRUnichar *valueDisplayUtf16 = NULL;
|
|
|
|
char *valueDisplayUtf8 = NULL;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
|
|
|
|
machine->vtbl->GetExtraData(machine, keyDislpayUtf16, &valueDisplayUtf16);
|
|
|
|
VBOX_UTF16_FREE(keyDislpayUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (valueDisplayUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(valueDisplayUtf16, &valueDisplayUtf8);
|
|
|
|
VBOX_UTF16_FREE(valueDisplayUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
if (strlen(valueDisplayUtf8) <= 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(valueDisplayUtf8);
|
2009-05-15 13:45:40 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (STREQ(valueTypeUtf8, "sdl")) {
|
|
|
|
sdlPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(sdlDisplay, valueDisplayUtf8) < 0) {
|
2009-12-04 13:49:45 +00:00
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* sdlDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
totalPresent++;
|
2009-05-15 13:45:40 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (STREQ(valueTypeUtf8, "gui")) {
|
|
|
|
guiPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(guiDisplay, valueDisplayUtf8) < 0) {
|
2009-05-15 13:45:40 +00:00
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
2009-12-04 13:49:45 +00:00
|
|
|
* guiDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
2009-05-15 13:45:40 +00:00
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
totalPresent++;
|
|
|
|
}
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(valueDisplayUtf8);
|
2009-05-15 13:45:40 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (STREQ(valueTypeUtf8, "vrdp"))
|
|
|
|
vrdpPresent = 1;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(valueTypeUtf8);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if ((totalPresent > 0) && (VIR_ALLOC_N(def->graphics, totalPresent) >= 0)) {
|
|
|
|
if ((guiPresent) && (VIR_ALLOC(def->graphics[def->ngraphics]) >= 0)) {
|
|
|
|
def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP;
|
|
|
|
if (guiDisplay)
|
|
|
|
def->graphics[def->ngraphics]->data.desktop.display = guiDisplay;
|
|
|
|
def->ngraphics++;
|
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if ((sdlPresent) && (VIR_ALLOC(def->graphics[def->ngraphics]) >= 0)) {
|
|
|
|
def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
|
|
|
|
if (sdlDisplay)
|
|
|
|
def->graphics[def->ngraphics]->data.sdl.display = sdlDisplay;
|
|
|
|
def->ngraphics++;
|
|
|
|
}
|
|
|
|
} else if ((vrdpPresent != 1) && (totalPresent == 0) && (VIR_ALLOC_N(def->graphics, 1) >= 0)) {
|
|
|
|
if (VIR_ALLOC(def->graphics[def->ngraphics]) >= 0) {
|
2013-10-09 10:18:15 +00:00
|
|
|
const char *tmp;
|
2009-12-04 13:49:45 +00:00
|
|
|
def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP;
|
2013-10-09 10:18:15 +00:00
|
|
|
tmp = virGetEnvBlockSUID("DISPLAY");
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->graphics[def->ngraphics]->data.desktop.display, tmp) < 0) {
|
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* display as NULL
|
|
|
|
*/
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
totalPresent++;
|
|
|
|
def->ngraphics++;
|
|
|
|
}
|
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
machine->vtbl->GetVRDPServer(machine, &VRDxServer);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
machine->vtbl->GetVRDEServer(machine, &VRDxServer);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
if (VRDxServer) {
|
|
|
|
VRDxServer->vtbl->GetEnabled(VRDxServer, &VRDxEnabled);
|
|
|
|
if (VRDxEnabled) {
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
totalPresent++;
|
|
|
|
|
|
|
|
if ((VIR_REALLOC_N(def->graphics, totalPresent) >= 0) &&
|
|
|
|
(VIR_ALLOC(def->graphics[def->ngraphics]) >= 0)) {
|
|
|
|
PRUnichar *netAddressUtf16 = NULL;
|
|
|
|
char *netAddressUtf8 = NULL;
|
|
|
|
PRBool allowMultiConnection = PR_FALSE;
|
|
|
|
PRBool reuseSingleConnection = PR_FALSE;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 VRDPport = 0;
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->GetPort(VRDxServer, &VRDPport);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (VRDPport) {
|
|
|
|
def->graphics[def->ngraphics]->data.rdp.port = VRDPport;
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION < 4000000 /* 3001000 <= VBOX_API_VERSION < 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *VRDPport = NULL;
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->GetPorts(VRDxServer, &VRDPport);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (VRDPport) {
|
|
|
|
/* even if vbox supports mutilpe ports, single port for now here */
|
|
|
|
def->graphics[def->ngraphics]->data.rdp.port = PRUnicharToInt(VRDPport);
|
|
|
|
VBOX_UTF16_FREE(VRDPport);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
PRUnichar *VRDEPortsKey = NULL;
|
|
|
|
PRUnichar *VRDEPortsValue = NULL;
|
|
|
|
VBOX_UTF8_TO_UTF16("TCP/Ports", &VRDEPortsKey);
|
|
|
|
VRDxServer->vtbl->GetVRDEProperty(VRDxServer, VRDEPortsKey, &VRDEPortsValue);
|
|
|
|
VBOX_UTF16_FREE(VRDEPortsKey);
|
|
|
|
if (VRDEPortsValue) {
|
|
|
|
/* even if vbox supports mutilpe ports, single port for now here */
|
|
|
|
def->graphics[def->ngraphics]->data.rdp.port = PRUnicharToInt(VRDEPortsValue);
|
|
|
|
VBOX_UTF16_FREE(VRDEPortsValue);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2013-04-12 08:49:38 +00:00
|
|
|
def->graphics[def->ngraphics]->data.rdp.autoport = true;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
PRUnichar *VRDENetAddressKey = NULL;
|
|
|
|
VBOX_UTF8_TO_UTF16("TCP/Address", &VRDENetAddressKey);
|
|
|
|
VRDxServer->vtbl->GetVRDEProperty(VRDxServer, VRDENetAddressKey, &netAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(VRDENetAddressKey);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION < 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->GetNetAddress(VRDxServer, &netAddressUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION < 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (netAddressUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(netAddressUtf16, &netAddressUtf8);
|
|
|
|
if (STRNEQ(netAddressUtf8, ""))
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
virDomainGraphicsListenSetAddress(def->graphics[def->ngraphics], 0,
|
|
|
|
netAddressUtf8, -1, true);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(netAddressUtf16);
|
|
|
|
VBOX_UTF8_FREE(netAddressUtf8);
|
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->GetAllowMultiConnection(VRDxServer, &allowMultiConnection);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (allowMultiConnection) {
|
2013-04-12 08:49:38 +00:00
|
|
|
def->graphics[def->ngraphics]->data.rdp.multiUser = true;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->GetReuseSingleConnection(VRDxServer, &reuseSingleConnection);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (reuseSingleConnection) {
|
2013-04-12 08:49:38 +00:00
|
|
|
def->graphics[def->ngraphics]->data.rdp.replaceUser = true;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->ngraphics++;
|
2009-09-07 15:44:12 +00:00
|
|
|
} else
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_RELEASE(VRDxServer);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump IDE hdds if present */
|
|
|
|
VBOX_UTF8_TO_UTF16(hddBus, &hddBusUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->ndisks = 0;
|
|
|
|
machine->vtbl->GetHardDisk(machine, hddBusUtf16, 0, 0, &hardDiskPM);
|
|
|
|
if (hardDiskPM)
|
|
|
|
def->ndisks++;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetHardDisk(machine, hddBusUtf16, 0, 1, &hardDiskPS);
|
|
|
|
if (hardDiskPS)
|
|
|
|
def->ndisks++;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetHardDisk(machine, hddBusUtf16, 1, 1, &hardDiskSS);
|
|
|
|
if (hardDiskSS)
|
|
|
|
def->ndisks++;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddBusUtf16);
|
|
|
|
|
|
|
|
if ((def->ndisks > 0) && (VIR_ALLOC_N(def->disks, def->ndisks) >= 0)) {
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
if (VIR_ALLOC(def->disks[i]) >= 0) {
|
|
|
|
def->disks[i]->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
|
|
|
def->disks[i]->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
|
|
|
def->disks[i]->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
2013-07-04 10:17:38 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDiskPM) {
|
|
|
|
PRUnichar *hddlocationUtf16 = NULL;
|
|
|
|
char *hddlocation = NULL;
|
|
|
|
PRUint32 hddType = HardDiskType_Normal;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskPM->vtbl->imedium.GetLocation((IMedium *)hardDiskPM, &hddlocationUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(hddlocationUtf16, &hddlocation);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskPM->vtbl->GetType(hardDiskPM, &hddType);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddType == HardDiskType_Immutable)
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[hddNum]->readonly = true;
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->src, hddlocation));
|
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->dst, "hda"));
|
2009-12-04 13:49:45 +00:00
|
|
|
hddNum++;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(hddlocation);
|
|
|
|
VBOX_UTF16_FREE(hddlocationUtf16);
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDiskPM);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDiskPS) {
|
|
|
|
PRUnichar *hddlocationUtf16 = NULL;
|
|
|
|
char *hddlocation = NULL;
|
|
|
|
PRUint32 hddType = HardDiskType_Normal;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskPS->vtbl->imedium.GetLocation((IMedium *)hardDiskPS, &hddlocationUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(hddlocationUtf16, &hddlocation);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskPS->vtbl->GetType(hardDiskPS, &hddType);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddType == HardDiskType_Immutable)
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[hddNum]->readonly = true;
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->src, hddlocation));
|
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->dst, "hdb"));
|
2009-12-04 13:49:45 +00:00
|
|
|
hddNum++;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(hddlocation);
|
|
|
|
VBOX_UTF16_FREE(hddlocationUtf16);
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDiskPS);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDiskSS) {
|
|
|
|
PRUnichar *hddlocationUtf16 = NULL;
|
|
|
|
char *hddlocation = NULL;
|
|
|
|
PRUint32 hddType = HardDiskType_Normal;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskSS->vtbl->imedium.GetLocation((IMedium *)hardDiskSS, &hddlocationUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(hddlocationUtf16, &hddlocation);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDiskSS->vtbl->GetType(hardDiskSS, &hddType);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddType == HardDiskType_Immutable)
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[hddNum]->readonly = true;
|
2013-05-20 09:48:34 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->src, hddlocation));
|
|
|
|
ignore_value(VIR_STRDUP(def->disks[hddNum]->dst, "hdd"));
|
|
|
|
hddNum++;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_FREE(hddlocation);
|
|
|
|
VBOX_UTF16_FREE(hddlocationUtf16);
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDiskSS);
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump IDE hdds if present */
|
|
|
|
|
|
|
|
bool error = false;
|
|
|
|
int diskCount = 0;
|
|
|
|
PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {};
|
|
|
|
PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {};
|
|
|
|
def->ndisks = 0;
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&mediumAttachments, machine, machine->vtbl->GetMediumAttachments);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* get the number of attachments */
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < mediumAttachments.count; i++) {
|
|
|
|
IMediumAttachment *imediumattach = mediumAttachments.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
if (imediumattach) {
|
|
|
|
IMedium *medium = NULL;
|
|
|
|
|
|
|
|
imediumattach->vtbl->GetMedium(imediumattach, &medium);
|
|
|
|
if (medium) {
|
|
|
|
def->ndisks++;
|
|
|
|
VBOX_RELEASE(medium);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Allocate mem, if fails return error */
|
|
|
|
if (VIR_ALLOC_N(def->disks, def->ndisks) >= 0) {
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
if (VIR_ALLOC(def->disks[i]) < 0) {
|
|
|
|
error = true;
|
|
|
|
break;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
error = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!error)
|
|
|
|
error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, maxSlotPerPort);
|
|
|
|
|
|
|
|
/* get the attachment details here */
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < mediumAttachments.count && diskCount < def->ndisks && !error; i++) {
|
|
|
|
IMediumAttachment *imediumattach = mediumAttachments.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
IStorageController *storageController = NULL;
|
|
|
|
PRUnichar *storageControllerName = NULL;
|
|
|
|
PRUint32 deviceType = DeviceType_Null;
|
|
|
|
PRUint32 storageBus = StorageBus_Null;
|
|
|
|
PRBool readOnly = PR_FALSE;
|
|
|
|
IMedium *medium = NULL;
|
|
|
|
PRUnichar *mediumLocUtf16 = NULL;
|
|
|
|
char *mediumLocUtf8 = NULL;
|
|
|
|
PRUint32 deviceInst = 0;
|
|
|
|
PRInt32 devicePort = 0;
|
|
|
|
PRInt32 deviceSlot = 0;
|
|
|
|
|
|
|
|
if (!imediumattach)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
imediumattach->vtbl->GetMedium(imediumattach, &medium);
|
|
|
|
if (!medium)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
imediumattach->vtbl->GetController(imediumattach, &storageControllerName);
|
|
|
|
if (!storageControllerName) {
|
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
machine->vtbl->GetStorageControllerByName(machine,
|
|
|
|
storageControllerName,
|
|
|
|
&storageController);
|
|
|
|
VBOX_UTF16_FREE(storageControllerName);
|
|
|
|
if (!storageController) {
|
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
continue;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
medium->vtbl->GetLocation(medium, &mediumLocUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(mediumLocUtf16, &mediumLocUtf8);
|
|
|
|
VBOX_UTF16_FREE(mediumLocUtf16);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[diskCount]->src, mediumLocUtf8));
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(mediumLocUtf8);
|
|
|
|
|
|
|
|
if (!(def->disks[diskCount]->src)) {
|
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_RELEASE(storageController);
|
|
|
|
error = true;
|
|
|
|
break;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
storageController->vtbl->GetBus(storageController, &storageBus);
|
|
|
|
if (storageBus == StorageBus_IDE) {
|
|
|
|
def->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
|
|
|
} else if (storageBus == StorageBus_SATA) {
|
|
|
|
def->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SATA;
|
|
|
|
} else if (storageBus == StorageBus_SCSI) {
|
|
|
|
def->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
|
|
|
} else if (storageBus == StorageBus_Floppy) {
|
|
|
|
def->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_FDC;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
imediumattach->vtbl->GetType(imediumattach, &deviceType);
|
|
|
|
if (deviceType == DeviceType_HardDisk)
|
|
|
|
def->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
|
|
|
else if (deviceType == DeviceType_Floppy)
|
|
|
|
def->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
|
|
|
|
else if (deviceType == DeviceType_DVD)
|
|
|
|
def->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
|
|
|
|
|
|
|
imediumattach->vtbl->GetPort(imediumattach, &devicePort);
|
|
|
|
imediumattach->vtbl->GetDevice(imediumattach, &deviceSlot);
|
2009-12-04 14:18:45 +00:00
|
|
|
def->disks[diskCount]->dst = vboxGenerateMediumName(storageBus,
|
2009-12-04 13:49:45 +00:00
|
|
|
deviceInst,
|
|
|
|
devicePort,
|
|
|
|
deviceSlot,
|
|
|
|
maxPortPerInst,
|
|
|
|
maxSlotPerPort);
|
|
|
|
if (!def->disks[diskCount]->dst) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not generate medium name for the disk "
|
|
|
|
"at: controller instance:%u, port:%d, slot:%d"),
|
|
|
|
deviceInst, devicePort, deviceSlot);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_RELEASE(storageController);
|
|
|
|
error = true;
|
|
|
|
break;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
medium->vtbl->GetReadOnly(medium, &readOnly);
|
|
|
|
if (readOnly == PR_TRUE)
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[diskCount]->readonly = true;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->disks[diskCount]->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_RELEASE(storageController);
|
|
|
|
diskCount++;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&mediumAttachments);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* cleanup on error */
|
|
|
|
if (error) {
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
VIR_FREE(def->disks[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(def->disks);
|
|
|
|
def->ndisks = 0;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-06-07 11:29:34 +00:00
|
|
|
/* shared folders */
|
|
|
|
vboxArray sharedFolders = VBOX_ARRAY_INITIALIZER;
|
|
|
|
|
|
|
|
def->nfss = 0;
|
|
|
|
|
|
|
|
vboxArrayGet(&sharedFolders, machine,
|
|
|
|
machine->vtbl->GetSharedFolders);
|
|
|
|
|
|
|
|
if (sharedFolders.count > 0) {
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC_N(def->fss, sharedFolders.count) < 0)
|
2011-06-07 11:29:34 +00:00
|
|
|
goto sharedFoldersCleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < sharedFolders.count; i++) {
|
|
|
|
ISharedFolder *sharedFolder = sharedFolders.items[i];
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
|
|
|
char *name = NULL;
|
|
|
|
PRUnichar *hostPathUtf16 = NULL;
|
|
|
|
char *hostPath = NULL;
|
|
|
|
PRBool writable = PR_FALSE;
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(def->fss[i]) < 0)
|
2011-06-07 11:29:34 +00:00
|
|
|
goto sharedFoldersCleanup;
|
|
|
|
|
|
|
|
def->fss[i]->type = VIR_DOMAIN_FS_TYPE_MOUNT;
|
|
|
|
|
|
|
|
sharedFolder->vtbl->GetHostPath(sharedFolder, &hostPathUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(hostPathUtf16, &hostPath);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->fss[i]->src, hostPath) < 0) {
|
|
|
|
VBOX_UTF8_FREE(hostPath);
|
|
|
|
VBOX_UTF16_FREE(hostPathUtf16);
|
2011-06-07 11:29:34 +00:00
|
|
|
goto sharedFoldersCleanup;
|
|
|
|
}
|
2013-05-03 12:50:19 +00:00
|
|
|
VBOX_UTF8_FREE(hostPath);
|
|
|
|
VBOX_UTF16_FREE(hostPathUtf16);
|
2011-06-07 11:29:34 +00:00
|
|
|
|
|
|
|
sharedFolder->vtbl->GetName(sharedFolder, &nameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &name);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->fss[i]->dst, name) < 0) {
|
|
|
|
VBOX_UTF8_FREE(name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2011-06-07 11:29:34 +00:00
|
|
|
goto sharedFoldersCleanup;
|
|
|
|
}
|
2013-05-03 12:50:19 +00:00
|
|
|
VBOX_UTF8_FREE(name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2011-06-07 11:29:34 +00:00
|
|
|
|
|
|
|
sharedFolder->vtbl->GetWritable(sharedFolder, &writable);
|
|
|
|
def->fss[i]->readonly = !writable;
|
|
|
|
|
|
|
|
++def->nfss;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sharedFoldersCleanup:
|
|
|
|
vboxArrayRelease(&sharedFolders);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump network cards if present */
|
|
|
|
def->nnets = 0;
|
|
|
|
/* Get which network cards are enabled */
|
|
|
|
for (i = 0; i < netAdpCnt; i++) {
|
|
|
|
INetworkAdapter *adapter = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetNetworkAdapter(machine, i, &adapter);
|
|
|
|
if (adapter) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetEnabled(adapter, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
def->nnets++;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(adapter);
|
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Allocate memory for the networkcards which are enabled */
|
|
|
|
if ((def->nnets > 0) && (VIR_ALLOC_N(def->nets, def->nnets) >= 0)) {
|
|
|
|
for (i = 0; i < def->nnets; i++) {
|
2013-07-04 10:17:38 +00:00
|
|
|
ignore_value(VIR_ALLOC(def->nets[i]));
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Now get the details about the network cards here */
|
2013-05-24 16:58:25 +00:00
|
|
|
for (i = 0; netAdpIncCnt < def->nnets && i < netAdpCnt; i++) {
|
2009-12-04 13:49:45 +00:00
|
|
|
INetworkAdapter *adapter = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetNetworkAdapter(machine, i, &adapter);
|
|
|
|
if (adapter) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetEnabled(adapter, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
PRUint32 attachmentType = NetworkAttachmentType_Null;
|
|
|
|
PRUint32 adapterType = NetworkAdapterType_Null;
|
|
|
|
PRUnichar *MACAddressUtf16 = NULL;
|
|
|
|
char *MACAddress = NULL;
|
|
|
|
char macaddr[VIR_MAC_STRING_BUFLEN] = {0};
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetAttachmentType(adapter, &attachmentType);
|
|
|
|
if (attachmentType == NetworkAttachmentType_NAT) {
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_USER;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (attachmentType == NetworkAttachmentType_Bridged) {
|
|
|
|
PRUnichar *hostIntUtf16 = NULL;
|
|
|
|
char *hostInt = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetHostInterface(adapter, &hostIntUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->GetBridgedInterface(adapter, &hostIntUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(hostIntUtf16, &hostInt);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->data.bridge.brname, hostInt));
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(hostInt);
|
|
|
|
VBOX_UTF16_FREE(hostIntUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (attachmentType == NetworkAttachmentType_Internal) {
|
|
|
|
PRUnichar *intNetUtf16 = NULL;
|
|
|
|
char *intNet = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_INTERNAL;
|
|
|
|
|
|
|
|
adapter->vtbl->GetInternalNetwork(adapter, &intNetUtf16);
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(intNetUtf16, &intNet);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->data.internal.name, intNet));
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_FREE(intNet);
|
|
|
|
VBOX_UTF16_FREE(intNetUtf16);
|
|
|
|
|
|
|
|
} else if (attachmentType == NetworkAttachmentType_HostOnly) {
|
|
|
|
PRUnichar *hostIntUtf16 = NULL;
|
|
|
|
char *hostInt = NULL;
|
|
|
|
|
|
|
|
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_NETWORK;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetHostInterface(adapter, &hostIntUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->GetHostOnlyInterface(adapter, &hostIntUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(hostIntUtf16, &hostInt);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->data.network.name, hostInt));
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_FREE(hostInt);
|
|
|
|
VBOX_UTF16_FREE(hostIntUtf16);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* default to user type i.e. NAT in VirtualBox if this
|
|
|
|
* dump is ever used to create a machine.
|
|
|
|
*/
|
|
|
|
def->nets[netAdpIncCnt]->type = VIR_DOMAIN_NET_TYPE_USER;
|
|
|
|
}
|
|
|
|
|
|
|
|
adapter->vtbl->GetAdapterType(adapter, &adapterType);
|
|
|
|
if (adapterType == NetworkAdapterType_Am79C970A) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "Am79C970A"));
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (adapterType == NetworkAdapterType_Am79C973) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "Am79C973"));
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (adapterType == NetworkAdapterType_I82540EM) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "82540EM"));
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (adapterType == NetworkAdapterType_I82545EM) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "82545EM"));
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (adapterType == NetworkAdapterType_I82543GC) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "82543GC"));
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (adapterType == NetworkAdapterType_Virtio) {
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->nets[netAdpIncCnt]->model, "virtio"));
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
adapter->vtbl->GetMACAddress(adapter, &MACAddressUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(MACAddressUtf16, &MACAddress);
|
|
|
|
snprintf(macaddr, VIR_MAC_STRING_BUFLEN,
|
|
|
|
"%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
|
|
|
|
MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3],
|
|
|
|
MACAddress[4], MACAddress[5], MACAddress[6], MACAddress[7],
|
|
|
|
MACAddress[8], MACAddress[9], MACAddress[10], MACAddress[11]);
|
|
|
|
|
|
|
|
/* XXX some real error handling here some day ... */
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrParse(macaddr, &def->nets[netAdpIncCnt]->mac) < 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
netAdpIncCnt++;
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(MACAddressUtf16);
|
|
|
|
VBOX_UTF8_FREE(MACAddress);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(adapter);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump sound card if active */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Set def->nsounds to one as VirtualBox currently supports
|
|
|
|
* only one sound card
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAudioAdapter(machine, &audioAdapter);
|
|
|
|
if (audioAdapter) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
|
|
|
|
|
|
|
audioAdapter->vtbl->GetEnabled(audioAdapter, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
PRUint32 audioController = AudioControllerType_AC97;
|
|
|
|
|
|
|
|
def->nsounds = 1;
|
|
|
|
if (VIR_ALLOC_N(def->sounds, def->nsounds) >= 0) {
|
|
|
|
if (VIR_ALLOC(def->sounds[0]) >= 0) {
|
|
|
|
audioAdapter->vtbl->GetAudioController(audioAdapter, &audioController);
|
|
|
|
if (audioController == AudioControllerType_SB16) {
|
|
|
|
def->sounds[0]->model = VIR_DOMAIN_SOUND_MODEL_SB16;
|
|
|
|
} else if (audioController == AudioControllerType_AC97) {
|
|
|
|
def->sounds[0]->model = VIR_DOMAIN_SOUND_MODEL_AC97;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
VIR_FREE(def->sounds);
|
|
|
|
def->nsounds = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
def->nsounds = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VBOX_RELEASE(audioAdapter);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump CDROM/DVD if the drive is attached and has DVD/CD in it */
|
|
|
|
machine->vtbl->GetDVDDrive(machine, &dvdDrive);
|
|
|
|
if (dvdDrive) {
|
|
|
|
PRUint32 state = DriveState_Null;
|
|
|
|
|
|
|
|
dvdDrive->vtbl->GetState(dvdDrive, &state);
|
|
|
|
if (state == DriveState_ImageMounted) {
|
|
|
|
IDVDImage *dvdImage = NULL;
|
|
|
|
|
|
|
|
dvdDrive->vtbl->GetImage(dvdDrive, &dvdImage);
|
|
|
|
if (dvdImage) {
|
|
|
|
PRUnichar *locationUtf16 = NULL;
|
|
|
|
char *location = NULL;
|
|
|
|
|
|
|
|
dvdImage->vtbl->imedium.GetLocation((IMedium *)dvdImage, &locationUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(locationUtf16, &location);
|
|
|
|
|
|
|
|
def->ndisks++;
|
|
|
|
if (VIR_REALLOC_N(def->disks, def->ndisks) >= 0) {
|
|
|
|
if (VIR_ALLOC(def->disks[def->ndisks - 1]) >= 0) {
|
|
|
|
def->disks[def->ndisks - 1]->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
|
|
|
def->disks[def->ndisks - 1]->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
|
|
|
def->disks[def->ndisks - 1]->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[def->ndisks - 1]->readonly = true;
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[def->ndisks - 1]->src, location));
|
|
|
|
ignore_value(VIR_STRDUP(def->disks[def->ndisks - 1]->dst, "hdc"));
|
|
|
|
def->ndisks--;
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
2009-12-04 13:49:45 +00:00
|
|
|
def->ndisks--;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
2009-12-04 13:49:45 +00:00
|
|
|
def->ndisks--;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_FREE(location);
|
|
|
|
VBOX_UTF16_FREE(locationUtf16);
|
|
|
|
VBOX_MEDIUM_RELEASE(dvdImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(dvdDrive);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump Floppy if the drive is attached and has floppy in it */
|
|
|
|
machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
|
|
|
|
if (floppyDrive) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
|
|
|
|
|
|
|
floppyDrive->vtbl->GetEnabled(floppyDrive, &enabled);
|
|
|
|
if (enabled) {
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state = DriveState_Null;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
floppyDrive->vtbl->GetState(floppyDrive, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
if (state == DriveState_ImageMounted) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IFloppyImage *floppyImage = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
floppyDrive->vtbl->GetImage(floppyDrive, &floppyImage);
|
|
|
|
if (floppyImage) {
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUnichar *locationUtf16 = NULL;
|
|
|
|
char *location = NULL;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
floppyImage->vtbl->imedium.GetLocation((IMedium *)floppyImage, &locationUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(locationUtf16, &location);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
def->ndisks++;
|
|
|
|
if (VIR_REALLOC_N(def->disks, def->ndisks) >= 0) {
|
|
|
|
if (VIR_ALLOC(def->disks[def->ndisks - 1]) >= 0) {
|
2009-12-04 13:49:45 +00:00
|
|
|
def->disks[def->ndisks - 1]->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
|
|
|
|
def->disks[def->ndisks - 1]->bus = VIR_DOMAIN_DISK_BUS_FDC;
|
2009-04-17 16:09:07 +00:00
|
|
|
def->disks[def->ndisks - 1]->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
2013-04-10 11:23:56 +00:00
|
|
|
def->disks[def->ndisks - 1]->readonly = false;
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->disks[def->ndisks - 1]->src, location));
|
|
|
|
ignore_value(VIR_STRDUP(def->disks[def->ndisks - 1]->dst, "fda"));
|
|
|
|
def->ndisks--;
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
|
|
|
def->ndisks--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
def->ndisks--;
|
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(location);
|
|
|
|
VBOX_UTF16_FREE(locationUtf16);
|
|
|
|
VBOX_MEDIUM_RELEASE(floppyImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(floppyDrive);
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* dump serial port if active */
|
|
|
|
def->nserials = 0;
|
|
|
|
/* Get which serial ports are enabled/active */
|
|
|
|
for (i = 0; i < serialPortCount; i++) {
|
|
|
|
ISerialPort *serialPort = NULL;
|
|
|
|
|
|
|
|
machine->vtbl->GetSerialPort(machine, i, &serialPort);
|
|
|
|
if (serialPort) {
|
2009-04-17 16:09:07 +00:00
|
|
|
PRBool enabled = PR_FALSE;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
serialPort->vtbl->GetEnabled(serialPort, &enabled);
|
2009-04-17 16:09:07 +00:00
|
|
|
if (enabled) {
|
2009-12-04 13:49:45 +00:00
|
|
|
def->nserials++;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(serialPort);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Allocate memory for the serial ports which are enabled */
|
|
|
|
if ((def->nserials > 0) && (VIR_ALLOC_N(def->serials, def->nserials) >= 0)) {
|
|
|
|
for (i = 0; i < def->nserials; i++) {
|
2013-07-04 10:17:38 +00:00
|
|
|
ignore_value(VIR_ALLOC(def->serials[i]));
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Now get the details about the serial ports here */
|
2013-05-24 16:58:25 +00:00
|
|
|
for (i = 0;
|
|
|
|
serialPortIncCount < def->nserials && i < serialPortCount;
|
|
|
|
i++) {
|
2009-12-04 13:49:45 +00:00
|
|
|
ISerialPort *serialPort = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetSerialPort(machine, i, &serialPort);
|
|
|
|
if (serialPort) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
serialPort->vtbl->GetEnabled(serialPort, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
PRUint32 hostMode = PortMode_Disconnected;
|
|
|
|
PRUint32 IOBase = 0;
|
|
|
|
PRUint32 IRQ = 0;
|
|
|
|
PRUnichar *pathUtf16 = NULL;
|
|
|
|
char *path = NULL;
|
|
|
|
|
|
|
|
serialPort->vtbl->GetHostMode(serialPort, &hostMode);
|
|
|
|
if (hostMode == PortMode_HostPipe) {
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
def->serials[serialPortIncCount]->source.type = VIR_DOMAIN_CHR_TYPE_PIPE;
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (hostMode == PortMode_HostDevice) {
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
def->serials[serialPortIncCount]->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3000000
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (hostMode == PortMode_RawFile) {
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
def->serials[serialPortIncCount]->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
def->serials[serialPortIncCount]->source.type = VIR_DOMAIN_CHR_TYPE_NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-07-13 19:05:34 +00:00
|
|
|
def->serials[serialPortIncCount]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
serialPort->vtbl->GetIRQ(serialPort, &IRQ);
|
|
|
|
serialPort->vtbl->GetIOBase(serialPort, &IOBase);
|
|
|
|
if ((IRQ == 4) && (IOBase == 1016)) {
|
|
|
|
def->serials[serialPortIncCount]->target.port = 0;
|
|
|
|
} else if ((IRQ == 3) && (IOBase == 760)) {
|
|
|
|
def->serials[serialPortIncCount]->target.port = 1;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
serialPort->vtbl->GetPath(serialPort, &pathUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (pathUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(pathUtf16, &path);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->serials[serialPortIncCount]->source.data.file.path, path));
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
serialPortIncCount++;
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(pathUtf16);
|
|
|
|
VBOX_UTF8_FREE(path);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(serialPort);
|
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump parallel ports if active */
|
|
|
|
def->nparallels = 0;
|
|
|
|
/* Get which parallel ports are enabled/active */
|
|
|
|
for (i = 0; i < parallelPortCount; i++) {
|
|
|
|
IParallelPort *parallelPort = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetParallelPort(machine, i, ¶llelPort);
|
|
|
|
if (parallelPort) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
parallelPort->vtbl->GetEnabled(parallelPort, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
def->nparallels++;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(parallelPort);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Allocate memory for the parallel ports which are enabled */
|
|
|
|
if ((def->nparallels > 0) && (VIR_ALLOC_N(def->parallels, def->nparallels) >= 0)) {
|
|
|
|
for (i = 0; i < def->nparallels; i++) {
|
2013-07-04 10:17:38 +00:00
|
|
|
ignore_value(VIR_ALLOC(def->parallels[i]));
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Now get the details about the parallel ports here */
|
2013-05-24 16:58:25 +00:00
|
|
|
for (i = 0;
|
|
|
|
parallelPortIncCount < def->nparallels &&
|
|
|
|
i < parallelPortCount;
|
|
|
|
i++) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IParallelPort *parallelPort = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetParallelPort(machine, i, ¶llelPort);
|
|
|
|
if (parallelPort) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
parallelPort->vtbl->GetEnabled(parallelPort, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
PRUint32 IOBase = 0;
|
|
|
|
PRUint32 IRQ = 0;
|
|
|
|
PRUnichar *pathUtf16 = NULL;
|
|
|
|
char *path = NULL;
|
|
|
|
|
|
|
|
parallelPort->vtbl->GetIRQ(parallelPort, &IRQ);
|
|
|
|
parallelPort->vtbl->GetIOBase(parallelPort, &IOBase);
|
|
|
|
if ((IRQ == 7) && (IOBase == 888)) {
|
|
|
|
def->parallels[parallelPortIncCount]->target.port = 0;
|
|
|
|
} else if ((IRQ == 5) && (IOBase == 632)) {
|
|
|
|
def->parallels[parallelPortIncCount]->target.port = 1;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
def->parallels[parallelPortIncCount]->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
|
2010-07-13 19:05:34 +00:00
|
|
|
def->parallels[parallelPortIncCount]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
parallelPort->vtbl->GetPath(parallelPort, &pathUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(pathUtf16, &path);
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(def->parallels[parallelPortIncCount]->source.data.file.path, path));
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
parallelPortIncCount++;
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(pathUtf16);
|
|
|
|
VBOX_UTF8_FREE(path);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(parallelPort);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* dump USB devices/filters if active */
|
2013-11-21 14:41:05 +00:00
|
|
|
vboxHostDeviceGetXMLDesc(data, def, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* all done so set gotAllABoutDef and pass def to virDomainDefFormat
|
|
|
|
* to generate XML for it
|
|
|
|
*/
|
|
|
|
gotAllABoutDef = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
machine = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gotAllABoutDef == 0)
|
2010-02-09 18:58:01 +00:00
|
|
|
ret = virDomainDefFormat(def, flags);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectListDefinedDomains(virConnectPtr conn, char ** const names, int maxnames) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
char *machineName = NULL;
|
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
|
|
|
PRUint32 state;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i, j;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of Defined Domains, rc=%08x"),
|
|
|
|
(unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
memset(names, 0, sizeof(names[i]) * maxnames);
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = 0;
|
|
|
|
for (i = 0, j = 0; (i < machines.count) && (j < maxnames); i++) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (machine) {
|
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state < MachineState_FirstOnline) ||
|
|
|
|
(state > MachineState_LastOnline)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineName);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(names[j], machineName) < 0) {
|
|
|
|
VBOX_UTF16_FREE(machineNameUtf16);
|
|
|
|
VBOX_UTF8_FREE(machineName);
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
for (j = 0; j < maxnames; j++)
|
2009-12-04 13:49:45 +00:00
|
|
|
VIR_FREE(names[j]);
|
|
|
|
ret = -1;
|
|
|
|
goto cleanup;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2013-05-03 12:50:19 +00:00
|
|
|
VBOX_UTF16_FREE(machineNameUtf16);
|
|
|
|
VBOX_UTF8_FREE(machineName);
|
2010-12-16 22:33:14 +00:00
|
|
|
j++;
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectNumOfDefinedDomains(virConnectPtr conn) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state = MachineState_Null;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get number of Defined Domains, rc=%08x"),
|
|
|
|
(unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = 0;
|
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (machine) {
|
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state < MachineState_FirstOnline) ||
|
|
|
|
(state > MachineState_LastOnline)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-08-18 23:20:07 +00:00
|
|
|
|
|
|
|
static int
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
vboxStartMachine(virDomainPtr dom, int maxDomID, IMachine *machine,
|
2010-12-27 22:35:30 +00:00
|
|
|
vboxIID *iid ATTRIBUTE_UNUSED /* >= 4.0 */)
|
2010-08-18 23:20:07 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
int vrdpPresent = 0;
|
|
|
|
int sdlPresent = 0;
|
|
|
|
int guiPresent = 0;
|
|
|
|
char *guiDisplay = NULL;
|
|
|
|
char *sdlDisplay = NULL;
|
|
|
|
PRUnichar *keyTypeUtf16 = NULL;
|
|
|
|
PRUnichar *valueTypeUtf16 = NULL;
|
|
|
|
char *valueTypeUtf8 = NULL;
|
|
|
|
PRUnichar *keyDislpayUtf16 = NULL;
|
|
|
|
PRUnichar *valueDisplayUtf16 = NULL;
|
|
|
|
char *valueDisplayUtf8 = NULL;
|
|
|
|
IProgress *progress = NULL;
|
|
|
|
PRUnichar *env = NULL;
|
|
|
|
PRUnichar *sessionType = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
|
|
|
|
machine->vtbl->GetExtraData(machine, keyTypeUtf16, &valueTypeUtf16);
|
|
|
|
VBOX_UTF16_FREE(keyTypeUtf16);
|
|
|
|
|
|
|
|
if (valueTypeUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(valueTypeUtf16, &valueTypeUtf8);
|
|
|
|
VBOX_UTF16_FREE(valueTypeUtf16);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (STREQ(valueTypeUtf8, "sdl") || STREQ(valueTypeUtf8, "gui")) {
|
2010-08-18 23:20:07 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
|
|
|
|
machine->vtbl->GetExtraData(machine, keyDislpayUtf16,
|
|
|
|
&valueDisplayUtf16);
|
|
|
|
VBOX_UTF16_FREE(keyDislpayUtf16);
|
|
|
|
|
|
|
|
if (valueDisplayUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(valueDisplayUtf16, &valueDisplayUtf8);
|
|
|
|
VBOX_UTF16_FREE(valueDisplayUtf16);
|
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
if (strlen(valueDisplayUtf8) <= 0)
|
2010-08-18 23:20:07 +00:00
|
|
|
VBOX_UTF8_FREE(valueDisplayUtf8);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STREQ(valueTypeUtf8, "sdl")) {
|
|
|
|
sdlPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(sdlDisplay, valueDisplayUtf8) < 0) {
|
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* sdlDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
|
|
|
*/
|
2010-08-18 23:20:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STREQ(valueTypeUtf8, "gui")) {
|
|
|
|
guiPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(guiDisplay, valueDisplayUtf8) < 0) {
|
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* guiDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
|
|
|
*/
|
2010-08-18 23:20:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STREQ(valueTypeUtf8, "vrdp")) {
|
|
|
|
vrdpPresent = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!vrdpPresent && !sdlPresent && !guiPresent) {
|
|
|
|
/* if nothing is selected it means either the machine xml
|
|
|
|
* file is really old or some values are missing so fallback
|
|
|
|
*/
|
|
|
|
guiPresent = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_FREE(valueTypeUtf8);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
guiPresent = 1;
|
|
|
|
}
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(valueDisplayUtf8);
|
2010-08-18 23:20:07 +00:00
|
|
|
|
|
|
|
if (guiPresent) {
|
|
|
|
if (guiDisplay) {
|
2010-08-18 23:31:39 +00:00
|
|
|
char *displayutf8;
|
2013-07-04 10:17:38 +00:00
|
|
|
if (virAsprintf(&displayutf8, "DISPLAY=%s", guiDisplay) >= 0) {
|
2010-08-18 23:31:39 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(displayutf8, &env);
|
|
|
|
VIR_FREE(displayutf8);
|
|
|
|
}
|
2010-08-18 23:20:07 +00:00
|
|
|
VIR_FREE(guiDisplay);
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("gui", &sessionType);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sdlPresent) {
|
|
|
|
if (sdlDisplay) {
|
2010-08-18 23:31:39 +00:00
|
|
|
char *displayutf8;
|
2013-07-04 10:17:38 +00:00
|
|
|
if (virAsprintf(&displayutf8, "DISPLAY=%s", sdlDisplay) >= 0) {
|
2010-08-18 23:31:39 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(displayutf8, &env);
|
|
|
|
VIR_FREE(displayutf8);
|
|
|
|
}
|
2010-08-18 23:20:07 +00:00
|
|
|
VIR_FREE(sdlDisplay);
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("sdl", &sessionType);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vrdpPresent) {
|
|
|
|
VBOX_UTF8_TO_UTF16("vrdp", &sessionType);
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-08-18 23:20:07 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenRemoteSession(data->vboxObj,
|
|
|
|
data->vboxSession,
|
2010-12-23 16:25:56 +00:00
|
|
|
iid->value,
|
2010-08-18 23:20:07 +00:00
|
|
|
sessionType,
|
|
|
|
env,
|
2012-10-17 09:23:12 +00:00
|
|
|
&progress);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = machine->vtbl->LaunchVMProcess(machine, data->vboxSession,
|
|
|
|
sessionType, env, &progress);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
|
2010-08-18 23:20:07 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("OpenRemoteSession/LaunchVMProcess failed, domain can't be started"));
|
2010-08-18 23:20:07 +00:00
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
PRBool completed = 0;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2010-08-18 23:20:07 +00:00
|
|
|
nsresult resultCode;
|
|
|
|
#else
|
|
|
|
PRInt32 resultCode;
|
|
|
|
#endif
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
rc = progress->vtbl->GetCompleted(progress, &completed);
|
|
|
|
if (NS_FAILED(rc)) {
|
|
|
|
/* error */
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
progress->vtbl->GetResultCode(progress, &resultCode);
|
|
|
|
if (NS_FAILED(resultCode)) {
|
|
|
|
/* error */
|
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
/* all ok set the domid */
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
dom->id = maxDomID + 1;
|
2010-08-18 23:20:07 +00:00
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2010-08-18 23:20:07 +00:00
|
|
|
|
|
|
|
VBOX_UTF16_FREE(env);
|
|
|
|
VBOX_UTF16_FREE(sessionType);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-06-10 15:55:36 +00:00
|
|
|
static int vboxDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN] = {0};
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-06-10 15:55:36 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
if (!dom->name) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Error while reading the domain name"));
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of machines, rc=%08x"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machines.count; ++i) {
|
|
|
|
IMachine *machine = machines.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRBool isAccessible = PR_FALSE;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!machine)
|
|
|
|
continue;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
if (NS_FAILED(rc))
|
2009-12-04 13:49:45 +00:00
|
|
|
continue;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDToUUID(&iid, uuid);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (memcmp(dom->uuid, uuid, VIR_UUID_BUFLEN) == 0) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 state = MachineState_Null;
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((state == MachineState_PoweredOff) ||
|
|
|
|
(state == MachineState_Saved) ||
|
|
|
|
(state == MachineState_Aborted)) {
|
2010-12-23 16:25:56 +00:00
|
|
|
ret = vboxStartMachine(dom, i, machine, &iid);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
2012-09-12 16:54:42 +00:00
|
|
|
_("machine is not in "
|
|
|
|
"poweroff|saved|aborted state, so "
|
|
|
|
"couldn't start it"));
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = -1;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (ret != -1)
|
|
|
|
break;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Do the cleanup and take care you dont leak any memory */
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&machines);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
cleanup:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-06-10 15:55:36 +00:00
|
|
|
static int vboxDomainCreate(virDomainPtr dom) {
|
|
|
|
return vboxDomainCreateWithFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxSetBootDeviceOrder(virDomainDefPtr def, vboxGlobalData *data,
|
|
|
|
IMachine *machine)
|
|
|
|
{
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
|
|
|
PRUint32 maxBootPosition = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("def->os.type %s", def->os.type);
|
2012-12-10 22:28:09 +00:00
|
|
|
VIR_DEBUG("def->os.arch %s", virArchToString(def->os.arch));
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("def->os.machine %s", def->os.machine);
|
2012-09-26 15:12:28 +00:00
|
|
|
VIR_DEBUG("def->os.nBootDevs %zu", def->os.nBootDevs);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("def->os.bootDevs[0] %d", def->os.bootDevs[0]);
|
|
|
|
VIR_DEBUG("def->os.bootDevs[1] %d", def->os.bootDevs[1]);
|
|
|
|
VIR_DEBUG("def->os.bootDevs[2] %d", def->os.bootDevs[2]);
|
|
|
|
VIR_DEBUG("def->os.bootDevs[3] %d", def->os.bootDevs[3]);
|
|
|
|
VIR_DEBUG("def->os.init %s", def->os.init);
|
|
|
|
VIR_DEBUG("def->os.kernel %s", def->os.kernel);
|
|
|
|
VIR_DEBUG("def->os.initrd %s", def->os.initrd);
|
|
|
|
VIR_DEBUG("def->os.cmdline %s", def->os.cmdline);
|
|
|
|
VIR_DEBUG("def->os.root %s", def->os.root);
|
|
|
|
VIR_DEBUG("def->os.loader %s", def->os.loader);
|
|
|
|
VIR_DEBUG("def->os.bootloader %s", def->os.bootloader);
|
|
|
|
VIR_DEBUG("def->os.bootloaderArgs %s", def->os.bootloaderArgs);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetMaxBootPosition(systemProperties,
|
|
|
|
&maxBootPosition);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
/* Clear the defaults first */
|
|
|
|
for (i = 0; i < maxBootPosition; i++) {
|
|
|
|
machine->vtbl->SetBootOrder(machine, i+1, DeviceType_Null);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
for (i = 0; (i < def->os.nBootDevs) && (i < maxBootPosition); i++) {
|
|
|
|
PRUint32 device = DeviceType_Null;
|
|
|
|
|
|
|
|
if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_FLOPPY) {
|
|
|
|
device = DeviceType_Floppy;
|
|
|
|
} else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_CDROM) {
|
|
|
|
device = DeviceType_DVD;
|
|
|
|
} else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_DISK) {
|
|
|
|
device = DeviceType_HardDisk;
|
|
|
|
} else if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
|
|
|
|
device = DeviceType_Network;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetBootOrder(machine, i+1, device);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-08-31 18:01:45 +00:00
|
|
|
nsresult rc;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->ndisks == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) type: %d", i, def->disks[i]->type);
|
|
|
|
VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]->device);
|
|
|
|
VIR_DEBUG("disk(%zu) bus: %d", i, def->disks[i]->bus);
|
|
|
|
VIR_DEBUG("disk(%zu) src: %s", i, def->disks[i]->src);
|
|
|
|
VIR_DEBUG("disk(%zu) dst: %s", i, def->disks[i]->dst);
|
|
|
|
VIR_DEBUG("disk(%zu) driverName: %s", i, def->disks[i]->driverName);
|
|
|
|
VIR_DEBUG("disk(%zu) driverType: %s", i,
|
2012-10-15 21:47:42 +00:00
|
|
|
virStorageFileFormatTypeToString(def->disks[i]->format));
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) cachemode: %d", i, def->disks[i]->cachemode);
|
|
|
|
VIR_DEBUG("disk(%zu) readonly: %s", i, (def->disks[i]->readonly
|
2010-08-31 18:01:45 +00:00
|
|
|
? "True" : "False"));
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) shared: %s", i, (def->disks[i]->shared
|
2010-08-31 18:01:45 +00:00
|
|
|
? "True" : "False"));
|
|
|
|
|
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
|
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
def->disks[i]->src != NULL) {
|
|
|
|
IDVDDrive *dvdDrive = NULL;
|
|
|
|
/* Currently CDROM/DVD Drive is always IDE
|
|
|
|
* Secondary Master so neglecting the following
|
|
|
|
* parameters:
|
|
|
|
* def->disks[i]->bus
|
|
|
|
* def->disks[i]->dst
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->GetDVDDrive(machine, &dvdDrive);
|
|
|
|
if (dvdDrive) {
|
|
|
|
IDVDImage *dvdImage = NULL;
|
|
|
|
PRUnichar *dvdfileUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID dvduuid = VBOX_IID_INITIALIZER;
|
|
|
|
vboxIID dvdemptyuuid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->disks[i]->src, &dvdfileUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->FindDVDImage(data->vboxObj,
|
|
|
|
dvdfileUtf16, &dvdImage);
|
|
|
|
if (!dvdImage) {
|
|
|
|
data->vboxObj->vtbl->OpenDVDImage(data->vboxObj,
|
|
|
|
dvdfileUtf16,
|
2010-12-23 16:25:56 +00:00
|
|
|
dvdemptyuuid.value,
|
2010-08-31 18:01:45 +00:00
|
|
|
&dvdImage);
|
|
|
|
}
|
|
|
|
if (dvdImage) {
|
|
|
|
rc = dvdImage->vtbl->imedium.GetId((IMedium *)dvdImage,
|
2010-12-23 16:25:56 +00:00
|
|
|
&dvduuid.value);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to "
|
|
|
|
"be attached to cdrom: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = dvdDrive->vtbl->MountImage(dvdDrive, dvduuid.value);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file to cdrom: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("CD/DVDImage UUID:", dvduuid.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(dvdImage);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&dvduuid);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(dvdfileUtf16);
|
|
|
|
VBOX_RELEASE(dvdDrive);
|
|
|
|
}
|
|
|
|
} else if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
|
|
|
}
|
|
|
|
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
|
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
def->disks[i]->src != NULL) {
|
|
|
|
IHardDisk *hardDisk = NULL;
|
|
|
|
PRUnichar *hddfileUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID hdduuid = VBOX_IID_INITIALIZER;
|
2010-08-31 18:01:45 +00:00
|
|
|
PRUnichar *hddEmpty = NULL;
|
|
|
|
/* Current Limitation: Harddisk can't be connected to
|
|
|
|
* Secondary Master as Secondary Master is always used
|
|
|
|
* for CD/DVD Drive, so don't connect the harddisk if it
|
|
|
|
* is requested to be connected to Secondary master
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->disks[i]->src, &hddfileUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16("", &hddEmpty);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddfileUtf16,
|
|
|
|
&hardDisk);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (!hardDisk) {
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION == 2002000
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->OpenHardDisk(data->vboxObj,
|
|
|
|
hddfileUtf16,
|
|
|
|
AccessMode_ReadWrite,
|
|
|
|
&hardDisk);
|
2010-03-09 18:22:22 +00:00
|
|
|
# else
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->OpenHardDisk(data->vboxObj,
|
|
|
|
hddfileUtf16,
|
|
|
|
AccessMode_ReadWrite,
|
|
|
|
0,
|
|
|
|
hddEmpty,
|
|
|
|
0,
|
|
|
|
hddEmpty,
|
|
|
|
&hardDisk);
|
2010-03-09 18:22:22 +00:00
|
|
|
# endif
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (hardDisk) {
|
|
|
|
rc = hardDisk->vtbl->imedium.GetId((IMedium *)hardDisk,
|
2010-12-23 16:25:56 +00:00
|
|
|
&hdduuid.value);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to be "
|
|
|
|
"attached as harddisk: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
if (def->disks[i]->readonly) {
|
|
|
|
hardDisk->vtbl->SetType(hardDisk,
|
|
|
|
HardDiskType_Immutable);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("setting harddisk to readonly");
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (!def->disks[i]->readonly) {
|
|
|
|
hardDisk->vtbl->SetType(hardDisk,
|
|
|
|
HardDiskType_Normal);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("setting harddisk type to normal");
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_IDE) {
|
|
|
|
if (STREQ(def->disks[i]->dst, "hdc")) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("Not connecting harddisk to hdc as hdc"
|
2010-08-31 18:01:45 +00:00
|
|
|
" is taken by CD/DVD Drive");
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-08-31 18:01:45 +00:00
|
|
|
PRInt32 channel = 0;
|
|
|
|
PRInt32 device = 0;
|
|
|
|
PRUnichar *hddcnameUtf16 = NULL;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
char *hddcname;
|
|
|
|
ignore_value(VIR_STRDUP(hddcname, "IDE"));
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(hddcname, &hddcnameUtf16);
|
|
|
|
VIR_FREE(hddcname);
|
|
|
|
|
|
|
|
if (STREQ(def->disks[i]->dst, "hda")) {
|
|
|
|
channel = 0;
|
|
|
|
device = 0;
|
|
|
|
} else if (STREQ(def->disks[i]->dst, "hdb")) {
|
|
|
|
channel = 0;
|
|
|
|
device = 1;
|
|
|
|
} else if (STREQ(def->disks[i]->dst, "hdd")) {
|
|
|
|
channel = 1;
|
|
|
|
device = 1;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
rc = machine->vtbl->AttachHardDisk(machine,
|
2010-12-23 16:25:56 +00:00
|
|
|
hdduuid.value,
|
2010-08-31 18:01:45 +00:00
|
|
|
hddcnameUtf16,
|
|
|
|
channel,
|
|
|
|
device);
|
|
|
|
VBOX_UTF16_FREE(hddcnameUtf16);
|
|
|
|
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file as "
|
|
|
|
"harddisk: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("Attached HDD with UUID", hdduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hdduuid);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddEmpty);
|
|
|
|
VBOX_UTF16_FREE(hddfileUtf16);
|
|
|
|
} else if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
|
|
|
}
|
|
|
|
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
|
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
def->disks[i]->src != NULL) {
|
|
|
|
IFloppyDrive *floppyDrive;
|
|
|
|
machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
|
|
|
|
if (floppyDrive) {
|
|
|
|
rc = floppyDrive->vtbl->SetEnabled(floppyDrive, 1);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
IFloppyImage *floppyImage = NULL;
|
|
|
|
PRUnichar *fdfileUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID fduuid = VBOX_IID_INITIALIZER;
|
|
|
|
vboxIID fdemptyuuid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->disks[i]->src, &fdfileUtf16);
|
|
|
|
rc = data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
|
|
|
|
fdfileUtf16,
|
|
|
|
&floppyImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (!floppyImage) {
|
|
|
|
data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
|
|
|
|
fdfileUtf16,
|
2010-12-23 16:25:56 +00:00
|
|
|
fdemptyuuid.value,
|
2010-08-31 18:01:45 +00:00
|
|
|
&floppyImage);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (floppyImage) {
|
|
|
|
rc = floppyImage->vtbl->imedium.GetId((IMedium *)floppyImage,
|
2010-12-23 16:25:56 +00:00
|
|
|
&fduuid.value);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to "
|
|
|
|
"be attached to floppy drive: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
rc = floppyDrive->vtbl->MountImage(floppyDrive,
|
2010-12-23 16:25:56 +00:00
|
|
|
fduuid.value);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file to "
|
|
|
|
"floppy drive: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("floppyImage UUID", fduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_MEDIUM_RELEASE(floppyImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&fduuid);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(fdfileUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(floppyDrive);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
PRUint32 maxPortPerInst[StorageBus_Floppy + 1] = {};
|
|
|
|
PRUint32 maxSlotPerPort[StorageBus_Floppy + 1] = {};
|
|
|
|
PRUnichar *storageCtlName = NULL;
|
|
|
|
bool error = false;
|
|
|
|
|
|
|
|
/* get the max port/slots/etc for the given storage bus */
|
|
|
|
error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst,
|
|
|
|
maxSlotPerPort);
|
|
|
|
|
|
|
|
/* add a storage controller for the mediums to be attached */
|
|
|
|
/* this needs to change when multiple controller are supported for
|
|
|
|
* ver > 3.1 */
|
2009-12-04 13:49:45 +00:00
|
|
|
{
|
2010-08-31 18:01:45 +00:00
|
|
|
IStorageController *storageCtl = NULL;
|
|
|
|
PRUnichar *sName = NULL;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("IDE Controller", &sName);
|
|
|
|
machine->vtbl->AddStorageController(machine,
|
|
|
|
sName,
|
|
|
|
StorageBus_IDE,
|
|
|
|
&storageCtl);
|
|
|
|
VBOX_UTF16_FREE(sName);
|
|
|
|
VBOX_RELEASE(storageCtl);
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("SATA Controller", &sName);
|
|
|
|
machine->vtbl->AddStorageController(machine,
|
|
|
|
sName,
|
|
|
|
StorageBus_SATA,
|
|
|
|
&storageCtl);
|
|
|
|
VBOX_UTF16_FREE(sName);
|
|
|
|
VBOX_RELEASE(storageCtl);
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("SCSI Controller", &sName);
|
|
|
|
machine->vtbl->AddStorageController(machine,
|
|
|
|
sName,
|
|
|
|
StorageBus_SCSI,
|
|
|
|
&storageCtl);
|
|
|
|
VBOX_UTF16_FREE(sName);
|
|
|
|
VBOX_RELEASE(storageCtl);
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("Floppy Controller", &sName);
|
|
|
|
machine->vtbl->AddStorageController(machine,
|
|
|
|
sName,
|
|
|
|
StorageBus_Floppy,
|
|
|
|
&storageCtl);
|
|
|
|
VBOX_UTF16_FREE(sName);
|
|
|
|
VBOX_RELEASE(storageCtl);
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
for (i = 0; i < def->ndisks && !error; i++) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) type: %d", i, def->disks[i]->type);
|
|
|
|
VIR_DEBUG("disk(%zu) device: %d", i, def->disks[i]->device);
|
|
|
|
VIR_DEBUG("disk(%zu) bus: %d", i, def->disks[i]->bus);
|
|
|
|
VIR_DEBUG("disk(%zu) src: %s", i, def->disks[i]->src);
|
|
|
|
VIR_DEBUG("disk(%zu) dst: %s", i, def->disks[i]->dst);
|
|
|
|
VIR_DEBUG("disk(%zu) driverName: %s", i, def->disks[i]->driverName);
|
|
|
|
VIR_DEBUG("disk(%zu) driverType: %s", i,
|
2012-10-15 21:47:42 +00:00
|
|
|
virStorageFileFormatTypeToString(def->disks[i]->format));
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) cachemode: %d", i, def->disks[i]->cachemode);
|
|
|
|
VIR_DEBUG("disk(%zu) readonly: %s", i, (def->disks[i]->readonly
|
2010-08-31 18:01:45 +00:00
|
|
|
? "True" : "False"));
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("disk(%zu) shared: %s", i, (def->disks[i]->shared
|
2010-08-31 18:01:45 +00:00
|
|
|
? "True" : "False"));
|
|
|
|
|
|
|
|
if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
def->disks[i]->src != NULL) {
|
|
|
|
IMedium *medium = NULL;
|
|
|
|
PRUnichar *mediumUUID = NULL;
|
|
|
|
PRUnichar *mediumFileUtf16 = NULL;
|
|
|
|
PRUint32 storageBus = StorageBus_Null;
|
|
|
|
PRUint32 deviceType = DeviceType_Null;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
PRUint32 accessMode = AccessMode_ReadOnly;
|
2011-04-14 12:10:36 +00:00
|
|
|
# endif
|
2010-08-31 18:01:45 +00:00
|
|
|
PRInt32 deviceInst = 0;
|
|
|
|
PRInt32 devicePort = 0;
|
|
|
|
PRInt32 deviceSlot = 0;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(def->disks[i]->src, &mediumFileUtf16);
|
|
|
|
|
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
|
|
|
deviceType = DeviceType_HardDisk;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4000000
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->FindHardDisk(data->vboxObj,
|
|
|
|
mediumFileUtf16, &medium);
|
2011-04-14 12:10:36 +00:00
|
|
|
# else
|
|
|
|
accessMode = AccessMode_ReadWrite;
|
2010-12-27 22:35:30 +00:00
|
|
|
# endif
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
|
|
|
deviceType = DeviceType_DVD;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4000000
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->FindDVDImage(data->vboxObj,
|
|
|
|
mediumFileUtf16, &medium);
|
2011-04-14 12:10:36 +00:00
|
|
|
# else
|
|
|
|
accessMode = AccessMode_ReadOnly;
|
2010-12-27 22:35:30 +00:00
|
|
|
# endif
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
|
|
|
deviceType = DeviceType_Floppy;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4000000
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
|
|
|
|
mediumFileUtf16, &medium);
|
2011-04-14 12:10:36 +00:00
|
|
|
# else
|
|
|
|
accessMode = AccessMode_ReadWrite;
|
2010-12-27 22:35:30 +00:00
|
|
|
# endif
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
VBOX_UTF16_FREE(mediumFileUtf16);
|
|
|
|
continue;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
data->vboxObj->vtbl->FindMedium(data->vboxObj, mediumFileUtf16,
|
|
|
|
deviceType, &medium);
|
2013-12-24 09:39:38 +00:00
|
|
|
# elif VBOX_API_VERSION >= 4002000
|
2012-10-02 09:00:54 +00:00
|
|
|
data->vboxObj->vtbl->OpenMedium(data->vboxObj, mediumFileUtf16,
|
|
|
|
deviceType, accessMode, PR_FALSE, &medium);
|
2010-12-27 22:35:30 +00:00
|
|
|
# endif
|
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (!medium) {
|
|
|
|
PRUnichar *mediumEmpty = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("", &mediumEmpty);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
2010-09-03 15:39:23 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenHardDisk(data->vboxObj,
|
|
|
|
mediumFileUtf16,
|
|
|
|
AccessMode_ReadWrite,
|
|
|
|
false,
|
|
|
|
mediumEmpty,
|
|
|
|
false,
|
|
|
|
mediumEmpty,
|
|
|
|
&medium);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->disks[i]->device ==
|
|
|
|
VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
2010-09-03 15:39:23 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenDVDImage(data->vboxObj,
|
|
|
|
mediumFileUtf16,
|
|
|
|
mediumEmpty,
|
|
|
|
&medium);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->disks[i]->device ==
|
|
|
|
VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
2010-09-03 15:39:23 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
|
|
|
|
mediumFileUtf16,
|
|
|
|
mediumEmpty,
|
|
|
|
&medium);
|
|
|
|
} else {
|
|
|
|
rc = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
# elif VBOX_API_VERSION == 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
|
|
|
|
mediumFileUtf16,
|
|
|
|
deviceType, accessMode,
|
|
|
|
&medium);
|
2013-12-24 09:39:38 +00:00
|
|
|
# elif VBOX_API_VERSION >= 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
|
|
|
|
mediumFileUtf16,
|
|
|
|
deviceType, accessMode,
|
|
|
|
false,
|
|
|
|
&medium);
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION >= 4001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(mediumEmpty);
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (!medium) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Failed to attach the following disk/dvd/floppy "
|
|
|
|
"to the machine: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(mediumFileUtf16);
|
|
|
|
continue;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
rc = medium->vtbl->GetId(medium, &mediumUUID);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to be attached "
|
|
|
|
"as harddisk/dvd/floppy: %s, rc=%08x"),
|
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_UTF16_FREE(mediumFileUtf16);
|
|
|
|
continue;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
|
|
|
if (def->disks[i]->readonly) {
|
|
|
|
medium->vtbl->SetType(medium, MediumType_Immutable);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("setting harddisk to immutable");
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (!def->disks[i]->readonly) {
|
|
|
|
medium->vtbl->SetType(medium, MediumType_Normal);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("setting harddisk type to normal");
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_IDE) {
|
|
|
|
VBOX_UTF8_TO_UTF16("IDE Controller", &storageCtlName);
|
|
|
|
storageBus = StorageBus_IDE;
|
|
|
|
} else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_SATA) {
|
|
|
|
VBOX_UTF8_TO_UTF16("SATA Controller", &storageCtlName);
|
|
|
|
storageBus = StorageBus_SATA;
|
|
|
|
} else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
|
|
|
|
VBOX_UTF8_TO_UTF16("SCSI Controller", &storageCtlName);
|
|
|
|
storageBus = StorageBus_SCSI;
|
|
|
|
} else if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_FDC) {
|
|
|
|
VBOX_UTF8_TO_UTF16("Floppy Controller", &storageCtlName);
|
|
|
|
storageBus = StorageBus_Floppy;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
/* get the device details i.e instance, port and slot */
|
|
|
|
if (!vboxGetDeviceDetails(def->disks[i]->dst,
|
|
|
|
maxPortPerInst,
|
|
|
|
maxSlotPerPort,
|
|
|
|
storageBus,
|
|
|
|
&deviceInst,
|
|
|
|
&devicePort,
|
|
|
|
&deviceSlot)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2012-09-12 16:54:42 +00:00
|
|
|
_("can't get the port/slot number of "
|
|
|
|
"harddisk/dvd/floppy to be attached: "
|
|
|
|
"%s, rc=%08x"),
|
2012-07-18 12:06:29 +00:00
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_UTF16_FREE(mediumUUID);
|
|
|
|
VBOX_UTF16_FREE(mediumFileUtf16);
|
2010-08-31 18:01:45 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attach the harddisk/dvd/Floppy to the storage controller */
|
|
|
|
rc = machine->vtbl->AttachDevice(machine,
|
|
|
|
storageCtlName,
|
|
|
|
devicePort,
|
|
|
|
deviceSlot,
|
|
|
|
deviceType,
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4000000
|
2010-08-31 18:01:45 +00:00
|
|
|
mediumUUID);
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
medium);
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION >= 4000000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2012-09-12 16:54:42 +00:00
|
|
|
_("could not attach the file as "
|
|
|
|
"harddisk/dvd/floppy: %s, rc=%08x"),
|
2012-07-18 12:06:29 +00:00
|
|
|
def->disks[i]->src, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
DEBUGIID("Attached HDD/DVD/Floppy with UUID", mediumUUID);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(medium);
|
|
|
|
VBOX_UTF16_FREE(mediumUUID);
|
|
|
|
VBOX_UTF16_FREE(mediumFileUtf16);
|
|
|
|
VBOX_UTF16_FREE(storageCtlName);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxAttachSound(virDomainDefPtr def, IMachine *machine)
|
|
|
|
{
|
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
/* Check if def->nsounds is one as VirtualBox currently supports
|
|
|
|
* only one sound card
|
|
|
|
*/
|
|
|
|
if (def->nsounds == 1) {
|
|
|
|
IAudioAdapter *audioAdapter = NULL;
|
|
|
|
|
|
|
|
machine->vtbl->GetAudioAdapter(machine, &audioAdapter);
|
|
|
|
if (audioAdapter) {
|
|
|
|
rc = audioAdapter->vtbl->SetEnabled(audioAdapter, 1);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_SB16) {
|
|
|
|
audioAdapter->vtbl->SetAudioController(audioAdapter,
|
|
|
|
AudioControllerType_SB16);
|
|
|
|
} else if (def->sounds[0]->model == VIR_DOMAIN_SOUND_MODEL_AC97) {
|
|
|
|
audioAdapter->vtbl->SetAudioController(audioAdapter,
|
|
|
|
AudioControllerType_AC97);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(audioAdapter);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxAttachNetwork(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
PRUint32 chipsetType = ChipsetType_Null;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
PRUint32 networkAdapterCount = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2010-08-31 18:01:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4001000
|
2011-10-29 19:26:57 +00:00
|
|
|
machine->vtbl->GetChipsetType(machine, &chipsetType);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
systemProperties->vtbl->GetNetworkAdapterCount(systemProperties,
|
|
|
|
&networkAdapterCount);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
systemProperties->vtbl->GetMaxNetworkAdapters(systemProperties, chipsetType,
|
|
|
|
&networkAdapterCount);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
|
|
|
}
|
|
|
|
|
2012-09-26 15:12:28 +00:00
|
|
|
VIR_DEBUG("Number of Network Cards to be connected: %zu", def->nnets);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Number of Network Cards available: %d", networkAdapterCount);
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
for (i = 0; (i < def->nnets) && (i < networkAdapterCount); i++) {
|
|
|
|
INetworkAdapter *adapter = NULL;
|
|
|
|
PRUint32 adapterType = NetworkAdapterType_Null;
|
|
|
|
char macaddr[VIR_MAC_STRING_BUFLEN] = {0};
|
|
|
|
char macaddrvbox[VIR_MAC_STRING_BUFLEN - 5] = {0};
|
|
|
|
|
2012-07-17 12:07:59 +00:00
|
|
|
virMacAddrFormat(&def->nets[i]->mac, macaddr);
|
2010-08-31 18:01:45 +00:00
|
|
|
snprintf(macaddrvbox, VIR_MAC_STRING_BUFLEN - 5,
|
|
|
|
"%02X%02X%02X%02X%02X%02X",
|
2012-07-17 12:07:59 +00:00
|
|
|
def->nets[i]->mac.addr[0],
|
|
|
|
def->nets[i]->mac.addr[1],
|
|
|
|
def->nets[i]->mac.addr[2],
|
|
|
|
def->nets[i]->mac.addr[3],
|
|
|
|
def->nets[i]->mac.addr[4],
|
|
|
|
def->nets[i]->mac.addr[5]);
|
2010-08-31 18:01:45 +00:00
|
|
|
macaddrvbox[VIR_MAC_STRING_BUFLEN - 6] = '\0';
|
|
|
|
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("NIC(%zu): Type: %d", i, def->nets[i]->type);
|
|
|
|
VIR_DEBUG("NIC(%zu): Model: %s", i, def->nets[i]->model);
|
|
|
|
VIR_DEBUG("NIC(%zu): Mac: %s", i, macaddr);
|
|
|
|
VIR_DEBUG("NIC(%zu): ifname: %s", i, def->nets[i]->ifname);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("NIC(%zu): name: %s", i, def->nets[i]->data.network.name);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("NIC(%zu): name: %s", i, def->nets[i]->data.internal.name);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("NIC(%zu): NAT.", i);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("NIC(%zu): brname: %s", i, def->nets[i]->data.bridge.brname);
|
|
|
|
VIR_DEBUG("NIC(%zu): script: %s", i, def->nets[i]->script);
|
|
|
|
VIR_DEBUG("NIC(%zu): ipaddr: %s", i, def->nets[i]->data.bridge.ipaddr);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->GetNetworkAdapter(machine, i, &adapter);
|
|
|
|
if (adapter) {
|
|
|
|
PRUnichar *MACAddress = NULL;
|
|
|
|
|
|
|
|
adapter->vtbl->SetEnabled(adapter, 1);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->model) {
|
2013-11-19 23:35:10 +00:00
|
|
|
if (STRCASEEQ(def->nets[i]->model, "Am79C970A")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_Am79C970A;
|
2013-11-19 23:35:10 +00:00
|
|
|
} else if (STRCASEEQ(def->nets[i]->model, "Am79C973")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_Am79C973;
|
2013-11-19 23:35:10 +00:00
|
|
|
} else if (STRCASEEQ(def->nets[i]->model, "82540EM")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_I82540EM;
|
2013-11-19 23:35:10 +00:00
|
|
|
} else if (STRCASEEQ(def->nets[i]->model, "82545EM")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_I82545EM;
|
2013-11-19 23:35:10 +00:00
|
|
|
} else if (STRCASEEQ(def->nets[i]->model, "82543GC")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_I82543GC;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3001000
|
2013-11-19 23:35:10 +00:00
|
|
|
} else if (STRCASEEQ(def->nets[i]->model, "virtio")) {
|
2010-08-31 18:01:45 +00:00
|
|
|
adapterType = NetworkAdapterType_Virtio;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
adapterType = NetworkAdapterType_Am79C973;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->SetAdapterType(adapter, adapterType);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
|
|
|
PRUnichar *hostInterface = NULL;
|
|
|
|
/* Bridged Network */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->AttachToBridgedInterface(adapter);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_Bridged);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->data.bridge.brname) {
|
|
|
|
VBOX_UTF8_TO_UTF16(def->nets[i]->data.bridge.brname,
|
|
|
|
&hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->SetHostInterface(adapter, hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetBridgedInterface(adapter, hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(hostInterface);
|
|
|
|
}
|
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_INTERNAL) {
|
|
|
|
PRUnichar *internalNetwork = NULL;
|
|
|
|
/* Internal Network */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->AttachToInternalNetwork(adapter);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_Internal);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->data.internal.name) {
|
|
|
|
VBOX_UTF8_TO_UTF16(def->nets[i]->data.internal.name,
|
|
|
|
&internalNetwork);
|
|
|
|
adapter->vtbl->SetInternalNetwork(adapter, internalNetwork);
|
|
|
|
VBOX_UTF16_FREE(internalNetwork);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
|
|
|
PRUnichar *hostInterface = NULL;
|
|
|
|
/* Host Only Networking (currently only vboxnet0 available
|
|
|
|
* on *nix and mac, on windows you can create and configure
|
|
|
|
* as many as you want)
|
|
|
|
*/
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->AttachToHostOnlyInterface(adapter);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_HostOnly);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->nets[i]->data.network.name) {
|
|
|
|
VBOX_UTF8_TO_UTF16(def->nets[i]->data.network.name,
|
|
|
|
&hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->SetHostInterface(adapter, hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetHostOnlyInterface(adapter, hostInterface);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(hostInterface);
|
|
|
|
}
|
|
|
|
} else if (def->nets[i]->type == VIR_DOMAIN_NET_TYPE_USER) {
|
|
|
|
/* NAT */
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->AttachToNAT(adapter);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_NAT);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
/* else always default to NAT if we don't understand
|
|
|
|
* what option is been passed to us
|
|
|
|
*/
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4001000
|
2010-08-31 18:01:45 +00:00
|
|
|
adapter->vtbl->AttachToNAT(adapter);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4001000 */
|
2011-10-29 19:26:57 +00:00
|
|
|
adapter->vtbl->SetAttachmentType(adapter, NetworkAttachmentType_NAT);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4001000 */
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(macaddrvbox, &MACAddress);
|
|
|
|
adapter->vtbl->SetMACAddress(adapter, MACAddress);
|
|
|
|
VBOX_UTF16_FREE(MACAddress);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxAttachSerial(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
|
|
|
PRUint32 serialPortCount = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetSerialPortCount(systemProperties,
|
|
|
|
&serialPortCount);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2012-09-26 15:12:28 +00:00
|
|
|
VIR_DEBUG("Number of Serial Ports to be connected: %zu", def->nserials);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Number of Serial Ports available: %d", serialPortCount);
|
2010-08-31 18:01:45 +00:00
|
|
|
for (i = 0; (i < def->nserials) && (i < serialPortCount); i++) {
|
|
|
|
ISerialPort *serialPort = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("SerialPort(%zu): Type: %d", i, def->serials[i]->source.type);
|
|
|
|
VIR_DEBUG("SerialPort(%zu): target.port: %d", i,
|
2010-08-31 18:01:45 +00:00
|
|
|
def->serials[i]->target.port);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->GetSerialPort(machine, i, &serialPort);
|
|
|
|
if (serialPort) {
|
|
|
|
PRUnichar *pathUtf16 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
serialPort->vtbl->SetEnabled(serialPort, 1);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
if (def->serials[i]->source.data.file.path) {
|
|
|
|
VBOX_UTF8_TO_UTF16(def->serials[i]->source.data.file.path,
|
|
|
|
&pathUtf16);
|
2010-08-31 18:01:45 +00:00
|
|
|
serialPort->vtbl->SetPath(serialPort, pathUtf16);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For now hard code the serial ports to COM1 and COM2,
|
|
|
|
* COM1 (Base Addr: 0x3F8 (decimal: 1016), IRQ: 4)
|
|
|
|
* COM2 (Base Addr: 0x2F8 (decimal: 760), IRQ: 3)
|
|
|
|
* TODO: make this more flexible
|
|
|
|
*/
|
|
|
|
/* TODO: to improve the libvirt XMl handling so
|
|
|
|
* that def->serials[i]->target.port shows real port
|
|
|
|
* and not always start at 0
|
|
|
|
*/
|
|
|
|
if (def->serials[i]->target.port == 0) {
|
|
|
|
serialPort->vtbl->SetIRQ(serialPort, 4);
|
|
|
|
serialPort->vtbl->SetIOBase(serialPort, 1016);
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
i, 4, 1016, def->serials[i]->source.data.file.path);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (def->serials[i]->target.port == 1) {
|
|
|
|
serialPort->vtbl->SetIRQ(serialPort, 3);
|
|
|
|
serialPort->vtbl->SetIOBase(serialPort, 760);
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG(" serialPort-%zu irq: %d, iobase 0x%x, path: %s",
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
i, 3, 760, def->serials[i]->source.data.file.path);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) {
|
2010-08-31 18:01:45 +00:00
|
|
|
serialPort->vtbl->SetHostMode(serialPort, PortMode_HostDevice);
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
} else if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE) {
|
2010-08-31 18:01:45 +00:00
|
|
|
serialPort->vtbl->SetHostMode(serialPort, PortMode_HostPipe);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3000000
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
} else if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) {
|
2010-08-31 18:01:45 +00:00
|
|
|
serialPort->vtbl->SetHostMode(serialPort, PortMode_RawFile);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3000000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
serialPort->vtbl->SetHostMode(serialPort,
|
|
|
|
PortMode_Disconnected);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(serialPort);
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF16_FREE(pathUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxAttachParallel(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
|
|
|
ISystemProperties *systemProperties = NULL;
|
|
|
|
PRUint32 parallelPortCount = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxObj->vtbl->GetSystemProperties(data->vboxObj, &systemProperties);
|
|
|
|
if (systemProperties) {
|
|
|
|
systemProperties->vtbl->GetParallelPortCount(systemProperties,
|
|
|
|
¶llelPortCount);
|
|
|
|
VBOX_RELEASE(systemProperties);
|
|
|
|
systemProperties = NULL;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2012-09-26 15:12:28 +00:00
|
|
|
VIR_DEBUG("Number of Parallel Ports to be connected: %zu", def->nparallels);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Number of Parallel Ports available: %d", parallelPortCount);
|
2010-08-31 18:01:45 +00:00
|
|
|
for (i = 0; (i < def->nparallels) && (i < parallelPortCount); i++) {
|
|
|
|
IParallelPort *parallelPort = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG("ParallelPort(%zu): Type: %d", i, def->parallels[i]->source.type);
|
|
|
|
VIR_DEBUG("ParallelPort(%zu): target.port: %d", i,
|
2010-08-31 18:01:45 +00:00
|
|
|
def->parallels[i]->target.port);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->GetParallelPort(machine, i, ¶llelPort);
|
|
|
|
if (parallelPort) {
|
|
|
|
PRUnichar *pathUtf16 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->parallels[i]->source.data.file.path, &pathUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
/* For now hard code the parallel ports to
|
|
|
|
* LPT1 (Base Addr: 0x378 (decimal: 888), IRQ: 7)
|
|
|
|
* LPT2 (Base Addr: 0x278 (decimal: 632), IRQ: 5)
|
|
|
|
* TODO: make this more flexible
|
|
|
|
*/
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
if ((def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_DEV) ||
|
|
|
|
(def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PTY) ||
|
|
|
|
(def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_FILE) ||
|
|
|
|
(def->parallels[i]->source.type == VIR_DOMAIN_CHR_TYPE_PIPE)) {
|
2010-08-31 18:01:45 +00:00
|
|
|
parallelPort->vtbl->SetPath(parallelPort, pathUtf16);
|
|
|
|
if (i == 0) {
|
|
|
|
parallelPort->vtbl->SetIRQ(parallelPort, 7);
|
|
|
|
parallelPort->vtbl->SetIOBase(parallelPort, 888);
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path: %s",
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
i, 7, 888, def->parallels[i]->source.data.file.path);
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if (i == 1) {
|
|
|
|
parallelPort->vtbl->SetIRQ(parallelPort, 5);
|
|
|
|
parallelPort->vtbl->SetIOBase(parallelPort, 632);
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
VIR_DEBUG(" parallePort-%zu irq: %d, iobase 0x%x, path: %s",
|
domain_conf: split source data out from ChrDef
This opens up the possibility of reusing the smaller ChrSourceDef
for both qemu monitor and a passthrough smartcard device.
* src/conf/domain_conf.h (_virDomainChrDef): Factor host
details...
(_virDomainChrSourceDef): ...into new struct.
(virDomainChrSourceDefFree): New prototype.
* src/conf/domain_conf.c (virDomainChrDefFree)
(virDomainChrDefParseXML, virDomainChrDefFormat): Split...
(virDomainChrSourceDefClear, virDomainChrSourceDefFree)
(virDomainChrSourceDefParseXML, virDomainChrSourceDefFormat):
...into new functions.
(virDomainChrDefParseTargetXML): Update clients to reflect type
split.
* src/vmx/vmx.c (virVMXParseSerial, virVMXParseParallel)
(virVMXFormatSerial, virVMXFormatParallel): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainOpenConsole): Likewise.
* src/xen/xend_internal.c (xenDaemonParseSxprChar)
(xenDaemonFormatSxprChr): Likewise.
* src/vbox/vbox_tmpl.c (vboxDomainDumpXML, vboxAttachSerial)
(vboxAttachParallel): Likewise.
* src/security/security_dac.c (virSecurityDACSetChardevLabel)
(virSecurityDACSetChardevCallback)
(virSecurityDACRestoreChardevLabel)
(virSecurityDACRestoreChardevCallback): Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback)
(SELinuxRestoreSecurityChardevLabel)
(SELinuxSetSecurityChardevCallback): Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
* src/lxc/lxc_driver.c (lxcVmStart, lxcDomainOpenConsole):
Likewise.
* src/uml/uml_conf.c (umlBuildCommandLineChr): Likewise.
* src/uml/uml_driver.c (umlIdentifyOneChrPTY, umlIdentifyChrPTY)
(umlDomainOpenConsole): Likewise.
* src/qemu/qemu_command.c (qemuBuildChrChardevStr)
(qemuBuildChrArgStr, qemuBuildCommandLine)
(qemuParseCommandLineChr): Likewise.
* src/qemu/qemu_domain.c (qemuDomainObjPrivateXMLFormat)
(qemuDomainObjPrivateXMLParse): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupChardevCgroup): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/qemu/qemu_driver.c (qemudFindCharDevicePTYsMonitor)
(qemudFindCharDevicePTYs, qemuPrepareChardevDevice)
(qemuPrepareMonitorChr, qemudShutdownVMDaemon)
(qemuDomainOpenConsole): Likewise.
* src/qemu/qemu_command.h (qemuBuildChrChardevStr)
(qemuBuildChrArgStr): Delete, now that they are static.
* src/libvirt_private.syms (domain_conf.h): New exports.
* cfg.mk (useless_free_options): Update list.
* tests/qemuxml2argvtest.c (testCompareXMLToArgvFiles): Update
tests.
2011-01-07 22:45:01 +00:00
|
|
|
i, 5, 632, def->parallels[i]->source.data.file.path);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
|
|
|
/* like serial port, parallel port can't be enabled unless
|
|
|
|
* correct IRQ and IOBase values are specified.
|
|
|
|
*/
|
|
|
|
parallelPort->vtbl->SetEnabled(parallelPort, 1);
|
|
|
|
|
|
|
|
VBOX_RELEASE(parallelPort);
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF16_FREE(pathUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vboxAttachVideo(virDomainDefPtr def, IMachine *machine)
|
|
|
|
{
|
|
|
|
if ((def->nvideos == 1) &&
|
|
|
|
(def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_VBOX)) {
|
2011-01-28 21:03:24 +00:00
|
|
|
machine->vtbl->SetVRAMSize(machine,
|
|
|
|
VIR_DIV_UP(def->videos[0]->vram, 1024));
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetMonitorCount(machine, def->videos[0]->heads);
|
|
|
|
if (def->videos[0]->accel) {
|
|
|
|
machine->vtbl->SetAccelerate3DEnabled(machine,
|
|
|
|
def->videos[0]->accel->support3d);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3001000
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetAccelerate2DVideoEnabled(machine,
|
|
|
|
def->videos[0]->accel->support2d);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
machine->vtbl->SetAccelerate3DEnabled(machine, 0);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3001000
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetAccelerate2DVideoEnabled(machine, 0);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
|
|
|
int vrdpPresent = 0;
|
|
|
|
int sdlPresent = 0;
|
|
|
|
int guiPresent = 0;
|
|
|
|
char *guiDisplay = NULL;
|
|
|
|
char *sdlDisplay = NULL;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
for (i = 0; i < def->ngraphics; i++) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
IVRDPServer *VRDxServer = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
IVRDEServer *VRDxServer = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) &&
|
|
|
|
(vrdpPresent == 0)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
vrdpPresent = 1;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
machine->vtbl->GetVRDPServer(machine, &VRDxServer);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
machine->vtbl->GetVRDEServer(machine, &VRDxServer);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
if (VRDxServer) {
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
const char *listenAddr
|
|
|
|
= virDomainGraphicsListenGetAddress(def->graphics[i], 0);
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetEnabled(VRDxServer, PR_TRUE);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("VRDP Support turned ON.");
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->graphics[i]->data.rdp.port) {
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetPort(VRDxServer,
|
2010-08-31 18:01:45 +00:00
|
|
|
def->graphics[i]->data.rdp.port);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("VRDP Port changed to: %d",
|
2010-08-31 18:01:45 +00:00
|
|
|
def->graphics[i]->data.rdp.port);
|
|
|
|
} else if (def->graphics[i]->data.rdp.autoport) {
|
|
|
|
/* Setting the port to 0 will reset its value to
|
|
|
|
* the default one which is 3389 currently
|
|
|
|
*/
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetPort(VRDxServer, 0);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("VRDP Port changed to default, which is 3389 currently");
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION < 4000000 /* 3001000 <= VBOX_API_VERSION < 4000000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
PRUnichar *portUtf16 = NULL;
|
|
|
|
portUtf16 = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetPorts(VRDxServer, portUtf16);
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(portUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
PRUnichar *VRDEPortsKey = NULL;
|
|
|
|
PRUnichar *VRDEPortsValue = NULL;
|
|
|
|
VBOX_UTF8_TO_UTF16("TCP/Ports", &VRDEPortsKey);
|
|
|
|
VRDEPortsValue = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
|
|
|
|
VRDxServer->vtbl->SetVRDEProperty(VRDxServer, VRDEPortsKey,
|
|
|
|
VRDEPortsValue);
|
|
|
|
VBOX_UTF16_FREE(VRDEPortsKey);
|
|
|
|
VBOX_UTF16_FREE(VRDEPortsValue);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->graphics[i]->data.rdp.replaceUser) {
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetReuseSingleConnection(VRDxServer,
|
2010-08-31 18:01:45 +00:00
|
|
|
PR_TRUE);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("VRDP set to reuse single connection");
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (def->graphics[i]->data.rdp.multiUser) {
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetAllowMultiConnection(VRDxServer,
|
2010-08-31 18:01:45 +00:00
|
|
|
PR_TRUE);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("VRDP set to allow multiple connection");
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
if (listenAddr) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
PRUnichar *netAddressKey = NULL;
|
|
|
|
#endif
|
2010-08-31 18:01:45 +00:00
|
|
|
PRUnichar *netAddressUtf16 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(listenAddr, &netAddressUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
VRDxServer->vtbl->SetNetAddress(VRDxServer,
|
2010-08-31 18:01:45 +00:00
|
|
|
netAddressUtf16);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("TCP/Address", &netAddressKey);
|
|
|
|
VRDxServer->vtbl->SetVRDEProperty(VRDxServer, netAddressKey,
|
|
|
|
netAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(netAddressKey);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("VRDP listen address is set to: %s",
|
conf: add <listen> subelement to domain <graphics> element
Once it's plugged in, the <listen> element will be an optional
replacement for the "listen" attribute that graphics elements already
have. If the <listen> element is type='address', it will have an
attribute called 'address' which will contain an IP address or dns
name that the guest's display server should listen on. If, however,
type='network', the <listen> element should have an attribute called
'network' that will be set to the name of a network configuration to
get the IP address from.
* docs/schemas/domain.rng: updated to allow the <listen> element
* docs/formatdomain.html.in: document the <listen> element and its
attributes.
* src/conf/domain_conf.[hc]:
1) The domain parser, formatter, and data structure are modified to
support 0 or more <listen> subelements to each <graphics>
element. The old style "legacy" listen attribute is also still
accepted, and will be stored internally just as if it were a
separate <listen> element. On output (i.e. format), the address
attribute of the first <listen> element of type 'address' will be
duplicated in the legacy "listen" attribute of the <graphic>
element.
2) The "listenAddr" attribute has been removed from the unions in
virDomainGRaphicsDef for graphics types vnc, rdp, and spice.
This attribute is now in the <listen> subelement (aka
virDomainGraphicsListenDef)
3) Helper functions were written to provide simple access
(both Get and Set) to the listen elements and their attributes.
* src/libvirt_private.syms: export the listen helper functions
* src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c,
src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c,
src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c
Modify all these files to use the listen helper functions rather
than directly referencing the (now missing) listenAddr
attribute. There can be multiple <listen> elements to a single
<graphics>, but the drivers all currently only support one, so all
replacements of direct access with a helper function indicate index
"0".
* tests/* - only 3 of these are new files added explicitly to test the
new <listen> element. All the others have been modified to reflect
the fact that any legacy "listen" attributes passed in to the domain
parse will be saved in a <listen> element (i.e. one of the
virDomainGraphicsListenDefs), and during the domain format function,
both the <listen> element as well as the legacy attributes will be
output.
2011-07-07 04:20:28 +00:00
|
|
|
listenAddr);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(netAddressUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_RELEASE(VRDxServer);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP) &&
|
|
|
|
(guiPresent == 0)) {
|
|
|
|
guiPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(guiDisplay, def->graphics[i]->data.desktop.display) < 0) {
|
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* guiDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
|
|
|
*/
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) &&
|
|
|
|
(sdlPresent == 0)) {
|
|
|
|
sdlPresent = 1;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(sdlDisplay, def->graphics[i]->data.sdl.display) < 0) {
|
|
|
|
/* just don't go to cleanup yet as it is ok to have
|
|
|
|
* sdlDisplay as NULL and we check it below if it
|
|
|
|
* exist and then only use it there
|
|
|
|
*/
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if ((vrdpPresent == 1) && (guiPresent == 0) && (sdlPresent == 0)) {
|
|
|
|
/* store extradata key that frontend is set to vrdp */
|
|
|
|
PRUnichar *keyTypeUtf16 = NULL;
|
|
|
|
PRUnichar *valueTypeUtf16 = NULL;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16("vrdp", &valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(keyTypeUtf16);
|
|
|
|
VBOX_UTF16_FREE(valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
} else if ((guiPresent == 0) && (sdlPresent == 1)) {
|
|
|
|
/* store extradata key that frontend is set to sdl */
|
|
|
|
PRUnichar *keyTypeUtf16 = NULL;
|
|
|
|
PRUnichar *valueTypeUtf16 = NULL;
|
|
|
|
PRUnichar *keyDislpayUtf16 = NULL;
|
|
|
|
PRUnichar *valueDisplayUtf16 = NULL;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16("sdl", &valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(keyTypeUtf16);
|
|
|
|
VBOX_UTF16_FREE(valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (sdlDisplay) {
|
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16(sdlDisplay, &valueDisplayUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetExtraData(machine, keyDislpayUtf16,
|
|
|
|
valueDisplayUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(keyDislpayUtf16);
|
|
|
|
VBOX_UTF16_FREE(valueDisplayUtf16);
|
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
} else {
|
|
|
|
/* if all are set then default is gui, with vrdp turned on */
|
|
|
|
PRUnichar *keyTypeUtf16 = NULL;
|
|
|
|
PRUnichar *valueTypeUtf16 = NULL;
|
|
|
|
PRUnichar *keyDislpayUtf16 = NULL;
|
|
|
|
PRUnichar *valueDisplayUtf16 = NULL;
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Type", &keyTypeUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16("gui", &valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetExtraData(machine, keyTypeUtf16, valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(keyTypeUtf16);
|
|
|
|
VBOX_UTF16_FREE(valueTypeUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
if (guiDisplay) {
|
|
|
|
VBOX_UTF8_TO_UTF16("FRONTEND/Display", &keyDislpayUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16(guiDisplay, &valueDisplayUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
machine->vtbl->SetExtraData(machine, keyDislpayUtf16,
|
|
|
|
valueDisplayUtf16);
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(keyDislpayUtf16);
|
|
|
|
VBOX_UTF16_FREE(valueDisplayUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
VIR_FREE(guiDisplay);
|
|
|
|
VIR_FREE(sdlDisplay);
|
|
|
|
}
|
2009-05-15 13:45:40 +00:00
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static void
|
|
|
|
vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2010-08-31 18:01:45 +00:00
|
|
|
IUSBController *USBController = NULL;
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
IUSBDeviceFilters *USBDeviceFilters = NULL;
|
|
|
|
#endif
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2010-08-31 18:01:45 +00:00
|
|
|
bool isUSB = false;
|
|
|
|
|
|
|
|
if (def->nhostdevs == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Loop through the devices first and see if you
|
|
|
|
* have a USB Device, only if you have one then
|
|
|
|
* start the USB controller else just proceed as
|
|
|
|
* usual
|
|
|
|
*/
|
|
|
|
for (i = 0; i < def->nhostdevs; i++) {
|
2013-11-21 14:41:04 +00:00
|
|
|
if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (def->hostdevs[i]->source.subsys.type !=
|
|
|
|
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
|
|
|
|
!def->hostdevs[i]->source.subsys.u.usb.product)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
VIR_DEBUG("USB Device detected, VendorId:0x%x, ProductId:0x%x",
|
|
|
|
def->hostdevs[i]->source.subsys.u.usb.vendor,
|
|
|
|
def->hostdevs[i]->source.subsys.u.usb.product);
|
|
|
|
isUSB = true;
|
|
|
|
break;
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
|
2013-11-21 14:41:04 +00:00
|
|
|
if (!isUSB)
|
|
|
|
return;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:04 +00:00
|
|
|
/* First Start the USB Controller and then loop
|
|
|
|
* to attach USB Devices to it
|
|
|
|
*/
|
|
|
|
machine->vtbl->GetUSBController(machine, &USBController);
|
|
|
|
|
|
|
|
if (!USBController)
|
|
|
|
return;
|
|
|
|
|
|
|
|
USBController->vtbl->SetEnabled(USBController, 1);
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4002000
|
2013-11-21 14:41:04 +00:00
|
|
|
USBController->vtbl->SetEnabledEhci(USBController, 1);
|
2013-11-21 14:41:07 +00:00
|
|
|
# else
|
2013-11-21 14:41:04 +00:00
|
|
|
USBController->vtbl->SetEnabledEHCI(USBController, 1);
|
2013-11-21 14:41:07 +00:00
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
machine->vtbl->GetUSBDeviceFilters(machine, &USBDeviceFilters);
|
|
|
|
|
|
|
|
if (!USBDeviceFilters)
|
|
|
|
return;
|
2012-10-02 09:00:54 +00:00
|
|
|
#endif
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-11-21 14:41:04 +00:00
|
|
|
for (i = 0; i < def->nhostdevs; i++) {
|
|
|
|
char *filtername = NULL;
|
|
|
|
PRUnichar *filternameUtf16 = NULL;
|
|
|
|
IUSBDeviceFilter *filter = NULL;
|
|
|
|
PRUnichar *vendorIdUtf16 = NULL;
|
|
|
|
char vendorId[40] = {0};
|
|
|
|
PRUnichar *productIdUtf16 = NULL;
|
|
|
|
char productId[40] = {0};
|
|
|
|
|
|
|
|
if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
|
|
|
continue;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-11-21 14:41:04 +00:00
|
|
|
if (def->hostdevs[i]->source.subsys.type !=
|
|
|
|
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
|
|
|
|
continue;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-11-21 14:41:04 +00:00
|
|
|
/* Zero pad for nice alignment when fewer than 9999
|
|
|
|
* devices.
|
|
|
|
*/
|
|
|
|
if (virAsprintf(&filtername, "filter%04zu", i) >= 0) {
|
|
|
|
VBOX_UTF8_TO_UTF16(filtername, &filternameUtf16);
|
|
|
|
VIR_FREE(filtername);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:04 +00:00
|
|
|
USBController->vtbl->CreateDeviceFilter(USBController,
|
|
|
|
filternameUtf16,
|
|
|
|
&filter);
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
USBDeviceFilters->vtbl->CreateDeviceFilter(USBDeviceFilters,
|
|
|
|
filternameUtf16,
|
|
|
|
&filter);
|
|
|
|
#endif
|
2013-11-21 14:41:04 +00:00
|
|
|
}
|
|
|
|
VBOX_UTF16_FREE(filternameUtf16);
|
2010-08-31 18:01:45 +00:00
|
|
|
|
2013-11-21 14:41:04 +00:00
|
|
|
if (!filter)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!def->hostdevs[i]->source.subsys.u.usb.vendor &&
|
|
|
|
!def->hostdevs[i]->source.subsys.u.usb.product)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (def->hostdevs[i]->source.subsys.u.usb.vendor) {
|
|
|
|
snprintf(vendorId, sizeof(vendorId), "%x",
|
|
|
|
def->hostdevs[i]->source.subsys.u.usb.vendor);
|
|
|
|
VBOX_UTF8_TO_UTF16(vendorId, &vendorIdUtf16);
|
|
|
|
filter->vtbl->SetVendorId(filter, vendorIdUtf16);
|
|
|
|
VBOX_UTF16_FREE(vendorIdUtf16);
|
|
|
|
}
|
|
|
|
if (def->hostdevs[i]->source.subsys.u.usb.product) {
|
|
|
|
snprintf(productId, sizeof(productId), "%x",
|
|
|
|
def->hostdevs[i]->source.subsys.u.usb.product);
|
|
|
|
VBOX_UTF8_TO_UTF16(productId, &productIdUtf16);
|
|
|
|
filter->vtbl->SetProductId(filter,
|
|
|
|
productIdUtf16);
|
|
|
|
VBOX_UTF16_FREE(productIdUtf16);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2013-11-21 14:41:04 +00:00
|
|
|
filter->vtbl->SetActive(filter, 1);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:04 +00:00
|
|
|
USBController->vtbl->InsertDeviceFilter(USBController,
|
|
|
|
i,
|
|
|
|
filter);
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
USBDeviceFilters->vtbl->InsertDeviceFilter(USBDeviceFilters,
|
|
|
|
i,
|
|
|
|
filter);
|
|
|
|
#endif
|
2013-11-21 14:41:04 +00:00
|
|
|
VBOX_RELEASE(filter);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2013-11-21 14:41:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2013-11-21 14:41:04 +00:00
|
|
|
VBOX_RELEASE(USBController);
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
VBOX_RELEASE(USBDeviceFilters);
|
|
|
|
#endif
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
|
2011-06-07 11:29:34 +00:00
|
|
|
static void
|
|
|
|
vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-06-07 11:29:34 +00:00
|
|
|
PRUnichar *nameUtf16;
|
|
|
|
PRUnichar *hostPathUtf16;
|
|
|
|
PRBool writable;
|
|
|
|
|
|
|
|
if (def->nfss == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < def->nfss; i++) {
|
|
|
|
if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(def->fss[i]->dst, &nameUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16(def->fss[i]->src, &hostPathUtf16);
|
|
|
|
writable = !def->fss[i]->readonly;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2011-06-07 11:29:34 +00:00
|
|
|
machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
|
|
|
|
writable);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2011-06-07 11:29:34 +00:00
|
|
|
machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
|
|
|
|
writable, PR_FALSE);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2011-06-07 11:29:34 +00:00
|
|
|
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_UTF16_FREE(hostPathUtf16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-31 18:01:45 +00:00
|
|
|
static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
|
|
|
|
VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
IBIOSSettings *bios = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
vboxIID mchiid = VBOX_IID_INITIALIZER;
|
2010-08-31 18:01:45 +00:00
|
|
|
virDomainDefPtr def = NULL;
|
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 3002000 && VBOX_API_VERSION < 4002000
|
2010-08-31 18:01:45 +00:00
|
|
|
PRBool override = PR_FALSE;
|
|
|
|
#endif
|
|
|
|
nsresult rc;
|
2012-10-02 09:00:54 +00:00
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4002000
|
2012-10-02 09:00:54 +00:00
|
|
|
const char *flagsUUIDPrefix = "UUID=";
|
|
|
|
const char *flagsForceOverwrite = "forceOverwrite=0";
|
|
|
|
const char *flagsSeparator = ",";
|
|
|
|
char createFlags[strlen(flagsUUIDPrefix) + VIR_UUID_STRING_BUFLEN + strlen(flagsSeparator) + strlen(flagsForceOverwrite) + 1];
|
|
|
|
PRUnichar *createFlagsUtf16 = NULL;
|
|
|
|
#endif
|
2010-08-31 18:01:45 +00:00
|
|
|
|
2013-03-28 13:55:55 +00:00
|
|
|
if (!(def = virDomainDefParseString(xml, data->caps, data->xmlopt,
|
|
|
|
1 << VIR_DOMAIN_VIRT_VBOX,
|
2010-08-31 18:01:45 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE))) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(def->name, &machineNameUtf16);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, def->uuid);
|
2012-10-02 09:00:54 +00:00
|
|
|
virUUIDFormat(def->uuid, uuidstr);
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3002000
|
2010-08-31 18:01:45 +00:00
|
|
|
rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
|
|
|
|
machineNameUtf16,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2010-12-23 16:25:56 +00:00
|
|
|
iid.value,
|
2010-08-31 18:01:45 +00:00
|
|
|
&machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION < 4000000 /* 3002000 <= VBOX_API_VERSION < 4000000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
|
|
|
|
machineNameUtf16,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2010-12-23 16:25:56 +00:00
|
|
|
iid.value,
|
2010-08-31 18:01:45 +00:00
|
|
|
override,
|
|
|
|
&machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
|
|
|
|
NULL,
|
|
|
|
machineNameUtf16,
|
|
|
|
NULL,
|
|
|
|
iid.value,
|
|
|
|
override,
|
|
|
|
&machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4002000 */
|
2012-10-02 09:00:54 +00:00
|
|
|
snprintf(createFlags, sizeof(createFlags), "%s%s%s%s",
|
|
|
|
flagsUUIDPrefix,
|
|
|
|
uuidstr,
|
|
|
|
flagsSeparator,
|
|
|
|
flagsForceOverwrite
|
|
|
|
);
|
|
|
|
VBOX_UTF8_TO_UTF16(createFlags, &createFlagsUtf16);
|
|
|
|
rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
|
|
|
|
NULL,
|
|
|
|
machineNameUtf16,
|
|
|
|
0,
|
|
|
|
nsnull,
|
|
|
|
nsnull,
|
|
|
|
createFlagsUtf16,
|
|
|
|
&machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4002000 */
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_UTF16_FREE(machineNameUtf16);
|
|
|
|
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not define a domain, rc=%08x"), (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-01-28 21:03:24 +00:00
|
|
|
rc = machine->vtbl->SetMemorySize(machine,
|
|
|
|
VIR_DIV_UP(def->mem.cur_balloon, 1024));
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not set the memory size of the domain to: %llu Kb, "
|
|
|
|
"rc=%08x"),
|
|
|
|
def->mem.cur_balloon, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
|
2010-09-29 16:20:07 +00:00
|
|
|
if (def->vcpus != def->maxvcpus) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("current vcpu count must equal maximum"));
|
2010-09-29 16:20:07 +00:00
|
|
|
}
|
|
|
|
rc = machine->vtbl->SetCPUCount(machine, def->maxvcpus);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not set the number of virtual CPUs to: %u, rc=%08x"),
|
|
|
|
def->maxvcpus, (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2013-09-23 13:02:38 +00:00
|
|
|
rc = machine->vtbl->SetPAEEnabled(machine,
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_PAE] ==
|
|
|
|
VIR_DOMAIN_FEATURE_STATE_ON);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION == 3001000
|
2010-08-31 18:01:45 +00:00
|
|
|
rc = machine->vtbl->SetCpuProperty(machine, CpuPropertyType_PAE,
|
2013-09-23 13:02:38 +00:00
|
|
|
def->features[VIR_DOMAIN_FEATURE_PAE] ==
|
|
|
|
VIR_DOMAIN_FEATURE_STATE_ON);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 3002000
|
2010-08-31 18:01:45 +00:00
|
|
|
rc = machine->vtbl->SetCPUProperty(machine, CPUPropertyType_PAE,
|
2013-09-23 13:02:38 +00:00
|
|
|
def->features[VIR_DOMAIN_FEATURE_PAE] ==
|
|
|
|
VIR_DOMAIN_FEATURE_STATE_ON);
|
2010-08-31 18:01:45 +00:00
|
|
|
#endif
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not change PAE status to: %s, rc=%08x"),
|
2013-09-23 13:02:38 +00:00
|
|
|
(def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_DOMAIN_FEATURE_STATE_ON)
|
2012-07-18 12:06:29 +00:00
|
|
|
? _("Enabled") : _("Disabled"), (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
machine->vtbl->GetBIOSSettings(machine, &bios);
|
|
|
|
if (bios) {
|
2013-09-23 13:02:38 +00:00
|
|
|
rc = bios->vtbl->SetACPIEnabled(bios,
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_ACPI] ==
|
|
|
|
VIR_DOMAIN_FEATURE_STATE_ON);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not change ACPI status to: %s, rc=%08x"),
|
2013-09-23 13:02:38 +00:00
|
|
|
(def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON)
|
2012-07-18 12:06:29 +00:00
|
|
|
? _("Enabled") : _("Disabled"), (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
}
|
2013-09-23 13:02:38 +00:00
|
|
|
rc = bios->vtbl->SetIOAPICEnabled(bios,
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_APIC] ==
|
|
|
|
VIR_DOMAIN_FEATURE_STATE_ON);
|
2010-08-31 18:01:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not change APIC status to: %s, rc=%08x"),
|
2013-09-23 13:02:38 +00:00
|
|
|
(def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON)
|
2012-07-18 12:06:29 +00:00
|
|
|
? _("Enabled") : _("Disabled"), (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-08-31 18:01:45 +00:00
|
|
|
VBOX_RELEASE(bios);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register the machine before attaching other devices to it */
|
|
|
|
rc = data->vboxObj->vtbl->RegisterMachine(data->vboxObj, machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not define a domain, rc=%08x"), (unsigned)rc);
|
2010-08-31 18:01:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the uuid of the machine, currently it is immutable
|
|
|
|
* object so open a session to it and get it back, so that
|
|
|
|
* you can make changes to the machine setting
|
|
|
|
*/
|
2010-12-23 16:25:56 +00:00
|
|
|
machine->vtbl->GetId(machine, &mchiid.value);
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_OPEN(mchiid.value, machine);
|
2010-08-31 18:01:45 +00:00
|
|
|
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
|
|
|
|
vboxSetBootDeviceOrder(def, data, machine);
|
|
|
|
vboxAttachDrives(def, data, machine);
|
|
|
|
vboxAttachSound(def, machine);
|
|
|
|
vboxAttachNetwork(def, data, machine);
|
|
|
|
vboxAttachSerial(def, data, machine);
|
|
|
|
vboxAttachParallel(def, data, machine);
|
|
|
|
vboxAttachVideo(def, machine);
|
|
|
|
vboxAttachDisplay(def, data, machine);
|
|
|
|
vboxAttachUSB(def, data, machine);
|
2011-06-07 11:29:34 +00:00
|
|
|
vboxAttachSharedFolder(def, data, machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Save the machine settings made till now and close the
|
|
|
|
* session. also free up the mchiid variable used.
|
|
|
|
*/
|
|
|
|
rc = machine->vtbl->SaveSettings(machine);
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&mchiid);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = virGetDomain(conn, def->name, def->uuid);
|
|
|
|
VBOX_RELEASE(machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
cleanup:
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
static int
|
2011-08-11 21:44:05 +00:00
|
|
|
vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags)
|
2010-12-27 22:35:30 +00:00
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
vboxArray media = VBOX_ARRAY_INITIALIZER;
|
|
|
|
#endif
|
2011-08-12 15:07:08 +00:00
|
|
|
/* No managed save, so we explicitly reject
|
|
|
|
* VIR_DOMAIN_UNDEFINE_MANAGED_SAVE. No snapshot metadata for
|
|
|
|
* VBox, so we can trivially ignore that flag. */
|
|
|
|
virCheckFlags(VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Block for checking if HDD's are attched to VM.
|
|
|
|
* considering just IDE bus for now. Also skipped
|
|
|
|
* chanel=1 and device=0 (Secondary Master) as currenlty
|
2010-12-27 22:35:30 +00:00
|
|
|
* it is allocated to CD/DVD Drive by default.
|
|
|
|
*
|
|
|
|
* Only do this for VirtualBox 3.x and before. Since
|
|
|
|
* VirtualBox 4.0 the Unregister method can do this for use.
|
2009-12-04 13:49:45 +00:00
|
|
|
*/
|
|
|
|
{
|
|
|
|
PRUnichar *hddcnameUtf16 = NULL;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
char *hddcname;
|
|
|
|
ignore_value(VIR_STRDUP(hddcname, "IDE"));
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(hddcname, &hddcnameUtf16);
|
|
|
|
VIR_FREE(hddcname);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Open a Session for the machine */
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (NS_SUCCEEDED(rc) && machine) {
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Disconnect all the drives if present */
|
|
|
|
machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 0);
|
|
|
|
machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 0, 1);
|
|
|
|
machine->vtbl->DetachHardDisk(machine, hddcnameUtf16, 1, 1);
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
/* get all the controller first, then the attachments and
|
|
|
|
* remove them all so that the machine can be undefined
|
|
|
|
*/
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray storageControllers = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0, j = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&storageControllers, machine,
|
|
|
|
machine->vtbl->GetStorageControllers);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < storageControllers.count; i++) {
|
|
|
|
IStorageController *strCtl = storageControllers.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *strCtlName = NULL;
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (!strCtl)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
strCtl->vtbl->GetName(strCtl, &strCtlName);
|
2010-12-27 22:35:30 +00:00
|
|
|
vboxArrayGetWithPtrArg(&mediumAttachments, machine,
|
|
|
|
machine->vtbl->GetMediumAttachmentsOfController,
|
|
|
|
strCtlName);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (j = 0; j < mediumAttachments.count; j++) {
|
|
|
|
IMediumAttachment *medAtt = mediumAttachments.items[j];
|
2009-12-04 13:49:45 +00:00
|
|
|
PRInt32 port = ~0U;
|
|
|
|
PRInt32 device = ~0U;
|
|
|
|
|
|
|
|
if (!medAtt)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
medAtt->vtbl->GetPort(medAtt, &port);
|
|
|
|
medAtt->vtbl->GetDevice(medAtt, &device);
|
|
|
|
|
|
|
|
if ((port != ~0U) && (device != ~0U)) {
|
|
|
|
machine->vtbl->DetachDevice(machine,
|
|
|
|
strCtlName,
|
|
|
|
port,
|
|
|
|
device);
|
|
|
|
}
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&storageControllers);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->RemoveStorageController(machine, strCtlName);
|
|
|
|
VBOX_UTF16_FREE(strCtlName);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
|
|
|
|
vboxArrayRelease(&storageControllers);
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
machine->vtbl->SaveSettings(machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddcnameUtf16);
|
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
#endif
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->UnregisterMachine(data->vboxObj, iid.value, &machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2010-12-27 22:35:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We're not interested in the array returned by the Unregister method,
|
|
|
|
* but in the side effect of unregistering the virtual machine. In order
|
|
|
|
* to call the Unregister method correctly we need to use the vboxArray
|
|
|
|
* wrapper here. */
|
|
|
|
rc = vboxArrayGetWithUintArg(&media, machine, machine->vtbl->Unregister,
|
|
|
|
CleanupMode_DetachAllReturnNone);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("UUID of machine being undefined", iid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->DeleteSettings(machine);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
IProgress *progress = NULL;
|
|
|
|
|
|
|
|
/* The IMachine Delete method takes an array of IMedium items to be
|
|
|
|
* deleted along with the virtual machine. We just want to pass an
|
|
|
|
* empty array. But instead of adding a full vboxArraySetWithReturn to
|
|
|
|
* the glue layer (in order to handle the required signature of the
|
|
|
|
* Delete method) we use a local solution here. */
|
|
|
|
# ifdef WIN32
|
|
|
|
SAFEARRAY *safeArray = NULL;
|
|
|
|
typedef HRESULT __stdcall (*IMachine_Delete)(IMachine *self,
|
|
|
|
SAFEARRAY **media,
|
|
|
|
IProgress **progress);
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4003000
|
2010-12-27 22:35:30 +00:00
|
|
|
((IMachine_Delete)machine->vtbl->Delete)(machine, &safeArray, &progress);
|
2013-11-21 14:41:07 +00:00
|
|
|
# else
|
|
|
|
((IMachine_Delete)machine->vtbl->DeleteConfig)(machine, &safeArray, &progress);
|
|
|
|
# endif
|
2010-12-27 22:35:30 +00:00
|
|
|
# else
|
2012-04-22 08:31:33 +00:00
|
|
|
/* XPCOM doesn't like NULL as an array, even when the array size is 0.
|
|
|
|
* Instead pass it a dummy array to avoid passing NULL. */
|
|
|
|
IMedium *array[] = { NULL };
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4003000
|
2012-04-22 08:31:33 +00:00
|
|
|
machine->vtbl->Delete(machine, 0, array, &progress);
|
2013-11-21 14:41:07 +00:00
|
|
|
# else
|
|
|
|
machine->vtbl->DeleteConfig(machine, 0, array, &progress);
|
|
|
|
# endif
|
2010-12-27 22:35:30 +00:00
|
|
|
# endif
|
|
|
|
if (progress != NULL) {
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not delete the domain, rc=%08x"), (unsigned)rc);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
vboxArrayUnalloc(&media);
|
|
|
|
#endif
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-08-11 21:44:05 +00:00
|
|
|
static int
|
|
|
|
vboxDomainUndefine(virDomainPtr dom)
|
|
|
|
{
|
|
|
|
return vboxDomainUndefineFlags(dom, 0);
|
|
|
|
}
|
|
|
|
|
2010-03-22 13:13:53 +00:00
|
|
|
static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
|
|
|
|
const char *xml,
|
|
|
|
int mediaChangeOnly ATTRIBUTE_UNUSED) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state = MachineState_Null;
|
|
|
|
virDomainDefPtr def = NULL;
|
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->os.type, "hvm") < 0)
|
2009-11-08 21:08:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-28 13:55:55 +00:00
|
|
|
dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE);
|
2013-02-14 08:05:36 +00:00
|
|
|
if (dev == NULL)
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (machine) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if ((state == MachineState_Running) ||
|
|
|
|
(state == MachineState_Paused)) {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (NS_SUCCEEDED(rc) && machine) {
|
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
2010-03-22 20:01:41 +00:00
|
|
|
if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
dev->data.disk->src != NULL) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IDVDDrive *dvdDrive = NULL;
|
|
|
|
/* Currently CDROM/DVD Drive is always IDE
|
|
|
|
* Secondary Master so neglecting the following
|
|
|
|
* parameter dev->data.disk->bus
|
|
|
|
*/
|
|
|
|
machine->vtbl->GetDVDDrive(machine, &dvdDrive);
|
|
|
|
if (dvdDrive) {
|
|
|
|
IDVDImage *dvdImage = NULL;
|
|
|
|
PRUnichar *dvdfileUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID dvduuid = VBOX_IID_INITIALIZER;
|
|
|
|
vboxIID dvdemptyuuid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(dev->data.disk->src, &dvdfileUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->FindDVDImage(data->vboxObj, dvdfileUtf16, &dvdImage);
|
|
|
|
if (!dvdImage) {
|
2010-12-23 16:25:56 +00:00
|
|
|
data->vboxObj->vtbl->OpenDVDImage(data->vboxObj, dvdfileUtf16, dvdemptyuuid.value, &dvdImage);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
if (dvdImage) {
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = dvdImage->vtbl->imedium.GetId((IMedium *)dvdImage, &dvduuid.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to "
|
|
|
|
"be attached to cdrom: %s, rc=%08x"),
|
|
|
|
dev->data.disk->src, (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
/* unmount the previous mounted image */
|
|
|
|
dvdDrive->vtbl->Unmount(dvdDrive);
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = dvdDrive->vtbl->MountImage(dvdDrive, dvduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file to cdrom: %s, rc=%08x"),
|
|
|
|
dev->data.disk->src, (unsigned)rc);
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("CD/DVD Image UUID:", dvduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(dvdImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&dvduuid);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(dvdfileUtf16);
|
|
|
|
VBOX_RELEASE(dvdDrive);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
|
|
|
}
|
|
|
|
} else if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
2010-03-22 20:01:41 +00:00
|
|
|
if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
|
|
|
dev->data.disk->src != NULL) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IFloppyDrive *floppyDrive;
|
|
|
|
machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
|
|
|
|
if (floppyDrive) {
|
|
|
|
rc = floppyDrive->vtbl->SetEnabled(floppyDrive, 1);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
IFloppyImage *floppyImage = NULL;
|
|
|
|
PRUnichar *fdfileUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID fduuid = VBOX_IID_INITIALIZER;
|
|
|
|
vboxIID fdemptyuuid = VBOX_IID_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(dev->data.disk->src, &fdfileUtf16);
|
|
|
|
rc = data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
|
|
|
|
fdfileUtf16,
|
|
|
|
&floppyImage);
|
|
|
|
|
|
|
|
if (!floppyImage) {
|
|
|
|
data->vboxObj->vtbl->OpenFloppyImage(data->vboxObj,
|
|
|
|
fdfileUtf16,
|
2010-12-23 16:25:56 +00:00
|
|
|
fdemptyuuid.value,
|
2009-12-04 13:49:45 +00:00
|
|
|
&floppyImage);
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (floppyImage) {
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = floppyImage->vtbl->imedium.GetId((IMedium *)floppyImage, &fduuid.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("can't get the uuid of the file to be "
|
|
|
|
"attached to floppy drive: %s, rc=%08x"),
|
|
|
|
dev->data.disk->src, (unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = floppyDrive->vtbl->MountImage(floppyDrive, fduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file to floppy drive: %s, rc=%08x"),
|
|
|
|
dev->data.disk->src, (unsigned)rc);
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("attached floppy, UUID:", fduuid.value);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_RELEASE(floppyImage);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&fduuid);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(fdfileUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(floppyDrive);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
|
|
|
if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
|
|
|
if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-07 11:29:34 +00:00
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
|
|
|
|
dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
|
|
|
|
PRUnichar *nameUtf16;
|
|
|
|
PRUnichar *hostPathUtf16;
|
|
|
|
PRBool writable;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
|
|
|
|
VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16);
|
|
|
|
writable = !dev->data.fs->readonly;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2011-06-07 11:29:34 +00:00
|
|
|
rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
|
|
|
|
writable);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2011-06-07 11:29:34 +00:00
|
|
|
rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
|
|
|
|
writable, PR_FALSE);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2011-06-07 11:29:34 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach shared folder '%s', rc=%08x"),
|
|
|
|
dev->data.fs->dst, (unsigned)rc);
|
2011-06-07 11:29:34 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_UTF16_FREE(hostPathUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->SaveSettings(machine);
|
|
|
|
VBOX_RELEASE(machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
virDomainDeviceDefFree(dev);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-22 13:13:53 +00:00
|
|
|
static int vboxDomainAttachDevice(virDomainPtr dom, const char *xml) {
|
|
|
|
return vboxDomainAttachDeviceImpl(dom, xml, 0);
|
|
|
|
}
|
|
|
|
|
2011-07-13 22:24:38 +00:00
|
|
|
static int
|
|
|
|
vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2011-06-08 06:33:33 +00:00
|
|
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot modify the persistent configuration of a domain"));
|
2010-01-14 01:44:26 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-03-22 13:13:53 +00:00
|
|
|
return vboxDomainAttachDeviceImpl(dom, xml, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxDomainUpdateDeviceFlags(virDomainPtr dom, const char *xml,
|
|
|
|
unsigned int flags) {
|
2011-06-08 06:33:33 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_CURRENT |
|
|
|
|
VIR_DOMAIN_AFFECT_LIVE |
|
|
|
|
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
2010-04-16 12:04:31 +00:00
|
|
|
|
2011-06-08 06:33:33 +00:00
|
|
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot modify the persistent configuration of a domain"));
|
2010-03-22 13:13:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vboxDomainAttachDeviceImpl(dom, xml, 1);
|
2010-01-14 01:44:26 +00:00
|
|
|
}
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2009-04-17 16:09:07 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-04-17 16:09:07 +00:00
|
|
|
PRUint32 state = MachineState_Null;
|
|
|
|
virDomainDefPtr def = NULL;
|
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2009-04-17 16:09:07 +00:00
|
|
|
return ret;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->os.type, "hvm") < 0)
|
2009-11-08 21:08:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-28 13:55:55 +00:00
|
|
|
dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
|
|
|
|
VIR_DOMAIN_XML_INACTIVE);
|
2013-02-14 08:05:36 +00:00
|
|
|
if (dev == NULL)
|
2009-04-17 16:09:07 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (machine) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
2009-04-17 16:09:07 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if ((state == MachineState_Running) ||
|
|
|
|
(state == MachineState_Paused)) {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(iid.value, machine);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (NS_SUCCEEDED(rc) && machine) {
|
|
|
|
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
|
|
|
if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
|
|
|
IDVDDrive *dvdDrive = NULL;
|
|
|
|
/* Currently CDROM/DVD Drive is always IDE
|
|
|
|
* Secondary Master so neglecting the following
|
|
|
|
* parameter dev->data.disk->bus
|
|
|
|
*/
|
|
|
|
machine->vtbl->GetDVDDrive(machine, &dvdDrive);
|
|
|
|
if (dvdDrive) {
|
|
|
|
rc = dvdDrive->vtbl->Unmount(dvdDrive);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not de-attach the mounted ISO, rc=%08x"),
|
|
|
|
(unsigned)rc);
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
VBOX_RELEASE(dvdDrive);
|
|
|
|
}
|
|
|
|
} else if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
|
|
|
}
|
|
|
|
} else if (dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
|
|
|
if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
|
|
|
IFloppyDrive *floppyDrive;
|
|
|
|
machine->vtbl->GetFloppyDrive(machine, &floppyDrive);
|
|
|
|
if (floppyDrive) {
|
|
|
|
PRBool enabled = PR_FALSE;
|
|
|
|
|
|
|
|
floppyDrive->vtbl->GetEnabled(floppyDrive, &enabled);
|
|
|
|
if (enabled) {
|
|
|
|
rc = floppyDrive->vtbl->Unmount(floppyDrive);
|
2009-04-17 16:09:07 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not attach the file "
|
|
|
|
"to floppy drive, rc=%08x"),
|
|
|
|
(unsigned)rc);
|
2009-04-17 16:09:07 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
/* If you are here means floppy drive is already unmounted
|
|
|
|
* so don't flag error, just say everything is fine and quit
|
|
|
|
*/
|
|
|
|
ret = 0;
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(floppyDrive);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (dev->data.disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
|
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
|
|
|
|
if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
|
|
|
|
if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-07 11:29:34 +00:00
|
|
|
} else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
|
|
|
|
dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
|
|
|
|
PRUnichar *nameUtf16;
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
|
|
|
|
|
|
|
|
rc = machine->vtbl->RemoveSharedFolder(machine, nameUtf16);
|
|
|
|
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not detach shared folder '%s', rc=%08x"),
|
|
|
|
dev->data.fs->dst, (unsigned)rc);
|
2011-06-07 11:29:34 +00:00
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
machine->vtbl->SaveSettings(machine);
|
|
|
|
VBOX_RELEASE(machine);
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-04-17 16:09:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-04-17 16:09:07 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
virDomainDeviceDefFree(dev);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-13 22:24:38 +00:00
|
|
|
static int
|
|
|
|
vboxDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2011-06-08 06:33:33 +00:00
|
|
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot modify the persistent configuration of a domain"));
|
2010-01-14 01:44:26 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vboxDomainDetachDevice(dom, xml);
|
|
|
|
}
|
|
|
|
|
2010-03-26 12:40:34 +00:00
|
|
|
static int
|
|
|
|
vboxDomainSnapshotGetAll(virDomainPtr dom,
|
|
|
|
IMachine *machine,
|
|
|
|
ISnapshot ***snapshots)
|
|
|
|
{
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID empty = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
ISnapshot **list = NULL;
|
|
|
|
PRUint32 count;
|
|
|
|
nsresult rc;
|
|
|
|
unsigned int next;
|
|
|
|
unsigned int top;
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetSnapshotCount(machine, &count);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get snapshot count for domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count == 0)
|
|
|
|
goto out;
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC_N(list, count) < 0)
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->GetSnapshot(machine, empty.value, list);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = machine->vtbl->FindSnapshot(machine, empty.value, list);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc) || !list[0]) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get root snapshot for domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BFS walk through snapshot tree */
|
|
|
|
top = 1;
|
|
|
|
for (next = 0; next < count; next++) {
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray children = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
if (!list[next]) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected number of snapshots < %u"), count);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&children, list[next],
|
|
|
|
list[next]->vtbl->GetChildren);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("could not get children snapshots"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < children.count; i++) {
|
|
|
|
ISnapshot *child = children.items[i];
|
|
|
|
if (!child)
|
2010-03-26 12:40:34 +00:00
|
|
|
continue;
|
|
|
|
if (top == count) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected number of snapshots > %u"), count);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&children);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto error;
|
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
VBOX_ADDREF(child);
|
|
|
|
list[top++] = child;
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&children);
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
*snapshots = list;
|
|
|
|
return count;
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (list) {
|
|
|
|
for (next = 0; next < count; next++)
|
|
|
|
VBOX_RELEASE(list[next]);
|
|
|
|
}
|
|
|
|
VIR_FREE(list);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ISnapshot *
|
|
|
|
vboxDomainSnapshotGet(vboxGlobalData *data,
|
|
|
|
virDomainPtr dom,
|
|
|
|
IMachine *machine,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
ISnapshot **snapshots = NULL;
|
|
|
|
ISnapshot *snapshot = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
int count = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
if ((count = vboxDomainSnapshotGetAll(dom, machine, &snapshots)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
PRUnichar *nameUtf16;
|
|
|
|
char *nameUtf8;
|
|
|
|
|
|
|
|
rc = snapshots[i]->vtbl->GetName(snapshots[i], &nameUtf16);
|
|
|
|
if (NS_FAILED(rc) || !nameUtf16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("could not get snapshot name"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
if (STREQ(name, nameUtf8))
|
|
|
|
snapshot = snapshots[i];
|
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
|
|
|
|
|
|
|
if (snapshot)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!snapshot) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("domain %s has no snapshots with name %s"),
|
|
|
|
dom->name, name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (count > 0) {
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
if (snapshots[i] != snapshot)
|
|
|
|
VBOX_RELEASE(snapshots[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(snapshots);
|
|
|
|
return snapshot;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vboxDomainSnapshotCreateXML(virDomainPtr dom,
|
|
|
|
const char *xmlDesc,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, virDomainSnapshotPtr, NULL);
|
|
|
|
virDomainSnapshotDefPtr def = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
IConsole *console = NULL;
|
|
|
|
IProgress *progress = NULL;
|
|
|
|
ISnapshot *snapshot = NULL;
|
|
|
|
PRUnichar *name = NULL;
|
|
|
|
PRUnichar *description = NULL;
|
|
|
|
PRUint32 state;
|
|
|
|
nsresult rc;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2010-03-26 12:40:34 +00:00
|
|
|
nsresult result;
|
|
|
|
#else
|
|
|
|
PRInt32 result;
|
|
|
|
#endif
|
|
|
|
|
snapshot: allow recreation of metadata
The first two flags are essential for being able to replicate
snapshot hierarchies across multiple hosts, which will come in
handy for supervised migrations. It also allows a management app
to take a snapshot of a transient domain, save the metadata, stop
the domain, recreate a new transient domain by the same name,
redefine the snapshot, then revert to it.
This is not quite as convenient as leaving the metadata behind
after a domain is no longer around, but doing that has a few
problems: 1. the libvirt API can only delete snapshot metadata
if there is a valid domain handle to use to get to that snapshot
object - if stale data is left behind without a domain, there is
no way to request that the data be cleaned up. 2. creating a new
domain with the same name but different uuid than the older
domain where a snapshot existed cannot use the older snapshot
data; this risks confusing libvirt, and forbidding the stale
data is similar to the recent patch to forbid stale managed save.
The first two flags might be useful on hypervisors with no metadata,
but only for modifying the notion of the current snapshot;
however, I don't know how to do that for ESX or VBox.
The third flag is a convenience option, to combine a creation with
a delete metadata into one step. It is trivial for hypervisors
with no metadata.
The qemu changes will be involved enough to warrant a separate patch.
* include/libvirt/libvirt.h.in
(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)
(VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)
(VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA): New flags.
* src/libvirt.c (virDomainSnapshotCreateXML): Document them, and
enforce mutual exclusion.
* src/esx/esx_driver.c (esxDomainSnapshotCreateXML): Trivial
implementation.
* src/vbox/vbox_tmpl.c (vboxDomainSnapshotCreateXML): Likewise.
* docs/formatsnapshot.html.in: Document re-creation.
2011-08-31 01:02:46 +00:00
|
|
|
/* VBox has no snapshot metadata, so this flag is trivial. */
|
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, NULL);
|
2010-04-16 12:04:31 +00:00
|
|
|
|
2013-03-05 15:17:24 +00:00
|
|
|
if (!(def = virDomainSnapshotDefParseString(xmlDesc, data->caps,
|
2013-03-31 18:03:42 +00:00
|
|
|
data->xmlopt, 0, 0)))
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2011-08-20 04:03:38 +00:00
|
|
|
if (def->ndisks) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("disk snapshots not supported yet"));
|
2011-08-20 04:03:38 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&domiid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetState(machine, &state);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get domain state"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((state >= MachineState_FirstOnline)
|
|
|
|
&& (state <= MachineState_LastOnline)) {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN_EXISTING(domiid.value, machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
} else {
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(domiid.value, machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_SUCCEEDED(rc))
|
|
|
|
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not open VirtualBox session with domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16(def->name, &name);
|
|
|
|
if (!name) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->description) {
|
|
|
|
VBOX_UTF8_TO_UTF16(def->description, &description);
|
|
|
|
if (!description) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = console->vtbl->TakeSnapshot(console, name, description, &progress);
|
|
|
|
if (NS_FAILED(rc) || !progress) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not take snapshot of domain %s"), dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
progress->vtbl->GetResultCode(progress, &result);
|
|
|
|
if (NS_FAILED(result)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not take snapshot of domain %s"), dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetCurrentSnapshot(machine, &snapshot);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get current snapshot of domain %s"),
|
2010-03-26 12:40:34 +00:00
|
|
|
dom->name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomainSnapshot(dom, def->name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
VBOX_UTF16_FREE(description);
|
|
|
|
VBOX_UTF16_FREE(name);
|
|
|
|
VBOX_RELEASE(console);
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2010-03-26 12:40:34 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&domiid);
|
2010-03-26 12:40:34 +00:00
|
|
|
virDomainSnapshotDefFree(def);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
2011-05-06 19:53:10 +00:00
|
|
|
vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snap = NULL;
|
|
|
|
ISnapshot *parent = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
virDomainSnapshotDefPtr def = NULL;
|
|
|
|
PRUnichar *str16;
|
|
|
|
char *str8;
|
|
|
|
PRInt64 timestamp;
|
|
|
|
PRBool online = PR_FALSE;
|
|
|
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&domiid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2013-07-04 10:17:38 +00:00
|
|
|
goto cleanup;
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->name, snapshot->name) < 0)
|
|
|
|
goto cleanup;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
rc = snap->vtbl->GetDescription(snap, &str16);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get description of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (str16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(str16, &str8);
|
|
|
|
VBOX_UTF16_FREE(str16);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->description, str8) < 0) {
|
|
|
|
VBOX_UTF8_FREE(str8);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-03-26 12:40:34 +00:00
|
|
|
VBOX_UTF8_FREE(str8);
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = snap->vtbl->GetTimeStamp(snap, ×tamp);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get creation time of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
/* timestamp is in milliseconds while creationTime in seconds */
|
|
|
|
def->creationTime = timestamp / 1000;
|
|
|
|
|
|
|
|
rc = snap->vtbl->GetParent(snap, &parent);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get parent of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (parent) {
|
|
|
|
rc = parent->vtbl->GetName(parent, &str16);
|
|
|
|
if (NS_FAILED(rc) || !str16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get name of parent of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VBOX_UTF16_TO_UTF8(str16, &str8);
|
|
|
|
VBOX_UTF16_FREE(str16);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def->parent, str8) < 0) {
|
|
|
|
VBOX_UTF8_FREE(str8);
|
2013-07-04 10:17:38 +00:00
|
|
|
goto cleanup;
|
2013-05-03 12:50:19 +00:00
|
|
|
}
|
|
|
|
VBOX_UTF8_FREE(str8);
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rc = snap->vtbl->GetOnline(snap, &online);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get online state of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (online)
|
|
|
|
def->state = VIR_DOMAIN_RUNNING;
|
|
|
|
else
|
|
|
|
def->state = VIR_DOMAIN_SHUTOFF;
|
|
|
|
|
|
|
|
virUUIDFormat(dom->uuid, uuidstr);
|
snapshot: allow full domain xml in snapshot
Just like VM saved state images (virsh save), snapshots MUST
track the inactive domain xml to detect any ABI incompatibilities.
The indentation is not perfect, but functionality comes before form.
Later patches will actually supply a full domain; for now, this
wires up the storage to support one, but doesn't ever generate one
in dumpxml output.
Happily, libvirt.c was already rejecting use of VIR_DOMAIN_XML_SECURE
from read-only connections, even though before this patch, there was
no information to be secured by the use of that flag.
And while we're at it, mark the libvirt snapshot metadata files
as internal-use only.
* src/libvirt.c (virDomainSnapshotGetXMLDesc): Document flag.
* src/conf/domain_conf.h (_virDomainSnapshotDef): Add member.
(virDomainSnapshotDefParseString, virDomainSnapshotDefFormat):
Update signature.
* src/conf/domain_conf.c (virDomainSnapshotDefFree): Clean up.
(virDomainSnapshotDefParseString): Optionally parse domain.
(virDomainSnapshotDefFormat): Output full domain.
* src/esx/esx_driver.c (esxDomainSnapshotCreateXML)
(esxDomainSnapshotGetXMLDesc): Update callers.
* src/vbox/vbox_tmpl.c (vboxDomainSnapshotCreateXML)
(vboxDomainSnapshotGetXMLDesc): Likewise.
* src/qemu/qemu_driver.c (qemuDomainSnapshotCreateXML)
(qemuDomainSnapshotLoad, qemuDomainSnapshotGetXMLDesc)
(qemuDomainSnapshotWriteMetadata): Likewise.
* docs/formatsnapshot.html.in: Rework doc example.
Based on a patch by Philipp Hahn.
2011-08-13 01:19:47 +00:00
|
|
|
ret = virDomainSnapshotDefFormat(uuidstr, def, flags, 0);
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainSnapshotDefFree(def);
|
|
|
|
VBOX_RELEASE(parent);
|
|
|
|
VBOX_RELEASE(snap);
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&domiid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotNum(virDomainPtr dom,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
PRUint32 snapshotCount;
|
|
|
|
|
2011-10-03 21:20:25 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
|
2010-04-16 12:04:31 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-08-12 14:51:15 +00:00
|
|
|
/* VBox snapshots do not require libvirt to maintain any metadata. */
|
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_LIST_METADATA) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-03-26 12:40:34 +00:00
|
|
|
rc = machine->vtbl->GetSnapshotCount(machine, &snapshotCount);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get snapshot count for domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-10-03 21:20:25 +00:00
|
|
|
/* VBox has at most one root snapshot. */
|
|
|
|
if (snapshotCount && (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS))
|
|
|
|
ret = 1;
|
|
|
|
else
|
|
|
|
ret = snapshotCount;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotListNames(virDomainPtr dom,
|
|
|
|
char **names,
|
|
|
|
int nameslen,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
ISnapshot **snapshots = NULL;
|
|
|
|
int count = 0;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
2011-10-03 21:20:25 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_LIST_ROOTS |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_LIST_METADATA, -1);
|
2010-04-16 12:04:31 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-08-12 14:51:15 +00:00
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_LIST_METADATA) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-10-03 21:20:25 +00:00
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) {
|
|
|
|
vboxIID empty = VBOX_IID_INITIALIZER;
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC_N(snapshots, 1) < 0)
|
2011-10-03 21:20:25 +00:00
|
|
|
goto cleanup;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2011-10-03 21:20:25 +00:00
|
|
|
rc = machine->vtbl->GetSnapshot(machine, empty.value, snapshots);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2011-10-03 21:20:25 +00:00
|
|
|
rc = machine->vtbl->FindSnapshot(machine, empty.value, snapshots);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2011-10-03 21:20:25 +00:00
|
|
|
if (NS_FAILED(rc) || !snapshots[0]) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get root snapshot for domain %s"),
|
|
|
|
dom->name);
|
2011-10-03 21:20:25 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
count = 1;
|
|
|
|
} else {
|
|
|
|
if ((count = vboxDomainSnapshotGetAll(dom, machine, &snapshots)) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2010-03-26 12:40:34 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nameslen; i++) {
|
|
|
|
PRUnichar *nameUtf16;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
if (i >= count)
|
|
|
|
break;
|
|
|
|
|
|
|
|
rc = snapshots[i]->vtbl->GetName(snapshots[i], &nameUtf16);
|
|
|
|
if (NS_FAILED(rc) || !nameUtf16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("could not get snapshot name"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(names[i], name) < 0) {
|
|
|
|
VBOX_UTF8_FREE(name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2013-05-03 12:50:19 +00:00
|
|
|
VBOX_UTF8_FREE(name);
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (count <= nameslen)
|
|
|
|
ret = count;
|
|
|
|
else
|
|
|
|
ret = nameslen;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (count > 0) {
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
VBOX_RELEASE(snapshots[i]);
|
|
|
|
}
|
|
|
|
VIR_FREE(snapshots);
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vboxDomainSnapshotLookupByName(virDomainPtr dom,
|
|
|
|
const char *name,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, virDomainSnapshotPtr, NULL);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snapshot = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(snapshot = vboxDomainSnapshotGet(data, dom, machine, name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = virGetDomainSnapshot(dom, name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(snapshot);
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainHasCurrentSnapshot(virDomainPtr dom,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snapshot = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetCurrentSnapshot(machine, &snapshot);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get current snapshot"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (snapshot)
|
|
|
|
ret = 1;
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-09-29 20:26:03 +00:00
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vboxDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, virDomainSnapshotPtr, NULL);
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snap = NULL;
|
|
|
|
ISnapshot *parent = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
|
|
|
char *name = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2011-09-29 20:26:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rc = snap->vtbl->GetParent(snap, &parent);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get parent of snapshot %s"),
|
|
|
|
snapshot->name);
|
2011-09-29 20:26:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!parent) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT,
|
|
|
|
_("snapshot '%s' does not have a parent"),
|
|
|
|
snapshot->name);
|
2011-09-29 20:26:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = parent->vtbl->GetName(parent, &nameUtf16);
|
|
|
|
if (NS_FAILED(rc) || !nameUtf16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get name of parent of snapshot %s"),
|
|
|
|
snapshot->name);
|
2011-09-29 20:26:03 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &name);
|
|
|
|
if (!name) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomainSnapshot(dom, name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_UTF8_FREE(name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_RELEASE(snap);
|
|
|
|
VBOX_RELEASE(parent);
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-26 12:40:34 +00:00
|
|
|
static virDomainSnapshotPtr
|
|
|
|
vboxDomainSnapshotCurrent(virDomainPtr dom,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, virDomainSnapshotPtr, NULL);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snapshot = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
|
|
|
char *name = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetCurrentSnapshot(machine, &snapshot);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get current snapshot"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!snapshot) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("domain has no snapshots"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = snapshot->vtbl->GetName(snapshot, &nameUtf16);
|
|
|
|
if (NS_FAILED(rc) || !nameUtf16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get current snapshot name"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &name);
|
|
|
|
if (!name) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetDomainSnapshot(dom, name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_UTF8_FREE(name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_RELEASE(snapshot);
|
|
|
|
VBOX_RELEASE(machine);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-05-25 02:28:54 +00:00
|
|
|
static int
|
|
|
|
vboxDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snap = NULL;
|
|
|
|
ISnapshot *current = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
|
|
|
char *name = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetCurrentSnapshot(machine, ¤t);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get current snapshot"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!current) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = current->vtbl->GetName(current, &nameUtf16);
|
|
|
|
if (NS_FAILED(rc) || !nameUtf16) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get current snapshot name"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &name);
|
|
|
|
if (!name) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = STREQ(snapshot->name, name);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_UTF8_FREE(name);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_RELEASE(snap);
|
|
|
|
VBOX_RELEASE(current);
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snap = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2012-05-25 02:28:54 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check that snapshot exists. If so, there is no metadata. */
|
|
|
|
if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(snap);
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-03-26 12:40:34 +00:00
|
|
|
static int
|
|
|
|
vboxDomainSnapshotRestore(virDomainPtr dom,
|
|
|
|
IMachine *machine,
|
|
|
|
ISnapshot *snapshot)
|
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
nsresult rc;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = snapshot->vtbl->GetId(snapshot, &iid.value);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get snapshot UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->SetCurrentSnapshot(machine, iid.value);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not restore snapshot for domain %s"), dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotRestore(virDomainPtr dom,
|
|
|
|
IMachine *machine,
|
|
|
|
ISnapshot *snapshot)
|
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
|
|
|
IConsole *console = NULL;
|
|
|
|
IProgress *progress = NULL;
|
|
|
|
PRUint32 state;
|
|
|
|
nsresult rc;
|
|
|
|
PRInt32 result;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = machine->vtbl->GetId(machine, &domiid.value);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get domain UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetState(machine, &state);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get domain state"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state >= MachineState_FirstOnline
|
|
|
|
&& state <= MachineState_LastOnline) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
|
_("domain %s is already running"), dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(domiid.value, machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_SUCCEEDED(rc))
|
|
|
|
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not open VirtualBox session with domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = console->vtbl->RestoreSnapshot(console, snapshot, &progress);
|
|
|
|
if (NS_FAILED(rc) || !progress) {
|
|
|
|
if (rc == VBOX_E_INVALID_VM_STATE) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot restore domain snapshot for running domain"));
|
2010-03-26 12:40:34 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not restore snapshot for domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
progress->vtbl->GetResultCode(progress, &result);
|
|
|
|
if (NS_FAILED(result)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not restore snapshot for domain %s"), dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
VBOX_RELEASE(console);
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&domiid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
2010-04-16 12:04:31 +00:00
|
|
|
unsigned int flags)
|
2010-03-26 12:40:34 +00:00
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *newSnapshot = NULL;
|
|
|
|
ISnapshot *prevSnapshot = NULL;
|
|
|
|
PRBool online = PR_FALSE;
|
|
|
|
PRUint32 state;
|
|
|
|
nsresult rc;
|
|
|
|
|
2010-04-16 12:04:31 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&domiid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
newSnapshot = vboxDomainSnapshotGet(data, dom, machine, snapshot->name);
|
|
|
|
if (!newSnapshot)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rc = newSnapshot->vtbl->GetOnline(newSnapshot, &online);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get online state of snapshot %s"),
|
|
|
|
snapshot->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetCurrentSnapshot(machine, &prevSnapshot);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get current snapshot of domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetState(machine, &state);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get domain state"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state >= MachineState_FirstOnline
|
|
|
|
&& state <= MachineState_LastOnline) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot revert snapshot of running domain"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vboxDomainSnapshotRestore(dom, machine, newSnapshot))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (online) {
|
|
|
|
ret = vboxDomainCreate(dom);
|
|
|
|
if (!ret)
|
|
|
|
vboxDomainSnapshotRestore(dom, machine, prevSnapshot);
|
|
|
|
} else
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(prevSnapshot);
|
|
|
|
VBOX_RELEASE(newSnapshot);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&domiid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotDeleteSingle(vboxGlobalData *data,
|
|
|
|
IConsole *console,
|
|
|
|
ISnapshot *snapshot)
|
|
|
|
{
|
|
|
|
IProgress *progress = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
int ret = -1;
|
|
|
|
nsresult rc;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2010-03-26 12:40:34 +00:00
|
|
|
nsresult result;
|
|
|
|
#else
|
|
|
|
PRInt32 result;
|
|
|
|
#endif
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = snapshot->vtbl->GetId(snapshot, &iid.value);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get snapshot UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = console->vtbl->DiscardSnapshot(console, iid.value, &progress);
|
2010-03-26 12:40:34 +00:00
|
|
|
#else
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = console->vtbl->DeleteSnapshot(console, iid.value, &progress);
|
2010-03-26 12:40:34 +00:00
|
|
|
#endif
|
|
|
|
if (NS_FAILED(rc) || !progress) {
|
|
|
|
if (rc == VBOX_E_INVALID_VM_STATE) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot delete domain snapshot for running domain"));
|
2010-03-26 12:40:34 +00:00
|
|
|
} else {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not delete snapshot"));
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
progress->vtbl->GetResultCode(progress, &result);
|
|
|
|
if (NS_FAILED(result)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not delete snapshot"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(progress);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotDeleteTree(vboxGlobalData *data,
|
|
|
|
IConsole *console,
|
|
|
|
ISnapshot *snapshot)
|
|
|
|
{
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray children = VBOX_ARRAY_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
int ret = -1;
|
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2010-03-26 12:40:34 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&children, snapshot, snapshot->vtbl->GetChildren);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get children snapshots"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < children.count; i++) {
|
|
|
|
if (vboxDomainSnapshotDeleteTree(data, console, children.items[i]))
|
|
|
|
goto cleanup;
|
2010-03-26 12:40:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = vboxDomainSnapshotDeleteSingle(data, console, snapshot);
|
|
|
|
|
|
|
|
cleanup:
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&children);
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virDomainPtr dom = snapshot->domain;
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID domiid = VBOX_IID_INITIALIZER;
|
2010-03-26 12:40:34 +00:00
|
|
|
IMachine *machine = NULL;
|
|
|
|
ISnapshot *snap = NULL;
|
|
|
|
IConsole *console = NULL;
|
|
|
|
PRUint32 state;
|
|
|
|
nsresult rc;
|
|
|
|
|
2011-08-12 03:12:05 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
|
|
|
|
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, -1);
|
2010-04-16 12:04:31 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&domiid, dom->uuid);
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching UUID"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name);
|
|
|
|
if (!snap)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetState(machine, &state);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not get domain state"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2011-08-12 03:12:05 +00:00
|
|
|
/* VBOX snapshots do not require any libvirt metadata, making this
|
|
|
|
* flag trivial once we know we have a valid snapshot. */
|
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY) {
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-03-26 12:40:34 +00:00
|
|
|
if (state >= MachineState_FirstOnline
|
|
|
|
&& state <= MachineState_LastOnline) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("cannot delete snapshots of running domain"));
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_SESSION_OPEN(domiid.value, machine);
|
2010-03-26 12:40:34 +00:00
|
|
|
if (NS_SUCCEEDED(rc))
|
|
|
|
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not open VirtualBox session with domain %s"),
|
|
|
|
dom->name);
|
2010-03-26 12:40:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN)
|
|
|
|
ret = vboxDomainSnapshotDeleteTree(data, console, snap);
|
|
|
|
else
|
|
|
|
ret = vboxDomainSnapshotDeleteSingle(data, console, snap);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
VBOX_RELEASE(snap);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&domiid);
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2010-03-26 12:40:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
|
2009-07-24 16:12:16 +00:00
|
|
|
/* No Callback support for VirtualBox 2.2.* series */
|
2011-10-29 19:26:57 +00:00
|
|
|
/* No Callback support for VirtualBox 4.* series */
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* !(VBOX_API_VERSION == 2002000 || VBOX_API_VERSION >= 4000000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* Functions needed for Callbacks */
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnMachineStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *machineId, PRUint32 state)
|
|
|
|
{
|
2009-07-24 16:12:16 +00:00
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
int event = 0;
|
|
|
|
int detail = 0;
|
|
|
|
|
|
|
|
vboxDriverLock(g_pVBoxGlobalData);
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p, State: %d", pThis, state);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
|
|
|
|
if (machineId) {
|
|
|
|
char *machineIdUtf8 = NULL;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
|
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(machineId, &machineIdUtf8);
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(machineIdUtf8, uuid));
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
|
|
|
|
if (dom) {
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr ev;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
if (state == MachineState_Starting) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STARTED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STARTED_BOOTED;
|
|
|
|
} else if (state == MachineState_Restoring) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STARTED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STARTED_RESTORED;
|
|
|
|
} else if (state == MachineState_Paused) {
|
|
|
|
event = VIR_DOMAIN_EVENT_SUSPENDED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
|
|
|
|
} else if (state == MachineState_Running) {
|
|
|
|
event = VIR_DOMAIN_EVENT_RESUMED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_RESUMED_UNPAUSED;
|
|
|
|
} else if (state == MachineState_PoweredOff) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STOPPED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN;
|
|
|
|
} else if (state == MachineState_Stopping) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STOPPED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STOPPED_DESTROYED;
|
|
|
|
} else if (state == MachineState_Aborted) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STOPPED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STOPPED_CRASHED;
|
|
|
|
} else if (state == MachineState_Saving) {
|
|
|
|
event = VIR_DOMAIN_EVENT_STOPPED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STOPPED_SAVED;
|
|
|
|
} else {
|
|
|
|
event = VIR_DOMAIN_EVENT_STOPPED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN;
|
|
|
|
}
|
|
|
|
|
2013-11-21 17:03:26 +00:00
|
|
|
ev = virDomainEventLifecycleNewFromDom(dom, event, detail);
|
2010-03-18 13:17:14 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
if (ev)
|
2013-11-21 10:43:10 +00:00
|
|
|
virObjectEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(g_pVBoxGlobalData);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnMachineDataChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *machineId)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnExtraDataCanChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *machineId, PRUnichar *key,
|
|
|
|
PRUnichar *value,
|
|
|
|
PRUnichar **error ATTRIBUTE_UNUSED,
|
2011-09-26 16:51:47 +00:00
|
|
|
PRBool *allowChange ATTRIBUTE_UNUSED)
|
2010-12-14 18:53:52 +00:00
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p, allowChange: %s", pThis, *allowChange ? "true" : "false");
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("key", key);
|
|
|
|
DEBUGPRUnichar("value", value);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnExtraDataChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *machineId,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *key, PRUnichar *value)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("key", key);
|
|
|
|
DEBUGPRUnichar("value", value);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 3001000
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnMediaRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *mediaId,
|
|
|
|
PRUint32 mediaType ATTRIBUTE_UNUSED,
|
|
|
|
PRBool registered ATTRIBUTE_UNUSED)
|
2010-12-14 18:53:52 +00:00
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p, registered: %s", pThis, registered ? "true" : "false");
|
|
|
|
VIR_DEBUG("mediaType: %d", mediaType);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("mediaId", mediaId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
# endif /* VBOX_API_VERSION >= 3001000 */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnMachineRegistered(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *machineId, PRBool registered)
|
|
|
|
{
|
2009-07-24 16:12:16 +00:00
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
int event = 0;
|
|
|
|
int detail = 0;
|
|
|
|
|
|
|
|
vboxDriverLock(g_pVBoxGlobalData);
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p, registered: %s", pThis, registered ? "true" : "false");
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
|
|
|
|
if (machineId) {
|
|
|
|
char *machineIdUtf8 = NULL;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
|
|
|
|
g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(machineId, &machineIdUtf8);
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(machineIdUtf8, uuid));
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
dom = vboxDomainLookupByUUID(g_pVBoxGlobalData->conn, uuid);
|
|
|
|
if (dom) {
|
2013-11-22 14:38:05 +00:00
|
|
|
virObjectEventPtr ev;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* CURRENT LIMITATION: we never get the VIR_DOMAIN_EVENT_UNDEFINED
|
2012-10-11 16:31:20 +00:00
|
|
|
* event because the when the machine is de-registered the call
|
2009-07-24 16:12:16 +00:00
|
|
|
* to vboxDomainLookupByUUID fails and thus we don't get any
|
|
|
|
* dom pointer which is necessary (null dom pointer doesn't work)
|
|
|
|
* to show the VIR_DOMAIN_EVENT_UNDEFINED event
|
|
|
|
*/
|
|
|
|
if (registered) {
|
|
|
|
event = VIR_DOMAIN_EVENT_DEFINED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_DEFINED_ADDED;
|
|
|
|
} else {
|
|
|
|
event = VIR_DOMAIN_EVENT_UNDEFINED;
|
|
|
|
detail = VIR_DOMAIN_EVENT_UNDEFINED_REMOVED;
|
|
|
|
}
|
|
|
|
|
2013-11-21 17:03:26 +00:00
|
|
|
ev = virDomainEventLifecycleNewFromDom(dom, event, detail);
|
2010-03-18 13:17:14 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
if (ev)
|
2013-11-21 10:43:10 +00:00
|
|
|
virObjectEventStateQueue(g_pVBoxGlobalData->domainEvents, ev);
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(g_pVBoxGlobalData);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnSessionStateChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *machineId,
|
|
|
|
PRUint32 state ATTRIBUTE_UNUSED)
|
2010-12-14 18:53:52 +00:00
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p, state: %d", pThis, state);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnSnapshotTaken(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *machineId,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *snapshotId)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("snapshotId", snapshotId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnSnapshotDiscarded(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *machineId,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *snapshotId)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("snapshotId", snapshotId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnSnapshotChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
|
|
|
PRUnichar *machineId,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *snapshotId)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("snapshotId", snapshotId);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackOnGuestPropertyChange(IVirtualBoxCallback *pThis ATTRIBUTE_UNUSED,
|
2010-12-14 18:53:52 +00:00
|
|
|
PRUnichar *machineId, PRUnichar *name,
|
|
|
|
PRUnichar *value, PRUnichar *flags)
|
|
|
|
{
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("IVirtualBoxCallback: %p", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGPRUnichar("machineId", machineId);
|
|
|
|
DEBUGPRUnichar("name", name);
|
|
|
|
DEBUGPRUnichar("value", value);
|
|
|
|
DEBUGPRUnichar("flags", flags);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
2011-09-26 16:51:47 +00:00
|
|
|
vboxCallbackAddRef(nsISupports *pThis ATTRIBUTE_UNUSED)
|
2010-12-14 18:53:52 +00:00
|
|
|
{
|
2009-07-24 16:12:16 +00:00
|
|
|
nsresult c;
|
|
|
|
|
|
|
|
c = ++g_pVBoxGlobalData->vboxCallBackRefCount;
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("pThis: %p, vboxCallback AddRef: %d", pThis, c);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
|
|
|
vboxCallbackRelease(nsISupports *pThis)
|
|
|
|
{
|
2009-07-24 16:12:16 +00:00
|
|
|
nsresult c;
|
|
|
|
|
|
|
|
c = --g_pVBoxGlobalData->vboxCallBackRefCount;
|
|
|
|
if (c == 0) {
|
|
|
|
/* delete object */
|
|
|
|
VIR_FREE(pThis->vtbl);
|
|
|
|
VIR_FREE(pThis);
|
|
|
|
}
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("pThis: %p, vboxCallback Release: %d", pThis, c);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2010-12-14 18:53:52 +00:00
|
|
|
static nsresult PR_COM_METHOD
|
|
|
|
vboxCallbackQueryInterface(nsISupports *pThis, const nsID *iid, void **resultp)
|
|
|
|
{
|
2009-07-24 16:12:16 +00:00
|
|
|
IVirtualBoxCallback *that = (IVirtualBoxCallback *)pThis;
|
|
|
|
static const nsID ivirtualboxCallbackUUID = IVIRTUALBOXCALLBACK_IID;
|
|
|
|
static const nsID isupportIID = NS_ISUPPORTS_IID;
|
|
|
|
|
|
|
|
/* Match UUID for IVirtualBoxCallback class */
|
2012-10-17 09:23:12 +00:00
|
|
|
if (memcmp(iid, &ivirtualboxCallbackUUID, sizeof(nsID)) == 0 ||
|
|
|
|
memcmp(iid, &isupportIID, sizeof(nsID)) == 0) {
|
2009-07-24 16:12:16 +00:00
|
|
|
g_pVBoxGlobalData->vboxCallBackRefCount++;
|
|
|
|
*resultp = that;
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("pThis: %p, vboxCallback QueryInterface: %d", pThis, g_pVBoxGlobalData->vboxCallBackRefCount);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("pThis: %p, vboxCallback QueryInterface didn't find a matching interface", pThis);
|
2009-07-24 16:12:16 +00:00
|
|
|
DEBUGUUID("The UUID Callback Interface expects", iid);
|
|
|
|
DEBUGUUID("The UUID Callback Interface got", &ivirtualboxCallbackUUID);
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-04 18:19:08 +00:00
|
|
|
static IVirtualBoxCallback *vboxAllocCallbackObj(void) {
|
2009-07-24 16:12:16 +00:00
|
|
|
IVirtualBoxCallback *vboxCallback = NULL;
|
|
|
|
|
2010-02-15 19:09:55 +00:00
|
|
|
/* Allocate, Initialize and return a valid
|
2009-07-24 16:12:16 +00:00
|
|
|
* IVirtualBoxCallback object here
|
|
|
|
*/
|
|
|
|
if ((VIR_ALLOC(vboxCallback) < 0) || (VIR_ALLOC(vboxCallback->vtbl) < 0)) {
|
2010-02-15 19:09:55 +00:00
|
|
|
VIR_FREE(vboxCallback);
|
2009-07-24 16:12:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
vboxCallback->vtbl->nsisupports.AddRef = &vboxCallbackAddRef;
|
|
|
|
vboxCallback->vtbl->nsisupports.Release = &vboxCallbackRelease;
|
|
|
|
vboxCallback->vtbl->nsisupports.QueryInterface = &vboxCallbackQueryInterface;
|
|
|
|
vboxCallback->vtbl->OnMachineStateChange = &vboxCallbackOnMachineStateChange;
|
|
|
|
vboxCallback->vtbl->OnMachineDataChange = &vboxCallbackOnMachineDataChange;
|
|
|
|
vboxCallback->vtbl->OnExtraDataCanChange = &vboxCallbackOnExtraDataCanChange;
|
|
|
|
vboxCallback->vtbl->OnExtraDataChange = &vboxCallbackOnExtraDataChange;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 3001000
|
2009-07-24 16:12:16 +00:00
|
|
|
vboxCallback->vtbl->OnMediaRegistered = &vboxCallbackOnMediaRegistered;
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION >= 3001000 */
|
|
|
|
# endif /* VBOX_API_VERSION >= 3001000 */
|
2009-07-24 16:12:16 +00:00
|
|
|
vboxCallback->vtbl->OnMachineRegistered = &vboxCallbackOnMachineRegistered;
|
|
|
|
vboxCallback->vtbl->OnSessionStateChange = &vboxCallbackOnSessionStateChange;
|
|
|
|
vboxCallback->vtbl->OnSnapshotTaken = &vboxCallbackOnSnapshotTaken;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 3002000
|
2009-07-24 16:12:16 +00:00
|
|
|
vboxCallback->vtbl->OnSnapshotDiscarded = &vboxCallbackOnSnapshotDiscarded;
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION >= 3002000 */
|
2010-05-26 11:54:16 +00:00
|
|
|
vboxCallback->vtbl->OnSnapshotDeleted = &vboxCallbackOnSnapshotDiscarded;
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION >= 3002000 */
|
2009-07-24 16:12:16 +00:00
|
|
|
vboxCallback->vtbl->OnSnapshotChange = &vboxCallbackOnSnapshotChange;
|
|
|
|
vboxCallback->vtbl->OnGuestPropertyChange = &vboxCallbackOnGuestPropertyChange;
|
|
|
|
g_pVBoxGlobalData->vboxCallBackRefCount = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return vboxCallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vboxReadCallback(int watch ATTRIBUTE_UNUSED,
|
|
|
|
int fd,
|
|
|
|
int events ATTRIBUTE_UNUSED,
|
|
|
|
void *opaque ATTRIBUTE_UNUSED) {
|
|
|
|
if (fd >= 0) {
|
|
|
|
g_pVBoxGlobalData->vboxQueue->vtbl->ProcessPendingEvents(g_pVBoxGlobalData->vboxQueue);
|
|
|
|
} else {
|
|
|
|
nsresult rc;
|
|
|
|
PLEvent *pEvent = NULL;
|
|
|
|
|
|
|
|
rc = g_pVBoxGlobalData->vboxQueue->vtbl->WaitForEvent(g_pVBoxGlobalData->vboxQueue, &pEvent);
|
|
|
|
if (NS_SUCCEEDED(rc))
|
|
|
|
g_pVBoxGlobalData->vboxQueue->vtbl->HandleEvent(g_pVBoxGlobalData->vboxQueue, pEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
static int
|
|
|
|
vboxConnectDomainEventRegister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2009-07-24 16:12:16 +00:00
|
|
|
int vboxRet = -1;
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult rc;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* Locking has to be there as callbacks are not
|
|
|
|
* really fully thread safe
|
|
|
|
*/
|
|
|
|
vboxDriverLock(data);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (data->vboxCallback == NULL) {
|
2010-02-04 18:19:08 +00:00
|
|
|
data->vboxCallback = vboxAllocCallbackObj();
|
2009-12-04 13:49:45 +00:00
|
|
|
if (data->vboxCallback != NULL) {
|
|
|
|
rc = data->vboxObj->vtbl->RegisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
vboxRet = 0;
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
vboxRet = 0;
|
|
|
|
}
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Get the vbox file handle and add a event handle to it
|
|
|
|
* so that the events can be passed down to the user
|
|
|
|
*/
|
|
|
|
if (vboxRet == 0) {
|
|
|
|
if (data->fdWatch < 0) {
|
|
|
|
PRInt32 vboxFileHandle;
|
|
|
|
vboxFileHandle = data->vboxQueue->vtbl->GetEventQueueSelectFD(data->vboxQueue);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->fdWatch = virEventAddHandle(vboxFileHandle, VIR_EVENT_HANDLE_READABLE, vboxReadCallback, NULL, NULL);
|
|
|
|
}
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (data->fdWatch >= 0) {
|
|
|
|
/* Once a callback is registered with virtualbox, use a list
|
|
|
|
* to store the callbacks registered with libvirt so that
|
|
|
|
* later you can iterate over them
|
|
|
|
*/
|
2009-07-24 16:12:16 +00:00
|
|
|
|
event: move event filtering to daemon (regression fix)
https://bugzilla.redhat.com/show_bug.cgi?id=1058839
Commit f9f56340 for CVE-2014-0028 almost had the right idea - we
need to check the ACL rules to filter which events to send. But
it overlooked one thing: the event dispatch queue is running in
the main loop thread, and therefore does not normally have a
current virIdentityPtr. But filter checks can be based on current
identity, so when libvirtd.conf contains access_drivers=["polkit"],
we ended up rejecting access for EVERY event due to failure to
look up the current identity, even if it should have been allowed.
Furthermore, even for events that are triggered by API calls, it
is important to remember that the point of events is that they can
be copied across multiple connections, which may have separate
identities and permissions. So even if events were dispatched
from a context where we have an identity, we must change to the
correct identity of the connection that will be receiving the
event, rather than basing a decision on the context that triggered
the event, when deciding whether to filter an event to a
particular connection.
If there were an easy way to get from virConnectPtr to the
appropriate virIdentityPtr, then object_event.c could adjust the
identity prior to checking whether to dispatch an event. But
setting up that back-reference is a bit invasive. Instead, it
is easier to delay the filtering check until lower down the
stack, at the point where we have direct access to the RPC
client object that owns an identity. As such, this patch ends
up reverting a large portion of the framework of commit f9f56340.
We also have to teach 'make check' to special-case the fact that
the event registration filtering is done at the point of dispatch,
rather than the point of registration. Note that even though we
don't actually use virConnectDomainEventRegisterCheckACL (because
the RegisterAny variant is sufficient), we still generate the
function for the purposes of documenting that the filtering
takes place.
Also note that I did not entirely delete the notion of a filter
from object_event.c; I still plan on using that for my upcoming
patch series for qemu monitor events in libvirt-qemu.so. In
other words, while this patch changes ACL filtering to live in
remote.c and therefore we have no current client of the filtering
in object_event.c, the notion of filtering in object_event.c is
still useful down the road.
* src/check-aclrules.pl: Exempt event registration from having to
pass checkACL filter down call stack.
* daemon/remote.c (remoteRelayDomainEventCheckACL)
(remoteRelayNetworkEventCheckACL): New functions.
(remoteRelay*Event*): Use new functions.
* src/conf/domain_event.h (virDomainEventStateRegister)
(virDomainEventStateRegisterID): Drop unused parameter.
* src/conf/network_event.h (virNetworkEventStateRegisterID):
Likewise.
* src/conf/domain_event.c (virDomainEventFilter): Delete unused
function.
* src/conf/network_event.c (virNetworkEventFilter): Likewise.
* src/libxl/libxl_driver.c: Adjust caller.
* src/lxc/lxc_driver.c: Likewise.
* src/network/bridge_driver.c: Likewise.
* src/qemu/qemu_driver.c: Likewise.
* src/remote/remote_driver.c: Likewise.
* src/test/test_driver.c: Likewise.
* src/uml/uml_driver.c: Likewise.
* src/vbox/vbox_tmpl.c: Likewise.
* src/xen/xen_driver.c: Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-28 21:50:02 +00:00
|
|
|
ret = virDomainEventStateRegister(conn, data->domainEvents,
|
2011-12-13 11:14:46 +00:00
|
|
|
callback, opaque, freecb);
|
2013-11-21 10:43:10 +00:00
|
|
|
VIR_DEBUG("virObjectEventStateRegister (ret = %d) (conn: %p, "
|
2011-12-13 11:14:46 +00:00
|
|
|
"callback: %p, opaque: %p, "
|
2012-10-17 09:23:12 +00:00
|
|
|
"freecb: %p)", ret, conn, callback,
|
2011-12-13 11:14:46 +00:00
|
|
|
opaque, freecb);
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
|
|
|
if (ret >= 0) {
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
return 0;
|
2009-07-24 16:12:16 +00:00
|
|
|
} else {
|
|
|
|
if (data->vboxObj && data->vboxCallback) {
|
|
|
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
static int
|
|
|
|
vboxConnectDomainEventDeregister(virConnectPtr conn,
|
|
|
|
virConnectDomainEventCallback callback)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2011-12-13 10:39:17 +00:00
|
|
|
int cnt;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
|
|
|
/* Locking has to be there as callbacks are not
|
|
|
|
* really fully thread safe
|
|
|
|
*/
|
|
|
|
vboxDriverLock(data);
|
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
cnt = virDomainEventStateDeregister(conn, data->domainEvents,
|
|
|
|
callback);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
if (data->vboxCallback && cnt == 0) {
|
|
|
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
VBOX_RELEASE(data->vboxCallback);
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
/* Remove the Event file handle on which we are listening as well */
|
|
|
|
virEventRemoveHandle(data->fdWatch);
|
|
|
|
data->fdWatch = -1;
|
2009-07-24 16:12:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
if (cnt >= 0)
|
|
|
|
ret = 0;
|
|
|
|
|
2009-07-24 16:12:16 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
|
|
|
|
virDomainPtr dom,
|
|
|
|
int eventID,
|
|
|
|
virConnectDomainEventGenericCallback callback,
|
|
|
|
void *opaque,
|
|
|
|
virFreeCallback freecb) {
|
2010-03-18 14:47:07 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
|
|
|
int vboxRet = -1;
|
|
|
|
nsresult rc;
|
|
|
|
|
|
|
|
/* Locking has to be there as callbacks are not
|
|
|
|
* really fully thread safe
|
|
|
|
*/
|
|
|
|
vboxDriverLock(data);
|
|
|
|
|
|
|
|
if (data->vboxCallback == NULL) {
|
|
|
|
data->vboxCallback = vboxAllocCallbackObj();
|
|
|
|
if (data->vboxCallback != NULL) {
|
|
|
|
rc = data->vboxObj->vtbl->RegisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
vboxRet = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vboxRet = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the vbox file handle and add a event handle to it
|
|
|
|
* so that the events can be passed down to the user
|
|
|
|
*/
|
|
|
|
if (vboxRet == 0) {
|
|
|
|
if (data->fdWatch < 0) {
|
|
|
|
PRInt32 vboxFileHandle;
|
|
|
|
vboxFileHandle = data->vboxQueue->vtbl->GetEventQueueSelectFD(data->vboxQueue);
|
|
|
|
|
|
|
|
data->fdWatch = virEventAddHandle(vboxFileHandle, VIR_EVENT_HANDLE_READABLE, vboxReadCallback, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data->fdWatch >= 0) {
|
|
|
|
/* Once a callback is registered with virtualbox, use a list
|
|
|
|
* to store the callbacks registered with libvirt so that
|
|
|
|
* later you can iterate over them
|
|
|
|
*/
|
|
|
|
|
event: move event filtering to daemon (regression fix)
https://bugzilla.redhat.com/show_bug.cgi?id=1058839
Commit f9f56340 for CVE-2014-0028 almost had the right idea - we
need to check the ACL rules to filter which events to send. But
it overlooked one thing: the event dispatch queue is running in
the main loop thread, and therefore does not normally have a
current virIdentityPtr. But filter checks can be based on current
identity, so when libvirtd.conf contains access_drivers=["polkit"],
we ended up rejecting access for EVERY event due to failure to
look up the current identity, even if it should have been allowed.
Furthermore, even for events that are triggered by API calls, it
is important to remember that the point of events is that they can
be copied across multiple connections, which may have separate
identities and permissions. So even if events were dispatched
from a context where we have an identity, we must change to the
correct identity of the connection that will be receiving the
event, rather than basing a decision on the context that triggered
the event, when deciding whether to filter an event to a
particular connection.
If there were an easy way to get from virConnectPtr to the
appropriate virIdentityPtr, then object_event.c could adjust the
identity prior to checking whether to dispatch an event. But
setting up that back-reference is a bit invasive. Instead, it
is easier to delay the filtering check until lower down the
stack, at the point where we have direct access to the RPC
client object that owns an identity. As such, this patch ends
up reverting a large portion of the framework of commit f9f56340.
We also have to teach 'make check' to special-case the fact that
the event registration filtering is done at the point of dispatch,
rather than the point of registration. Note that even though we
don't actually use virConnectDomainEventRegisterCheckACL (because
the RegisterAny variant is sufficient), we still generate the
function for the purposes of documenting that the filtering
takes place.
Also note that I did not entirely delete the notion of a filter
from object_event.c; I still plan on using that for my upcoming
patch series for qemu monitor events in libvirt-qemu.so. In
other words, while this patch changes ACL filtering to live in
remote.c and therefore we have no current client of the filtering
in object_event.c, the notion of filtering in object_event.c is
still useful down the road.
* src/check-aclrules.pl: Exempt event registration from having to
pass checkACL filter down call stack.
* daemon/remote.c (remoteRelayDomainEventCheckACL)
(remoteRelayNetworkEventCheckACL): New functions.
(remoteRelay*Event*): Use new functions.
* src/conf/domain_event.h (virDomainEventStateRegister)
(virDomainEventStateRegisterID): Drop unused parameter.
* src/conf/network_event.h (virNetworkEventStateRegisterID):
Likewise.
* src/conf/domain_event.c (virDomainEventFilter): Delete unused
function.
* src/conf/network_event.c (virNetworkEventFilter): Likewise.
* src/libxl/libxl_driver.c: Adjust caller.
* src/lxc/lxc_driver.c: Likewise.
* src/network/bridge_driver.c: Likewise.
* src/qemu/qemu_driver.c: Likewise.
* src/remote/remote_driver.c: Likewise.
* src/test/test_driver.c: Likewise.
* src/uml/uml_driver.c: Likewise.
* src/vbox/vbox_tmpl.c: Likewise.
* src/xen/xen_driver.c: Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-28 21:50:02 +00:00
|
|
|
if (virDomainEventStateRegisterID(conn, data->domainEvents,
|
2011-12-13 11:14:46 +00:00
|
|
|
dom, eventID,
|
|
|
|
callback, opaque, freecb, &ret) < 0)
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
ret = -1;
|
2012-10-17 09:23:12 +00:00
|
|
|
VIR_DEBUG("virDomainEventStateRegisterID (ret = %d) (conn: %p, "
|
2011-12-13 11:14:46 +00:00
|
|
|
"callback: %p, opaque: %p, "
|
2012-10-17 09:23:12 +00:00
|
|
|
"freecb: %p)", ret, conn, callback,
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
opaque, freecb);
|
2010-03-18 14:47:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
|
|
|
if (ret >= 0) {
|
|
|
|
return ret;
|
|
|
|
} else {
|
|
|
|
if (data->vboxObj && data->vboxCallback) {
|
|
|
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
static int
|
|
|
|
vboxConnectDomainEventDeregisterAny(virConnectPtr conn,
|
|
|
|
int callbackID)
|
|
|
|
{
|
2010-03-18 14:47:07 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
2011-12-13 10:39:17 +00:00
|
|
|
int cnt;
|
2010-03-18 14:47:07 +00:00
|
|
|
|
|
|
|
/* Locking has to be there as callbacks are not
|
|
|
|
* really fully thread safe
|
|
|
|
*/
|
|
|
|
vboxDriverLock(data);
|
|
|
|
|
2013-11-21 10:43:10 +00:00
|
|
|
cnt = virObjectEventStateDeregisterID(conn, data->domainEvents,
|
Return count of callbacks when registering callbacks
When registering a callback for a particular event some callers
need to know how many callbacks already exist for that event.
While it is possible to ask for a count, this is not free from
race conditions when threaded. Thus the API for registering
callbacks should return the count of callbacks. Also rename
virDomainEventStateDeregisterAny to virDomainEventStateDeregisterID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Return count of callbacks when
registering callbacks
* src/libxl/libxl_driver.c, src/libxl/libxl_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/remote/remote_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Update
for change in APIs
2011-12-13 23:38:54 +00:00
|
|
|
callbackID);
|
2010-03-18 14:47:07 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
if (data->vboxCallback && cnt == 0) {
|
|
|
|
data->vboxObj->vtbl->UnregisterCallback(data->vboxObj, data->vboxCallback);
|
|
|
|
VBOX_RELEASE(data->vboxCallback);
|
2010-03-18 14:47:07 +00:00
|
|
|
|
2011-12-13 10:39:17 +00:00
|
|
|
/* Remove the Event file handle on which we are listening as well */
|
|
|
|
virEventRemoveHandle(data->fdWatch);
|
|
|
|
data->fdWatch = -1;
|
2010-03-18 14:47:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vboxDriverUnlock(data);
|
|
|
|
|
event: make deregister return value match docs
Ever since their introduction (commit 1509b80 in v0.5.0 for
virConnectDomainEventRegister, commit 4445723 in v0.8.0 for
virConnectDomainEventDeregisterAny), the event deregistration
functions have been documented as returning 0 on success;
likewise for older registration (only the newer RegisterAny
must return a non-zero callbackID). And now that we are
adding virConnectNetworkEventDeregisterAny for v1.2.1, it
should have the same semantics.
Fortunately, all of the stateful drivers have been obeying
the docs and returning 0, thanks to the way the remote_driver
tracks things (in fact, the RPC wire protocol is unable to
send a return value for DomainEventRegisterAny, at least not
without adding a new RPC number). Well, except for vbox,
which was always failing deregistration, due to failure to
set the return value to anything besides its initial -1.
But for local drivers, such as test:///default, we've been
returning non-zero numbers; worse, the non-zero numbers have
differed over time. For example, in Fedora 12 (libvirt 0.8.2),
calling Register twice would return 0 and 1 [the callbackID
generated under the hood]; while in Fedora 20 (libvirt 1.1.3),
it returns 1 and 2 [the number of callbacks registered for
that event type]. Since we have changed the behavior over
time, and since it differs by local vs. remote, we can safely
argue that no one could have been reasonably relying on any
particular behavior, so we might as well obey the docs, as well
as prepare callers that might deal with older clients to not be
surprised if the docs are not strictly followed.
For consistency, this patch fixes the code for all drivers,
even though it only makes an impact for vbox and for local
drivers. By fixing all drivers, future copy and paste from
a remote driver to a local driver is less likely to
reintroduce the bug.
Finally, update the testsuite to gain some coverage of the
issue for local drivers, including the first test of old-style
domain event registration via function pointer instead of
event id.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventDeregister)
(virConnectDomainEventDeregisterAny): Clarify docs.
* src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
(libxlConnectDomainEventDeregister)
(libxlConnectDomainEventDeregisterAny): Match documentation.
* src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
(lxcConnectDomainEventDeregister)
(lxcConnectDomainEventDeregisterAny): Likewise.
* src/test/test_driver.c (testConnectDomainEventRegister)
(testConnectDomainEventDeregister)
(testConnectDomainEventDeregisterAny)
(testConnectNetworkEventDeregisterAny): Likewise.
* src/uml/uml_driver.c (umlConnectDomainEventRegister)
(umlConnectDomainEventDeregister)
(umlConnectDomainEventDeregisterAny): Likewise.
* src/vbox/vbox_tmpl.c (vboxConnectDomainEventRegister)
(vboxConnectDomainEventDeregister)
(vboxConnectDomainEventDeregisterAny): Likewise.
* src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
(xenUnifiedConnectDomainEventDeregister)
(xenUnifiedConnectDomainEventDeregisterAny): Likewise.
* src/network/bridge_driver.c
(networkConnectNetworkEventDeregisterAny): Likewise.
* tests/objecteventtest.c (testDomainCreateXMLOld): New test.
(mymain): Run it.
(testDomainCreateXML): Check return values.
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-01-03 21:21:17 +00:00
|
|
|
if (cnt >= 0)
|
|
|
|
ret = 0;
|
|
|
|
|
2010-03-18 14:47:07 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* !(VBOX_API_VERSION == 2002000 || VBOX_API_VERSION >= 4000000) */
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
/**
|
|
|
|
* The Network Functions here on
|
|
|
|
*/
|
|
|
|
static virDrvOpenStatus vboxNetworkOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
2011-07-06 23:06:11 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-05-15 14:00:50 +00:00
|
|
|
vboxGlobalData *data = conn->privateData;
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
if (STRNEQ(conn->driver->name, "VBOX"))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if ((data->pFuncs == NULL) ||
|
|
|
|
(data->vboxObj == NULL) ||
|
|
|
|
(data->vboxSession == NULL))
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("network initialized");
|
2009-05-15 14:00:50 +00:00
|
|
|
/* conn->networkPrivateData = some network specific data */
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxNetworkClose(virConnectPtr conn) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("network uninitialized");
|
2009-05-15 14:00:50 +00:00
|
|
|
conn->networkPrivateData = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectNumOfNetworks(virConnectPtr conn) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, int, 0);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&networkInterfaces, host, host->vtbl->GetNetworkInterfaces);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < networkInterfaces.count; i++) {
|
|
|
|
IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
|
|
|
|
|
|
|
|
if (networkInterface) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUint32 status = HostNetworkInterfaceStatus_Unknown;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetStatus(networkInterface, &status);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (status == HostNetworkInterfaceStatus_Up)
|
|
|
|
ret++;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&networkInterfaces);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("numActive: %d", ret);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectListNetworks(virConnectPtr conn, char **const names, int nnames) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, int, 0);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&networkInterfaces, host, host->vtbl->GetNetworkInterfaces);
|
|
|
|
|
|
|
|
for (i = 0; (ret < nnames) && (i < networkInterfaces.count); i++) {
|
|
|
|
IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
if (networkInterface) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUint32 status = HostNetworkInterfaceStatus_Unknown;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetStatus(networkInterface, &status);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (status == HostNetworkInterfaceStatus_Up) {
|
|
|
|
char *nameUtf8 = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetName(networkInterface, &nameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("nnames[%d]: %s", ret, nameUtf8);
|
2013-05-20 09:48:34 +00:00
|
|
|
if (VIR_STRDUP(names[ret], nameUtf8) >= 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&networkInterfaces);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(host);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectNumOfDefinedNetworks(virConnectPtr conn) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, int, 0);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&networkInterfaces, host, host->vtbl->GetNetworkInterfaces);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < networkInterfaces.count; i++) {
|
|
|
|
IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
|
|
|
|
|
|
|
|
if (networkInterface) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUint32 status = HostNetworkInterfaceStatus_Unknown;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetStatus(networkInterface, &status);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (status == HostNetworkInterfaceStatus_Down)
|
|
|
|
ret++;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&networkInterfaces);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("numActive: %d", ret);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, int, 0);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&networkInterfaces, host, host->vtbl->GetNetworkInterfaces);
|
|
|
|
|
|
|
|
for (i = 0; (ret < nnames) && (i < networkInterfaces.count); i++) {
|
|
|
|
IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
if (networkInterface) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUint32 status = HostNetworkInterfaceStatus_Unknown;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetStatus(networkInterface, &status);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (status == HostNetworkInterfaceStatus_Down) {
|
|
|
|
char *nameUtf8 = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
networkInterface->vtbl->GetName(networkInterface, &nameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("nnames[%d]: %s", ret, nameUtf8);
|
2013-05-20 09:48:34 +00:00
|
|
|
if (VIR_STRDUP(names[ret], nameUtf8) >= 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
ret++;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&networkInterfaces);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
|
|
|
return ret;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
static virNetworkPtr
|
|
|
|
vboxNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, virNetworkPtr, NULL);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-07-24 16:12:16 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&iid, uuid);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-07-24 16:12:16 +00:00
|
|
|
/* TODO: "internal" networks are just strings and
|
|
|
|
* thus can't do much with them
|
|
|
|
*/
|
2009-12-04 13:49:45 +00:00
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
host->vtbl->FindHostNetworkInterfaceById(host, iid.value, &networkInterface);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
char *nameUtf8 = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetName(networkInterface, &nameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = virGetNetwork(conn, nameUtf8, uuid);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Network Name: %s", nameUtf8);
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("Network UUID", iid.value);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-05-15 14:00:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *name) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, virNetworkPtr, NULL);
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(name, &nameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
host->vtbl->FindHostNetworkInterfaceByName(host, nameUtf16, &networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
networkInterface->vtbl->GetId(networkInterface, &iid.value);
|
|
|
|
vboxIIDToUUID(&iid, uuid);
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = virGetNetwork(conn, name, uuid);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Network Name: %s", name);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("Network UUID", iid.value);
|
|
|
|
vboxIIDUnalloc(&iid);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:06:03 +00:00
|
|
|
static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(conn, virNetworkPtr, NULL);
|
|
|
|
PRUnichar *networkInterfaceNameUtf16 = NULL;
|
|
|
|
char *networkInterfaceNameUtf8 = NULL;
|
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
nsresult rc;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-02-10 10:22:52 +00:00
|
|
|
virNetworkDefPtr def = virNetworkDefParseString(xml);
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkIpDefPtr ipdef;
|
|
|
|
virSocketAddr netmask;
|
2009-09-03 15:06:03 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if ((!def) ||
|
2012-11-08 02:16:17 +00:00
|
|
|
(def->forward.type != VIR_NETWORK_FORWARD_NONE) ||
|
2012-10-17 09:23:12 +00:00
|
|
|
(def->nips == 0 || !def->ips))
|
2010-11-17 18:36:19 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* Look for the first IPv4 IP address definition and use that.
|
|
|
|
* If there weren't any IPv4 addresses, ignore the network (since it's
|
|
|
|
* required below to have an IPv4 address)
|
|
|
|
*/
|
|
|
|
ipdef = virNetworkDefGetIpByIndex(def, AF_INET, 0);
|
|
|
|
if (!ipdef)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virNetworkIpDefNetmask(ipdef, &netmask) < 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* the current limitation of hostonly network is that you can't
|
|
|
|
* assign a name to it and it defaults to vboxnet*, for e.g:
|
|
|
|
* vboxnet0, vboxnet1, etc. Also the UUID is assigned to it
|
|
|
|
* automatically depending on the mac address and thus both
|
|
|
|
* these paramters are ignored here for now.
|
|
|
|
*/
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2010-12-23 16:25:56 +00:00
|
|
|
if (STREQ(def->name, "vboxnet0")) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->name, &networkInterfaceNameUtf16);
|
|
|
|
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
|
|
|
if (interfaceType != HostNetworkInterfaceType_HostOnly) {
|
|
|
|
VBOX_RELEASE(networkInterface);
|
|
|
|
networkInterface = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION != 2002000 */
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
{
|
|
|
|
IProgress *progress = NULL;
|
|
|
|
host->vtbl->CreateHostOnlyNetworkInterface(host, &networkInterface,
|
|
|
|
&progress);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
if (progress) {
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION != 2002000 */
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
char *networkNameUtf8 = NULL;
|
|
|
|
PRUnichar *networkNameUtf16 = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID vboxnetiid = VBOX_IID_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
networkInterface->vtbl->GetName(networkInterface, &networkInterfaceNameUtf16);
|
|
|
|
if (networkInterfaceNameUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(networkInterfaceNameUtf16, &networkInterfaceNameUtf8);
|
|
|
|
|
|
|
|
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", networkInterfaceNameUtf8) < 0) {
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
VBOX_RELEASE(networkInterface);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-11-19 23:35:10 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Currently support only one dhcp server per network
|
|
|
|
* with contigious address space from start to end
|
|
|
|
*/
|
2010-11-17 18:36:19 +00:00
|
|
|
if ((ipdef->nranges >= 1) &&
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start) &&
|
|
|
|
VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IDHCPServer *dhcpServer = NULL;
|
|
|
|
|
|
|
|
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
|
|
|
|
networkNameUtf16,
|
|
|
|
&dhcpServer);
|
|
|
|
if (!dhcpServer) {
|
|
|
|
/* create a dhcp server */
|
|
|
|
data->vboxObj->vtbl->CreateDHCPServer(data->vboxObj,
|
|
|
|
networkNameUtf16,
|
|
|
|
&dhcpServer);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("couldn't find dhcp server so creating one");
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
|
|
|
if (dhcpServer) {
|
|
|
|
PRUnichar *ipAddressUtf16 = NULL;
|
|
|
|
PRUnichar *networkMaskUtf16 = NULL;
|
|
|
|
PRUnichar *fromIPAddressUtf16 = NULL;
|
|
|
|
PRUnichar *toIPAddressUtf16 = NULL;
|
|
|
|
PRUnichar *trunkTypeUtf16 = NULL;
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->address);
|
|
|
|
networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask);
|
|
|
|
fromIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].start);
|
|
|
|
toIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].end);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL ||
|
|
|
|
fromIPAddressUtf16 == NULL || toIPAddressUtf16 == NULL) {
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
VBOX_UTF16_FREE(fromIPAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(toIPAddressUtf16);
|
|
|
|
VBOX_RELEASE(dhcpServer);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16);
|
|
|
|
|
|
|
|
dhcpServer->vtbl->SetEnabled(dhcpServer, PR_TRUE);
|
|
|
|
|
|
|
|
dhcpServer->vtbl->SetConfiguration(dhcpServer,
|
|
|
|
ipAddressUtf16,
|
|
|
|
networkMaskUtf16,
|
|
|
|
fromIPAddressUtf16,
|
|
|
|
toIPAddressUtf16);
|
|
|
|
|
|
|
|
if (start)
|
|
|
|
dhcpServer->vtbl->Start(dhcpServer,
|
|
|
|
networkNameUtf16,
|
|
|
|
networkInterfaceNameUtf16,
|
|
|
|
trunkTypeUtf16);
|
|
|
|
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
VBOX_UTF16_FREE(fromIPAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(toIPAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(trunkTypeUtf16);
|
|
|
|
VBOX_RELEASE(dhcpServer);
|
|
|
|
}
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
if ((ipdef->nhosts >= 1) &&
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
VIR_SOCKET_ADDR_VALID(&ipdef->hosts[0].ip)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *ipAddressUtf16 = NULL;
|
|
|
|
PRUnichar *networkMaskUtf16 = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->hosts[0].ip);
|
|
|
|
networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL) {
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* Current drawback is that since EnableStaticIpConfig() sets
|
|
|
|
* IP and enables the interface so even if the dhcpserver is not
|
|
|
|
* started the interface is still up and running
|
|
|
|
*/
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4002000
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->EnableStaticIpConfig(networkInterface,
|
|
|
|
ipAddressUtf16,
|
|
|
|
networkMaskUtf16);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
networkInterface->vtbl->EnableStaticIPConfig(networkInterface,
|
|
|
|
ipAddressUtf16,
|
|
|
|
networkMaskUtf16);
|
|
|
|
#endif
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
} else {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4002000
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->EnableDynamicIpConfig(networkInterface);
|
|
|
|
networkInterface->vtbl->DhcpRediscover(networkInterface);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
networkInterface->vtbl->EnableDynamicIPConfig(networkInterface);
|
|
|
|
networkInterface->vtbl->DHCPRediscover(networkInterface);
|
|
|
|
#endif
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-09-03 15:06:03 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = networkInterface->vtbl->GetId(networkInterface, &vboxnetiid.value);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
vboxIIDToUUID(&vboxnetiid, uuid);
|
|
|
|
DEBUGIID("Real Network UUID", vboxnetiid.value);
|
|
|
|
vboxIIDUnalloc(&vboxnetiid);
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = virGetNetwork(conn, networkInterfaceNameUtf8, uuid);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VIR_FREE(networkNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(networkNameUtf16);
|
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(networkInterfaceNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(networkInterfaceNameUtf16);
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
cleanup:
|
|
|
|
virNetworkDefFree(def);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:06:03 +00:00
|
|
|
static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) {
|
|
|
|
return vboxNetworkDefineCreateXML(conn, xml, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static virNetworkPtr vboxNetworkDefineXML(virConnectPtr conn, const char *xml) {
|
|
|
|
return vboxNetworkDefineCreateXML(conn, xml, false);
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:08:52 +00:00
|
|
|
static int vboxNetworkUndefineDestroy(virNetworkPtr network, bool removeinterface) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(network->conn, int, -1);
|
2009-05-15 14:00:50 +00:00
|
|
|
char *networkNameUtf8 = NULL;
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
PRUnichar *networkInterfaceNameUtf16 = NULL;
|
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
|
|
|
/* Current limitation of the function for VirtualBox 2.2.* is
|
|
|
|
* that you can't delete the default hostonly adaptor namely:
|
|
|
|
* vboxnet0 and thus all this functions does is remove the
|
|
|
|
* dhcp server configuration, but the network can still be used
|
|
|
|
* by giving the machine static IP and also it will still
|
|
|
|
* show up in the net-list in virsh
|
|
|
|
*/
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0)
|
2009-05-15 14:00:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUnichar *networkNameUtf16 = NULL;
|
|
|
|
IDHCPServer *dhcpServer = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION != 2002000
|
2009-12-04 13:49:45 +00:00
|
|
|
if (removeinterface) {
|
|
|
|
PRUnichar *iidUtf16 = NULL;
|
|
|
|
IProgress *progress = NULL;
|
2009-09-03 15:08:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetId(networkInterface, &iidUtf16);
|
2009-09-03 15:08:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (iidUtf16) {
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION == 3000000
|
2009-12-04 13:49:45 +00:00
|
|
|
IHostNetworkInterface *netInt = NULL;
|
|
|
|
host->vtbl->RemoveHostOnlyNetworkInterface(host, iidUtf16, &netInt, &progress);
|
|
|
|
VBOX_RELEASE(netInt);
|
2013-12-24 09:39:38 +00:00
|
|
|
# else /* VBOX_API_VERSION > 3000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
host->vtbl->RemoveHostOnlyNetworkInterface(host, iidUtf16, &progress);
|
2013-12-24 09:39:38 +00:00
|
|
|
# endif /* VBOX_API_VERSION > 3000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(iidUtf16);
|
|
|
|
}
|
2009-09-03 15:08:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (progress) {
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
VBOX_RELEASE(progress);
|
|
|
|
}
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION != 2002000 */
|
2009-09-03 15:08:52 +00:00
|
|
|
|
2013-11-19 23:35:10 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
|
|
|
|
networkNameUtf16,
|
|
|
|
&dhcpServer);
|
|
|
|
if (dhcpServer) {
|
|
|
|
dhcpServer->vtbl->SetEnabled(dhcpServer, PR_FALSE);
|
|
|
|
dhcpServer->vtbl->Stop(dhcpServer);
|
|
|
|
if (removeinterface)
|
|
|
|
data->vboxObj->vtbl->RemoveDHCPServer(data->vboxObj, dhcpServer);
|
|
|
|
VBOX_RELEASE(dhcpServer);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkNameUtf16);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkInterfaceNameUtf16);
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(networkNameUtf8);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-03 15:08:52 +00:00
|
|
|
static int vboxNetworkUndefine(virNetworkPtr network) {
|
|
|
|
return vboxNetworkUndefineDestroy(network, true);
|
|
|
|
}
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
static int vboxNetworkCreate(virNetworkPtr network) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(network->conn, int, -1);
|
2009-05-15 14:00:50 +00:00
|
|
|
char *networkNameUtf8 = NULL;
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
PRUnichar *networkInterfaceNameUtf16 = NULL;
|
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
|
|
|
/* Current limitation of the function for VirtualBox 2.2.* is
|
|
|
|
* that the default hostonly network "vboxnet0" is always active
|
|
|
|
* and thus all this functions does is start the dhcp server,
|
|
|
|
* but the network can still be used without starting the dhcp
|
|
|
|
* server by giving the machine static IP
|
|
|
|
*/
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0)
|
2009-05-15 14:00:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
|
|
|
PRUnichar *networkNameUtf16 = NULL;
|
|
|
|
IDHCPServer *dhcpServer = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
|
|
|
|
2013-11-19 23:35:10 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
|
|
|
|
networkNameUtf16,
|
|
|
|
&dhcpServer);
|
|
|
|
if (dhcpServer) {
|
|
|
|
PRUnichar *trunkTypeUtf16 = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
dhcpServer->vtbl->SetEnabled(dhcpServer, PR_TRUE);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
dhcpServer->vtbl->Start(dhcpServer,
|
|
|
|
networkNameUtf16,
|
|
|
|
networkInterfaceNameUtf16,
|
|
|
|
trunkTypeUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(trunkTypeUtf16);
|
|
|
|
VBOX_RELEASE(dhcpServer);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkInterfaceNameUtf16);
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(networkNameUtf8);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxNetworkDestroy(virNetworkPtr network) {
|
2009-09-03 15:08:52 +00:00
|
|
|
return vboxNetworkUndefineDestroy(network, false);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2011-07-06 20:40:19 +00:00
|
|
|
static char *vboxNetworkGetXMLDesc(virNetworkPtr network,
|
2011-07-06 23:06:11 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_HOST_CHECK(network->conn, char *, NULL);
|
2009-05-15 14:00:50 +00:00
|
|
|
virNetworkDefPtr def = NULL;
|
2010-11-17 18:36:19 +00:00
|
|
|
virNetworkIpDefPtr ipdef = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
char *networkNameUtf8 = NULL;
|
build: detect potentential uninitialized variables
Even with -Wuninitialized (which is part of autobuild.sh
--enable-compile-warnings=error), gcc does NOT catch this
use of an uninitialized variable:
{
if (cond)
goto error;
int a = 1;
error:
printf("%d", a);
}
which prints 0 (supposing the stack started life wiped) if
cond was true. Clang will catch it, but we don't use clang
as often. Using gcc -Wjump-misses-init catches it, but also
gives false positives:
{
if (cond)
goto error;
int a = 1;
return a;
error:
return 0;
}
Here, a was never used in the scope of the error block, so
declaring it after goto is technically fine (and clang agrees).
However, given that our HACKING already documents a preference
to C89 decl-before-statement, the false positive warning is
enough of a prod to comply with HACKING.
[Personally, I'd _really_ rather use C99 decl-after-statement
to minimize scope, but until gcc can efficiently and reliably
catch scoping and uninitialized usage bugs, I'll settle with
the compromise of enforcing a coding standard that happens to
reject false positives if it can also detect real bugs.]
* acinclude.m4 (LIBVIRT_COMPILE_WARNINGS): Add -Wjump-misses-init.
* src/util/util.c (__virExec): Adjust offenders.
* src/conf/domain_conf.c (virDomainTimerDefParseXML): Likewise.
* src/remote/remote_driver.c (doRemoteOpen): Likewise.
* src/phyp/phyp_driver.c (phypGetLparNAME, phypGetLparProfile)
(phypGetVIOSFreeSCSIAdapter, phypVolumeGetKey)
(phypGetStoragePoolDevice)
(phypVolumeGetPhysicalVolumeByStoragePool)
(phypVolumeGetPath): Likewise.
* src/vbox/vbox_tmpl.c (vboxNetworkUndefineDestroy)
(vboxNetworkCreate, vboxNetworkDumpXML)
(vboxNetworkDefineCreateXML): Likewise.
* src/xenapi/xenapi_driver.c (getCapsObject)
(xenapiDomainDumpXML): Likewise.
* src/xenapi/xenapi_utils.c (createVMRecordFromXml): Likewise.
* src/security/security_selinux.c (SELinuxGenNewContext):
Likewise.
* src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia):
Likewise.
* src/qemu/qemu_process.c (qemuProcessWaitForMonitor): Likewise.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetPtyPaths):
Likewise.
* src/qemu/qemu_driver.c (qemudDomainShutdown)
(qemudDomainBlockStats, qemudDomainMemoryPeek): Likewise.
* src/storage/storage_backend_iscsi.c
(virStorageBackendCreateIfaceIQN): Likewise.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
2011-04-01 15:41:45 +00:00
|
|
|
PRUnichar *networkInterfaceNameUtf16 = NULL;
|
|
|
|
IHostNetworkInterface *networkInterface = NULL;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(def) < 0)
|
2009-05-15 14:00:50 +00:00
|
|
|
goto cleanup;
|
2013-07-04 10:17:38 +00:00
|
|
|
if (VIR_ALLOC(ipdef) < 0)
|
2010-11-17 18:36:19 +00:00
|
|
|
goto cleanup;
|
|
|
|
def->ips = ipdef;
|
|
|
|
def->nips = 1;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-07-04 10:17:38 +00:00
|
|
|
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0)
|
2009-05-15 14:00:50 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (networkInterface) {
|
|
|
|
PRUint32 interfaceType = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
|
2013-05-20 09:48:34 +00:00
|
|
|
if (VIR_STRDUP(def->name, network->name) >= 0) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *networkNameUtf16 = NULL;
|
|
|
|
IDHCPServer *dhcpServer = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID vboxnet0IID = VBOX_IID_INITIALIZER;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
networkInterface->vtbl->GetId(networkInterface, &vboxnet0IID.value);
|
|
|
|
vboxIIDToUUID(&vboxnet0IID, def->uuid);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-11-19 23:35:10 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2012-11-08 02:16:17 +00:00
|
|
|
def->forward.type = VIR_NETWORK_FORWARD_NONE;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
|
|
|
|
networkNameUtf16,
|
|
|
|
&dhcpServer);
|
|
|
|
if (dhcpServer) {
|
2010-11-17 18:36:19 +00:00
|
|
|
ipdef->nranges = 1;
|
2012-10-17 09:23:12 +00:00
|
|
|
if (VIR_ALLOC_N(ipdef->ranges, ipdef->nranges) >=0) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *ipAddressUtf16 = NULL;
|
|
|
|
PRUnichar *networkMaskUtf16 = NULL;
|
|
|
|
PRUnichar *fromIPAddressUtf16 = NULL;
|
|
|
|
PRUnichar *toIPAddressUtf16 = NULL;
|
2010-10-22 12:21:31 +00:00
|
|
|
bool errorOccurred = false;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
dhcpServer->vtbl->GetIPAddress(dhcpServer, &ipAddressUtf16);
|
|
|
|
dhcpServer->vtbl->GetNetworkMask(dhcpServer, &networkMaskUtf16);
|
|
|
|
dhcpServer->vtbl->GetLowerIP(dhcpServer, &fromIPAddressUtf16);
|
|
|
|
dhcpServer->vtbl->GetUpperIP(dhcpServer, &toIPAddressUtf16);
|
|
|
|
/* Currently virtualbox supports only one dhcp server per network
|
|
|
|
* with contigious address space from start to end
|
|
|
|
*/
|
2010-10-22 12:21:31 +00:00
|
|
|
if (vboxSocketParseAddrUtf16(data, ipAddressUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->address) < 0 ||
|
2010-10-22 12:21:31 +00:00
|
|
|
vboxSocketParseAddrUtf16(data, networkMaskUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->netmask) < 0 ||
|
2010-10-22 12:21:31 +00:00
|
|
|
vboxSocketParseAddrUtf16(data, fromIPAddressUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->ranges[0].start) < 0 ||
|
2010-10-22 12:21:31 +00:00
|
|
|
vboxSocketParseAddrUtf16(data, toIPAddressUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->ranges[0].end) < 0) {
|
2010-10-22 12:21:31 +00:00
|
|
|
errorOccurred = true;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
VBOX_UTF16_FREE(fromIPAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(toIPAddressUtf16);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (errorOccurred) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-11-17 18:36:19 +00:00
|
|
|
ipdef->nranges = 0;
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
ipdef->nhosts = 1;
|
2012-10-17 09:23:12 +00:00
|
|
|
if (VIR_ALLOC_N(ipdef->hosts, ipdef->nhosts) >=0) {
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(ipdef->hosts[0].name, network->name) < 0) {
|
2010-11-17 18:36:19 +00:00
|
|
|
VIR_FREE(ipdef->hosts);
|
|
|
|
ipdef->nhosts = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
} else {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *macAddressUtf16 = NULL;
|
|
|
|
PRUnichar *ipAddressUtf16 = NULL;
|
2010-10-22 12:21:31 +00:00
|
|
|
bool errorOccurred = false;
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
networkInterface->vtbl->GetHardwareAddress(networkInterface, &macAddressUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
networkInterface->vtbl->GetIPAddress(networkInterface, &ipAddressUtf16);
|
|
|
|
|
2010-11-17 18:36:19 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(macAddressUtf16, &ipdef->hosts[0].mac);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (vboxSocketParseAddrUtf16(data, ipAddressUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->hosts[0].ip) < 0) {
|
2010-10-22 12:21:31 +00:00
|
|
|
errorOccurred = true;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(macAddressUtf16);
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (errorOccurred) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-11-17 18:36:19 +00:00
|
|
|
ipdef->nhosts = 0;
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(dhcpServer);
|
|
|
|
} else {
|
|
|
|
PRUnichar *networkMaskUtf16 = NULL;
|
|
|
|
PRUnichar *ipAddressUtf16 = NULL;
|
2010-10-22 12:21:31 +00:00
|
|
|
bool errorOccurred = false;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
networkInterface->vtbl->GetNetworkMask(networkInterface, &networkMaskUtf16);
|
|
|
|
networkInterface->vtbl->GetIPAddress(networkInterface, &ipAddressUtf16);
|
|
|
|
|
2010-10-22 12:21:31 +00:00
|
|
|
if (vboxSocketParseAddrUtf16(data, networkMaskUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->netmask) < 0 ||
|
2010-10-22 12:21:31 +00:00
|
|
|
vboxSocketParseAddrUtf16(data, ipAddressUtf16,
|
2010-11-17 18:36:19 +00:00
|
|
|
&ipdef->address) < 0) {
|
2010-10-22 12:21:31 +00:00
|
|
|
errorOccurred = true;
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF16_FREE(networkMaskUtf16);
|
|
|
|
VBOX_UTF16_FREE(ipAddressUtf16);
|
2010-10-22 12:21:31 +00:00
|
|
|
|
|
|
|
if (errorOccurred) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("Network UUID", vboxnet0IID.value);
|
|
|
|
vboxIIDUnalloc(&vboxnet0IID);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkNameUtf16);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_RELEASE(networkInterface);
|
2009-05-15 14:00:50 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(networkInterfaceNameUtf16);
|
|
|
|
VBOX_RELEASE(host);
|
|
|
|
|
2011-12-14 10:50:40 +00:00
|
|
|
ret = virNetworkDefFormat(def, 0);
|
2009-05-15 14:00:50 +00:00
|
|
|
|
|
|
|
cleanup:
|
2010-02-15 16:54:15 +00:00
|
|
|
virNetworkDefFree(def);
|
2009-05-15 14:00:50 +00:00
|
|
|
VIR_FREE(networkNameUtf8);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
/**
|
|
|
|
* The Storage Functions here on
|
|
|
|
*/
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
static virDrvOpenStatus vboxStorageOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int flags)
|
2011-07-06 23:06:11 +00:00
|
|
|
{
|
2009-09-04 14:28:52 +00:00
|
|
|
vboxGlobalData *data = conn->privateData;
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
if (STRNEQ(conn->driver->name, "VBOX"))
|
2011-07-07 07:21:37 +00:00
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
if ((data->pFuncs == NULL) ||
|
|
|
|
(data->vboxObj == NULL) ||
|
|
|
|
(data->vboxSession == NULL))
|
2011-07-07 07:21:37 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("vbox storage initialized");
|
2009-09-04 14:28:52 +00:00
|
|
|
/* conn->storagePrivateData = some storage specific data */
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
static int vboxStorageClose(virConnectPtr conn) {
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("vbox storage uninitialized");
|
2009-09-04 14:28:52 +00:00
|
|
|
conn->storagePrivateData = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectNumOfStoragePools(virConnectPtr conn ATTRIBUTE_UNUSED) {
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
/** Currently only one pool supported, the default one
|
|
|
|
* given by ISystemProperties::defaultHardDiskFolder()
|
|
|
|
*/
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-04-23 12:50:18 +00:00
|
|
|
static int vboxConnectListStoragePools(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
char **const names, int nnames) {
|
2009-09-04 14:28:52 +00:00
|
|
|
int numActive = 0;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (nnames == 1 &&
|
|
|
|
VIR_STRDUP(names[numActive], "default-pool") > 0)
|
|
|
|
numActive++;
|
2009-09-04 14:28:52 +00:00
|
|
|
return numActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStoragePoolPtr vboxStoragePoolLookupByName(virConnectPtr conn, const char *name) {
|
|
|
|
virStoragePoolPtr ret = NULL;
|
|
|
|
|
|
|
|
/** Current limitation of the function: since
|
|
|
|
* the default pool doesn't have UUID just assign
|
|
|
|
* one till vbox can handle pools
|
|
|
|
*/
|
|
|
|
if (STREQ("default-pool", name)) {
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
const char *uuidstr = "1deff1ff-1481-464f-967f-a50fe8936cc4";
|
|
|
|
|
2011-10-12 23:24:52 +00:00
|
|
|
ignore_value(virUUIDParse(uuidstr, uuid));
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2012-11-10 07:18:07 +00:00
|
|
|
ret = virGetStoragePool(conn, name, uuid, NULL, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxStoragePoolNumOfVolumes(virStoragePoolPtr pool) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(pool->conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray hardDisks = VBOX_ARRAY_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
PRUint32 hardDiskAccessible = 0;
|
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&hardDisks, data->vboxObj, data->vboxObj->vtbl->GetHardDisks);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < hardDisks.count; ++i) {
|
|
|
|
IHardDisk *hardDisk = hardDisks.items[i];
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDisk) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible)
|
|
|
|
hardDiskAccessible++;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
|
|
|
|
vboxArrayRelease(&hardDisks);
|
|
|
|
|
|
|
|
ret = hardDiskAccessible;
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = -1;
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get number of volumes in the pool: %s, rc=%08x"),
|
|
|
|
pool->name, (unsigned)rc);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int nnames) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(pool->conn, int, -1);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray hardDisks = VBOX_ARRAY_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
PRUint32 numActive = 0;
|
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&hardDisks, data->vboxObj, data->vboxObj->vtbl->GetHardDisks);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < hardDisks.count && numActive < nnames; ++i) {
|
|
|
|
IHardDisk *hardDisk = hardDisks.items[i];
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDisk) {
|
|
|
|
PRUint32 hddstate;
|
|
|
|
char *nameUtf8 = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &nameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (nameUtf8) {
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("nnames[%d]: %s", numActive, nameUtf8);
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(names[numActive], nameUtf8) > 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
numActive++;
|
|
|
|
|
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
|
|
|
|
vboxArrayRelease(&hardDisks);
|
|
|
|
|
|
|
|
ret = numActive;
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
2010-12-16 22:05:48 +00:00
|
|
|
ret = -1;
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("could not get the volume list in the pool: %s, rc=%08x"),
|
|
|
|
pool->name, (unsigned)rc);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr vboxStorageVolLookupByName(virStoragePoolPtr pool, const char *name) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(pool->conn, virStorageVolPtr, NULL);
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray hardDisks = VBOX_ARRAY_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!name)
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
rc = vboxArrayGet(&hardDisks, data->vboxObj, data->vboxObj->vtbl->GetHardDisks);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < hardDisks.count; ++i) {
|
|
|
|
IHardDisk *hardDisk = hardDisks.items[i];
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hardDisk) {
|
|
|
|
PRUint32 hddstate;
|
|
|
|
char *nameUtf8 = NULL;
|
|
|
|
PRUnichar *nameUtf16 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &nameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (nameUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
|
|
|
|
VBOX_UTF16_FREE(nameUtf16);
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (nameUtf8 && STREQ(nameUtf8, name)) {
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
char key[VIR_UUID_STRING_BUFLEN] = "";
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
vboxIIDToUUID(&hddIID, uuid);
|
|
|
|
virUUIDFormat(uuid, key);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2012-11-10 07:18:07 +00:00
|
|
|
ret = virGetStorageVol(pool->conn, pool->name, name, key,
|
|
|
|
NULL, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("virStorageVolPtr: %p", ret);
|
|
|
|
VIR_DEBUG("Storage Volume Name: %s", name);
|
|
|
|
VIR_DEBUG("Storage Volume key : %s", key);
|
|
|
|
VIR_DEBUG("Storage Volume Pool: %s", pool->name);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
|
|
|
break;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(nameUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&hardDisks);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr vboxStorageVolLookupByKey(virConnectPtr conn, const char *key) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
2009-09-04 14:28:52 +00:00
|
|
|
IHardDisk *hardDisk = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!key)
|
|
|
|
return ret;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (virUUIDParse(key, uuid) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Could not parse UUID from '%s'"), key);
|
2010-12-23 16:25:56 +00:00
|
|
|
return NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&hddIID, uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
PRUnichar *hddNameUtf16 = NULL;
|
|
|
|
char *hddNameUtf8 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddNameUtf8) {
|
2013-04-23 12:50:18 +00:00
|
|
|
if (vboxConnectNumOfStoragePools(conn) == 1) {
|
2012-11-10 07:18:07 +00:00
|
|
|
ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key,
|
|
|
|
NULL, NULL);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Pool: %s", "default-pool");
|
2009-12-04 13:49:45 +00:00
|
|
|
} else {
|
|
|
|
/* TODO: currently only one default pool and thus
|
|
|
|
* nothing here, change it when pools are supported
|
|
|
|
*/
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Name: %s", key);
|
|
|
|
VIR_DEBUG("Storage Volume key : %s", hddNameUtf8);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_UTF8_FREE(hddNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(hddNameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-09-04 14:28:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr vboxStorageVolLookupByPath(virConnectPtr conn, const char *path) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(conn, virStorageVolPtr, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
PRUnichar *hddPathUtf16 = NULL;
|
|
|
|
IHardDisk *hardDisk = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!path)
|
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(path, &hddPathUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (!hddPathUtf16)
|
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddPathUtf16, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddPathUtf16,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddPathUtf16,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
PRUnichar *hddNameUtf16 = NULL;
|
|
|
|
char *hddNameUtf8 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetName, &hddNameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddNameUtf16) {
|
|
|
|
VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(hddNameUtf16);
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (hddNameUtf8) {
|
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
char key[VIR_UUID_STRING_BUFLEN] = "";
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
vboxIIDToUUID(&hddIID, uuid);
|
|
|
|
virUUIDFormat(uuid, key);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
/* TODO: currently only one default pool and thus
|
|
|
|
* the check below, change it when pools are supported
|
|
|
|
*/
|
2013-04-23 12:50:18 +00:00
|
|
|
if (vboxConnectNumOfStoragePools(conn) == 1)
|
2012-11-10 07:18:07 +00:00
|
|
|
ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key,
|
|
|
|
NULL, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Pool: %s", "default-pool");
|
|
|
|
VIR_DEBUG("Storage Volume Name: %s", hddNameUtf8);
|
|
|
|
VIR_DEBUG("Storage Volume key : %s", key);
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF8_FREE(hddNameUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddPathUtf16);
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool,
|
|
|
|
const char *xml,
|
2011-07-06 23:06:11 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(pool->conn, virStorageVolPtr, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
virStorageVolDefPtr def = NULL;
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *hddFormatUtf16 = NULL;
|
|
|
|
PRUnichar *hddNameUtf16 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
virStoragePoolDef poolDef;
|
|
|
|
nsresult rc;
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
/* since there is currently one default pool now
|
|
|
|
* and virStorageVolDefFormat() just checks it type
|
|
|
|
* so just assign it for now, change the behaviour
|
|
|
|
* when vbox supports pools.
|
|
|
|
*/
|
|
|
|
memset(&poolDef, 0, sizeof(poolDef));
|
|
|
|
poolDef.type = VIR_STORAGE_POOL_DIR;
|
|
|
|
|
2010-02-10 11:42:56 +00:00
|
|
|
if ((def = virStorageVolDefParseString(&poolDef, xml)) == NULL)
|
2009-09-04 14:28:52 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!def->name ||
|
|
|
|
(def->type != VIR_STORAGE_VOL_FILE))
|
2009-12-04 13:49:45 +00:00
|
|
|
goto cleanup;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* TODO: for now only the vmdk, vpc and vdi type harddisk
|
|
|
|
* variants can be created, also since there is no vdi
|
|
|
|
* type in enum virStorageFileFormat {} the default
|
|
|
|
* will be to create vdi if nothing is specified in
|
|
|
|
* def->target.format
|
|
|
|
*/
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (def->target.format == VIR_STORAGE_FILE_VMDK) {
|
|
|
|
VBOX_UTF8_TO_UTF16("VMDK", &hddFormatUtf16);
|
|
|
|
} else if (def->target.format == VIR_STORAGE_FILE_VPC) {
|
|
|
|
VBOX_UTF8_TO_UTF16("VHD", &hddFormatUtf16);
|
|
|
|
} else {
|
|
|
|
VBOX_UTF8_TO_UTF16("VDI", &hddFormatUtf16);
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_TO_UTF16(def->name, &hddNameUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (hddFormatUtf16 && hddNameUtf16) {
|
|
|
|
IHardDisk *hardDisk = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = data->vboxObj->vtbl->CreateHardDisk(data->vboxObj, hddFormatUtf16, hddNameUtf16, &hardDisk);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
IProgress *progress = NULL;
|
2011-01-28 21:03:24 +00:00
|
|
|
PRUint64 logicalSize = VIR_DIV_UP(def->capacity, 1024 * 1024);
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint32 variant = HardDiskVariant_Standard;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (def->capacity == def->allocation)
|
|
|
|
variant = HardDiskVariant_Fixed;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4003000
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, variant, &progress);
|
2013-11-21 14:41:07 +00:00
|
|
|
#else
|
|
|
|
rc = hardDisk->vtbl->CreateBaseStorage(hardDisk, logicalSize, 1, &variant, &progress);
|
|
|
|
#endif
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc) && progress) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000
|
2009-12-04 13:49:45 +00:00
|
|
|
nsresult resultCode;
|
2009-09-04 14:28:52 +00:00
|
|
|
#else
|
2009-12-04 13:49:45 +00:00
|
|
|
PRInt32 resultCode;
|
2009-09-04 14:28:52 +00:00
|
|
|
#endif
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
progress->vtbl->GetResultCode(progress, &resultCode);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(resultCode)) {
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
char key[VIR_UUID_STRING_BUFLEN] = "";
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetId, &hddIID.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDToUUID(&hddIID, uuid);
|
|
|
|
virUUIDFormat(uuid, key);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2012-11-10 07:18:07 +00:00
|
|
|
ret = virGetStorageVol(pool->conn, pool->name, def->name, key,
|
|
|
|
NULL, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
|
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(progress);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddFormatUtf16);
|
|
|
|
VBOX_UTF16_FREE(hddNameUtf16);
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
cleanup:
|
|
|
|
virStorageVolDefFree(def);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxStorageVolDelete(virStorageVolPtr vol,
|
2011-07-06 23:06:11 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(vol->conn, int, -1);
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
2009-09-04 14:28:52 +00:00
|
|
|
IHardDisk *hardDisk = NULL;
|
|
|
|
int deregister = 0;
|
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i = 0;
|
|
|
|
size_t j = 0;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (virUUIDParse(vol->key, uuid) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Could not parse UUID from '%s'"), vol->key);
|
2010-12-23 16:25:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&hddIID, uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
PRUint32 machineIdsSize = 0;
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray machineIds = VBOX_ARRAY_INITIALIZER;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&machineIds, hardDisk, hardDisk->vtbl->imedium.GetMachineIds);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&machineIds, hardDisk, hardDisk->vtbl->GetMachineIds);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION == 2002000 && defined WIN32
|
2010-12-23 16:25:56 +00:00
|
|
|
/* VirtualBox 2.2 on Windows represents IIDs as GUIDs and the
|
|
|
|
* machineIds array contains direct instances of the GUID struct
|
|
|
|
* instead of pointers to the actual struct instances. But there
|
|
|
|
* is no 128bit width simple item type for a SafeArray to fit a
|
|
|
|
* GUID in. The largest simple type it 64bit width and VirtualBox
|
|
|
|
* uses two of this 64bit items to represents one GUID. Therefore,
|
2012-10-11 16:31:20 +00:00
|
|
|
* we divide the size of the SafeArray by two, to compensate for
|
2010-12-23 16:25:56 +00:00
|
|
|
* this workaround in VirtualBox */
|
|
|
|
machineIds.count /= 2;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 2002000 */
|
2010-12-23 16:25:56 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
machineIdsSize = machineIds.count;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
for (i = 0; i < machineIds.count; i++) {
|
2009-12-04 13:49:45 +00:00
|
|
|
IMachine *machine = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID machineId = VBOX_IID_INITIALIZER;
|
|
|
|
|
|
|
|
vboxIIDFromArrayItem(&machineId, &machineIds, i);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(machineId.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2010-12-27 22:35:30 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
rc = VBOX_SESSION_OPEN(machineId.value, machine);
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArray hddAttachments = VBOX_ARRAY_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&hddAttachments, machine,
|
|
|
|
machine->vtbl->GetHardDiskAttachments);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayGet(&hddAttachments, machine,
|
|
|
|
machine->vtbl->GetMediumAttachments);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2010-12-16 22:05:48 +00:00
|
|
|
for (j = 0; j < hddAttachments.count; j++) {
|
|
|
|
IHardDiskAttachment *hddAttachment = hddAttachments.items[j];
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (hddAttachment) {
|
|
|
|
IHardDisk *hdd = NULL;
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = hddAttachment->vtbl->GetHardDisk(hddAttachment, &hdd);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = hddAttachment->vtbl->GetMedium(hddAttachment, &hdd);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc) && hdd) {
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = VBOX_MEDIUM_FUNC_ARG1(hdd, GetId, &iid.value);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("HardDisk (to delete) UUID", hddIID.value);
|
|
|
|
DEBUGIID("HardDisk (currently processing) UUID", iid.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (vboxIIDIsEqual(&hddIID, &iid)) {
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUnichar *controller = NULL;
|
|
|
|
PRInt32 port = 0;
|
|
|
|
PRInt32 device = 0;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("Found HardDisk to delete, UUID", hddIID.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
hddAttachment->vtbl->GetController(hddAttachment, &controller);
|
|
|
|
hddAttachment->vtbl->GetPort(hddAttachment, &port);
|
|
|
|
hddAttachment->vtbl->GetDevice(hddAttachment, &device);
|
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 3001000
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = machine->vtbl->DetachHardDisk(machine, controller, port, device);
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = machine->vtbl->DetachDevice(machine, controller, port, device);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 3001000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = machine->vtbl->SaveSettings(machine);
|
2011-05-09 09:24:09 +00:00
|
|
|
VIR_DEBUG("saving machine settings");
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
deregister++;
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("deregistering hdd:%d", deregister);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2013-01-24 00:34:48 +00:00
|
|
|
VBOX_UTF16_FREE(controller);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&iid);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_RELEASE(hdd);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayRelease(&hddAttachments);
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_RELEASE(machine);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2010-12-27 22:35:30 +00:00
|
|
|
VBOX_SESSION_CLOSE();
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2010-12-23 16:25:56 +00:00
|
|
|
|
|
|
|
vboxIIDUnalloc(&machineId);
|
2009-12-04 13:49:45 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-16 22:05:48 +00:00
|
|
|
vboxArrayUnalloc(&machineIds);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (machineIdsSize == 0 || machineIdsSize == deregister) {
|
|
|
|
IProgress *progress = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
rc = hardDisk->vtbl->DeleteStorage(hardDisk, &progress);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc) && progress) {
|
|
|
|
progress->vtbl->WaitForCompletion(progress, -1);
|
|
|
|
VBOX_RELEASE(progress);
|
2010-12-23 16:25:56 +00:00
|
|
|
DEBUGIID("HardDisk deleted, UUID", hddIID.value);
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(vol->conn, int, -1);
|
2009-09-04 14:28:52 +00:00
|
|
|
IHardDisk *hardDisk = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
nsresult rc;
|
|
|
|
|
2010-01-18 08:58:57 +00:00
|
|
|
if (!info)
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (virUUIDParse(vol->key, uuid) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Could not parse UUID from '%s'"), vol->key);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&hddIID, uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint64 hddLogicalSize;
|
|
|
|
PRUint64 hddActualSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
PRInt64 hddLogicalSize;
|
|
|
|
PRInt64 hddActualSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
info->type = VIR_STORAGE_VOL_FILE;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
info->capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
info->capacity = hddLogicalSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
|
|
|
|
info->allocation = hddActualSize;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
ret = 0;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Name: %s", vol->name);
|
|
|
|
VIR_DEBUG("Storage Volume Type: %s", info->type == VIR_STORAGE_VOL_BLOCK ? "Block" : "File");
|
|
|
|
VIR_DEBUG("Storage Volume Capacity: %llu", info->capacity);
|
|
|
|
VIR_DEBUG("Storage Volume Allocation: %llu", info->allocation);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
|
|
|
|
{
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
IHardDisk *hardDisk = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
virStoragePoolDef pool;
|
|
|
|
virStorageVolDef def;
|
|
|
|
int defOk = 0;
|
|
|
|
nsresult rc;
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
memset(&pool, 0, sizeof(pool));
|
|
|
|
memset(&def, 0, sizeof(def));
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (virUUIDParse(vol->key, uuid) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Could not parse UUID from '%s'"), vol->key);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&hddIID, uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
|
|
|
|
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (NS_SUCCEEDED(rc) && hddstate != MediaState_Inaccessible) {
|
|
|
|
PRUnichar *hddFormatUtf16 = NULL;
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
PRUint64 hddLogicalSize;
|
|
|
|
PRUint64 hddActualSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
PRInt64 hddLogicalSize;
|
|
|
|
PRInt64 hddActualSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
/* since there is currently one default pool now
|
|
|
|
* and virStorageVolDefFormat() just checks it type
|
|
|
|
* so just assign it for now, change the behaviour
|
|
|
|
* when vbox supports pools.
|
|
|
|
*/
|
|
|
|
pool.type = VIR_STORAGE_POOL_DIR;
|
|
|
|
def.type = VIR_STORAGE_VOL_FILE;
|
|
|
|
defOk = 1;
|
|
|
|
|
|
|
|
rc = hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
|
2010-12-27 22:35:30 +00:00
|
|
|
if (NS_SUCCEEDED(rc) && defOk) {
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2009-12-04 13:49:45 +00:00
|
|
|
def.capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
|
2013-12-24 09:39:38 +00:00
|
|
|
#else /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
def.capacity = hddLogicalSize;
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2010-12-27 22:35:30 +00:00
|
|
|
} else
|
2009-12-04 13:49:45 +00:00
|
|
|
defOk = 0;
|
|
|
|
|
|
|
|
rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
|
|
|
|
if (NS_SUCCEEDED(rc) && defOk)
|
|
|
|
def.allocation = hddActualSize;
|
|
|
|
else
|
|
|
|
defOk = 0;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def.name, vol->name) < 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
defOk = 0;
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(def.key, vol->key) < 0)
|
2009-12-04 13:49:45 +00:00
|
|
|
defOk = 0;
|
|
|
|
|
|
|
|
rc = hardDisk->vtbl->GetFormat(hardDisk, &hddFormatUtf16);
|
|
|
|
if (NS_SUCCEEDED(rc) && defOk) {
|
|
|
|
char *hddFormatUtf8 = NULL;
|
|
|
|
|
|
|
|
VBOX_UTF16_TO_UTF8(hddFormatUtf16, &hddFormatUtf8);
|
|
|
|
if (hddFormatUtf8) {
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Format: %s", hddFormatUtf8);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
if (STRCASEEQ("vmdk", hddFormatUtf8))
|
|
|
|
def.target.format = VIR_STORAGE_FILE_VMDK;
|
|
|
|
else if (STRCASEEQ("vhd", hddFormatUtf8))
|
|
|
|
def.target.format = VIR_STORAGE_FILE_VPC;
|
2009-09-04 14:28:52 +00:00
|
|
|
else
|
2009-12-04 13:49:45 +00:00
|
|
|
def.target.format = VIR_STORAGE_FILE_RAW;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
/* TODO: need to add vdi to enum virStorageFileFormat {}
|
|
|
|
* and then add it here
|
|
|
|
*/
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(hddFormatUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddFormatUtf16);
|
|
|
|
} else {
|
|
|
|
defOk = 0;
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
if (defOk)
|
2010-02-10 11:42:56 +00:00
|
|
|
ret = virStorageVolDefFormat(&pool, &def);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_OBJECT_CHECK(vol->conn, char *, NULL);
|
2009-09-04 14:28:52 +00:00
|
|
|
IHardDisk *hardDisk = NULL;
|
2010-12-23 16:25:56 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
vboxIID hddIID = VBOX_IID_INITIALIZER;
|
2009-09-04 14:28:52 +00:00
|
|
|
nsresult rc;
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
if (virUUIDParse(vol->key, uuid) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("Could not parse UUID from '%s'"), vol->key);
|
2009-12-04 13:49:45 +00:00
|
|
|
return ret;
|
2010-12-23 16:25:56 +00:00
|
|
|
}
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDFromUUID(&hddIID, uuid);
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION < 4000000
|
2010-12-23 16:25:56 +00:00
|
|
|
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#elif VBOX_API_VERSION >= 4000000 && VBOX_API_VERSION < 4002000
|
2010-12-27 22:35:30 +00:00
|
|
|
rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, &hardDisk);
|
2012-10-02 09:00:54 +00:00
|
|
|
#else
|
|
|
|
rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj, hddIID.value,
|
|
|
|
DeviceType_HardDisk, AccessMode_ReadWrite,
|
|
|
|
PR_FALSE, &hardDisk);
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2009-12-04 13:49:45 +00:00
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
PRUint32 hddstate;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
|
|
|
|
if (hddstate != MediaState_Inaccessible) {
|
|
|
|
PRUnichar *hddLocationUtf16 = NULL;
|
|
|
|
char *hddLocationUtf8 = NULL;
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetLocation, &hddLocationUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_TO_UTF8(hddLocationUtf16, &hddLocationUtf8);
|
|
|
|
if (hddLocationUtf8) {
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
ignore_value(VIR_STRDUP(ret, hddLocationUtf8));
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Storage Volume Name: %s", vol->name);
|
|
|
|
VIR_DEBUG("Storage Volume Path: %s", hddLocationUtf8);
|
|
|
|
VIR_DEBUG("Storage Volume Pool: %s", vol->pool);
|
2009-09-04 14:28:52 +00:00
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF8_FREE(hddLocationUtf8);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2009-12-04 13:49:45 +00:00
|
|
|
VBOX_UTF16_FREE(hddLocationUtf16);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
2009-12-04 13:49:45 +00:00
|
|
|
|
|
|
|
VBOX_MEDIUM_RELEASE(hardDisk);
|
2009-09-04 14:28:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-23 16:25:56 +00:00
|
|
|
vboxIIDUnalloc(&hddIID);
|
2009-12-04 13:49:45 +00:00
|
|
|
|
2009-09-04 14:28:52 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2009-05-15 14:00:50 +00:00
|
|
|
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2011-04-01 13:34:23 +00:00
|
|
|
static char *
|
|
|
|
vboxDomainScreenshot(virDomainPtr dom,
|
|
|
|
virStreamPtr st,
|
|
|
|
unsigned int screen,
|
2011-07-06 23:06:11 +00:00
|
|
|
unsigned int flags)
|
2011-04-01 13:34:23 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(dom->conn, char *, NULL);
|
|
|
|
IConsole *console = NULL;
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
IMachine *machine = NULL;
|
|
|
|
nsresult rc;
|
|
|
|
char *tmp;
|
|
|
|
int tmp_fd = -1;
|
|
|
|
unsigned int max_screen;
|
|
|
|
|
2011-07-06 23:06:11 +00:00
|
|
|
virCheckFlags(0, NULL);
|
|
|
|
|
2011-04-01 13:34:23 +00:00
|
|
|
vboxIIDFromUUID(&iid, dom->uuid);
|
|
|
|
rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_NO_DOMAIN, "%s",
|
|
|
|
_("no domain with matching uuid"));
|
2011-04-01 13:34:23 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = machine->vtbl->GetMonitorCount(machine, &max_screen);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("unable to get monitor count"));
|
2011-04-01 13:34:23 +00:00
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (screen >= max_screen) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("screen ID higher than monitor "
|
|
|
|
"count (%d)"), max_screen);
|
2011-04-01 13:34:23 +00:00
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX", LOCALSTATEDIR) < 0) {
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-10-31 14:13:47 +00:00
|
|
|
if ((tmp_fd = mkostemp(tmp, O_CLOEXEC)) == -1) {
|
|
|
|
virReportSystemError(errno, _("mkostemp(\"%s\") failed"), tmp);
|
2011-04-01 13:34:23 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
|
|
|
|
if (NS_SUCCEEDED(rc)) {
|
|
|
|
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
|
|
|
|
if (NS_SUCCEEDED(rc) && console) {
|
|
|
|
IDisplay *display = NULL;
|
|
|
|
|
|
|
|
console->vtbl->GetDisplay(console, &display);
|
|
|
|
|
|
|
|
if (display) {
|
|
|
|
PRUint32 width, height, bitsPerPixel;
|
|
|
|
PRUint32 screenDataSize;
|
|
|
|
PRUint8 *screenData;
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION >= 4003000
|
2013-11-21 14:41:07 +00:00
|
|
|
PRInt32 xOrigin, yOrigin;
|
|
|
|
# endif
|
2011-04-01 13:34:23 +00:00
|
|
|
|
|
|
|
rc = display->vtbl->GetScreenResolution(display, screen,
|
|
|
|
&width, &height,
|
2013-12-24 09:39:38 +00:00
|
|
|
# if VBOX_API_VERSION < 4003000
|
2011-04-01 13:34:23 +00:00
|
|
|
&bitsPerPixel);
|
2013-11-21 14:41:07 +00:00
|
|
|
# else
|
|
|
|
&bitsPerPixel,
|
|
|
|
&xOrigin, &yOrigin);
|
|
|
|
# endif
|
2011-04-01 13:34:23 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rc) || !width || !height) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("unable to get screen resolution"));
|
2011-04-01 13:34:23 +00:00
|
|
|
goto endjob;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = display->vtbl->TakeScreenShotPNGToArray(display, screen,
|
|
|
|
width, height,
|
|
|
|
&screenDataSize,
|
|
|
|
&screenData);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("failed to take screenshot"));
|
2011-04-01 13:34:23 +00:00
|
|
|
goto endjob;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (safewrite(tmp_fd, (char *) screenData,
|
|
|
|
screenDataSize) < 0) {
|
|
|
|
virReportSystemError(errno, _("unable to write data "
|
|
|
|
"to '%s'"), tmp);
|
|
|
|
goto endjob;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_CLOSE(tmp_fd) < 0) {
|
|
|
|
virReportSystemError(errno, _("unable to close %s"), tmp);
|
|
|
|
goto endjob;
|
|
|
|
}
|
|
|
|
|
2013-05-03 12:50:19 +00:00
|
|
|
if (VIR_STRDUP(ret, "image/png") < 0)
|
|
|
|
goto endjob;
|
|
|
|
|
2011-08-02 17:19:53 +00:00
|
|
|
if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY) < 0) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
|
|
|
|
_("unable to open stream"));
|
2013-05-03 12:50:19 +00:00
|
|
|
VIR_FREE(ret);
|
2011-04-01 13:34:23 +00:00
|
|
|
}
|
|
|
|
endjob:
|
|
|
|
VIR_FREE(screenData);
|
|
|
|
VBOX_RELEASE(display);
|
|
|
|
}
|
|
|
|
VBOX_RELEASE(console);
|
|
|
|
}
|
|
|
|
VBOX_SESSION_CLOSE();
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FORCE_CLOSE(tmp_fd);
|
2011-08-02 17:19:53 +00:00
|
|
|
unlink(tmp);
|
2011-04-01 13:34:23 +00:00
|
|
|
VIR_FREE(tmp);
|
|
|
|
VBOX_RELEASE(machine);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
return ret;
|
|
|
|
}
|
2013-12-24 09:39:38 +00:00
|
|
|
#endif /* VBOX_API_VERSION >= 4000000 */
|
2011-04-01 13:34:23 +00:00
|
|
|
|
2012-06-05 12:12:21 +00:00
|
|
|
|
|
|
|
#define MATCH(FLAG) (flags & (FLAG))
|
|
|
|
static int
|
2013-04-23 12:50:18 +00:00
|
|
|
vboxConnectListAllDomains(virConnectPtr conn,
|
|
|
|
virDomainPtr **domains,
|
|
|
|
unsigned int flags)
|
2012-06-05 12:12:21 +00:00
|
|
|
{
|
|
|
|
VBOX_OBJECT_CHECK(conn, int, -1);
|
|
|
|
vboxArray machines = VBOX_ARRAY_INITIALIZER;
|
|
|
|
char *machineNameUtf8 = NULL;
|
|
|
|
PRUnichar *machineNameUtf16 = NULL;
|
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
|
|
|
vboxIID iid = VBOX_IID_INITIALIZER;
|
|
|
|
PRUint32 state;
|
|
|
|
nsresult rc;
|
Convert 'int i' to 'size_t i' in src/vbox/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2012-06-05 12:12:21 +00:00
|
|
|
virDomainPtr dom;
|
|
|
|
virDomainPtr *doms = NULL;
|
|
|
|
int count = 0;
|
|
|
|
bool active;
|
|
|
|
PRUint32 snapshotCount;
|
|
|
|
|
2012-08-03 15:48:05 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1);
|
2012-06-05 12:12:21 +00:00
|
|
|
|
|
|
|
/* filter out flag options that will produce 0 results in vbox driver:
|
|
|
|
* - managed save: vbox guests don't have managed save images
|
|
|
|
* - autostart: vbox doesn't support autostarting guests
|
|
|
|
* - persistance: vbox doesn't support transient guests
|
|
|
|
*/
|
|
|
|
if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
|
|
|
|
!MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
|
|
|
|
!MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
|
|
|
|
!MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) {
|
|
|
|
if (domains &&
|
|
|
|
VIR_ALLOC_N(*domains, 1) < 0)
|
2013-07-04 10:17:38 +00:00
|
|
|
goto cleanup;
|
2012-06-05 12:12:21 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = vboxArrayGet(&machines, data->vboxObj, data->vboxObj->vtbl->GetMachines);
|
|
|
|
if (NS_FAILED(rc)) {
|
2012-07-18 12:06:29 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Could not get list of domains, rc=%08x"), (unsigned)rc);
|
2012-06-05 12:12:21 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (domains &&
|
|
|
|
VIR_ALLOC_N(doms, machines.count + 1) < 0)
|
2013-07-04 10:17:38 +00:00
|
|
|
goto cleanup;
|
2012-06-05 12:12:21 +00:00
|
|
|
|
|
|
|
for (i = 0; i < machines.count; i++) {
|
|
|
|
IMachine *machine = machines.items[i];
|
|
|
|
|
|
|
|
if (machine) {
|
|
|
|
PRBool isAccessible = PR_FALSE;
|
|
|
|
machine->vtbl->GetAccessible(machine, &isAccessible);
|
|
|
|
if (isAccessible) {
|
|
|
|
machine->vtbl->GetState(machine, &state);
|
|
|
|
|
|
|
|
if (state >= MachineState_FirstOnline &&
|
|
|
|
state <= MachineState_LastOnline)
|
|
|
|
active = true;
|
|
|
|
else
|
|
|
|
active = false;
|
|
|
|
|
|
|
|
/* filter by active state */
|
2012-08-03 15:48:05 +00:00
|
|
|
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
|
2012-06-05 12:12:21 +00:00
|
|
|
!((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && active) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && !active)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* filter by snapshot existence */
|
2012-08-03 15:48:05 +00:00
|
|
|
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
|
2012-06-05 12:12:21 +00:00
|
|
|
rc = machine->vtbl->GetSnapshotCount(machine, &snapshotCount);
|
|
|
|
if (NS_FAILED(rc)) {
|
maint: don't permit format strings without %
Any time we have a string with no % passed through gettext, a
translator can inject a % to cause a stack overread. When there
is nothing to format, it's easier to ask for a string that cannot
be used as a formatter, by using a trivial "%s" format instead.
In the past, we have used --disable-nls to catch some of the
offenders, but that doesn't get run very often, and many more
uses have crept in. Syntax check to the rescue!
The syntax check can catch uses such as
virReportError(code,
_("split "
"string"));
by using a sed script to fold context lines into one pattern
space before checking for a string without %.
This patch is just mechanical insertion of %s; there are probably
several messages touched by this patch where we would be better
off giving the user more information than a fixed string.
* cfg.mk (sc_prohibit_diagnostic_without_format): New rule.
* src/datatypes.c (virUnrefConnect, virGetDomain)
(virUnrefDomain, virGetNetwork, virUnrefNetwork, virGetInterface)
(virUnrefInterface, virGetStoragePool, virUnrefStoragePool)
(virGetStorageVol, virUnrefStorageVol, virGetNodeDevice)
(virGetSecret, virUnrefSecret, virGetNWFilter, virUnrefNWFilter)
(virGetDomainSnapshot, virUnrefDomainSnapshot): Add %s wrapper.
* src/lxc/lxc_driver.c (lxcDomainSetBlkioParameters)
(lxcDomainGetBlkioParameters): Likewise.
* src/conf/domain_conf.c (virSecurityDeviceLabelDefParseXML)
(virDomainDiskDefParseXML, virDomainGraphicsDefParseXML):
Likewise.
* src/conf/network_conf.c (virNetworkDNSHostsDefParseXML)
(virNetworkDefParseXML): Likewise.
* src/conf/nwfilter_conf.c (virNWFilterIsValidChainName):
Likewise.
* src/conf/nwfilter_params.c (virNWFilterVarValueCreateSimple)
(virNWFilterVarAccessParse): Likewise.
* src/libvirt.c (virDomainSave, virDomainSaveFlags)
(virDomainRestore, virDomainRestoreFlags)
(virDomainSaveImageGetXMLDesc, virDomainSaveImageDefineXML)
(virDomainCoreDump, virDomainGetXMLDesc)
(virDomainMigrateVersion1, virDomainMigrateVersion2)
(virDomainMigrateVersion3, virDomainMigrate, virDomainMigrate2)
(virStreamSendAll, virStreamRecvAll)
(virDomainSnapshotGetXMLDesc): Likewise.
* src/nwfilter/nwfilter_dhcpsnoop.c (virNWFilterSnoopReqLeaseDel)
(virNWFilterDHCPSnoopReq): Likewise.
* src/openvz/openvz_driver.c (openvzUpdateDevice): Likewise.
* src/openvz/openvz_util.c (openvzKBPerPages): Likewise.
* src/qemu/qemu_cgroup.c (qemuSetupCgroup): Likewise.
* src/qemu/qemu_command.c (qemuBuildHubDevStr, qemuBuildChrChardevStr)
(qemuBuildCommandLine): Likewise.
* src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Likewise.
* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise.
* src/rpc/virnetsaslcontext.c (virNetSASLSessionGetIdentity):
Likewise.
* src/rpc/virnetsocket.c (virNetSocketNewConnectUNIX)
(virNetSocketSendFD, virNetSocketRecvFD): Likewise.
* src/storage/storage_backend_disk.c
(virStorageBackendDiskBuildPool): Likewise.
* src/storage/storage_backend_fs.c
(virStorageBackendFileSystemProbe)
(virStorageBackendFileSystemBuild): Likewise.
* src/storage/storage_backend_rbd.c
(virStorageBackendRBDOpenRADOSConn): Likewise.
* src/storage/storage_driver.c (storageVolumeResize): Likewise.
* src/test/test_driver.c (testInterfaceChangeBegin)
(testInterfaceChangeCommit, testInterfaceChangeRollback):
Likewise.
* src/vbox/vbox_tmpl.c (vboxListAllDomains): Likewise.
* src/xenxs/xen_sxpr.c (xenFormatSxprDisk, xenFormatSxpr):
Likewise.
* src/xenxs/xen_xm.c (xenXMConfigGetUUID, xenFormatXMDisk)
(xenFormatXM): Likewise.
2012-07-23 20:33:08 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
2012-07-18 12:06:29 +00:00
|
|
|
_("could not get snapshot count for listed domains"));
|
2012-06-05 12:12:21 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
|
|
|
|
snapshotCount > 0) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) &&
|
|
|
|
snapshotCount == 0)))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* filter by machine state */
|
2012-08-03 15:48:05 +00:00
|
|
|
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE) &&
|
2012-06-05 12:12:21 +00:00
|
|
|
!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
|
|
|
|
state == MachineState_Running) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
|
|
|
|
state == MachineState_Paused) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) &&
|
|
|
|
state == MachineState_PoweredOff) ||
|
|
|
|
(MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) &&
|
|
|
|
(state != MachineState_Running &&
|
|
|
|
state != MachineState_Paused &&
|
|
|
|
state != MachineState_PoweredOff))))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* just count the machines */
|
|
|
|
if (!doms) {
|
|
|
|
count++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
machine->vtbl->GetName(machine, &machineNameUtf16);
|
|
|
|
VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8);
|
|
|
|
machine->vtbl->GetId(machine, &iid.value);
|
|
|
|
vboxIIDToUUID(&iid, uuid);
|
|
|
|
vboxIIDUnalloc(&iid);
|
|
|
|
|
|
|
|
dom = virGetDomain(conn, machineNameUtf8, uuid);
|
|
|
|
|
|
|
|
VBOX_UTF8_FREE(machineNameUtf8);
|
|
|
|
VBOX_UTF16_FREE(machineNameUtf16);
|
|
|
|
|
|
|
|
if (!dom)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (active)
|
|
|
|
dom->id = i + 1;
|
|
|
|
|
|
|
|
doms[count++] = dom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doms) {
|
|
|
|
/* safe to ignore, new size will be equal or less than
|
|
|
|
* previous allocation*/
|
|
|
|
ignore_value(VIR_REALLOC_N(doms, count + 1));
|
|
|
|
*domains = doms;
|
|
|
|
doms = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = count;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (doms) {
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
if (doms[i])
|
|
|
|
virDomainFree(doms[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VIR_FREE(doms);
|
|
|
|
|
|
|
|
vboxArrayRelease(&machines);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#undef MATCH
|
|
|
|
|
|
|
|
|
2013-04-26 17:21:58 +00:00
|
|
|
static int
|
|
|
|
vboxNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
virNodeInfoPtr nodeinfo)
|
|
|
|
{
|
|
|
|
return nodeGetInfo(nodeinfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
vboxNodeGetCellsFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
|
unsigned long long *freeMems,
|
|
|
|
int startCell,
|
|
|
|
int maxCells)
|
|
|
|
{
|
|
|
|
return nodeGetCellsFreeMemory(freeMems, startCell, maxCells);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned long long
|
|
|
|
vboxNodeGetFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
return nodeGetFreeMemory();
|
|
|
|
}
|
|
|
|
|
2012-06-05 12:12:21 +00:00
|
|
|
|
2009-05-15 14:00:50 +00:00
|
|
|
/**
|
|
|
|
* Function Tables
|
|
|
|
*/
|
|
|
|
|
2009-04-17 16:09:07 +00:00
|
|
|
virDriver NAME(Driver) = {
|
Convert all driver struct intializers to C99 style
Change all the driver struct initializers to use the
C99 style, leaving out unused fields. This will make
it possible to add new APIs without changing every
driver. eg change:
qemudDomainResume, /* domainResume */
qemudDomainShutdown, /* domainShutdown */
NULL, /* domainReboot */
qemudDomainDestroy, /* domainDestroy */
to
.domainResume = qemudDomainResume,
.domainShutdown = qemudDomainShutdown,
.domainDestroy = qemudDomainDestroy,
And get rid of any existing C99 style initializersr which
set NULL, eg change
.listPools = vboxStorageListPools,
.numOfDefinedPools = NULL,
.listDefinedPools = NULL,
.findPoolSources = NULL,
.poolLookupByName = vboxStoragePoolLookupByName,
to
.listPools = vboxStorageListPools,
.poolLookupByName = vboxStoragePoolLookupByName,
2011-05-13 10:16:31 +00:00
|
|
|
.no = VIR_DRV_VBOX,
|
|
|
|
.name = "VBOX",
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectOpen = vboxConnectOpen, /* 0.6.3 */
|
|
|
|
.connectClose = vboxConnectClose, /* 0.6.3 */
|
|
|
|
.connectGetVersion = vboxConnectGetVersion, /* 0.6.3 */
|
2013-04-26 16:39:11 +00:00
|
|
|
.connectGetHostname = vboxConnectGetHostname, /* 0.6.3 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectGetMaxVcpus = vboxConnectGetMaxVcpus, /* 0.6.3 */
|
2013-04-26 17:21:58 +00:00
|
|
|
.nodeGetInfo = vboxNodeGetInfo, /* 0.6.3 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectGetCapabilities = vboxConnectGetCapabilities, /* 0.6.3 */
|
|
|
|
.connectListDomains = vboxConnectListDomains, /* 0.6.3 */
|
|
|
|
.connectNumOfDomains = vboxConnectNumOfDomains, /* 0.6.3 */
|
|
|
|
.connectListAllDomains = vboxConnectListAllDomains, /* 0.9.13 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainCreateXML = vboxDomainCreateXML, /* 0.6.3 */
|
|
|
|
.domainLookupByID = vboxDomainLookupByID, /* 0.6.3 */
|
|
|
|
.domainLookupByUUID = vboxDomainLookupByUUID, /* 0.6.3 */
|
|
|
|
.domainLookupByName = vboxDomainLookupByName, /* 0.6.3 */
|
|
|
|
.domainSuspend = vboxDomainSuspend, /* 0.6.3 */
|
|
|
|
.domainResume = vboxDomainResume, /* 0.6.3 */
|
|
|
|
.domainShutdown = vboxDomainShutdown, /* 0.6.3 */
|
2011-10-05 17:31:55 +00:00
|
|
|
.domainShutdownFlags = vboxDomainShutdownFlags, /* 0.9.10 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainReboot = vboxDomainReboot, /* 0.6.3 */
|
|
|
|
.domainDestroy = vboxDomainDestroy, /* 0.6.3 */
|
2011-07-21 07:59:16 +00:00
|
|
|
.domainDestroyFlags = vboxDomainDestroyFlags, /* 0.9.4 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainGetOSType = vboxDomainGetOSType, /* 0.6.3 */
|
|
|
|
.domainSetMemory = vboxDomainSetMemory, /* 0.6.3 */
|
|
|
|
.domainGetInfo = vboxDomainGetInfo, /* 0.6.3 */
|
|
|
|
.domainGetState = vboxDomainGetState, /* 0.9.2 */
|
|
|
|
.domainSave = vboxDomainSave, /* 0.6.3 */
|
|
|
|
.domainSetVcpus = vboxDomainSetVcpus, /* 0.7.1 */
|
|
|
|
.domainSetVcpusFlags = vboxDomainSetVcpusFlags, /* 0.8.5 */
|
|
|
|
.domainGetVcpusFlags = vboxDomainGetVcpusFlags, /* 0.8.5 */
|
|
|
|
.domainGetMaxVcpus = vboxDomainGetMaxVcpus, /* 0.7.1 */
|
|
|
|
.domainGetXMLDesc = vboxDomainGetXMLDesc, /* 0.6.3 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectListDefinedDomains = vboxConnectListDefinedDomains, /* 0.6.3 */
|
|
|
|
.connectNumOfDefinedDomains = vboxConnectNumOfDefinedDomains, /* 0.6.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainCreate = vboxDomainCreate, /* 0.6.3 */
|
|
|
|
.domainCreateWithFlags = vboxDomainCreateWithFlags, /* 0.8.2 */
|
|
|
|
.domainDefineXML = vboxDomainDefineXML, /* 0.6.3 */
|
|
|
|
.domainUndefine = vboxDomainUndefine, /* 0.6.3 */
|
2011-08-11 21:44:05 +00:00
|
|
|
.domainUndefineFlags = vboxDomainUndefineFlags, /* 0.9.5 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainAttachDevice = vboxDomainAttachDevice, /* 0.6.3 */
|
|
|
|
.domainAttachDeviceFlags = vboxDomainAttachDeviceFlags, /* 0.7.7 */
|
|
|
|
.domainDetachDevice = vboxDomainDetachDevice, /* 0.6.3 */
|
|
|
|
.domainDetachDeviceFlags = vboxDomainDetachDeviceFlags, /* 0.7.7 */
|
|
|
|
.domainUpdateDeviceFlags = vboxDomainUpdateDeviceFlags, /* 0.8.0 */
|
2013-04-26 17:21:58 +00:00
|
|
|
.nodeGetCellsFreeMemory = vboxNodeGetCellsFreeMemory, /* 0.6.5 */
|
|
|
|
.nodeGetFreeMemory = vboxNodeGetFreeMemory, /* 0.6.5 */
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION >= 4000000
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainScreenshot = vboxDomainScreenshot, /* 0.9.2 */
|
2011-04-01 13:34:23 +00:00
|
|
|
#endif
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION > 2002000 && VBOX_API_VERSION < 4000000
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectDomainEventRegister = vboxConnectDomainEventRegister, /* 0.7.0 */
|
|
|
|
.connectDomainEventDeregister = vboxConnectDomainEventDeregister, /* 0.7.0 */
|
2009-07-24 16:12:16 +00:00
|
|
|
#endif
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectIsEncrypted = vboxConnectIsEncrypted, /* 0.7.3 */
|
|
|
|
.connectIsSecure = vboxConnectIsSecure, /* 0.7.3 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainIsActive = vboxDomainIsActive, /* 0.7.3 */
|
|
|
|
.domainIsPersistent = vboxDomainIsPersistent, /* 0.7.3 */
|
|
|
|
.domainIsUpdated = vboxDomainIsUpdated, /* 0.8.6 */
|
2013-12-24 09:39:38 +00:00
|
|
|
#if VBOX_API_VERSION > 2002000 && VBOX_API_VERSION < 4000000
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectDomainEventRegisterAny = vboxConnectDomainEventRegisterAny, /* 0.8.0 */
|
|
|
|
.connectDomainEventDeregisterAny = vboxConnectDomainEventDeregisterAny, /* 0.8.0 */
|
2010-03-18 14:47:07 +00:00
|
|
|
#endif
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotCreateXML = vboxDomainSnapshotCreateXML, /* 0.8.0 */
|
|
|
|
.domainSnapshotGetXMLDesc = vboxDomainSnapshotGetXMLDesc, /* 0.8.0 */
|
|
|
|
.domainSnapshotNum = vboxDomainSnapshotNum, /* 0.8.0 */
|
|
|
|
.domainSnapshotListNames = vboxDomainSnapshotListNames, /* 0.8.0 */
|
|
|
|
.domainSnapshotLookupByName = vboxDomainSnapshotLookupByName, /* 0.8.0 */
|
|
|
|
.domainHasCurrentSnapshot = vboxDomainHasCurrentSnapshot, /* 0.8.0 */
|
2011-09-29 20:26:03 +00:00
|
|
|
.domainSnapshotGetParent = vboxDomainSnapshotGetParent, /* 0.9.7 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainSnapshotCurrent = vboxDomainSnapshotCurrent, /* 0.8.0 */
|
2012-05-25 02:28:54 +00:00
|
|
|
.domainSnapshotIsCurrent = vboxDomainSnapshotIsCurrent, /* 0.9.13 */
|
|
|
|
.domainSnapshotHasMetadata = vboxDomainSnapshotHasMetadata, /* 0.9.13 */
|
2011-05-13 13:35:01 +00:00
|
|
|
.domainRevertToSnapshot = vboxDomainRevertToSnapshot, /* 0.8.0 */
|
|
|
|
.domainSnapshotDelete = vboxDomainSnapshotDelete, /* 0.8.0 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectIsAlive = vboxConnectIsAlive, /* 0.9.8 */
|
2009-04-17 16:09:07 +00:00
|
|
|
};
|
2009-05-15 14:00:50 +00:00
|
|
|
|
|
|
|
virNetworkDriver NAME(NetworkDriver) = {
|
|
|
|
"VBOX",
|
2013-04-23 12:49:21 +00:00
|
|
|
.networkOpen = vboxNetworkOpen, /* 0.6.4 */
|
|
|
|
.networkClose = vboxNetworkClose, /* 0.6.4 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectNumOfNetworks = vboxConnectNumOfNetworks, /* 0.6.4 */
|
|
|
|
.connectListNetworks = vboxConnectListNetworks, /* 0.6.4 */
|
|
|
|
.connectNumOfDefinedNetworks = vboxConnectNumOfDefinedNetworks, /* 0.6.4 */
|
|
|
|
.connectListDefinedNetworks = vboxConnectListDefinedNetworks, /* 0.6.4 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.networkLookupByUUID = vboxNetworkLookupByUUID, /* 0.6.4 */
|
|
|
|
.networkLookupByName = vboxNetworkLookupByName, /* 0.6.4 */
|
|
|
|
.networkCreateXML = vboxNetworkCreateXML, /* 0.6.4 */
|
|
|
|
.networkDefineXML = vboxNetworkDefineXML, /* 0.6.4 */
|
|
|
|
.networkUndefine = vboxNetworkUndefine, /* 0.6.4 */
|
|
|
|
.networkCreate = vboxNetworkCreate, /* 0.6.4 */
|
|
|
|
.networkDestroy = vboxNetworkDestroy, /* 0.6.4 */
|
|
|
|
.networkGetXMLDesc = vboxNetworkGetXMLDesc, /* 0.6.4 */
|
2009-05-15 14:00:50 +00:00
|
|
|
};
|
2009-09-04 14:28:52 +00:00
|
|
|
|
|
|
|
virStorageDriver NAME(StorageDriver) = {
|
|
|
|
.name = "VBOX",
|
2013-04-23 12:49:21 +00:00
|
|
|
.storageOpen = vboxStorageOpen, /* 0.7.1 */
|
|
|
|
.storageClose = vboxStorageClose, /* 0.7.1 */
|
2013-04-23 12:50:18 +00:00
|
|
|
.connectNumOfStoragePools = vboxConnectNumOfStoragePools, /* 0.7.1 */
|
|
|
|
.connectListStoragePools = vboxConnectListStoragePools, /* 0.7.1 */
|
2013-04-22 17:26:01 +00:00
|
|
|
.storagePoolLookupByName = vboxStoragePoolLookupByName, /* 0.7.1 */
|
|
|
|
.storagePoolNumOfVolumes = vboxStoragePoolNumOfVolumes, /* 0.7.1 */
|
|
|
|
.storagePoolListVolumes = vboxStoragePoolListVolumes, /* 0.7.1 */
|
|
|
|
|
|
|
|
.storageVolLookupByName = vboxStorageVolLookupByName, /* 0.7.1 */
|
|
|
|
.storageVolLookupByKey = vboxStorageVolLookupByKey, /* 0.7.1 */
|
|
|
|
.storageVolLookupByPath = vboxStorageVolLookupByPath, /* 0.7.1 */
|
|
|
|
.storageVolCreateXML = vboxStorageVolCreateXML, /* 0.7.1 */
|
|
|
|
.storageVolDelete = vboxStorageVolDelete, /* 0.7.1 */
|
|
|
|
.storageVolGetInfo = vboxStorageVolGetInfo, /* 0.7.1 */
|
|
|
|
.storageVolGetXMLDesc = vboxStorageVolGetXMLDesc, /* 0.7.1 */
|
|
|
|
.storageVolGetPath = vboxStorageVolGetPath /* 0.7.1 */
|
2009-09-04 14:28:52 +00:00
|
|
|
};
|