All the informations concerning snapshots (and snapshot disks)
will be deleted from the vbox xml. But the differencing disks will be
kept so you will be able to redefine the snapshots.
---
src/vbox/vbox_tmpl.c | 448 +-
1 file changed, 447 insertions(+), 1 deletion(-)
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 50b541d..6171a79 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -6176,6 +6176,68 @@ vboxSnapshotXmlAppendDiskToMediaRegistry(xmlNodePtr
*inMediaRegistry,
}
}
+
+static void
+vboxRemoveAllDisksExceptParentFromMediaRegistry(xmlNodePtr mediaRegistryNode){
+xmlNodePtr cur_node = NULL;
+for (cur_node = mediaRegistryNode; cur_node; cur_node = cur_node-next) {
+if (cur_node) {
+if (cur_node-type == XML_ELEMENT_NODE
+ !xmlStrcmp(cur_node-name, (const xmlChar *) HardDisk)) {
+xmlNodePtr child = NULL;
+for (child = cur_node-children; child; child = child-next) {
+/*We look over all the children
+ *If there is a node element, we delete it
+ */
+if (child-type == XML_ELEMENT_NODE) {
+xmlUnlinkNode(child);
+xmlFreeNode(child);
+}
+}
+}
+}
+if ((cur_node-children))
+
vboxRemoveAllDisksExceptParentFromMediaRegistry((cur_node-children));
+}
+}
+
+static void
+vboxRemoveDiskFromMediaRegistryIfNoChildren(xmlNodePtr mediaRegistryNode,
+char *diskLocation)
+{
+/*
+ *This function will remove a disk from the media registry only if it
doesn't
+ *have any children
+ */
+xmlNodePtr cur_node = NULL;
+for (cur_node = mediaRegistryNode; cur_node; cur_node = cur_node-next) {
+if (cur_node) {
+if (cur_node-type == XML_ELEMENT_NODE
+ !xmlStrcmp(cur_node-name, (const xmlChar *) HardDisk)
+ xmlHasProp(cur_node, BAD_CAST location) != NULL
+ strstr(diskLocation, (char *)xmlHasProp(cur_node, BAD_CAST
location)-children-content) != NULL) {
+
+xmlNodePtr child = NULL;
+bool deleteNode = true;
+for (child = cur_node-children; child; child = child-next) {
+/*We look over all the children
+ *If there is a node element, we don't delete it
+ */
+if (child-type == XML_ELEMENT_NODE)
+deleteNode = false;
+}
+if (deleteNode) {
+xmlUnlinkNode(cur_node);
+xmlFreeNode(cur_node);
+}
+return;
+}
+}
+if ((cur_node-children))
+vboxRemoveDiskFromMediaRegistryIfNoChildren((cur_node-children),
diskLocation);
+}
+}
+
static int
vboxSnapshotGenerateVboxXML(xmlNodePtr rootElementVboxXML,
char *storageControllerString,
@@ -8412,8 +8474,377 @@ cleanup:
vboxArrayRelease(children);
return ret;
}
+#if VBOX_API_VERSION = 4002000
+static int
+vboxCloseDisk(virDomainPtr dom,
+ IMedium *baseDisk) {
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+nsresult rc;
+vboxArray childrenDiskArray = VBOX_ARRAY_INITIALIZER;
+size_t i = 0;
+if (!baseDisk)
+goto cleanup;
+
+rc = vboxArrayGet(childrenDiskArray, baseDisk,
baseDisk-vtbl-GetChildren);
+if (NS_FAILED(rc)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, %s,
+ _(could not get children disks));
+goto cleanup;
+}
+for (i = 0; i childrenDiskArray.count; ++i)
+vboxCloseDisk(dom, childrenDiskArray.items[i]);
+
+baseDisk-vtbl-Close(baseDisk);
+ret = 0;
+cleanup:
+vboxArrayRelease(childrenDiskArray);
+return ret;
+}
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, we will set the
current snapshot of the machine to
+ *its parent.
+ *
+ *Before the writing of the modified xml file, we undefine the machine
from vbox
+ *After the modification, we redefine the machine
+ */
+
+virDomainPtr dom = snapshot-domain;
+VBOX_OBJECT_CHECK(dom-conn, int, -1);
+IMachine *machine = NULL;
+IMachine