[libvirt] [PATCH] vbox: fix a bug in _machineStateInactive

2014-11-19 Thread Yohan BELLEGUIC
This function returned non-inactive domains instead of active domains.
This broke virConnectNumOfDefinedDomains() and virConnectListDefinedDomains()
functions.
---
 src/vbox/vbox_tmpl.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index de8744d..37ec8e1 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -4607,8 +4607,8 @@ static bool _machineStateOnline(PRUint32 state)
 
 static bool _machineStateInactive(PRUint32 state)
 {
-return ((state  MachineState_FirstOnline) 
-(state  MachineState_LastOnline));
+return ((state  MachineState_FirstOnline) ||
+(state  MachineState_LastOnline));
 }
 
 static bool _machineStateNotStart(PRUint32 state)
-- 
1.7.10.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 00/66] vbox: Rewrite vbox domain driver

2014-08-14 Thread Yohan Belleguic
Le Wednesday 13 August 2014 17:18:44, Michal Privoznik a écrit :
 [CC-ing Yohan BELLEGUIC and Manuel VIVES]
 
 On 12.08.2014 17:31, Michal Privoznik wrote:
  On 11.08.2014 12:06, Taowei wrote:
  This series of patches rewrite the vbox's domain
  driver. The driver is separated into two parts: the version
  specified and the common part. The common driver use
  vboxUniformedAPI to build a general driver for all vbox
  versions. The vboxUniformedAPI take the responsiblity to
  communicate with virtualbox. Since there are some incompatible
  changes in virtualbox, vboxUniformedAPI should be aware of
  these changes and provide a uniformed api for the upper layer.
  
  The significant result of this patch is that we replace all
  vir${vbox_version}Driver into one virCommonDriver. So, we will
  have only one vbox driver implementation for all vbox versions
  in libvirt.
  
  PS: I have send part of my patches before:
  https://www.redhat.com/archives/libvir-list/2014-July/msg00937.html
  But I have to resend it beacuse I did some improvement on previous
  patches:
  *Remove the test case for vboxUniformedAPI, because it would raise
  
break strict-aliasing rules warning in some distibutions
  
  *Merged the flag fdWatchNeedInitialize into domainEventCallbacks,
  
So, we use one flag to indicate whether vbox support callbacks
as well as we need to initialize variables for it.
  
  Taowei (66):
 vbox: Begin to rewrite, vboxConnectOpen
 vbox: Rewrite vboxConnectClose
 vbox: Rewrite vboxDomainSave
 vbox: Rewrite vboxConnectGetVersion
 vbox: Rewrite vboxConnectGetHostname
 vbox: Rewrite vboxConnectIsSecure
 vbox: Rewrite vboxConnectIsEncrypted
 vbox: Rewrite vboxConnectIsAlive
 vbox: Rewrite vboxConnectGetMaxVcpus
 vbox: Rewrite vboxConnectGetCapabilities
 vbox: Rewrite vboxConnectListDomains
 vbox: Rewrite vboxConnectNumOfDomains
 vbox: Rewrite vboxDomainLookupById
 vbox: Rewrite vboxDomainLookupByUUID
 vbox: Rewrite vboxDomainUndefineFlags
 vbox: Rewrite vboxDomainDefineXML
 vbox: Rewrite vboxDomainCreateWithFlags
 vbox: Rewrite vboxDomainCreate
 vbox: Rewrite vboxDomainCreateXML
 vbox: Rewrite vboxDomainLookupByName
 vbox: Rewrite vboxDomainIsActive
 vbox: Rewrite vboxDomainIsPersistent
 vbox: Rewrite vboxDomainIsUpdated
 vbox: Rewrite vboxDomainSuspend
 vbox: Rewrite vboxDomainResume
 vbox: Rewrite vboxDomainShutdownFlags
 vbox: Rewrite vboxDomainShutdown
 vbox: Rewrite vboxDomainReboot
 vbox: Rewrite vboxDomainDestroyFlags
 vbox: Rewrite vboxDomainDestroy
 vbox: Rewrite vboxDomainGetOSType
 vbox: Rewrite vboxDomainSetMemory
 vbox: Rewrite vboxDomainGetInfo
 vbox: Rewrite vboxDomainGetState
 vbox: Rewrite vboxDomainSetVcpusFlags
 vbox: Rewrite vboxDomainSetVcpus
 vbox: Rewrite vboxDomainGetVcpusFlags
 vbox: Rewrite vboxDomainGetMaxVcpus
 vbox: Add API for vboxDomainGetXMLDesc
 vbox: Rewrite vboxDomainGetXMLDesc
 vbox: Rewrite vboxConnectListDefinedDomains
 vbox: Rewrite vboxConnectNumOfDefinedDomains
 vbox: Rewrite vboxDomainUndefine
 vbox: Rewrite vboxDomainAttachDevice
 vbox: Rewrite vboxDomainAttachDeviceFlags
 vbox: Rewrite vboxDomainUpdateDeviceFlags
 vbox: Rewrite vboxDomainDetachDevice
 vbox: Rewrite vboxDomainDetachDeviceFlags
 vbox: Add API for vboxDomainSnapshotCreateXML
 vbox: Rewrite vboxDomainSnapshotCreateXML
 vbox: Rewrite vboxDomainSnapshotGetXMLDesc
 vbox: Rewrite vboxDomainSnapshotNum
 vbox: Rewrite vboxDomainSnapshotListNames
 vbox: Rewrite vboxSnapshotLookupByName
 vbox: Rewrite vboxDomainHasCurrentSnapshot
 vbox: Rewrite vboxDomainSnapshotGetParent
 vbox: Rewrite vboxDomainSnapshotCurrent
 vbox: Rewrite vboxDomainSnapshotIsCurrent
 vbox: Rewrite vboxDomainSnapshotHasMetadata
 vbox: Rewrite vboxDomainRevertToSnapshot
 vbox: Rewrite vboxDomainSnapshotDelete
 vbox: Rewrite vboxDomainScreenshot
 vbox: Rewrite vboxConnectListAllDomains
 vbox: Rewrite vboxNode functions
 vbox: Add registerDomainEvent
 vbox: Introducing vboxCommonDriver

po/POTFILES.in|1 +
src/Makefile.am   |5 +-
src/vbox/README   |7 +-
src/vbox/vbox_common.c| 7550 +
src/vbox/vbox_common.h|  306 +
src/vbox/vbox_driver.c|   40 +-
src/vbox/vbox_install_api.h   |   26 +
src/vbox/vbox_tmpl.c  |14557
  
  +
  
src/vbox/vbox_uniformed_api.h |  551 ++
9 files changed, 13186 insertions(+), 9857 deletions(-)
create mode 100644 src/vbox/vbox_common.c
create mode 100644 src/vbox/vbox_common.h
create mode 100644 src/vbox/vbox_install_api.h
create mode 100644 src/vbox/vbox_uniformed_api.h
  
  ACK to all the patches. I've fixed all the small nits I found. I'm
  keeping

[libvirt] [PATCH] vbox: fix a segfault when taking a snapshot

2014-06-17 Thread Yohan BELLEGUIC
there is a segfault in the vbox driver when taking a snapshot in the
following functions:
- vboxDomainGetXMLDesc
- vboxSnapshotGetReadWriteDisks
- vboxSnapshotGetReadOnlyDisks

The virStorageSourcePtr in virDomainDiskDef was not correctly allocated.
---
 src/vbox/vbox_tmpl.c |   24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 1ed2729..6365f2a 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2872,10 +2872,12 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, 
unsigned int flags) {
 /* 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) {
+virDomainDiskDefPtr disk = virDomainDiskDefNew();
+if (!disk) {
 error = true;
 break;
 }
+def-disks[i] = disk;
 }
 } else {
 error = true;
@@ -7175,6 +7177,10 @@ int 
vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
 /* Allocate mem, if fails return error */
 if (VIR_ALLOC_N(def-disks, def-ndisks)  0)
 goto cleanup;
+for (i = 0; i  def-ndisks; i++) {
+if (VIR_ALLOC(def-disks[i].src)  0)
+goto cleanup;
+}
 
 if (!vboxGetMaxPortSlotValues(data-vboxObj, maxPortPerInst, 
maxSlotPerPort))
 goto cleanup;
@@ -7302,11 +7308,11 @@ int 
vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
 ret = 0;
  cleanup:
 if (ret  0) {
-for (i = 0; i  def-dom-ndisks; i++)
-VIR_FREE(def-dom-disks[i]);
-VIR_FREE(def-dom-disks);
-def-dom-ndisks = 0;
-ret = -1;
+for (i = 0; i  def-ndisks; i++) {
+VIR_FREE(def-disks[i].src);
+}
+VIR_FREE(def-disks);
+def-ndisks = 0;
 }
 VBOX_RELEASE(snap);
 return ret;
@@ -7380,8 +7386,10 @@ int vboxSnapshotGetReadOnlyDisks(virDomainSnapshotPtr 
snapshot,
 /* Allocate mem, if fails return error */
 if (VIR_ALLOC_N(def-dom-disks, def-dom-ndisks) = 0) {
 for (i = 0; i  def-dom-ndisks; i++) {
-if (VIR_ALLOC(def-dom-disks[i])  0)
+virDomainDiskDefPtr diskDef = virDomainDiskDefNew();
+if (!diskDef)
 goto cleanup;
+def-dom-disks[i] = diskDef;
 }
 } else {
 goto cleanup;
@@ -7516,7 +7524,7 @@ int vboxSnapshotGetReadOnlyDisks(virDomainSnapshotPtr 
snapshot,
  cleanup:
 if (ret  0) {
 for (i = 0; i  def-dom-ndisks; i++)
-VIR_FREE(def-dom-disks[i]);
+virDomainDiskDefFree(def-dom-disks[i]);
 VIR_FREE(def-dom-disks);
 def-dom-ndisks = 0;
 }
-- 
1.7.10.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/3] vbox: snapshot: Avoid memleak in virVBoxSnapshotConfAllChildren

2014-06-17 Thread Yohan Belleguic
Le Tuesday 17 June 2014 11:24:08, Peter Krempa a écrit :
 On re-allocation failure the function would leak already allocated
 memory.
 ---
  src/vbox/vbox_snapshot_conf.c | 10 --
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/src/vbox/vbox_snapshot_conf.c b/src/vbox/vbox_snapshot_conf.c
 index 30ac6fe..69c7e42 100644
 --- a/src/vbox/vbox_snapshot_conf.c
 +++ b/src/vbox/vbox_snapshot_conf.c
 @@ -483,18 +483,24 @@
 virVBoxSnapshotConfAllChildren(virVBoxSnapshotConfHardDiskPtr disk, for (i
 = 0; i  disk-nchildren; i++) {
  tempSize = virVBoxSnapshotConfAllChildren(disk-children[i],
 tempList); if (VIR_EXPAND_N(ret, returnSize, tempSize)  0)
 -return 0;
 +goto error;
 
  for (j = 0; j  tempSize; j++) {
  ret[returnSize - tempSize + j] = tempList[j];
  }
  }
  if (VIR_EXPAND_N(ret, returnSize, 1)  0)
 -return 0;
 +goto error;
 
  ret[returnSize - 1] = disk;
  *list = ret;
  return returnSize;
 +
 + error:
 +for (i = 0; i  returnSize; i++)
 +virVboxSnapshotConfHardDiskFree(ret[i]);
 +VIR_FREE(ret);
 +return 0;
  }

I think we don't have to use virVboxSnapshotConfHardDiskFree because there is 
not memory allocation in this function. It's just a pointer recopy, so if the 
disks are freed, this might lead to a segfault or a bad behaviour.
 
  void

-- 
Yohan BELLEGUIC
Software Engineer - diateam : Architectes de l'information
Phone : +33 (0)2 98 050 050 Fax : +33 (0)2 98 050 05

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/3] vbox: snapshot: Avoid memleaks in functions dealing with disk arrays

2014-06-17 Thread Yohan Belleguic
Le Tuesday 17 June 2014 11:24:09, Peter Krempa a écrit :
 In virVBoxSnapshotConfRemoveFakeDisks and
 virVBoxSnapshotConfDiskIsInMediaRegistry the disk array constructed from
 all the disks would be leaked at the end of the function and on
 allocation errors. Also the temporary disk list would be leaked.
 
 Add a cleanup section and free the memory properly.
 
 Found by coverity.
 ---
  src/vbox/vbox_snapshot_conf.c | 54
 +++ 1 file changed, 44
 insertions(+), 10 deletions(-)
 
 diff --git a/src/vbox/vbox_snapshot_conf.c b/src/vbox/vbox_snapshot_conf.c
 index 69c7e42..49fd2b6 100644
 --- a/src/vbox/vbox_snapshot_conf.c
 +++ b/src/vbox/vbox_snapshot_conf.c
 @@ -1471,28 +1471,45 @@
 virVBoxSnapshotConfRemoveFakeDisks(virVBoxSnapshotConfMachinePtr machine)
 size_t diskSize = 0;
  virVBoxSnapshotConfHardDiskPtr *tempList = NULL;
  virVBoxSnapshotConfHardDiskPtr *diskList = NULL;
 +
  if (VIR_ALLOC_N(diskList, 0)  0)
 -return ret;
 +return -1;
 
  for (i = 0; i  machine-mediaRegistry-ndisks; i++) {
  tempSize =
 virVBoxSnapshotConfAllChildren(machine-mediaRegistry-disks[i],
 tempList); if (VIR_EXPAND_N(diskList, diskSize, tempSize)  0)
 -return ret;
 -for (j = 0; j  tempSize; j++) {
 +goto cleanup;
 +
 +for (j = 0; j  tempSize; j++)
  diskList[diskSize - tempSize + j] = tempList[j];
 -}
 +
 +VIR_FREE(tempList);
  }
 +
  for (i = 0; i  diskSize; i++) {
  if (strstr(diskList[i]-location, fake) != NULL) {
  if (virVBoxSnapshotConfRemoveHardDisk(machine-mediaRegistry,
 diskList[i]-uuid)  0) { virReportError(VIR_ERR_INTERNAL_ERROR,
 _(Unable to remove hard disk %s from media
 registry), diskList[i]-location);
 -return ret;
 +goto cleanup;
  }
  }
  }
 +
  ret = 0;
 +
 + cleanup:
 +for (i = 0; i  diskSize; i++)
 +virVboxSnapshotConfHardDiskFree(diskList[i]);
 +VIR_FREE(diskList);
 +
 +if (tempList) {
 +for (i = 0; i  tempSize; i++)
 +virVboxSnapshotConfHardDiskFree(tempList[i]);
 +VIR_FREE(tempList);
 +}
Same comments than the previous patch
 +
  return ret;
  }
 
 @@ -1513,24 +1530,41 @@
 virVBoxSnapshotConfDiskIsInMediaRegistry(virVBoxSnapshotConfMachinePtr
 machine, size_t diskSize = 0;
  virVBoxSnapshotConfHardDiskPtr *tempList = NULL;
  virVBoxSnapshotConfHardDiskPtr *diskList = NULL;
 +
  if (VIR_ALLOC_N(diskList, 0)  0)
 -return ret;
 +return -1;
 
  for (i = 0; i  machine-mediaRegistry-ndisks; i++) {
  tempSize =
 virVBoxSnapshotConfAllChildren(machine-mediaRegistry-disks[i],
 tempList); if (VIR_EXPAND_N(diskList, diskSize, tempSize)  0)
 -return ret;
 -for (j = 0; j  tempSize; j++) {
 +goto cleanup;
 +
 +for (j = 0; j  tempSize; j++)
  diskList[diskSize - tempSize + j] = tempList[j];
 -}
 +
 +VIR_FREE(tempList);
  }
 +
  for (i = 0; i  diskSize; i++) {
  if (STREQ(diskList[i]-location, location)) {
  ret = 1;
 -return ret;
 +goto cleanup;
  }
  }
 +
  ret = 0;
 +
 + cleanup:
 +for (i = 0; i  diskSize; i++)
 +virVboxSnapshotConfHardDiskFree(diskList[i]);
 +VIR_FREE(diskList);
 +
 +if (tempList) {
 +for (i = 0; i  tempSize; i++)
 +virVboxSnapshotConfHardDiskFree(tempList[i]);
 +VIR_FREE(tempList);
 +}
Same comments than the previous patch
 +
  return ret;
  }

-- 
Yohan BELLEGUIC
Software Engineer - diateam : Architectes de l'information
Phone : +33 (0)2 98 050 050 Fax : +33 (0)2 98 050 05

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v8 0/4] Handling of undefine and re define snapshots with VirtualBox 4.2 or higher

2014-05-19 Thread Yohan BELLEGUIC
Hello,

This is a new series of patches in order to support undefining and redefining 
snapshots with VirtualBox 4.2 or higher.
These patches are based on Manuel Vives' patches, taking into account Daniel 
P. Berrange's remarks.

The VirtualBox API provides only high level operations to manipulate snapshots,
so it not possible to support flags like VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE and
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY with only API calls.
Following an IRC talk with Eric Blake, the decision was made to emulate these
behaviours by manipulating directly the .vbox XML files.

The first patch adds extra details in the snapshot XML returned by libvirt. We 
will need those details in order to redefine the snapshots.

The second patch adds a new API to manipulate the VirtualBox XML file. It 
provides several structs describing the VirtualBox XML file nodes and 
functions which can manipulate these structs.

The third patch adds support of the VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE 
and VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT flags in virDomainSnapshotCreateXML.
The idea is to unregister the machine, add the snapshot in the Virtualbox XML 
file and re-register the machine.
However, VirtualBox forbids a machine to have snapshots but no current 
snapshot. So, if the real current snapshot has not been redefined yet, we 
create fake disks, allowing us to have an intermediate state in order to not 
corrupt the snapshot's read-write disks. These fake disks will be deleted 
during the 
next redefine.

The fourth and last patch adds support of the 
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY flag in virDomainSnapshotDelete.
As in the third patch, we also create fake disks to not corrupt the snapshot's 
read-write disks.

The patches were only tested with VirtualBox 4.3.10 and VirtualBox 4.2.24.

Regards
Yohan BELLEGUIC

v8:
* Fix patches according to Daniel P. Berrange review (May 01, 2014)
* Rename all the methods in vbox_snapshot.{c,h} 
* Add a test case for serialize and deserialize a virVBoxSnapshotConfMachine
* Fix memory leaks

v7:
* Add vbox_snapshot_conf.{h,c} files to (de)serialize VirtualBox XML files
* Update the code to use the API exposed by vbox_snapshot_conf.h
* Handle the fact that VirtualBox forbids a machine to have snapshots but no
current snapshot

v6:
* Rebased because of a massive change in vbox_tmpl.c due to changes in
  the handling of different versions of VirtualBox

v5:
* The patches are modified according to a first review by Laine Stump:
* renamed virSearchUuid to virSearchRegex and moved it from
  viruuid.{c,h} to virstring.{c,h}.
* Various fixes.

v4:
* The code is compliant with Virtualbox 4.3 API
* Some minor modifications in order to satisfy make syntax-check

v3:
* Use of STREQ_NULLABLE instead of STREQ in one case
* Fix the method for finding uuids according to Ján Tomko review

v2:
* Fix a licence problem with the method for string replacement

Manuel VIVES (1):
  vbox_tmpl.c: Better XML description for snapshots

Yohan BELLEGUIC (3):
  Add vbox_snapshot_conf struct
  vbox_tmpl.c: Patch for redefining snapshots
  vbox_tmpl.c: Add function for undefining snapshot

 po/POTFILES.in |1 +
 src/Makefile.am|1 +
 src/vbox/vbox_snapshot_conf.c  | 1490 +++
 src/vbox/vbox_snapshot_conf.h  |  105 ++
 src/vbox/vbox_tmpl.c   | 1982 +++-
 tests/Makefile.am  |   15 +
 tests/vboxsnapshotxmldata/2disks-1snap.vbox|  322 
 tests/vboxsnapshotxmldata/2disks-2snap.vbox|  478 +
 .../vboxsnapshotxmldata/2disks-3snap-brother.vbox  |  786 
 tests/vboxsnapshotxmldata/2disks-3snap.vbox|  636 +++
 tests/vboxsnapshotxmldata/2disks-nosnap.vbox   |  168 ++
 tests/vboxsnapshotxmltest.c|  161 ++
 12 files changed, 6100 insertions(+), 45 deletions(-)
 create mode 100644 src/vbox/vbox_snapshot_conf.c
 create mode 100644 src/vbox/vbox_snapshot_conf.h
 create mode 100644 tests/vboxsnapshotxmldata/2disks-1snap.vbox
 create mode 100644 tests/vboxsnapshotxmldata/2disks-2snap.vbox
 create mode 100644 tests/vboxsnapshotxmldata/2disks-3snap-brother.vbox
 create mode 100644 tests/vboxsnapshotxmldata/2disks-3snap.vbox
 create mode 100644 tests/vboxsnapshotxmldata/2disks-nosnap.vbox
 create mode 100644 tests/vboxsnapshotxmltest.c

-- 
1.7.10.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v8 1/4] vbox_tmpl.c: Better XML description for snapshots

2014-05-19 Thread Yohan BELLEGUIC
From: Manuel VIVES manuel.vi...@diateam.net

It will be needed for the future patches because we will
redefine snapshots
---
 src/vbox/vbox_tmpl.c |  476 +-
 1 file changed, 471 insertions(+), 5 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index e124e69..5d4a7ba 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -58,6 +58,8 @@
 #include fdstream.h
 #include viruri.h
 #include virstring.h
+#include virtime.h
+#include virutil.h
 
 /* This one changes from version to version. */
 #if VBOX_API_VERSION == 2002000
@@ -6039,7 +6041,9 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, NULL);
 
 if (!(def = virDomainSnapshotDefParseString(xmlDesc, data-caps,
-data-xmlopt, 0, 0)))
+data-xmlopt, -1,
+
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
+
VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE)))
 goto cleanup;
 
 if (def-ndisks) {
@@ -6130,6 +6134,431 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
 return ret;
 }
 
+#if VBOX_API_VERSION =4002000
+static
+int vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
+virDomainSnapshotPtr snapshot)
+{
+virDomainPtr dom = snapshot-domain;
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+vboxIID domiid = VBOX_IID_INITIALIZER;
+IMachine *machine = NULL;
+ISnapshot *snap = NULL;
+IMachine *snapMachine = NULL;
+vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
+PRUint32   maxPortPerInst[StorageBus_Floppy + 1] = {};
+PRUint32   maxSlotPerPort[StorageBus_Floppy + 1] = {};
+int diskCount = 0;
+nsresult rc;
+vboxIID snapIid = VBOX_IID_INITIALIZER;
+char *snapshotUuidStr = NULL;
+size_t i = 0;
+
+vboxIIDFromUUID(domiid, dom-uuid);
+rc = VBOX_OBJECT_GET_MACHINE(domiid.value, machine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(no domain with matching UUID));
+goto cleanup;
+}
+if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot-name)))
+goto cleanup;
+
+rc = snap-vtbl-GetId(snap, snapIid.value);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Could not get snapshot id));
+goto cleanup;
+}
+
+VBOX_UTF16_TO_UTF8(snapIid.value, snapshotUuidStr);
+rc = snap-vtbl-GetMachine(snap, snapMachine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(could not get machine));
+goto cleanup;
+}
+def-ndisks = 0;
+rc = vboxArrayGet(mediumAttachments, snapMachine, 
snapMachine-vtbl-GetMediumAttachments);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(no medium attachments));
+goto cleanup;
+}
+/* get the number of attachments */
+for (i = 0; i  mediumAttachments.count; i++) {
+IMediumAttachment *imediumattach = mediumAttachments.items[i];
+if (imediumattach) {
+IMedium *medium = NULL;
+
+rc = imediumattach-vtbl-GetMedium(imediumattach, medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get medium));
+goto cleanup;
+}
+if (medium) {
+def-ndisks++;
+VBOX_RELEASE(medium);
+}
+}
+}
+/* Allocate mem, if fails return error */
+if (VIR_ALLOC_N(def-disks, def-ndisks)  0)
+goto cleanup;
+
+if (!vboxGetMaxPortSlotValues(data-vboxObj, maxPortPerInst, 
maxSlotPerPort))
+goto cleanup;
+
+/* get the attachment details here */
+for (i = 0; i  mediumAttachments.count  diskCount  def-ndisks; i++) {
+IStorageController *storageController = NULL;
+PRUnichar *storageControllerName = NULL;
+PRUint32   deviceType = DeviceType_Null;
+PRUint32   storageBus = StorageBus_Null;
+IMedium   *disk = NULL;
+PRUnichar *childLocUtf16 = NULL;
+char  *childLocUtf8  = NULL;
+PRUint32   deviceInst = 0;
+PRInt32devicePort = 0;
+PRInt32deviceSlot = 0;
+vboxArray children = VBOX_ARRAY_INITIALIZER;
+vboxArray snapshotIids = VBOX_ARRAY_INITIALIZER;
+IMediumAttachment *imediumattach = mediumAttachments.items[i];
+size_t j = 0;
+size_t k = 0;
+if (!imediumattach)
+continue;
+rc = imediumattach-vtbl-GetMedium(imediumattach, disk);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   

[libvirt] [PATCH v8 4/4] vbox_tmpl.c: Add function for undefining snapshot

2014-05-19 Thread Yohan BELLEGUIC
All snapshots information will be deleted from the vbox XML, but
differencing disks will be kept so the user will be able to redefine the
snapshot.
---
 src/vbox/vbox_tmpl.c |  464 +-
 1 file changed, 463 insertions(+), 1 deletion(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index a7f15d4..eb577f4 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8364,7 +8364,454 @@ vboxDomainSnapshotDeleteTree(vboxGlobalData *data,
 return ret;
 }
 
+#if VBOX_API_VERSION = 4002000
+static int
+vboxDomainSnapshotDeleteMetadataOnly(virDomainSnapshotPtr snapshot)
+{
+/*
+ * This function will remove the node in the vbox xml corresponding to the 
snapshot.
+ * It is usually called by vboxDomainSnapshotDelete() with the flag
+ * VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY.
+ * If you want to use it anywhere else, be careful, if the snapshot you 
want to delete
+ * has children, the result is not granted, they will probably will be 
deleted in the
+ * xml, but you may have a problem with hard drives.
+ *
+ * If the snapshot which is being deleted is the current one, we will set 
the current
+ * snapshot of the machine to the parent of this snapshot. Before writing 
the modified
+ * xml file, we undefine the machine from vbox. After writing the file, we 
redefine
+ * the machine with the new file.
+ */
+
+virDomainPtr dom = snapshot-domain;
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+virDomainSnapshotDefPtr def= NULL;
+char *defXml = NULL;
+vboxIID domiid = VBOX_IID_INITIALIZER;
+nsresult rc;
+IMachine *machine = NULL;
+PRUnichar *settingsFilePathUtf16 = NULL;
+char *settingsFilepath = NULL;
+virVBoxSnapshotConfMachinePtr snapshotMachineDesc = NULL;
+int isCurrent = -1;
+int it = 0;
+PRUnichar *machineNameUtf16 = NULL;
+char *machineName = NULL;
+char *nameTmpUse = NULL;
+char *machineLocationPath = NULL;
+PRUint32 aMediaSize = 0;
+IMedium **aMedia = NULL;
 
+defXml = vboxDomainSnapshotGetXMLDesc(snapshot, 0);
+if (!defXml) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get XML Desc of snapshot));
+goto cleanup;
+}
+def = virDomainSnapshotDefParseString(defXml,
+  data-caps,
+  data-xmlopt,
+  -1,
+  VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
+  VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
+if (!def) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get a virDomainSnapshotDefPtr));
+goto cleanup;
+}
+
+vboxIIDFromUUID(domiid, dom-uuid);
+rc = VBOX_OBJECT_GET_MACHINE(domiid.value, machine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_NO_DOMAIN, %s,
+   _(no domain with matching UUID));
+goto cleanup;
+}
+rc = machine-vtbl-GetSettingsFilePath(machine, settingsFilePathUtf16);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get settings file path));
+goto cleanup;
+}
+VBOX_UTF16_TO_UTF8(settingsFilePathUtf16, settingsFilepath);
+
+/*Getting the machine name to retrieve the machine location path.*/
+rc = machine-vtbl-GetName(machine, machineNameUtf16);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get machine name));
+goto cleanup;
+}
+VBOX_UTF16_TO_UTF8(machineNameUtf16, machineName);
+if (virAsprintf(nameTmpUse, %s.vbox, machineName)  0)
+goto cleanup;
+machineLocationPath = virStringReplace(settingsFilepath, nameTmpUse, );
+if (machineLocationPath == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get the machine location path));
+goto cleanup;
+}
+snapshotMachineDesc = virVBoxSnapshotConfLoadVboxFile(settingsFilepath, 
machineLocationPath);
+if (!snapshotMachineDesc) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot create a vboxSnapshotXmlPtr));
+goto cleanup;
+}
+
+isCurrent = virVBoxSnapshotConfIsCurrentSnapshot(snapshotMachineDesc, 
def-name);
+if (isCurrent  0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to know if the snapshot is the current 
snapshot));
+goto cleanup;
+}
+if (isCurrent) {
+/*
+ * If the snapshot is the current snapshot, it means that the machine 
has read-write
+ * disks. The first thing to do is to manipulate VirtualBox API to 
create
+ * differential read-write disks if the parent snapshot is not null.
+ */
+if (def-parent != NULL) {
+

[libvirt] [PATCH v8 3/4] vbox_tmpl.c: Patch for redefining snapshots

2014-05-19 Thread Yohan BELLEGUIC
The machine is unregistered and its vbox XML file is changed in order to
add snapshot information. The machine is then registered with the
snapshot to redefine.
---
 src/vbox/vbox_tmpl.c |  976 +-
 1 file changed, 970 insertions(+), 6 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 5d4a7ba..a7f15d4 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -43,6 +43,7 @@
 #include datatypes.h
 #include domain_conf.h
 #include snapshot_conf.h
+#include vbox_snapshot_conf.h
 #include network_conf.h
 #include virerror.h
 #include domain_event.h
@@ -6015,6 +6016,958 @@ vboxDomainSnapshotGet(vboxGlobalData *data,
 return snapshot;
 }
 
+#if VBOX_API_VERSION = 4002000
+static int vboxCloseDisksRecursively(virDomainPtr dom, char *location)
+{
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+nsresult rc;
+size_t i = 0;
+PRUnichar *locationUtf = NULL;
+IMedium *medium = NULL;
+IMedium **children = NULL;
+PRUint32 childrenSize = 0;
+VBOX_UTF8_TO_UTF16(location, locationUtf);
+rc = data-vboxObj-vtbl-OpenMedium(data-vboxObj,
+ locationUtf,
+ DeviceType_HardDisk,
+ AccessMode_ReadWrite,
+ false,
+ medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _(Unable to open HardDisk, rc=%08x),
+   (unsigned)rc);
+goto cleanup;
+}
+rc = medium-vtbl-GetChildren(medium, childrenSize, children);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s
+   , _(Unable to get disk children));
+goto cleanup;
+}
+for (i = 0; i  childrenSize; i++) {
+IMedium *childMedium = children[i];
+if (childMedium) {
+PRUnichar *childLocationUtf = NULL;
+char *childLocation = NULL;
+rc = childMedium-vtbl-GetLocation(childMedium, 
childLocationUtf);
+VBOX_UTF16_TO_UTF8(childLocationUtf, childLocation);
+VBOX_UTF16_FREE(childLocationUtf);
+if (vboxCloseDisksRecursively(dom, childLocation)  0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s
+   , _(Unable to close disk children));
+goto cleanup;
+}
+VIR_FREE(childLocation);
+}
+}
+rc = medium-vtbl-Close(medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _(Unable to close HardDisk, rc=%08x),
+   (unsigned)rc);
+goto cleanup;
+}
+
+ret = 0;
+ cleanup:
+VBOX_UTF16_FREE(locationUtf);
+return ret;
+}
+
+static int
+vboxSnapshotRedefine(virDomainPtr dom,
+ virDomainSnapshotDefPtr def,
+ bool isCurrent)
+{
+/*
+ * If your snapshot has a parent,
+ * it will only be redefined if you have already
+ * redefined the parent.
+ *
+ * The general algorithm of this function is below :
+ * First of all, we are going to create our vboxSnapshotXmlMachinePtr 
struct from
+ * the machine settings path.
+ * Then, if the machine current snapshot xml file is saved in the machine 
location,
+ * it means that this snapshot was previously modified by us and has fake 
disks.
+ * Fake disks are added when the flag VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT 
was not set
+ * yet, in order to not corrupt read-only disks. The first thing to do is 
to remove those
+ * disks and restore the read-write disks, if any, in the 
vboxSnapshotXmlMachinePtr struct.
+ * We also delete the current snapshot xml file.
+ *
+ * After that, we are going to register the snapshot read-only disks that 
we want to redefine,
+ * if they are not in the media registry struct.
+ *
+ * The next step is to unregister the machine and close all disks.
+ *
+ * Then, we check if the flag VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE has 
already been set.
+ * If this flag was set, we just add read-write disks to the media registry
+ * struct. Otherwise, we save the snapshot xml file into the machine 
location in order
+ * to recover the read-write disks during the next redefine and we create 
differential disks
+ * from the snapshot read-only disks and add them to the media registry 
struct.
+ *
+ * Finally, we register the machine with the new virtualbox description 
file.
+ */
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+vboxIID domiid = VBOX_IID_INITIALIZER;
+IMachine *machine = NULL;
+nsresult rc;
+PRUnichar *settingsFilePath = NULL;
+char *settingsFilePath_Utf8 = NULL;
+virVBoxSnapshotConfMachinePtr snapshotMachineDesc = NULL;
+char *currentSnapshotXmlFilePath = NULL;
+  

[libvirt] [PATCH v7 1/4] vbox_tmpl.c: Better XML description for snapshots

2014-04-18 Thread Yohan BELLEGUIC
From: Manuel VIVES manuel.vi...@diateam.net

It will be needed for the future patches because we will
redefine snapshots
---
 src/vbox/vbox_tmpl.c |  513 +-
 1 file changed, 504 insertions(+), 9 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index a305fe2..ac000cf 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -38,6 +38,7 @@
 #include sys/types.h
 #include sys/stat.h
 #include fcntl.h
+#include libxml/xmlwriter.h
 
 #include internal.h
 #include datatypes.h
@@ -58,6 +59,8 @@
 #include fdstream.h
 #include viruri.h
 #include virstring.h
+#include virtime.h
+#include virutil.h
 
 /* This one changes from version to version. */
 #if VBOX_API_VERSION == 2002000
@@ -294,6 +297,13 @@ static void vboxDriverUnlock(vboxGlobalData *data)
 virMutexUnlock(data-lock);
 }
 
+typedef enum {
+VBOX_STORAGE_DELETE_FLAG = 0,
+#if VBOX_API_VERSION = 4002000
+VBOX_STORAGE_CLOSE_FLAG = 1,
+#endif
+} vboxStorageDeleteOrCloseFlags;
+
 #if VBOX_API_VERSION == 2002000
 
 static void nsIDtoChar(unsigned char *uuid, const nsID *iid)
@@ -6039,7 +6049,9 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, NULL);
 
 if (!(def = virDomainSnapshotDefParseString(xmlDesc, data-caps,
-data-xmlopt, 0, 0)))
+data-xmlopt, -1,
+
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
+
VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE)))
 goto cleanup;
 
 if (def-ndisks) {
@@ -6130,6 +6142,436 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
 return ret;
 }
 
+#if VBOX_API_VERSION =4002000
+static
+int vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
+virDomainSnapshotPtr snapshot)
+{
+virDomainPtr dom = snapshot-domain;
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+vboxIID domiid = VBOX_IID_INITIALIZER;
+IMachine *machine = NULL;
+ISnapshot *snap = NULL;
+IMachine *snapMachine = NULL;
+vboxArray mediumAttachments = VBOX_ARRAY_INITIALIZER;
+PRUint32   maxPortPerInst[StorageBus_Floppy + 1] = {};
+PRUint32   maxSlotPerPort[StorageBus_Floppy + 1] = {};
+int diskCount = 0;
+nsresult rc;
+vboxIID snapIid = VBOX_IID_INITIALIZER;
+char *snapshotUuidStr = NULL;
+size_t i = 0;
+
+vboxIIDFromUUID(domiid, dom-uuid);
+rc = VBOX_OBJECT_GET_MACHINE(domiid.value, machine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(no domain with matching UUID));
+goto cleanup;
+}
+if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot-name)))
+goto cleanup;
+
+rc = snap-vtbl-GetId(snap, snapIid.value);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Could not get snapshot id));
+goto cleanup;
+}
+
+VBOX_UTF16_TO_UTF8(snapIid.value, snapshotUuidStr);
+rc = snap-vtbl-GetMachine(snap, snapMachine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(could not get machine));
+goto cleanup;
+}
+def-ndisks = 0;
+rc = vboxArrayGet(mediumAttachments, snapMachine, 
snapMachine-vtbl-GetMediumAttachments);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(no medium attachments));
+goto cleanup;
+}
+/* get the number of attachments */
+for (i = 0; i  mediumAttachments.count; i++) {
+IMediumAttachment *imediumattach = mediumAttachments.items[i];
+if (imediumattach) {
+IMedium *medium = NULL;
+
+rc = imediumattach-vtbl-GetMedium(imediumattach, medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get medium));
+goto cleanup;
+}
+if (medium) {
+def-ndisks++;
+VBOX_RELEASE(medium);
+}
+}
+}
+/* Allocate mem, if fails return error */
+if (VIR_ALLOC_N(def-disks, def-ndisks)  0)
+goto cleanup;
+
+if (!vboxGetMaxPortSlotValues(data-vboxObj, maxPortPerInst, 
maxSlotPerPort))
+goto cleanup;
+
+/* get the attachment details here */
+for (i = 0; i  mediumAttachments.count  diskCount  def-ndisks; i++) {
+IStorageController *storageController = NULL;
+PRUnichar *storageControllerName = NULL;
+PRUint32   deviceType = DeviceType_Null;
+PRUint32   storageBus = StorageBus_Null;
+IMedium   *disk = NULL;
+PRUnichar *childLocUtf16 = NULL;
+char  *childLocUtf8  = NULL;
+PRUint32   deviceInst = 0;
+PRInt32

[libvirt] [PATCH v7 0/4] Handling of undefine and re define snapshots with VirtualBox 4.2 or higher

2014-04-18 Thread Yohan BELLEGUIC
Hello,

This is a new series of patches in order to support undefining and redefining 
snapshots with VirtualBox 4.2 or higher.
These patches are based on Manuel Vives' patches, taking into account Daniel 
P. Berrange's remarks.

The VirtualBox API provides only high level operations to manipulate snapshots,
so it not possible to support flags like VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE and
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY with only API calls.
Following an IRC talk with Eric Blake, the decision was made to emulate these
behaviours by manipulating directly the .vbox XML files.

The first patch adds extra details in the snapshot XML returned by libvirt. We 
will need those details in order to redefine the snapshots.

The second patch adds a new API to manipulate the VirtualBox XML file. It 
provides several structs describing the VirtualBox XML file nodes and 
functions which can manipulate these structs.

The third patch adds support of the VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE 
and VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT flags in virDomainSnapshotCreateXML.
The idea is to unregister the machine, add the snapshot in the Virtualbox XML 
file and re-register the machine.
However, VirtualBox forbids a machine to have snapshots but no current 
snapshot. So, if the real current snapshot has not been redefined yet, we 
create fake disks, allowing us to have an intermediate state in order to not 
corrupt the snapshot's read-write disks. These fake disks will be deleted 
during the 
next redefine.

The fourth and last patch adds support of the 
VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY flag in virDomainSnapshotDelete.
As in the third patch, we also create fake disks to not corrupt the snapshot's 
read-write disks.

The patches were only tested with VirtualBox 4.3.10 and VirtualBox 4.2.24.

Regards
Yohan BELLEGUIC

v7:
* Add vbox_snapshot_conf.{h,c} files to (de)serialize VirtualBox XML files
* Update the code to use the API exposed by vbox_snapshot_conf.h
* Handle the fact that VirtualBox forbids a machine to have snapshots but no
current snapshot

v6:
* Rebased because of a massive change in vbox_tmpl.c due to changes in
the handling of different versions of VirtualBox

v5:
* The patches are modified according to a first review by Laine Stump:
* renamed virSearchUuid to virSearchRegex and moved it from
viruuid.{c,h} to virstring.{c,h}.
* Various fixes.

v4:
* The code is compliant with Virtualbox 4.3 API
* Some minor modifications in order to satisfy make syntax-check

v3:
* Use of STREQ_NULLABLE instead of STREQ in one case
* Fix the method for finding uuids according to Ján Tomko review

v2:
* Fix a licence problem with the method for string replacement


Manuel VIVES (1):
  vbox_tmpl.c: Better XML description for snapshots

Yohan BELLEGUIC (3):
  Add vbox_snapshot_conf struct
  vbox_tmpl.c: Patch for redefining snapshots
  vbox_tmpl.c: Add function for undefining snapshot

 po/POTFILES.in|1 +
 src/Makefile.am   |1 +
 src/vbox/vbox_snapshot_conf.c | 1383 +
 src/vbox/vbox_snapshot_conf.h |  100 ++
 src/vbox/vbox_tmpl.c  | 2225 +
 5 files changed, 3538 insertions(+), 172 deletions(-)
 create mode 100644 src/vbox/vbox_snapshot_conf.c
 create mode 100644 src/vbox/vbox_snapshot_conf.h

-- 
1.7.10.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v7 4/4] vbox_tmpl.c: Add function for undefining snapshot

2014-04-18 Thread Yohan BELLEGUIC
All snapshots information will be deleted from the vbox XML, but
differencing disks will be kept so the user will be able to redefine the
snapshot.
---
 src/vbox/vbox_tmpl.c |  453 +-
 1 file changed, 452 insertions(+), 1 deletion(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index f8667f6..c5b5074 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8347,7 +8347,443 @@ vboxDomainSnapshotDeleteTree(vboxGlobalData *data,
 return ret;
 }
 
+#if VBOX_API_VERSION = 4002000
+static int
+vboxDomainSnapshotDeleteMetadataOnly(virDomainSnapshotPtr snapshot)
+{
+/*
+ * This function will remove the node in the vbox xml corresponding to the 
snapshot.
+ * It is usually called by vboxDomainSnapshotDelete() with the flag
+ * VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY.
+ * If you want to use it anywhere else, be careful, if the snapshot you 
want to delete
+ * has children, the result is not granted, they will probably will be 
deleted in the
+ * xml, but you may have a problem with hard drives.
+ *
+ * If the snapshot which is being deleted is the current one, we will set 
the current
+ * snapshot of the machine to the parent of this snapshot. Before writing 
the modified
+ * xml file, we undefine the machine from vbox. After writing the file, we 
redefine
+ * the machine with the new file.
+ */
+
+virDomainPtr dom = snapshot-domain;
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+virDomainSnapshotDefPtr def= NULL;
+char *defXml = NULL;
+vboxIID domiid = VBOX_IID_INITIALIZER;
+nsresult rc;
+IMachine *machine = NULL;
+PRUnichar *settingsFilePathUtf16 = NULL;
+char *settingsFilepath = NULL;
+vboxSnapshotXmlMachinePtr snapshotMachineDesc = NULL;
+int isCurrent = -1;
+int it = 0;
+PRUnichar *machineNameUtf16 = NULL;
+char *machineName = NULL;
+char *nameTmpUse = NULL;
+char *machineLocationPath = NULL;
+PRUint32 aMediaSize = 0;
+IMedium **aMedia = NULL;
+
+defXml = vboxDomainSnapshotGetXMLDesc(snapshot, 0);
+if (!defXml) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get XML Desc of snapshot));
+goto cleanup;
+}
+def = virDomainSnapshotDefParseString(defXml,
+  data-caps,
+  data-xmlopt,
+  -1,
+  VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
+  VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
+if (!def) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get a virDomainSnapshotDefPtr));
+goto cleanup;
+}
+
+vboxIIDFromUUID(domiid, dom-uuid);
+rc = VBOX_OBJECT_GET_MACHINE(domiid.value, machine);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_NO_DOMAIN, %s,
+   _(no domain with matching UUID));
+goto cleanup;
+}
+rc = machine-vtbl-GetSettingsFilePath(machine, settingsFilePathUtf16);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get settings file path));
+goto cleanup;
+}
+VBOX_UTF16_TO_UTF8(settingsFilePathUtf16, settingsFilepath);
 
+/*Getting the machine name to retrieve the machine location path.*/
+rc = machine-vtbl-GetName(machine, machineNameUtf16);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot get machine name));
+goto cleanup;
+}
+VBOX_UTF16_TO_UTF8(machineNameUtf16, machineName);
+if (virAsprintf(nameTmpUse, %s.vbox, machineName)  0)
+goto cleanup;
+machineLocationPath = virStringReplace(settingsFilepath, nameTmpUse, );
+if (machineLocationPath == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to get the machine location path));
+goto cleanup;
+}
+snapshotMachineDesc = vboxSnapshotLoadVboxFile(settingsFilepath, 
machineLocationPath);
+if (!snapshotMachineDesc) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(cannot create a vboxSnapshotXmlPtr));
+goto cleanup;
+}
+
+isCurrent = isCurrentSnapshot(snapshotMachineDesc, def-name);
+if (isCurrent  0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+   _(Unable to know if the snapshot is the current 
snapshot));
+goto cleanup;
+}
+if (isCurrent) {
+/*
+ * If the snapshot is the current snapshot, it means that the machine 
has read-write
+ * disks. The first thing to do is to manipulate VirtualBox API to 
create
+ * differential read-write disks if the parent snapshot is not null.
+ */
+if (def-parent != NULL) {
+for (it = 0; it  

[libvirt] [PATCH v7 3/4] vbox_tmpl.c: Patch for redefining snapshots

2014-04-18 Thread Yohan BELLEGUIC
The machine is unregistered and its vbox XML file is changed in order to
add snapshot information. The machine is then registered with the
snapshot to redefine.
---
 src/vbox/vbox_tmpl.c |  949 +-
 1 file changed, 942 insertions(+), 7 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index ac000cf..f8667f6 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -38,12 +38,12 @@
 #include sys/types.h
 #include sys/stat.h
 #include fcntl.h
-#include libxml/xmlwriter.h
 
 #include internal.h
 #include datatypes.h
 #include domain_conf.h
 #include snapshot_conf.h
+#include vbox_snapshot_conf.h
 #include network_conf.h
 #include virerror.h
 #include domain_event.h
@@ -6023,6 +6023,930 @@ vboxDomainSnapshotGet(vboxGlobalData *data,
 return snapshot;
 }
 
+#if VBOX_API_VERSION = 4002000
+static int vboxCloseDisksRecursively(virDomainPtr dom, char *location)
+{
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+nsresult rc;
+size_t i = 0;
+PRUnichar *locationUtf = NULL;
+IMedium *medium = NULL;
+IMedium **children = NULL;
+PRUint32 childrenSize = 0;
+VBOX_UTF8_TO_UTF16(location, locationUtf);
+rc = data-vboxObj-vtbl-OpenMedium(data-vboxObj,
+ locationUtf,
+ DeviceType_HardDisk,
+ AccessMode_ReadWrite,
+ false,
+ medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s %x
+   , _(Unable to open HardDisk), rc);
+goto cleanup;
+}
+rc = medium-vtbl-GetChildren(medium, childrenSize, children);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s
+   , _(Unable to get disk children));
+goto cleanup;
+}
+for (i = 0; i  childrenSize; i++) {
+IMedium *childMedium = children[i];
+if (childMedium) {
+PRUnichar *childLocationUtf = NULL;
+char *childLocation = NULL;
+rc = childMedium-vtbl-GetLocation(childMedium, 
childLocationUtf);
+VBOX_UTF16_TO_UTF8(childLocationUtf, childLocation);
+VBOX_UTF16_FREE(childLocationUtf);
+if (vboxCloseDisksRecursively(dom, childLocation)  0) {
+VIR_DEBUG(Something wrong in the recurse);
+goto cleanup;
+}
+VIR_FREE(childLocation);
+}
+}
+rc = medium-vtbl-Close(medium);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s %x
+   , _(Unable to CLOSE HardDisk), rc);
+goto cleanup;
+}
+
+ret = 0;
+ cleanup:
+VBOX_UTF16_FREE(locationUtf);
+return ret;
+}
+
+static int
+vboxSnapshotRedefine(virDomainPtr dom,
+ virDomainSnapshotDefPtr def,
+ bool isCurrent)
+{
+/*
+ * If your snapshot has a parent,
+ * it will only be redefined if you have already
+ * redefined the parent.
+ *
+ * The general algorithm of this function is below :
+ * First of all, we are going to create our vboxSnapshotXmlMachinePtr 
struct from
+ * the machine settings path.
+ * Then, if the machine current snapshot xml file is saved in the machine 
location,
+ * it means that this snapshot was previously modified by us and has fake 
disks.
+ * Fake disks are added when the flag VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT 
was not set
+ * yet, in order to not corrupt read-only disks. The first thing to do is 
to remove those
+ * disks and restore the read-write disks, if any, in the 
vboxSnapshotXmlMachinePtr struct.
+ * We also delete the current snapshot xml file.
+ *
+ * After that, we are going to register the snapshot read-only disks that 
we want to redefine,
+ * if they are not in the media registry struct.
+ *
+ * The next step is to unregister the machine and close all disks.
+ *
+ * Then, we check if the flag VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE has 
already been set.
+ * If this flag was set, we just add read-write disks to the media registry
+ * struct. Otherwise, we save the snapshot xml file into the machine 
location in order
+ * to recover the read-write disks during the next redefine and we create 
differential disks
+ * from the snapshot read-only disks and add them to the media registry 
struct.
+ *
+ * Finally, we register the machine with the new virtualbox description 
file.
+ */
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+vboxIID domiid = VBOX_IID_INITIALIZER;
+IMachine *machine = NULL;
+nsresult rc;
+PRUnichar *settingsFilePath = NULL;
+char *settingsFilePath_Utf8 = NULL;
+vboxSnapshotXmlMachinePtr snapshotMachineDesc = NULL;
+char *currentSnapshotXmlFilePath = NULL;
+PRUnichar 

[libvirt] [PATCH v7 2/4] Add vbox_snapshot_conf struct

2014-04-18 Thread Yohan BELLEGUIC
This structure contains the data to be saved in the VirtualBox XML file
and can be manipulated with severals exposed functions.
The structure is created by vboxSnapshotLoadVboxFile taking the
machine XML file.
It also can rewrite the XML by using vboxSnapshotSaveVboxFile.
---
 po/POTFILES.in|1 +
 src/Makefile.am   |1 +
 src/vbox/vbox_snapshot_conf.c | 1383 +
 src/vbox/vbox_snapshot_conf.h |  100 +++
 4 files changed, 1485 insertions(+)
 create mode 100644 src/vbox/vbox_snapshot_conf.c
 create mode 100644 src/vbox/vbox_snapshot_conf.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 122b853..ad56b88 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -208,6 +208,7 @@ src/util/virxml.c
 src/vbox/vbox_MSCOMGlue.c
 src/vbox/vbox_XPCOMCGlue.c
 src/vbox/vbox_driver.c
+src/vbox/vbox_snapshot_conf.c
 src/vbox/vbox_tmpl.c
 src/vmware/vmware_conf.c
 src/vmware/vmware_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 21d56fc..37f4df0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -658,6 +658,7 @@ VMWARE_DRIVER_SOURCES = 
\
 VBOX_DRIVER_SOURCES =  \
vbox/vbox_glue.c vbox/vbox_glue.h   \
vbox/vbox_driver.c vbox/vbox_driver.h   \
+   vbox/vbox_snapshot_conf.c vbox/vbox_snapshot_conf.h \
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  \
diff --git a/src/vbox/vbox_snapshot_conf.c b/src/vbox/vbox_snapshot_conf.c
new file mode 100644
index 000..81e780a
--- /dev/null
+++ b/src/vbox/vbox_snapshot_conf.c
@@ -0,0 +1,1383 @@
+/*
+ * Copyright 2014, diateam (www.diateam.net)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * http://www.gnu.org/licenses/.
+ */
+
+#include config.h
+
+#include vbox_snapshot_conf.h
+#include virerror.h
+#include viralloc.h
+#include virlog.h
+#include virstring.h
+#include virxml.h
+
+#include libxml/xpathInternals.h
+#include libxml2/libxml/xmlwriter.h
+
+#define VIR_FROM_THIS   VIR_FROM_VBOX
+VIR_LOG_INIT(vbox.vbox_snapshot_conf);
+
+static vboxSnapshotXmlHardDiskPtr createvboxSnapshotXmlHardDiskPtr(xmlNodePtr 
diskNode,
+   
xmlXPathContextPtr xPathContext,
+   char 
*machineLocation)
+{
+vboxSnapshotXmlHardDiskPtr hardDisk = NULL;
+xmlNodePtr *nodes = NULL;
+char *uuid = NULL;
+char **searchTabResult = NULL;
+int resultSize = 0;
+size_t i = 0;
+int result = -1;
+char *location = NULL;
+char *tmp = NULL;
+if (VIR_ALLOC(hardDisk)  0)
+goto cleanup;
+
+xPathContext-node = diskNode;
+
+hardDisk-nchildren = virXPathNodeSet(./vbox:HardDisk, xPathContext, 
nodes);
+if (hardDisk-nchildren  VIR_ALLOC_N(hardDisk-children, 
hardDisk-nchildren)  0)
+goto cleanup;
+for (i = 0; i  hardDisk-nchildren; i++) {
+hardDisk-children[i] = createvboxSnapshotXmlHardDiskPtr(nodes[i], 
xPathContext, machineLocation);
+if (hardDisk-children[i] == NULL)
+goto cleanup;
+hardDisk-children[i]-parent = hardDisk;
+}
+uuid = virXMLPropString(diskNode, uuid);
+/*we use virStringSearch because the uuid is between brackets*/
+resultSize = virStringSearch(uuid,
+ VBOX_UUID_REGEX,
+ 1,
+ searchTabResult);
+if (resultSize != 1) {
+virReportError(VIR_ERR_XML_ERROR, %s
+   , _(Cannot parse HardDisk 'uuid' attribute));
+goto cleanup;
+}
+if (VIR_STRDUP(hardDisk-uuid, searchTabResult[0])  0)
+goto cleanup;
+
+location = virXMLPropString(diskNode, location);
+if (location == NULL) {
+virReportError(VIR_ERR_XML_ERROR, %s
+   , _(Cannot parse HardDisk 'location' attribute));
+goto cleanup;
+}
+if (location[0] != '/') {
+/*The location is a relative path, so we must change it into an 
absolute one. */
+if (virAsprintf(tmp, %s%s, machineLocation, location)  0)
+goto cleanup;