[libvirt] [PATCH] node_device: udev driver does not handle SR-IOV devices
by Chris Wright
The udev driver does not update a PCI device with its SR-IOV capabilities,
when applicable, the way the hal driver does. As a result, dumping the
device's XML will not include the relevant physical or virtual function
information.
With this patch, the XML is correct:
# virsh nodedev-dumpxml pci_0000_09_00_0
<device>
<name>pci_0000_09_00_0</name>
<parent>pci_0000_00_1c_0</parent>
<driver>
<name>vxge</name>
</driver>
<capability type='pci'>
<domain>0</domain>
<bus>9</bus>
<slot>0</slot>
<function>0</function>
<product id='0x5833'>X3100 Series 10 Gigabit Ethernet PCIe</product>
<vendor id='0x17d5'>Neterion Inc.</vendor>
<capability type='virt_functions'>
<address domain='0x0000' bus='0x0a' slot='0x00' function='0x1'/>
<address domain='0x0000' bus='0x0a' slot='0x00' function='0x2'/>
<address domain='0x0000' bus='0x0a' slot='0x00' function='0x3'/>
</capability>
</capability>
</device>
# virsh nodedev-dumpxml pci_0000_0a_00_1
<device>
<name>pci_0000_0a_00_1</name>
<parent>pci_0000_00_1c_0</parent>
<driver>
<name>vxge</name>
</driver>
<capability type='pci'>
<domain>0</domain>
<bus>10</bus>
<slot>0</slot>
<function>1</function>
<product id='0x5833'>X3100 Series 10 Gigabit Ethernet PCIe</product>
<vendor id='0x17d5'>Neterion Inc.</vendor>
<capability type='phys_function'>
<address domain='0x0000' bus='0x09' slot='0x00' function='0x0'/>
</capability>
</capability>
</device>
Cc: Dave Allan <dallan(a)redhat.com>
Signed-off-by: Chris Wright <chrisw(a)redhat.com>
---
src/node_device/node_device_udev.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 02e44a1..379af86 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -419,11 +419,11 @@ out:
static int udevProcessPCI(struct udev_device *device,
virNodeDeviceDefPtr def)
{
- const char *devpath = NULL;
+ const char *syspath = NULL;
union _virNodeDevCapData *data = &def->caps->data;
int ret = -1;
- devpath = udev_device_get_devpath(device);
+ syspath = udev_device_get_syspath(device);
if (udevGetUintProperty(device,
"PCI_CLASS",
@@ -432,7 +432,7 @@ static int udevProcessPCI(struct udev_device *device,
goto out;
}
- char *p = strrchr(devpath, '/');
+ char *p = strrchr(syspath, '/');
if ((p == NULL) || (udevStrToLong_ui(p+1,
&p,
@@ -487,6 +487,9 @@ static int udevProcessPCI(struct udev_device *device,
goto out;
}
+ get_physical_function(syspath, data);
+ get_virtual_functions(syspath, data);
+
ret = 0;
out:
13 years, 10 months
[libvirt] [PATCH] virExec: fix logic bug
by Eric Blake
As pointed out in https://bugzilla.redhat.com/show_bug.cgi?id=659855#c9,
commit c3568ec2 introduced a regression where we no longer close any
fd's beyond FD_SETSIZE.
* src/util/util.c (__virExec): Continue to close fd's beyond
keepfd range.
Reported by Stefan Praszalowicz.
---
src/util/util.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index d6fa81b..197c571 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -570,7 +570,7 @@ __virExec(const char *const*argv,
i != null &&
i != childout &&
i != childerr &&
- (!keepfd || (i < FD_SETSIZE && !FD_ISSET(i, keepfd)))) {
+ (!keepfd || i >= FD_SETSIZE || !FD_ISSET(i, keepfd))) {
tmpfd = i;
VIR_FORCE_CLOSE(tmpfd);
}
--
1.7.3.4
13 years, 10 months
[libvirt] [PATCH 1/3] Virtual network cleanup/bugfixes
by Laine Stump
The first two patches remedy a bug found by Stefan Berger in the new
brAddInetInterface() function that resulted in the broadcast address
not being properly set. This is a regression from previous releases,
so it should be pushed prior to the upcoming release.
The third patch improves the API for a couple of functions that were
recently added, but does not change any behavior. I'd be happy pushing
it now or after the release.
13 years, 10 months
[libvirt] [PATCHv2 00/13] IPv6 support for virtual networks using bridge driver
by Laine Stump
This is a resend of
https://www.redhat.com/archives/libvir-list/2010-December/msg00765.html
incorporating changes due to comments from Eric Blake and Paweł Krześniak.
changes from v1 to v2 are noted in each individual mail
-----
Most of this patchset is setup for patch 09/13, which updates the
network XML parser to support IPv6, and 12/13, which turns on IPv6 in
the bridge driver.
In order to have each patch individually pass make check and
(otherwise function properly in case someone is doing a bisect), there
is a bit of extra code churn (lines that are changed in one patch,
only to be changed again in a later patch); I tried to minimize this
as much as possible.
For for IPv6 to work correctly, target *and build* systems will
now need to have ip6tables and radvd available. The way I added
ip6tables into autoconfigure.ac is identical to existing iptables, and
the way I added radvd is identical to dnsmasq. Unfortunately this
doesn't communicate the requirement downstream in a programmatic
fashion, so I guess we need to make sure that this is adequately
reported in the next set of release notes.
13 years, 10 months
[libvirt] potential bug in qemu snapshots
by Eric Blake
Right now, we create qemu snapshots to a file by using an exec: monitor
command that passes 'compressor | { dd && dd; }' with stdout connected
to the target file. However, since dd is using a larger bs= than
PIPE_MAX, it is conceivable that under heavy machine load, that dd will
get a short read from the pipe, and unless we use the GNU extension of
iflag=fullblock, that short read will be padded out to the output block
size and result in data corruption in the destination file.
The possibility of corruption due to short reads when dd is fed input
through a pipe but produces output through a large block size has
occurred several times on the coreutils mailing list:
http://lists.gnu.org/archive/html/bug-coreutils/2010-11/msg00092.html
Coreutils currently obeys the (non-intuitive) POSIX requirements for
this short read behavior, and while it is being considered to make dd
when POSIXLY_CORRECT is unset be more sensible, you can't rely on that
being a default.
Should we refuse to make snapshots if we don't detect the GNU extension
of 'dd iflag=fullblock'? Probably safe to do on GNU/Linux machines, but
I'm wondering if it will have negative effects on BSD machines where GNU
coreutils is not installed.
Is there a way to make monitor commands use fd: style migration, where
we can avoid dd altogether by just passing an already open fd that has
already positioned correctly via lseek()? Then again, it seems like fd:
migration requires passing an open fd, which only seems possible on the
command line at startup rather than something you can do on the fly with
monitor commands.
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years, 11 months
[libvirt] libvirt-java thoughts
by Stefan Majer
Hi,
we use libvirt-java in our kvm based virtualization infrastructure a
lot. Thanks therefor. Sometimes we see crashes of the libvirtd and i
was thinking of the right way to handle such a situation from the java
side.
My first aproach was to use the ErrorCallback:
Connect.setErrorCallback(new VirErrorCallback() {
@Override
public void errorCallback(Pointer arg0, virError error) {
// Do something usefull (reconnect for example)
}
}
);
} catch (LibvirtException e) {
LOG.error("Exception occurred. Stacktrace: ", e);
}
}
But this give me a jvm crash on shutdown of my application. No Idea why.
The next idea was to Intercept all calls to org.libvirt.Connect and
check if the connection is still working (isConnected) and reconnect
on false.
But the current API design makes this difficult and ugly, as Connect
is a concrete Class without an Interface.
Do you have any other Ideas ?
If no, do you probably accept patches which will resolve this issue ?
We can share Ideas what the best strategie could be.
Greetings
--
Stefan Majer
13 years, 11 months
[libvirt] [PATCH] esx: Fix "occurence" typo (again)
by Matthias Bolte
Also include some whitespace changes. No functional change included.
---
I pushed this one under the trivial rule.
Matthias
src/esx/esx_driver.c | 10 ++++++++++
src/esx/esx_vi.c | 25 ++++++++++++++-----------
src/esx/esx_vi.h | 8 ++++----
3 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 55847bc..2241532 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2475,6 +2475,7 @@ esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
}
+
static int
esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
{
@@ -2482,6 +2483,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
}
+
static int
esxDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
@@ -2540,6 +2542,8 @@ esxDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
return priv->maxVcpus;
}
+
+
static int
esxDomainGetMaxVcpus(virDomainPtr domain)
{
@@ -2547,6 +2551,8 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
VIR_DOMAIN_VCPU_MAXIMUM));
}
+
+
static char *
esxDomainDumpXML(virDomainPtr domain, int flags)
{
@@ -3809,12 +3815,16 @@ esxDomainIsPersistent(virDomainPtr domain ATTRIBUTE_UNUSED)
return 1;
}
+
+
static int
esxDomainIsUpdated(virDomainPtr domain ATTRIBUTE_UNUSED)
{
return 0;
}
+
+
static virDomainSnapshotPtr
esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
unsigned int flags)
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 76be5a4..5dbf744 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -1812,7 +1812,7 @@ esxVI_GetVirtualMachineQuestionInfo
int
esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
- esxVI_Boolean *value, esxVI_Occurrence occurence)
+ esxVI_Boolean *value, esxVI_Occurrence occurrence)
{
esxVI_DynamicProperty *dynamicProperty;
@@ -1835,7 +1835,7 @@ esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
}
if (*value == esxVI_Boolean_Undefined &&
- occurence == esxVI_Occurrence_RequiredItem) {
+ occurrence == esxVI_Occurrence_RequiredItem) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Missing '%s' property"), propertyName);
return -1;
@@ -1844,9 +1844,11 @@ esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
return 0;
}
+
+
int
esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
- esxVI_Long **value, esxVI_Occurrence occurence)
+ esxVI_Long **value, esxVI_Occurrence occurrence)
{
esxVI_DynamicProperty *dynamicProperty;
@@ -1866,7 +1868,7 @@ esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
}
}
- if (*value == NULL && occurence == esxVI_Occurrence_RequiredItem) {
+ if (*value == NULL && occurrence == esxVI_Occurrence_RequiredItem) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Missing '%s' property"), propertyName);
return -1;
@@ -1880,7 +1882,7 @@ esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
int
esxVI_GetStringValue(esxVI_ObjectContent *objectContent,
const char *propertyName,
- char **value, esxVI_Occurrence occurence)
+ char **value, esxVI_Occurrence occurrence)
{
esxVI_DynamicProperty *dynamicProperty;
@@ -1902,7 +1904,7 @@ esxVI_GetStringValue(esxVI_ObjectContent *objectContent,
}
}
- if (*value == NULL && occurence == esxVI_Occurrence_RequiredItem) {
+ if (*value == NULL && occurrence == esxVI_Occurrence_RequiredItem) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Missing '%s' property"), propertyName);
return -1;
@@ -1917,7 +1919,7 @@ int
esxVI_GetManagedObjectReference(esxVI_ObjectContent *objectContent,
const char *propertyName,
esxVI_ManagedObjectReference **value,
- esxVI_Occurrence occurence)
+ esxVI_Occurrence occurrence)
{
esxVI_DynamicProperty *dynamicProperty;
@@ -1938,7 +1940,7 @@ esxVI_GetManagedObjectReference(esxVI_ObjectContent *objectContent,
}
}
- if (*value == NULL && occurence == esxVI_Occurrence_RequiredItem) {
+ if (*value == NULL && occurrence == esxVI_Occurrence_RequiredItem) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Missing '%s' property"), propertyName);
return -1;
@@ -2265,9 +2267,10 @@ esxVI_GetSnapshotTreeBySnapshot
-int esxVI_LookupHostSystemProperties(esxVI_Context *ctx,
- esxVI_String *propertyNameList,
- esxVI_ObjectContent **hostSystem)
+int
+esxVI_LookupHostSystemProperties(esxVI_Context *ctx,
+ esxVI_String *propertyNameList,
+ esxVI_ObjectContent **hostSystem)
{
return esxVI_LookupObjectContentByType(ctx, ctx->hostSystem->_reference,
"HostSystem", propertyNameList,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index d512add..553967b 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -300,19 +300,19 @@ int esxVI_GetVirtualMachineQuestionInfo
int esxVI_GetBoolean(esxVI_ObjectContent *objectContent,
const char *propertyName,
- esxVI_Boolean *value, esxVI_Occurrence occurence);
+ esxVI_Boolean *value, esxVI_Occurrence occurrence);
int esxVI_GetLong(esxVI_ObjectContent *objectContent, const char *propertyName,
- esxVI_Long **value, esxVI_Occurrence occurence);
+ esxVI_Long **value, esxVI_Occurrence occurrence);
int esxVI_GetStringValue(esxVI_ObjectContent *objectContent,
const char *propertyName,
- char **value, esxVI_Occurrence occurence);
+ char **value, esxVI_Occurrence occurrence);
int esxVI_GetManagedObjectReference(esxVI_ObjectContent *objectContent,
const char *propertyName,
esxVI_ManagedObjectReference **value,
- esxVI_Occurrence occurence);
+ esxVI_Occurrence occurrence);
int esxVI_LookupNumberOfDomainsByPowerState
(esxVI_Context *ctx, esxVI_VirtualMachinePowerState powerState,
--
1.7.0.4
13 years, 11 months
[libvirt] [TCK] [PATCH] Test cases for network ipv6 support
by Stefan Berger
This patch adds a couple of test cases for the recently added network
ipv6 support.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
scripts/networks/networkxml2hostout/tck-testnet-3.dat | 31
+++++++++++++
scripts/networks/networkxml2hostout/tck-testnet-3.post.dat | 12 +++++
scripts/networks/networkxml2xmlin/tck-testnet-3.xml | 22
+++++++++
3 files changed, 65 insertions(+)
Index: libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-3.xml
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2xmlin/tck-testnet-3.xml
@@ -0,0 +1,22 @@
+<network>
+ <name>tck-testnet</name>
+ <uuid>aadc8920-502a-4774-ac2b-cd382a204d06</uuid>
+ <bridge name="tck-testbr" />
+ <forward mode="nat" />
+ <ip address="10.1.2.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="10.1.2.2" end="10.1.2.254" />
+ <host mac="00:16:3e:77:e2:ed" name="a.example.com" ip="10.1.2.10" />
+ <host mac="00:16:3e:3e:a9:1a" name="b.example.com" ip="10.1.2.11" />
+ </dhcp>
+ </ip>
+ <ip family="ipv4" address="192.168.123.1" netmask="255.255.255.0">
+ </ip>
+ <ip family="ipv6" address="2001:db8:ac10:fe01::1" prefix="64">
+ </ip>
+ <ip family="ipv6" address="2001:db8:ac10:fd01::1" prefix="64">
+ </ip>
+ <ip family="ipv4" address="10.24.10.1">
+ </ip>
+</network>
+
Index: libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-3.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-3.dat
@@ -0,0 +1,31 @@
+#iptables -t nat -L -n | grep ' 10\.1\.2\.'
+MASQUERADE tcp -- 10.1.2.0/24 !10.1.2.0/24 masq
ports: 1024-65535
+MASQUERADE udp -- 10.1.2.0/24 !10.1.2.0/24 masq
ports: 1024-65535
+MASQUERADE all -- 10.1.2.0/24 !10.1.2.0/24
+#iptables -n -L FORWARD | grep ' 10\.1\.2\.'
+ACCEPT all -- 0.0.0.0/0 10.1.2.0/24 state
RELATED,ESTABLISHED
+ACCEPT all -- 10.1.2.0/24 0.0.0.0/0
+#ip6tables -n -L FORWARD | grep ' 2001:db8:ac10'
+ACCEPT all ::/0 2001:db8:ac10:fd01::/64
+ACCEPT all 2001:db8:ac10:fd01::/64 ::/0
+ACCEPT all ::/0 2001:db8:ac10:fe01::/64
+ACCEPT all 2001:db8:ac10:fe01::/64 ::/0
+#ps aux | sed -n '/dnsmasq .*10\.1\.2\./ s|.*\(dnsmasq [[:print:]*]\)|\1|p'
+dnsmasq --strict-order --bind-interfaces
--pid-file=/var/run/libvirt/network/tck-testnet.pid --conf-file=
--listen-address 10.1.2.1 --except-interface lo --dhcp-range
10.1.2.2,10.1.2.254 --dhcp-lease-max=253 --dhcp-no-override
+#ps aux | sed -n '/radvd .*tck\-testnet\-/ s|.*\(radvd [[:print:]*]\)|\1|p'
+radvd --debug 1 --config /var/lib/libvirt/radvd/tck-testnet-radvd.conf
--pidfile /var/run/libvirt/network/tck-testnet-radvd.pid-bin
+#route -n | grep '10\.1\.2\.'
+10.1.2.0 0.0.0.0 255.255.255.0 U 0 0 0
tck-testbr
+#route -n | grep '192\.168\.123\.'
+192.168.123.0 0.0.0.0 255.255.255.0 U 0 0 0
tck-testbr
+#route -n | grep '10\.0\.0\.0'
+10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0
tck-testbr
+#brctl show | grep tck-testbr
+tck-testbr 8000.000000000000 yes
+#ifconfig tck-testbr | grep ':10\.1\.2\.'
+ inet addr:10.1.2.1 Bcast:10.1.2.255 Mask:255.255.255.0
+#ifconfig tck-testbr | grep 'inet6 addr: 2001'
+ inet6 addr: 2001:db8:ac10:fd01::1/64 Scope:Global
+ inet6 addr: 2001:db8:ac10:fe01::1/64 Scope:Global
+#virsh net-list | grep tck-testnet
+tck-testnet active no
Index:
libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-3.post.dat
===================================================================
--- /dev/null
+++ libvirt-tck/scripts/networks/networkxml2hostout/tck-testnet-3.post.dat
@@ -0,0 +1,12 @@
+#iptables -t nat -L -n | grep ' 10\.1\.2\.'
+#iptables -n -L FORWARD | grep ' 10\.1\.2\.'
+#ip6tables -n -L FORWARD | grep ' 2001:db8:ac10'
+#ps aux | sed -n '/dnsmasq .*10\.1\.2\./ s|.*\(dnsmasq [[:print:]*]\)|\1|p'
+#ps aux | sed -n '/radvd .*tck\-testnet\-/ s|.*\(radvd [[:print:]*]\)|\1|p'
+#route -n | grep '10\.1\.2\.'
+#route -n | grep '192\.168\.123\.'
+#route -n | grep '10\.0\.0\.0'
+#brctl show | grep tck-testbr
+#ifconfig tck-testbr 2>/dev/null | grep ':10\.1\.2\.'
+#ifconfig tck-testbr 2>/dev/null | grep 'inet6 addr: 2001'
+#virsh net-list | grep tck-testnet
13 years, 11 months
[libvirt] [PATCH] vbox: Add support for VirtualBox 4.0
by Matthias Bolte
Add vboxArrayGetWithUintArg to handle new signature variations. Also
refactor vboxArrayGet* implementation to use a common helper function.
Deal with the incompatible changes in the VirtualBox 4.0 API. This
includes major changes in virtual machine and storage medium lookup,
in RDP server property handling, in session/lock handling and other
minor areas.
VirtualBox 4.0 also dropped the old event API and replaced it with a
completely new one. This is not fixed yet and will be addressed in
another patch. Therefore, currently the domain events are supported
for VirtualBox 3.x only.
Based on initial work from Jean-Baptiste Rouault.
---
This mail omits the 7451 lines of addition for the vbox_CAPI_v4_0.h
file on purpose. vbox_CAPI_v4_0.h is taken from the VirtualBox 4.0 SDK
and got the same treatment as the other vbox_CAPI_v*.h files. Like
the note about not to regenerate it in the context of libvirt, it's
preprocessor code is indented to pass the syntax-check, all methods
are marked with __stdcall on Windows, etc.
Matthias
src/Makefile.am | 3 +-
src/vbox/vbox_CAPI_v4_0.h | 7451 ++++++++++++++++++++++++++++++++++++++++++++
src/vbox/vbox_MSCOMGlue.c | 65 +-
src/vbox/vbox_MSCOMGlue.h | 3 +-
src/vbox/vbox_V4_0.c | 13 +
src/vbox/vbox_XPCOMCGlue.c | 58 +-
src/vbox/vbox_XPCOMCGlue.h | 3 +-
src/vbox/vbox_driver.c | 8 +
src/vbox/vbox_tmpl.c | 489 +++-
9 files changed, 7923 insertions(+), 170 deletions(-)
create mode 100644 src/vbox/vbox_CAPI_v4_0.h
create mode 100644 src/vbox/vbox_V4_0.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 41d4b34..c13724a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -264,7 +264,8 @@ VBOX_DRIVER_SOURCES = \
vbox/vbox_V2_2.c vbox/vbox_CAPI_v2_2.h \
vbox/vbox_V3_0.c vbox/vbox_CAPI_v3_0.h \
vbox/vbox_V3_1.c vbox/vbox_CAPI_v3_1.h \
- vbox/vbox_V3_2.c vbox/vbox_CAPI_v3_2.h
+ vbox/vbox_V3_2.c vbox/vbox_CAPI_v3_2.h \
+ vbox/vbox_V4_0.c vbox/vbox_CAPI_v4_0.h
VBOX_DRIVER_EXTRA_DIST = \
vbox/vbox_tmpl.c vbox/README \
diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c
index cf68d38..e6a886f 100644
--- a/src/vbox/vbox_MSCOMGlue.c
+++ b/src/vbox/vbox_MSCOMGlue.c
@@ -660,25 +660,18 @@ VBoxCGlueTerm(void)
*/
typedef HRESULT __stdcall (*SafeArrayGetter)(void *self, SAFEARRAY **array);
-typedef HRESULT __stdcall (*SafeArrayGetterWithArg)(void *self, void *arg, SAFEARRAY **array);
+typedef HRESULT __stdcall (*SafeArrayGetterWithPtrArg)(void *self, void *arg, SAFEARRAY **array);
+typedef HRESULT __stdcall (*SafeArrayGetterWithUintArg)(void *self, PRUint32 arg, SAFEARRAY **array);
-/*
- * Call the getter with self as first argument and fill the array with the
- * returned items.
- */
-nsresult
-vboxArrayGet(vboxArray *array, void *self, void *getter)
+static nsresult
+vboxArrayGetHelper(vboxArray *array, HRESULT hrc, SAFEARRAY *safeArray)
{
- HRESULT hrc;
- SAFEARRAY *safeArray = NULL;
void **items = NULL;
array->items = NULL;
array->count = 0;
array->handle = NULL;
- hrc = ((SafeArrayGetter)getter)(self, &safeArray);
-
if (FAILED(hrc)) {
return hrc;
}
@@ -698,38 +691,48 @@ vboxArrayGet(vboxArray *array, void *self, void *getter)
}
/*
- * Call the getter with self as first argument and arg as second argument
- * and fill the array with the returned items.
+ * Call the getter with self as first argument and fill the array with the
+ * returned items.
*/
nsresult
-vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg)
+vboxArrayGet(vboxArray *array, void *self, void *getter)
{
HRESULT hrc;
SAFEARRAY *safeArray = NULL;
- void **items = NULL;
- array->items = NULL;
- array->count = 0;
- array->handle = NULL;
+ hrc = ((SafeArrayGetter)getter)(self, &safeArray);
- hrc = ((SafeArrayGetterWithArg)getter)(self, arg, &safeArray);
+ return vboxArrayGetHelper(array, hrc, safeArray);
+}
- if (FAILED(hrc)) {
- return hrc;
- }
+/*
+ * Call the getter with self as first argument and arg as second argument
+ * and fill the array with the returned items.
+ */
+nsresult
+vboxArrayGetWithPtrArg(vboxArray *array, void *self, void *getter, void *arg)
+{
+ HRESULT hrc;
+ SAFEARRAY *safeArray = NULL;
- hrc = SafeArrayAccessData(safeArray, (void **)&items);
+ hrc = ((SafeArrayGetterWithPtrArg)getter)(self, arg, &safeArray);
- if (FAILED(hrc)) {
- SafeArrayDestroy(safeArray);
- return hrc;
- }
+ return vboxArrayGetHelper(array, hrc, safeArray);
+}
- array->items = items;
- array->count = safeArray->rgsabound[0].cElements;
- array->handle = safeArray;
+/*
+ * Call the getter with self as first argument and arg as second argument
+ * and fill the array with the returned items.
+ */
+nsresult
+vboxArrayGetWithUintArg(vboxArray *array, void *self, void *getter, PRUint32 arg)
+{
+ HRESULT hrc;
+ SAFEARRAY *safeArray = NULL;
- return hrc;
+ hrc = ((SafeArrayGetterWithUintArg)getter)(self, arg, &safeArray);
+
+ return vboxArrayGetHelper(array, hrc, safeArray);
}
/*
diff --git a/src/vbox/vbox_MSCOMGlue.h b/src/vbox/vbox_MSCOMGlue.h
index f1d6c74..83b2ce1 100644
--- a/src/vbox/vbox_MSCOMGlue.h
+++ b/src/vbox/vbox_MSCOMGlue.h
@@ -41,7 +41,8 @@ struct _vboxArray {
# define VBOX_ARRAY_INITIALIZER { NULL, 0, NULL }
nsresult vboxArrayGet(vboxArray *array, void *self, void *getter);
-nsresult vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg);
+nsresult vboxArrayGetWithPtrArg(vboxArray *array, void *self, void *getter, void *arg);
+nsresult vboxArrayGetWithUintArg(vboxArray *array, void *self, void *getter, PRUint32 arg);
void vboxArrayRelease(vboxArray *array);
# define vboxArrayUnalloc vboxArrayRelease
diff --git a/src/vbox/vbox_V4_0.c b/src/vbox/vbox_V4_0.c
new file mode 100644
index 0000000..f976a1a
--- /dev/null
+++ b/src/vbox/vbox_V4_0.c
@@ -0,0 +1,13 @@
+/** @file vbox_V4_0.c
+ * C file to include support for multiple versions of VirtualBox
+ * at runtime.
+ */
+
+#include <config.h>
+
+/** The API Version */
+#define VBOX_API_VERSION 4000
+/** Version specific prefix. */
+#define NAME(name) vbox40##name
+
+#include "vbox_tmpl.c"
diff --git a/src/vbox/vbox_XPCOMCGlue.c b/src/vbox/vbox_XPCOMCGlue.c
index dcaf682..fbe210c 100644
--- a/src/vbox/vbox_XPCOMCGlue.c
+++ b/src/vbox/vbox_XPCOMCGlue.c
@@ -264,7 +264,24 @@ VBoxCGlueTerm(void)
*/
typedef nsresult (*ArrayGetter)(void *self, PRUint32 *count, void ***items);
-typedef nsresult (*ArrayGetterWithArg)(void *self, void *arg, PRUint32 *count, void ***items);
+typedef nsresult (*ArrayGetterWithPtrArg)(void *self, void *arg, PRUint32 *count, void ***items);
+typedef nsresult (*ArrayGetterWithUintArg)(void *self, PRUint32 arg, PRUint32 *count, void ***items);
+
+static nsresult
+vboxArrayGetHelper(vboxArray *array, nsresult nsrc, void **items, PRUint32 count)
+{
+ array->items = NULL;
+ array->count = 0;
+
+ if (NS_FAILED(nsrc)) {
+ return nsrc;
+ }
+
+ array->items = items;
+ array->count = count;
+
+ return nsrc;
+}
/*
* Call the getter with self as first argument and fill the array with the
@@ -277,19 +294,9 @@ vboxArrayGet(vboxArray *array, void *self, void *getter)
void **items = NULL;
PRUint32 count = 0;
- array->items = NULL;
- array->count = 0;
-
nsrc = ((ArrayGetter)getter)(self, &count, &items);
- if (NS_FAILED(nsrc)) {
- return nsrc;
- }
-
- array->items = items;
- array->count = count;
-
- return nsrc;
+ return vboxArrayGetHelper(array, nsrc, items, count);
}
/*
@@ -297,25 +304,31 @@ vboxArrayGet(vboxArray *array, void *self, void *getter)
* and fill the array with the returned items.
*/
nsresult
-vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg)
+vboxArrayGetWithPtrArg(vboxArray *array, void *self, void *getter, void *arg)
{
nsresult nsrc;
void **items = NULL;
PRUint32 count = 0;
- array->items = NULL;
- array->count = 0;
+ nsrc = ((ArrayGetterWithPtrArg)getter)(self, arg, &count, &items);
- nsrc = ((ArrayGetterWithArg)getter)(self, arg, &count, &items);
+ return vboxArrayGetHelper(array, nsrc, items, count);
+}
- if (NS_FAILED(nsrc)) {
- return nsrc;
- }
+/*
+ * Call the getter with self as first argument and arg as second argument
+ * and fill the array with the returned items.
+ */
+nsresult
+vboxArrayGetWithUintArg(vboxArray *array, void *self, void *getter, PRUint32 arg)
+{
+ nsresult nsrc;
+ void **items = NULL;
+ PRUint32 count = 0;
- array->items = items;
- array->count = count;
+ nsrc = ((ArrayGetterWithUintArg)getter)(self, arg, &count, &items);
- return nsrc;
+ return vboxArrayGetHelper(array, nsrc, items, count);
}
/*
@@ -345,7 +358,6 @@ vboxArrayRelease(vboxArray *array)
array->count = 0;
}
-
/*
* Unalloc all items in the array and reset it.
*/
diff --git a/src/vbox/vbox_XPCOMCGlue.h b/src/vbox/vbox_XPCOMCGlue.h
index 8fd2f13..2a50404 100644
--- a/src/vbox/vbox_XPCOMCGlue.h
+++ b/src/vbox/vbox_XPCOMCGlue.h
@@ -48,7 +48,8 @@ struct _vboxArray {
# define VBOX_ARRAY_INITIALIZER { NULL, 0 }
nsresult vboxArrayGet(vboxArray *array, void *self, void *getter);
-nsresult vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg);
+nsresult vboxArrayGetWithPtrArg(vboxArray *array, void *self, void *getter, void *arg);
+nsresult vboxArrayGetWithUintArg(vboxArray *array, void *self, void *getter, PRUint32 arg);
void vboxArrayRelease(vboxArray *array);
void vboxArrayUnalloc(vboxArray *array);
diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index b39a63b..f647eb9 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -57,6 +57,9 @@ extern virStorageDriver vbox31StorageDriver;
extern virDriver vbox32Driver;
extern virNetworkDriver vbox32NetworkDriver;
extern virStorageDriver vbox32StorageDriver;
+extern virDriver vbox40Driver;
+extern virNetworkDriver vbox40NetworkDriver;
+extern virStorageDriver vbox40StorageDriver;
static virDriver vboxDriverDummy;
@@ -114,6 +117,11 @@ int vboxRegister(void) {
driver = &vbox32Driver;
networkDriver = &vbox32NetworkDriver;
storageDriver = &vbox32StorageDriver;
+ } else if (uVersion >= 3002051 && uVersion < 4000051) {
+ DEBUG0("VirtualBox API version: 4.0");
+ driver = &vbox40Driver;
+ networkDriver = &vbox40NetworkDriver;
+ storageDriver = &vbox40StorageDriver;
} else {
DEBUG0("Unsupport VirtualBox API version");
}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 2b170ec..f45e8ed 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -62,6 +62,8 @@
# include "vbox_CAPI_v3_1.h"
#elif VBOX_API_VERSION == 3002
# include "vbox_CAPI_v3_2.h"
+#elif VBOX_API_VERSION == 4000
+# include "vbox_CAPI_v4_0.h"
#else
# error "Unsupport VBOX_API_VERSION"
#endif
@@ -79,9 +81,13 @@
#define VBOX_ADDREF(arg) (arg)->vtbl->nsisupports.AddRef((nsISupports *)(arg))
-#define VBOX_RELEASE(arg) \
-if(arg)\
- (arg)->vtbl->nsisupports.Release((nsISupports *)(arg))
+#define VBOX_RELEASE(arg) \
+ do { \
+ if (arg) { \
+ (arg)->vtbl->nsisupports.Release((nsISupports *)(arg)); \
+ (arg) = NULL; \
+ } \
+ } while (0)
#define VBOX_OBJECT_CHECK(conn, type, value) \
vboxGlobalData *data = conn->privateData;\
@@ -182,7 +188,10 @@ typedef struct {
int fdWatch;
int domainEventDispatching;
+# if VBOX_API_VERSION <= 3002
+ /* IVirtualBoxCallback is used in VirtualBox 3.x only */
IVirtualBoxCallback *vboxCallback;
+# endif /* VBOX_API_VERSION <= 3002 */
nsIEventQueue *vboxQueue;
int volatile vboxCallBackRefCount;
@@ -206,6 +215,36 @@ static vboxGlobalData *g_pVBoxGlobalData = NULL;
#endif /* !(VBOX_API_VERSION == 2002) */
+#if VBOX_API_VERSION < 4000
+
+# 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)
+
+#else /* VBOX_API_VERSION >= 4000 */
+
+# 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)
+
+#endif /* VBOX_API_VERSION >= 4000 */
+
static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml);
static int vboxDomainCreate(virDomainPtr dom);
static int vboxDomainUndefine(virDomainPtr dom);
@@ -1451,7 +1490,7 @@ static int vboxDomainSuspend(virDomainPtr dom) {
nsresult rc;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1466,8 +1505,8 @@ static int vboxDomainSuspend(virDomainPtr dom) {
machine->vtbl->GetState(machine, &state);
if (state == MachineState_Running) {
- /* set state pause */
- data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ /* set state pause */
+ VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (console) {
console->vtbl->Pause(console);
@@ -1478,7 +1517,7 @@ static int vboxDomainSuspend(virDomainPtr dom) {
_("error while suspending the domain"));
goto cleanup;
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
} else {
vboxError(VIR_ERR_OPERATION_FAILED, "%s",
_("machine not in running state to suspend it"));
@@ -1503,7 +1542,7 @@ static int vboxDomainResume(virDomainPtr dom) {
PRBool isAccessible = PR_FALSE;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1518,8 +1557,8 @@ static int vboxDomainResume(virDomainPtr dom) {
machine->vtbl->GetState(machine, &state);
if (state == MachineState_Paused) {
- /* resume the machine here */
- data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ /* resume the machine here */
+ VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (console) {
console->vtbl->Resume(console);
@@ -1530,7 +1569,7 @@ static int vboxDomainResume(virDomainPtr dom) {
_("error while resuming the domain"));
goto cleanup;
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
} else {
vboxError(VIR_ERR_OPERATION_FAILED, "%s",
_("machine not paused, so can't resume it"));
@@ -1554,7 +1593,7 @@ static int vboxDomainShutdown(virDomainPtr dom) {
nsresult rc;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1578,14 +1617,14 @@ static int vboxDomainShutdown(virDomainPtr dom) {
goto cleanup;
}
- data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (console) {
console->vtbl->PowerButton(console);
VBOX_RELEASE(console);
ret = 0;
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
cleanup:
@@ -1604,7 +1643,7 @@ static int vboxDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSE
nsresult rc;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1619,14 +1658,14 @@ static int vboxDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSE
machine->vtbl->GetState(machine, &state);
if (state == MachineState_Running) {
- data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (console) {
console->vtbl->Reset(console);
VBOX_RELEASE(console);
ret = 0;
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
} else {
vboxError(VIR_ERR_OPERATION_FAILED, "%s",
_("machine not running, so can't reboot it"));
@@ -1650,7 +1689,7 @@ static int vboxDomainDestroy(virDomainPtr dom) {
nsresult rc;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1670,7 +1709,7 @@ static int vboxDomainDestroy(virDomainPtr dom) {
goto cleanup;
}
- data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (console) {
@@ -1688,7 +1727,7 @@ static int vboxDomainDestroy(virDomainPtr dom) {
dom->id = -1;
ret = 0;
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
cleanup:
@@ -1720,7 +1759,7 @@ static int vboxDomainSetMemory(virDomainPtr dom, unsigned long memory) {
nsresult rc;
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN,
_("no domain with matching id %d"), dom->id);
@@ -1740,7 +1779,7 @@ static int vboxDomainSetMemory(virDomainPtr dom, unsigned long memory) {
goto cleanup;
}
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
if (NS_SUCCEEDED(rc)) {
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
if (NS_SUCCEEDED(rc) && machine) {
@@ -1756,7 +1795,7 @@ static int vboxDomainSetMemory(virDomainPtr dom, unsigned long memory) {
memory, (unsigned)rc);
}
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
}
@@ -1874,6 +1913,7 @@ static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) {
VBOX_OBJECT_CHECK(dom->conn, int, -1);
IConsole *console = NULL;
vboxIID iid = VBOX_IID_INITIALIZER;
+ IMachine *machine = NULL;
nsresult rc;
/* VirtualBox currently doesn't support saving to a file
@@ -1885,7 +1925,17 @@ static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) {
/* Open a Session for the machine */
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+#if VBOX_API_VERSION >= 4000
+ /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ vboxError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return -1;
+ }
+#endif
+
+ 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) {
@@ -1909,11 +1959,12 @@ static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED) {
}
VBOX_RELEASE(console);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
DEBUGIID("UUID of machine being saved:", iid.value);
+ VBOX_RELEASE(machine);
vboxIIDUnalloc(&iid);
return ret;
}
@@ -1934,7 +1985,17 @@ vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
}
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid.value);
+#if VBOX_API_VERSION >= 4000
+ /* Get machine for the call to VBOX_SESSION_OPEN */
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ vboxError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return -1;
+ }
+#endif
+
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
if (NS_SUCCEEDED(rc)) {
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
if (machine) {
@@ -1957,7 +2018,7 @@ vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
vboxError(VIR_ERR_NO_DOMAIN,
_("can't open session to the domain with id %d"), dom->id);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
vboxIIDUnalloc(&iid);
return ret;
@@ -2020,7 +2081,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
}
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_SUCCEEDED(rc)) {
PRBool accessible = PR_FALSE;
@@ -2031,7 +2092,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
PRBool PAEEnabled = PR_FALSE;
PRBool ACPIEnabled = PR_FALSE;
PRBool IOAPICEnabled = PR_FALSE;
- PRBool VRDPEnabled = PR_FALSE;
+ PRBool VRDxEnabled = PR_FALSE;
PRUint32 CPUCount = 0;
PRUint32 memorySize = 0;
PRUint32 netAdpCnt = 0;
@@ -2056,7 +2117,11 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
#else /* VBOX_API_VERSION >= 3001 */
vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
#endif /* VBOX_API_VERSION >= 3001 */
- IVRDPServer *VRDPServer = NULL;
+#if VBOX_API_VERSION < 4000
+ IVRDPServer *VRDxServer = NULL;
+#else /* VBOX_API_VERSION >= 4000 */
+ IVRDEServer *VRDxServer = NULL;
+#endif /* VBOX_API_VERSION >= 4000 */
IAudioAdapter *audioAdapter = NULL;
IUSBController *USBController = NULL;
ISystemProperties *systemProperties = NULL;
@@ -2296,10 +2361,14 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
}
}
- machine->vtbl->GetVRDPServer(machine, &VRDPServer);
- if (VRDPServer) {
- VRDPServer->vtbl->GetEnabled(VRDPServer, &VRDPEnabled);
- if (VRDPEnabled) {
+#if VBOX_API_VERSION < 4000
+ machine->vtbl->GetVRDPServer(machine, &VRDxServer);
+#else /* VBOX_API_VERSION >= 4000 */
+ machine->vtbl->GetVRDEServer(machine, &VRDxServer);
+#endif /* VBOX_API_VERSION >= 4000 */
+ if (VRDxServer) {
+ VRDxServer->vtbl->GetEnabled(VRDxServer, &VRDxEnabled);
+ if (VRDxEnabled) {
totalPresent++;
@@ -2311,24 +2380,41 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
PRBool reuseSingleConnection = PR_FALSE;
#if VBOX_API_VERSION < 3001
PRUint32 VRDPport = 0;
- VRDPServer->vtbl->GetPort(VRDPServer, &VRDPport);
+ VRDxServer->vtbl->GetPort(VRDxServer, &VRDPport);
if (VRDPport) {
def->graphics[def->ngraphics]->data.rdp.port = VRDPport;
-#else /* VBOX_API_VERSION >= 3001 */
+#elif VBOX_API_VERSION < 4000 /* 3001 <= VBOX_API_VERSION < 4000 */
PRUnichar *VRDPport = NULL;
- VRDPServer->vtbl->GetPorts(VRDPServer, &VRDPport);
+ VRDxServer->vtbl->GetPorts(VRDxServer, &VRDPport);
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);
-#endif /* VBOX_API_VERSION >= 3001 */
+#else /* VBOX_API_VERSION >= 4000 */
+ 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);
+#endif /* VBOX_API_VERSION >= 4000 */
} else {
def->graphics[def->ngraphics]->data.rdp.autoport = 1;
}
def->graphics[def->ngraphics]->type = VIR_DOMAIN_GRAPHICS_TYPE_RDP;
- VRDPServer->vtbl->GetNetAddress(VRDPServer, &netAddressUtf16);
+#if VBOX_API_VERSION >= 4000
+ PRUnichar *VRDENetAddressKey = NULL;
+ VBOX_UTF8_TO_UTF16("TCP/Address", &VRDENetAddressKey);
+ VRDxServer->vtbl->GetVRDEProperty(VRDxServer, VRDENetAddressKey, &netAddressUtf16);
+ VBOX_UTF16_FREE(VRDENetAddressKey);
+#else /* VBOX_API_VERSION < 4000 */
+ VRDxServer->vtbl->GetNetAddress(VRDxServer, &netAddressUtf16);
+#endif /* VBOX_API_VERSION < 4000 */
if (netAddressUtf16) {
VBOX_UTF16_TO_UTF8(netAddressUtf16, &netAddressUtf8);
if (STRNEQ(netAddressUtf8, ""))
@@ -2337,12 +2423,12 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
VBOX_UTF8_FREE(netAddressUtf8);
}
- VRDPServer->vtbl->GetAllowMultiConnection(VRDPServer, &allowMultiConnection);
+ VRDxServer->vtbl->GetAllowMultiConnection(VRDxServer, &allowMultiConnection);
if (allowMultiConnection) {
def->graphics[def->ngraphics]->data.rdp.multiUser = 1;
}
- VRDPServer->vtbl->GetReuseSingleConnection(VRDPServer, &reuseSingleConnection);
+ VRDxServer->vtbl->GetReuseSingleConnection(VRDxServer, &reuseSingleConnection);
if (reuseSingleConnection) {
def->graphics[def->ngraphics]->data.rdp.replaceUser = 1;
}
@@ -2351,7 +2437,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
} else
virReportOOMError();
}
- VBOX_RELEASE(VRDPServer);
+ VBOX_RELEASE(VRDxServer);
}
}
@@ -3218,7 +3304,8 @@ cleanup:
static int
-vboxStartMachine(virDomainPtr dom, int i, IMachine *machine, vboxIID *iid)
+vboxStartMachine(virDomainPtr dom, int i, IMachine *machine,
+ vboxIID *iid ATTRIBUTE_UNUSED /* >= 4.0 */)
{
VBOX_OBJECT_CHECK(dom->conn, int, -1);
int vrdpPresent = 0;
@@ -3344,15 +3431,21 @@ vboxStartMachine(virDomainPtr dom, int i, IMachine *machine, vboxIID *iid)
VBOX_UTF8_TO_UTF16("vrdp", &sessionType);
}
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->OpenRemoteSession(data->vboxObj,
data->vboxSession,
iid->value,
sessionType,
env,
&progress );
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = machine->vtbl->LaunchVMProcess(machine, data->vboxSession,
+ sessionType, env, &progress);
+#endif /* VBOX_API_VERSION >= 4000 */
+
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_OPERATION_FAILED, "%s",
- _("openremotesession failed, domain can't be started"));
+ _("OpenRemoteSession/LaunchVMProcess failed, domain can't be started"));
ret = -1;
} else {
PRBool completed = 0;
@@ -3380,7 +3473,7 @@ vboxStartMachine(virDomainPtr dom, int i, IMachine *machine, vboxIID *iid)
VBOX_RELEASE(progress);
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
VBOX_UTF16_FREE(env);
VBOX_UTF16_FREE(sessionType);
@@ -3822,6 +3915,7 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
PRUnichar *mediumFileUtf16 = NULL;
PRUint32 storageBus = StorageBus_Null;
PRUint32 deviceType = DeviceType_Null;
+ PRUint32 accessMode = AccessMode_ReadOnly;
PRInt32 deviceInst = 0;
PRInt32 devicePort = 0;
PRInt32 deviceSlot = 0;
@@ -3830,26 +3924,41 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
deviceType = DeviceType_HardDisk;
+ accessMode = AccessMode_ReadWrite;
+# if VBOX_API_VERSION < 4000
data->vboxObj->vtbl->FindHardDisk(data->vboxObj,
mediumFileUtf16, &medium);
+# endif
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
deviceType = DeviceType_DVD;
+ accessMode = AccessMode_ReadOnly;
+# if VBOX_API_VERSION < 4000
data->vboxObj->vtbl->FindDVDImage(data->vboxObj,
mediumFileUtf16, &medium);
+# endif
} else if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
deviceType = DeviceType_Floppy;
+ accessMode = AccessMode_ReadWrite;
+# if VBOX_API_VERSION < 4000
data->vboxObj->vtbl->FindFloppyImage(data->vboxObj,
mediumFileUtf16, &medium);
+# endif
} else {
VBOX_UTF16_FREE(mediumFileUtf16);
continue;
}
+# if VBOX_API_VERSION >= 4000
+ data->vboxObj->vtbl->FindMedium(data->vboxObj, mediumFileUtf16,
+ deviceType, &medium);
+# endif
+
if (!medium) {
PRUnichar *mediumEmpty = NULL;
VBOX_UTF8_TO_UTF16("", &mediumEmpty);
+# if VBOX_API_VERSION < 4000
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
rc = data->vboxObj->vtbl->OpenHardDisk(data->vboxObj,
mediumFileUtf16,
@@ -3874,6 +3983,12 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
} else {
rc = 0;
}
+# else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->OpenMedium(data->vboxObj,
+ mediumFileUtf16,
+ deviceType, accessMode,
+ &medium);
+# endif /* VBOX_API_VERSION >= 4000 */
VBOX_UTF16_FREE(mediumEmpty);
}
@@ -3946,7 +4061,11 @@ vboxAttachDrives(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
devicePort,
deviceSlot,
deviceType,
+# if VBOX_API_VERSION < 4000
mediumUUID);
+# else /* VBOX_API_VERSION >= 4000 */
+ medium);
+# endif /* VBOX_API_VERSION >= 4000 */
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_INTERNAL_ERROR,
@@ -4307,20 +4426,28 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
int i = 0;
for (i = 0; i < def->ngraphics; i++) {
- IVRDPServer *VRDPServer = NULL;
+#if VBOX_API_VERSION < 4000
+ IVRDPServer *VRDxServer = NULL;
+#else /* VBOX_API_VERSION >= 4000 */
+ IVRDEServer *VRDxServer = NULL;
+#endif /* VBOX_API_VERSION >= 4000 */
if ((def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_RDP) &&
(vrdpPresent == 0)) {
vrdpPresent = 1;
- machine->vtbl->GetVRDPServer(machine, &VRDPServer);
- if (VRDPServer) {
- VRDPServer->vtbl->SetEnabled(VRDPServer, PR_TRUE);
+#if VBOX_API_VERSION < 4000
+ machine->vtbl->GetVRDPServer(machine, &VRDxServer);
+#else /* VBOX_API_VERSION >= 4000 */
+ machine->vtbl->GetVRDEServer(machine, &VRDxServer);
+#endif /* VBOX_API_VERSION >= 4000 */
+ if (VRDxServer) {
+ VRDxServer->vtbl->SetEnabled(VRDxServer, PR_TRUE);
DEBUG0("VRDP Support turned ON.");
#if VBOX_API_VERSION < 3001
if (def->graphics[i]->data.rdp.port) {
- VRDPServer->vtbl->SetPort(VRDPServer,
+ VRDxServer->vtbl->SetPort(VRDxServer,
def->graphics[i]->data.rdp.port);
DEBUG("VRDP Port changed to: %d",
def->graphics[i]->data.rdp.port);
@@ -4328,42 +4455,61 @@ vboxAttachDisplay(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
/* Setting the port to 0 will reset its value to
* the default one which is 3389 currently
*/
- VRDPServer->vtbl->SetPort(VRDPServer, 0);
+ VRDxServer->vtbl->SetPort(VRDxServer, 0);
DEBUG0("VRDP Port changed to default, which is 3389 currently");
}
-#else /* VBOX_API_VERSION >= 3001 */
+#elif VBOX_API_VERSION < 4000 /* 3001 <= VBOX_API_VERSION < 4000 */
PRUnichar *portUtf16 = NULL;
portUtf16 = PRUnicharFromInt(def->graphics[i]->data.rdp.port);
- VRDPServer->vtbl->SetPorts(VRDPServer, portUtf16);
+ VRDxServer->vtbl->SetPorts(VRDxServer, portUtf16);
VBOX_UTF16_FREE(portUtf16);
-#endif /* VBOX_API_VERSION >= 3001 */
+#else /* VBOX_API_VERSION >= 4000 */
+ 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);
+#endif /* VBOX_API_VERSION >= 4000 */
if (def->graphics[i]->data.rdp.replaceUser) {
- VRDPServer->vtbl->SetReuseSingleConnection(VRDPServer,
+ VRDxServer->vtbl->SetReuseSingleConnection(VRDxServer,
PR_TRUE);
DEBUG0("VRDP set to reuse single connection");
}
if (def->graphics[i]->data.rdp.multiUser) {
- VRDPServer->vtbl->SetAllowMultiConnection(VRDPServer,
+ VRDxServer->vtbl->SetAllowMultiConnection(VRDxServer,
PR_TRUE);
DEBUG0("VRDP set to allow multiple connection");
}
if (def->graphics[i]->data.rdp.listenAddr) {
+#if VBOX_API_VERSION >= 4000
+ PRUnichar *netAddressKey = NULL;
+#endif
PRUnichar *netAddressUtf16 = NULL;
VBOX_UTF8_TO_UTF16(def->graphics[i]->data.rdp.listenAddr,
&netAddressUtf16);
- VRDPServer->vtbl->SetNetAddress(VRDPServer,
+#if VBOX_API_VERSION < 4000
+ VRDxServer->vtbl->SetNetAddress(VRDxServer,
netAddressUtf16);
+#else /* VBOX_API_VERSION >= 4000 */
+ VBOX_UTF8_TO_UTF16("TCP/Address", &netAddressKey);
+ VRDxServer->vtbl->SetVRDEProperty(VRDxServer, netAddressKey,
+ netAddressUtf16);
+ VBOX_UTF16_FREE(netAddressKey);
+#endif /* VBOX_API_VERSION >= 4000 */
DEBUG("VRDP listen address is set to: %s",
def->graphics[i]->data.rdp.listenAddr);
VBOX_UTF16_FREE(netAddressUtf16);
}
- VBOX_RELEASE(VRDPServer);
+ VBOX_RELEASE(VRDxServer);
}
}
@@ -4599,7 +4745,7 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
NULL,
iid.value,
&machine);
-#else /* VBOX_API_VERSION >= 3002 */
+#elif VBOX_API_VERSION < 4000 /* 3002 <= VBOX_API_VERSION < 4000 */
rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
machineNameUtf16,
NULL,
@@ -4607,7 +4753,15 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
iid.value,
override,
&machine);
-#endif /* VBOX_API_VERSION >= 3002 */
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->CreateMachine(data->vboxObj,
+ NULL,
+ machineNameUtf16,
+ NULL,
+ iid.value,
+ override,
+ &machine);
+#endif /* VBOX_API_VERSION >= 4000 */
VBOX_UTF16_FREE(machineNameUtf16);
if (NS_FAILED(rc)) {
@@ -4688,7 +4842,7 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
* you can make changes to the machine setting
*/
machine->vtbl->GetId(machine, &mchiid.value);
- data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, mchiid.value);
+ VBOX_SESSION_OPEN(mchiid.value, machine);
data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
vboxSetBootDeviceOrder(def, data, machine);
@@ -4705,12 +4859,11 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
* session. also free up the mchiid variable used.
*/
rc = machine->vtbl->SaveSettings(machine);
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
vboxIIDUnalloc(&mchiid);
ret = virGetDomain(conn, def->name, def->uuid);
VBOX_RELEASE(machine);
- machine = NULL;
vboxIIDUnalloc(&iid);
virDomainDefFree(def);
@@ -4724,18 +4877,27 @@ cleanup:
return NULL;
}
-static int vboxDomainUndefine(virDomainPtr dom) {
+static int
+vboxDomainUndefine(virDomainPtr dom)
+{
VBOX_OBJECT_CHECK(dom->conn, int, -1);
IMachine *machine = NULL;
vboxIID iid = VBOX_IID_INITIALIZER;
nsresult rc;
+#if VBOX_API_VERSION >= 4000
+ vboxArray media = VBOX_ARRAY_INITIALIZER;
+#endif
vboxIIDFromUUID(&iid, dom->uuid);
+#if VBOX_API_VERSION < 4000
/* 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
- * it is allocated to CD/DVD Drive bt default
+ * 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.
*/
{
PRUnichar *hddcnameUtf16 = NULL;
@@ -4745,17 +4907,17 @@ static int vboxDomainUndefine(virDomainPtr dom) {
VIR_FREE(hddcname);
/* Open a Session for the machine */
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
if (NS_SUCCEEDED(rc)) {
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
if (NS_SUCCEEDED(rc) && machine) {
-#if VBOX_API_VERSION < 3001
+# if VBOX_API_VERSION < 3001
/* 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);
-#else /* VBOX_API_VERSION >= 3001 */
+# else /* VBOX_API_VERSION >= 3001 */
/* get all the controller first, then the attachments and
* remove them all so that the machine can be undefined
*/
@@ -4774,9 +4936,9 @@ static int vboxDomainUndefine(virDomainPtr dom) {
continue;
strCtl->vtbl->GetName(strCtl, &strCtlName);
- vboxArrayGetWithArg(&mediumAttachments, machine,
- machine->vtbl->GetMediumAttachmentsOfController,
- strCtlName);
+ vboxArrayGetWithPtrArg(&mediumAttachments, machine,
+ machine->vtbl->GetMediumAttachmentsOfController,
+ strCtlName);
for (j = 0; j < mediumAttachments.count; j++) {
IMediumAttachment *medAtt = mediumAttachments.items[j];
@@ -4804,26 +4966,70 @@ static int vboxDomainUndefine(virDomainPtr dom) {
}
vboxArrayRelease(&storageControllers);
-#endif /* VBOX_API_VERSION >= 3001 */
+# endif /* VBOX_API_VERSION >= 3001 */
machine->vtbl->SaveSettings(machine);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
VBOX_UTF16_FREE(hddcnameUtf16);
}
+#endif
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->UnregisterMachine(data->vboxObj, iid.value, &machine);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
+ if (NS_FAILED(rc)) {
+ vboxError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ 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);
+#endif /* VBOX_API_VERSION >= 4000 */
DEBUGIID("UUID of machine being undefined", iid.value);
- if (NS_SUCCEEDED(rc) && machine){
+ if (NS_SUCCEEDED(rc)) {
+#if VBOX_API_VERSION < 4000
machine->vtbl->DeleteSettings(machine);
+#else /* VBOX_API_VERSION >= 4000 */
+ 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);
+
+ ((IMachine_Delete)machine->vtbl->Delete)(machine, &safeArray, &progress);
+# else
+ machine->vtbl->Delete(machine, 0, NULL, &progress);
+# endif
+ if (progress != NULL) {
+ progress->vtbl->WaitForCompletion(progress, -1);
+ VBOX_RELEASE(progress);
+ }
+#endif /* VBOX_API_VERSION >= 4000 */
ret = 0;
} else {
vboxError(VIR_ERR_INTERNAL_ERROR,
_("could not delete the domain, rc=%08x"), (unsigned)rc);
}
+#if VBOX_API_VERSION >= 4000
+ vboxArrayUnalloc(&media);
+#endif
vboxIIDUnalloc(&iid);
VBOX_RELEASE(machine);
@@ -4861,7 +5067,7 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
}
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching uuid"));
@@ -4873,9 +5079,9 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
if ((state == MachineState_Running) ||
(state == MachineState_Paused)) {
- rc = data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
} else {
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
}
if (NS_SUCCEEDED(rc)) {
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
@@ -4996,7 +5202,7 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
machine->vtbl->SaveSettings(machine);
VBOX_RELEASE(machine);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
}
@@ -5066,7 +5272,7 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
}
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching uuid"));
@@ -5078,9 +5284,9 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
if ((state == MachineState_Running) ||
(state == MachineState_Paused)) {
- rc = data->vboxObj->vtbl->OpenExistingSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
} else {
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, iid.value);
+ rc = VBOX_SESSION_OPEN(iid.value, machine);
}
if (NS_SUCCEEDED(rc)) {
@@ -5150,7 +5356,7 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
machine->vtbl->SaveSettings(machine);
VBOX_RELEASE(machine);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
}
@@ -5200,7 +5406,11 @@ vboxDomainSnapshotGetAll(virDomainPtr dom,
goto error;
}
+#if VBOX_API_VERSION < 4000
rc = machine->vtbl->GetSnapshot(machine, empty.value, list);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = machine->vtbl->FindSnapshot(machine, empty.value, list);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_FAILED(rc) || !list[0]) {
vboxError(VIR_ERR_INTERNAL_ERROR,
_("could not get root snapshot for domain %s"),
@@ -5338,7 +5548,7 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
goto cleanup;
vboxIIDFromUUID(&domiid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, domiid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5354,14 +5564,11 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
if ((state >= MachineState_FirstOnline)
&& (state <= MachineState_LastOnline)) {
- rc = data->vboxObj->vtbl->OpenExistingSession(data->vboxObj,
- data->vboxSession,
- domiid.value);
+ rc = VBOX_SESSION_OPEN_EXISTING(domiid.value, machine);
} else {
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj,
- data->vboxSession,
- domiid.value);
+ rc = VBOX_SESSION_OPEN(domiid.value, machine);
}
+
if (NS_SUCCEEDED(rc))
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (NS_FAILED(rc)) {
@@ -5415,7 +5622,7 @@ cleanup:
VBOX_UTF16_FREE(description);
VBOX_UTF16_FREE(name);
VBOX_RELEASE(console);
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
VBOX_RELEASE(machine);
vboxIIDUnalloc(&domiid);
virDomainSnapshotDefFree(def);
@@ -5443,7 +5650,7 @@ vboxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
virCheckFlags(0, NULL);
vboxIIDFromUUID(&domiid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, domiid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5547,7 +5754,7 @@ vboxDomainSnapshotNum(virDomainPtr dom,
virCheckFlags(0, -1);
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5587,7 +5794,7 @@ vboxDomainSnapshotListNames(virDomainPtr dom,
virCheckFlags(0, -1);
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5650,7 +5857,7 @@ vboxDomainSnapshotLookupByName(virDomainPtr dom,
virCheckFlags(0, NULL);
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5682,7 +5889,7 @@ vboxDomainHasCurrentSnapshot(virDomainPtr dom,
virCheckFlags(0, -1);
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5722,7 +5929,7 @@ vboxDomainSnapshotCurrent(virDomainPtr dom,
virCheckFlags(0, NULL);
vboxIIDFromUUID(&iid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, iid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -5831,8 +6038,7 @@ vboxDomainSnapshotRestore(virDomainPtr dom,
goto cleanup;
}
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession,
- domiid.value);
+ rc = VBOX_SESSION_OPEN(domiid.value, machine);
if (NS_SUCCEEDED(rc))
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (NS_FAILED(rc)) {
@@ -5868,7 +6074,7 @@ vboxDomainSnapshotRestore(virDomainPtr dom,
cleanup:
VBOX_RELEASE(progress);
VBOX_RELEASE(console);
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
vboxIIDUnalloc(&domiid);
return ret;
}
@@ -5891,7 +6097,7 @@ vboxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
virCheckFlags(0, -1);
vboxIIDFromUUID(&domiid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, domiid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -6048,7 +6254,7 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
vboxIIDFromUUID(&domiid, dom->uuid);
- rc = data->vboxObj->vtbl->GetMachine(data->vboxObj, domiid.value, &machine);
+ rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
if (NS_FAILED(rc)) {
vboxError(VIR_ERR_NO_DOMAIN, "%s",
_("no domain with matching UUID"));
@@ -6073,8 +6279,7 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
goto cleanup;
}
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession,
- domiid.value);
+ rc = VBOX_SESSION_OPEN(domiid.value, machine);
if (NS_SUCCEEDED(rc))
rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console);
if (NS_FAILED(rc)) {
@@ -6093,13 +6298,13 @@ cleanup:
VBOX_RELEASE(console);
VBOX_RELEASE(snap);
vboxIIDUnalloc(&domiid);
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
return ret;
}
-#if VBOX_API_VERSION == 2002
+#if VBOX_API_VERSION == 2002 || VBOX_API_VERSION == 4000
/* No Callback support for VirtualBox 2.2.* series */
-#else /* !(VBOX_API_VERSION == 2002) */
+#else /* !(VBOX_API_VERSION == 2002) && !(VBOX_API_VERSION == 4000) */
/* Functions needed for Callbacks */
static nsresult PR_COM_METHOD
@@ -6654,7 +6859,7 @@ static int vboxDomainEventDeregisterAny(virConnectPtr conn,
return ret;
}
-#endif /* !(VBOX_API_VERSION == 2002) */
+#endif /* !(VBOX_API_VERSION == 2002) && !(VBOX_API_VERSION == 4000) */
/**
* The Network Functions here on
@@ -7705,7 +7910,12 @@ static virStorageVolPtr vboxStorageVolLookupByKey(virConnectPtr conn, const char
}
vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
@@ -7756,7 +7966,12 @@ static virStorageVolPtr vboxStorageVolLookupByPath(virConnectPtr conn, const cha
if (!hddPathUtf16)
return ret;
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->FindHardDisk(data->vboxObj, hddPathUtf16, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddPathUtf16,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
@@ -7920,7 +8135,12 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
}
vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
@@ -7955,7 +8175,17 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
vboxIIDFromArrayItem(&machineId, &machineIds, i);
- rc = data->vboxObj->vtbl->OpenSession(data->vboxObj, data->vboxSession, machineId.value);
+#if VBOX_API_VERSION >= 4000
+ rc = VBOX_OBJECT_GET_MACHINE(machineId.value, &machine);
+ if (NS_FAILED(rc)) {
+ vboxError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ break;
+ }
+#endif
+
+ rc = VBOX_SESSION_OPEN(machineId.value, machine);
+
if (NS_SUCCEEDED(rc)) {
rc = data->vboxSession->vtbl->GetMachine(data->vboxSession, &machine);
@@ -8027,7 +8257,7 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
vboxArrayRelease(&hddAttachments);
VBOX_RELEASE(machine);
}
- data->vboxSession->vtbl->Close(data->vboxSession);
+ VBOX_SESSION_CLOSE();
}
vboxIIDUnalloc(&machineId);
@@ -8074,19 +8304,33 @@ static int vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info
}
vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
if (hddstate != MediaState_Inaccessible) {
+#if VBOX_API_VERSION < 4000
PRUint64 hddLogicalSize;
PRUint64 hddActualSize;
+#else /* VBOX_API_VERSION >= 4000 */
+ PRInt64 hddLogicalSize;
+ PRInt64 hddActualSize;
+#endif /* VBOX_API_VERSION >= 4000 */
info->type = VIR_STORAGE_VOL_FILE;
hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
+#if VBOX_API_VERSION < 4000
info->capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
+#else /* VBOX_API_VERSION >= 4000 */
+ info->capacity = hddLogicalSize;
+#endif /* VBOX_API_VERSION >= 4000 */
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
info->allocation = hddActualSize;
@@ -8127,15 +8371,25 @@ static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags A
}
vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetState, &hddstate);
if (NS_SUCCEEDED(rc) && hddstate != MediaState_Inaccessible) {
PRUnichar *hddFormatUtf16 = NULL;
+#if VBOX_API_VERSION < 4000
PRUint64 hddLogicalSize;
PRUint64 hddActualSize;
+#else /* VBOX_API_VERSION >= 4000 */
+ PRInt64 hddLogicalSize;
+ PRInt64 hddActualSize;
+#endif /* VBOX_API_VERSION >= 4000 */
/* since there is currently one default pool now
* and virStorageVolDefFormat() just checks it type
@@ -8147,9 +8401,13 @@ static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags A
defOk = 1;
rc = hardDisk->vtbl->GetLogicalSize(hardDisk, &hddLogicalSize);
- if (NS_SUCCEEDED(rc) && defOk)
+ if (NS_SUCCEEDED(rc) && defOk) {
+#if VBOX_API_VERSION < 4000
def.capacity = hddLogicalSize * 1024 * 1024; /* MB => Bytes */
- else
+#else /* VBOX_API_VERSION >= 4000 */
+ def.capacity = hddLogicalSize;
+#endif /* VBOX_API_VERSION >= 4000 */
+ } else
defOk = 0;
rc = VBOX_MEDIUM_FUNC_ARG1(hardDisk, GetSize, &hddActualSize);
@@ -8220,7 +8478,12 @@ static char *vboxStorageVolGetPath(virStorageVolPtr vol) {
}
vboxIIDFromUUID(&hddIID, uuid);
+#if VBOX_API_VERSION < 4000
rc = data->vboxObj->vtbl->GetHardDisk(data->vboxObj, hddIID.value, &hardDisk);
+#else /* VBOX_API_VERSION >= 4000 */
+ rc = data->vboxObj->vtbl->FindMedium(data->vboxObj, hddIID.value,
+ DeviceType_HardDisk, &hardDisk);
+#endif /* VBOX_API_VERSION >= 4000 */
if (NS_SUCCEEDED(rc)) {
PRUint32 hddstate;
@@ -8330,7 +8593,7 @@ virDriver NAME(Driver) = {
NULL, /* domainGetBlockInfo */
nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
nodeGetFreeMemory, /* getFreeMemory */
-#if VBOX_API_VERSION == 2002
+#if VBOX_API_VERSION == 2002 || VBOX_API_VERSION == 4000
NULL, /* domainEventRegister */
NULL, /* domainEventDeregister */
#else
@@ -8353,7 +8616,7 @@ virDriver NAME(Driver) = {
NULL, /* domainGetJobInfo */
NULL, /* domainAbortJob */
NULL, /* domainMigrateSetMaxDowntime */
-#if VBOX_API_VERSION == 2002
+#if VBOX_API_VERSION == 2002 || VBOX_API_VERSION == 4000
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
#else
--
1.7.0.4
13 years, 11 months