[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [RESEND PATCH 3/5] vbox_tmpl.c: Better XML description for snapshots



It will be needed for the futur patches because we will
redefine snapshots
---
 src/conf/domain_conf.c |   20 ++-
 src/vbox/vbox_tmpl.c   |  426 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 425 insertions(+), 21 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 57cd9b1..5a5783f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16689,15 +16689,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
         if (virDomainChrDefFormat(buf, &console, flags) < 0)
             goto error;
     }
-    if (STREQ(def->os.type, "hvm") &&
-        def->nconsoles == 0 &&
-        def->nserials > 0) {
-        virDomainChrDef console;
-        memcpy(&console, def->serials[n], sizeof(console));
-        console.deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
-        console.targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
-        if (virDomainChrDefFormat(buf, &console, flags) < 0)
-            goto error;
+    if (def->os.type) {
+        if (STREQ(def->os.type, "hvm") &&
+            def->nconsoles == 0 &&
+            def->nserials > 0) {
+            virDomainChrDef console;
+            memcpy(&console, def->serials[n], sizeof(console));
+            console.deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
+            console.targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
+            if (virDomainChrDefFormat(buf, &console, flags) < 0)
+                goto error;
+        }
     }
 
     for (n = 0; n < def->nchannels; n++)
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 5e5ea85..3dd9e8a 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 == 2002
@@ -271,10 +274,16 @@ static vboxGlobalData *g_pVBoxGlobalData = NULL;
 
 #endif /* VBOX_API_VERSION >= 4000 */
 
+#define reportInternalErrorIfNS_FAILED(message) \
+    if (NS_FAILED(rc)) { \
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(message)); \
+        goto cleanup; \
+    }
+
+
 static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml);
 static int vboxDomainCreate(virDomainPtr dom);
 static int vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags);
-
 static void vboxDriverLock(vboxGlobalData *data) {
     virMutexLock(&data->lock);
 }
@@ -283,6 +292,12 @@ static void vboxDriverUnlock(vboxGlobalData *data) {
     virMutexUnlock(&data->lock);
 }
 
+typedef enum {
+    VBOX_STORAGE_DELETE_FLAG = 0,
+#if VBOX_API_VERSION >= 4002
+    VBOX_STORAGE_CLOSE_FLAG = 1,
+#endif
+} vboxStorageDeleteOrCloseFlags;
 #if VBOX_API_VERSION == 2002
 
 static void nsIDtoChar(unsigned char *uuid, const nsID *iid) {
@@ -3395,9 +3410,9 @@ sharedFoldersCleanup:
                                             VBOX_UTF8_FREE(productIdUtf8);
 
                                             USBFilterCount++;
-                                        }
                                     }
                                 }
+                                }
                             }
                         }
                     }
@@ -5907,7 +5922,8 @@ 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) {
@@ -5915,7 +5931,6 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
                        _("disk snapshots not supported yet"));
         goto cleanup;
     }
-
     vboxIIDFromUUID(&domiid, dom->uuid);
     rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
     if (NS_FAILED(rc)) {
@@ -5923,7 +5938,6 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
                        _("no domain with matching UUID"));
         goto cleanup;
     }
-
     rc = machine->vtbl->GetState(machine, &state);
     if (NS_FAILED(rc)) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -5998,6 +6012,341 @@ cleanup:
     return ret;
 }
 
+#if VBOX_API_VERSION >=4002
+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;
+    bool error = false;
+    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;
+    vboxIIDFromUUID(&domiid, dom->uuid);
+    rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
+    reportInternalErrorIfNS_FAILED("no domain with matching UUID");
+    if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name))) {
+        ret = -1;
+        goto cleanup;
+    }
+    rc = snap->vtbl->GetId(snap, &snapIid.value);
+    reportInternalErrorIfNS_FAILED("Could not get snapshot id");
+
+    VBOX_UTF16_TO_UTF8(snapIid.value, &snapshotUuidStr);
+    rc = snap->vtbl->GetMachine(snap, &snapMachine);
+    reportInternalErrorIfNS_FAILED("could not get machine");
+    def->ndisks = 0;
+    rc = vboxArrayGet(&mediumAttachments, snapMachine, snapMachine->vtbl->GetMediumAttachments);
+    reportInternalErrorIfNS_FAILED("no medium attachments");
+    /* get the number of attachments */
+    for (size_t i = 0; i < mediumAttachments.count; i++) {
+        IMediumAttachment *imediumattach = mediumAttachments.items[i];
+        if (imediumattach) {
+            IMedium *medium = NULL;
+
+            rc = imediumattach->vtbl->GetMedium(imediumattach, &medium);
+            reportInternalErrorIfNS_FAILED("cannot get medium");
+            if (medium) {
+                def->ndisks++;
+                VBOX_RELEASE(medium);
+            }
+        }
+    }
+    /* Allocate mem, if fails return error */
+    if (VIR_ALLOC_N(def->disks, def->ndisks) < 0) {
+        virReportOOMError();
+        error = true;
+    }
+    if (!error)
+        error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, maxSlotPerPort);
+
+    /* get the attachment details here */
+    for (size_t i = 0; i < mediumAttachments.count && diskCount < def->ndisks && !error; 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    devicePort     = 0;
+        PRInt32    deviceSlot     = 0;
+        vboxArray children = VBOX_ARRAY_INITIALIZER;
+        vboxArray snapshotIids = VBOX_ARRAY_INITIALIZER;
+        IMediumAttachment *imediumattach = mediumAttachments.items[i];
+        if (!imediumattach)
+            continue;
+        rc = imediumattach->vtbl->GetMedium(imediumattach, &disk);
+        reportInternalErrorIfNS_FAILED("cannot get medium");
+        if (!disk)
+            continue;
+        rc = imediumattach->vtbl->GetController(imediumattach, &storageControllerName);
+        reportInternalErrorIfNS_FAILED("cannot get medium");
+        if (!storageControllerName) {
+            VBOX_RELEASE(disk);
+            continue;
+        }
+        rc= vboxArrayGet(&children, disk, disk->vtbl->GetChildren);
+        reportInternalErrorIfNS_FAILED("cannot get children disk");
+        rc = vboxArrayGetWithPtrArg(&snapshotIids, disk, disk->vtbl->GetSnapshotIds, domiid.value);
+        reportInternalErrorIfNS_FAILED("cannot get snapshot ids");
+        for (size_t it = 0; it < children.count; ++it) {
+            IMedium *child = children.items[it];
+            for (size_t j = 0; j < snapshotIids.count; ++j) {
+                PRUnichar *diskSnapId = snapshotIids.items[j];
+                char *diskSnapIdStr = NULL;
+                VBOX_UTF16_TO_UTF8(diskSnapId, &diskSnapIdStr);
+                if (STREQ(diskSnapIdStr, snapshotUuidStr)) {
+                    rc = machine->vtbl->GetStorageControllerByName(machine,
+                                                              storageControllerName,
+                                                              &storageController);
+                    VBOX_UTF16_FREE(storageControllerName);
+                    if (!storageController) {
+                        VBOX_RELEASE(child);
+                        break;
+                    }
+                    rc = child->vtbl->GetLocation(child, &childLocUtf16);
+                    reportInternalErrorIfNS_FAILED("cannot get disk location");
+                    VBOX_UTF16_TO_UTF8(childLocUtf16, &childLocUtf8);
+                    VBOX_UTF16_FREE(childLocUtf16);
+                    ignore_value(VIR_STRDUP(def->disks[diskCount].file, childLocUtf8));
+                    if (!(def->disks[diskCount].file)) {
+                        VBOX_RELEASE(child);
+                        VBOX_RELEASE(storageController);
+                        virReportOOMError();
+                        error = true;
+                        break;
+                    }
+                    VBOX_UTF8_FREE(childLocUtf8);
+
+                    rc = storageController->vtbl->GetBus(storageController, &storageBus);
+                    reportInternalErrorIfNS_FAILED("cannot get storage controller bus");
+                    rc = imediumattach->vtbl->GetType(imediumattach, &deviceType);
+                    reportInternalErrorIfNS_FAILED("cannot get medium attachment type");
+                    rc = imediumattach->vtbl->GetPort(imediumattach, &devicePort);
+                    reportInternalErrorIfNS_FAILED("cannot get medium attachchment type");
+                    rc = imediumattach->vtbl->GetDevice(imediumattach, &deviceSlot);
+                    reportInternalErrorIfNS_FAILED("cannot get medium attachment device");
+                    def->disks[diskCount].name = vboxGenerateMediumName(storageBus,
+                                                                        deviceInst,
+                                                                        devicePort,
+                                                                        deviceSlot,
+                                                                        maxPortPerInst,
+                                                                        maxSlotPerPort);
+                }
+                VBOX_UTF8_FREE(diskSnapIdStr);
+            }
+        }
+        VBOX_RELEASE(storageController);
+        VBOX_RELEASE(disk);
+        diskCount++;
+    }
+    vboxArrayRelease(&mediumAttachments);
+    /* cleanup on error */
+    if (error) {
+        for (size_t i = 0; i < def->dom->ndisks; i++) {
+            VIR_FREE(def->dom->disks[i]);
+        }
+        VIR_FREE(def->dom->disks);
+        def->dom->ndisks = 0;
+        return -1;
+    }
+    return 0;
+
+cleanup:
+    VBOX_RELEASE(snap);
+    return ret;
+}
+
+static
+int vboxSnapshotGetReadOnlyDisks(virDomainSnapshotPtr snapshot,
+                                    virDomainSnapshotDefPtr def)
+{
+    virDomainPtr dom = snapshot->domain;
+    VBOX_OBJECT_CHECK(dom->conn, int, -1);
+    vboxIID domiid = VBOX_IID_INITIALIZER;
+    ISnapshot *snap = NULL;
+    IMachine *machine = NULL;
+    IMachine *snapMachine = NULL;
+    IStorageController *storageController = NULL;
+    IMedium   *disk         = NULL;
+    nsresult rc;
+    vboxIIDFromUUID(&domiid, dom->uuid);
+    bool error = false;
+    vboxArray mediumAttachments         = VBOX_ARRAY_INITIALIZER;
+    size_t i = 0;
+    PRUint32   maxPortPerInst[StorageBus_Floppy + 1] = {};
+    PRUint32   maxSlotPerPort[StorageBus_Floppy + 1] = {};
+    int diskCount = 0;
+    rc = VBOX_OBJECT_GET_MACHINE(domiid.value, &machine);
+    if (NS_FAILED(rc)) {
+        virReportError(VIR_ERR_NO_DOMAIN, "%s",
+                       _("no domain with matching UUID"));
+        return -1;
+    }
+
+    if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
+        return -1;
+    rc = snap->vtbl->GetMachine(snap, &snapMachine);
+    reportInternalErrorIfNS_FAILED("cannot get machine");
+    /*
+     * Get READ ONLY disks
+     * In the snapshot metadata, these are the disks written inside the <domain> node
+    */
+    rc = vboxArrayGet(&mediumAttachments, snapMachine, snapMachine->vtbl->GetMediumAttachments);
+    reportInternalErrorIfNS_FAILED("cannot get medium attachments");
+    /* 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);
+            reportInternalErrorIfNS_FAILED("cannot get medium");
+            if (medium) {
+                def->dom->ndisks++;
+                VBOX_RELEASE(medium);
+            }
+        }
+    }
+
+    /* 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) {
+                virReportOOMError();
+                error = true;
+                break;
+    }
+        }
+    } else {
+        virReportOOMError();
+        error = true;
+    }
+
+    if (!error)
+        error = !vboxGetMaxPortSlotValues(data->vboxObj, maxPortPerInst, maxSlotPerPort);
+
+    /* get the attachment details here */
+    for (i = 0; i < mediumAttachments.count && diskCount < def->dom->ndisks && !error; i++) {
+        PRUnichar *storageControllerName = NULL;
+        PRUint32   deviceType     = DeviceType_Null;
+        PRUint32   storageBus     = StorageBus_Null;
+        PRBool     readOnly       = PR_FALSE;
+        PRUnichar *mediumLocUtf16 = NULL;
+        char      *mediumLocUtf8  = NULL;
+        PRUint32   deviceInst     = 0;
+        PRInt32    devicePort     = 0;
+        PRInt32    deviceSlot     = 0;
+        IMediumAttachment *imediumattach = mediumAttachments.items[i];
+        if (!imediumattach)
+            continue;
+        rc = imediumattach->vtbl->GetMedium(imediumattach, &disk);
+        reportInternalErrorIfNS_FAILED("cannot get medium");
+        if (!disk)
+            continue;
+        rc = imediumattach->vtbl->GetController(imediumattach, &storageControllerName);
+        reportInternalErrorIfNS_FAILED("cannot get storage controller name");
+        if (!storageControllerName) {
+            continue;
+        }
+        rc = machine->vtbl->GetStorageControllerByName(machine,
+                                                  storageControllerName,
+                                                  &storageController);
+        reportInternalErrorIfNS_FAILED("cannot get storage controller");
+        VBOX_UTF16_FREE(storageControllerName);
+        if (!storageController) {
+            continue;
+        }
+        rc = disk->vtbl->GetLocation(disk, &mediumLocUtf16);
+        reportInternalErrorIfNS_FAILED("cannot get disk location");
+        VBOX_UTF16_TO_UTF8(mediumLocUtf16, &mediumLocUtf8);
+        VBOX_UTF16_FREE(mediumLocUtf16);
+        ignore_value(VIR_STRDUP(def->dom->disks[diskCount]->src, mediumLocUtf8));
+
+        if (!(def->dom->disks[diskCount]->src)) {
+            virReportOOMError();
+            ret = -1;
+            goto cleanup;
+        }
+        VBOX_UTF8_FREE(mediumLocUtf8);
+
+        rc = storageController->vtbl->GetBus(storageController, &storageBus);
+        reportInternalErrorIfNS_FAILED("cannot get storage controller bus");
+        if (storageBus == StorageBus_IDE) {
+            def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_IDE;
+        } else if (storageBus == StorageBus_SATA) {
+            def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SATA;
+        } else if (storageBus == StorageBus_SCSI) {
+            def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SCSI;
+        } else if (storageBus == StorageBus_Floppy) {
+            def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_FDC;
+        }
+
+        rc = imediumattach->vtbl->GetType(imediumattach, &deviceType);
+        reportInternalErrorIfNS_FAILED("cannot get medium attachment type");
+        if (deviceType == DeviceType_HardDisk)
+            def->dom->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_DISK;
+        else if (deviceType == DeviceType_Floppy)
+            def->dom->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
+        else if (deviceType == DeviceType_DVD)
+            def->dom->disks[diskCount]->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
+
+        rc = imediumattach->vtbl->GetPort(imediumattach, &devicePort);
+        reportInternalErrorIfNS_FAILED("cannot get medium attachment port");
+        rc = imediumattach->vtbl->GetDevice(imediumattach, &deviceSlot);
+        reportInternalErrorIfNS_FAILED("cannot get device");
+        rc = disk->vtbl->GetReadOnly(disk, &readOnly);
+        reportInternalErrorIfNS_FAILED("cannot get read only attribute");
+        if (readOnly == PR_TRUE)
+            def->dom->disks[diskCount]->readonly = true;
+        def->dom->disks[diskCount]->type = VIR_DOMAIN_DISK_TYPE_FILE;
+        def->dom->disks[diskCount]->dst = vboxGenerateMediumName(storageBus,
+                                                                 deviceInst,
+                                                                 devicePort,
+                                                                 deviceSlot,
+                                                                 maxPortPerInst,
+                                                                 maxSlotPerPort);
+        if (!def->dom->disks[diskCount]->dst) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not generate medium name for the disk "
+                             "at: controller instance:%u, port:%d, slot:%d"),
+                           deviceInst, devicePort, deviceSlot);
+            ret = -1;
+            goto cleanup;
+        }
+        diskCount ++;
+    }
+    /* cleanup on error */
+    if (error) {
+        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;
+        goto cleanup;
+    }
+    ret = 0;
+cleanup:
+    VBOX_RELEASE(disk);
+    VBOX_RELEASE(storageController);
+    vboxArrayRelease(&mediumAttachments);
+    VBOX_RELEASE(snap);
+    return ret;
+}
+#endif
+
 static char *
 vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
                              unsigned int flags)
@@ -6015,6 +6364,10 @@ vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
     PRInt64 timestamp;
     PRBool online = PR_FALSE;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
+#if VBOX_API_VERSION >=4002
+    PRUint32 memorySize                 = 0;
+    PRUint32 CPUCount                 = 0;
+#endif
 
     virCheckFlags(0, NULL);
 
@@ -6029,11 +6382,40 @@ vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
     if (!(snap = vboxDomainSnapshotGet(data, dom, machine, snapshot->name)))
         goto cleanup;
 
-    if (VIR_ALLOC(def) < 0)
+    if (VIR_ALLOC(def) < 0
+        || VIR_ALLOC(def->dom) < 0)
         goto cleanup;
     if (VIR_STRDUP(def->name, snapshot->name) < 0)
         goto cleanup;
 
+#if VBOX_API_VERSION >=4002
+    /* Register def->dom properties for them to be saved inside the snapshot XMl
+     * Otherwise, there is a problem while parsing the xml
+     */
+    def->dom->virtType = VIR_DOMAIN_VIRT_VBOX;
+    def->dom->id = dom->id;
+    memcpy(def->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
+    ignore_value(VIR_STRDUP(def->dom->name, dom->name));
+    machine->vtbl->GetMemorySize(machine, &memorySize);
+    def->dom->mem.cur_balloon = memorySize * 1024;
+    /* Currently setting memory and maxMemory as same, cause
+     * the notation here seems to be inconsistent while
+     * reading and while dumping xml
+     */
+    def->dom->mem.max_balloon = memorySize * 1024;
+    ignore_value(VIR_STRDUP(def->dom->os.type, "hvm"));
+    def->dom->os.arch = virArchFromHost();
+    machine->vtbl->GetCPUCount(machine, &CPUCount);
+    def->dom->maxvcpus = def->dom->vcpus = CPUCount;
+    if (vboxSnapshotGetReadWriteDisks(def, snapshot) < 0) {
+        VIR_DEBUG("Could not get read write disks for snapshot");
+    }
+
+    if (vboxSnapshotGetReadOnlyDisks(snapshot, def) <0) {
+        VIR_DEBUG("Could not get Readonly disks for snapshot");
+    }
+#endif /* VBOX_API_VERSION >= 4002 */
+
     rc = snap->vtbl->GetDescription(snap, &str16);
     if (NS_FAILED(rc)) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -6098,8 +6480,8 @@ vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
         def->state = VIR_DOMAIN_SHUTOFF;
 
     virUUIDFormat(dom->uuid, uuidstr);
+    memcpy(def->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
     ret = virDomainSnapshotDefFormat(uuidstr, def, flags, 0);
-
 cleanup:
     virDomainSnapshotDefFree(def);
     VBOX_RELEASE(parent);
@@ -6804,6 +7186,8 @@ cleanup:
     return ret;
 }
 
+
+
 static int
 vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                          unsigned int flags)
@@ -6839,8 +7223,9 @@ vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
         goto cleanup;
     }
 
-    /* VBOX snapshots do not require any libvirt metadata, making this
-     * flag trivial once we know we have a valid snapshot.  */
+    /* In case we just want to delete the metadata, we will edit the vbox file in order
+     *to remove the node concerning the snapshot
+    */
     if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY) {
         ret = 0;
         goto cleanup;
@@ -8662,8 +9047,9 @@ cleanup:
     return ret;
 }
 
-static int vboxStorageVolDelete(virStorageVolPtr vol,
-                                unsigned int flags)
+static int vboxStorageDeleteOrClose(virStorageVolPtr vol,
+                                    unsigned int flags,
+                                    unsigned int flagDeleteOrClose)
 {
     VBOX_OBJECT_CHECK(vol->conn, int, -1);
     vboxIID hddIID = VBOX_IID_INITIALIZER;
@@ -8818,8 +9204,18 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
 
             if (machineIdsSize == 0 || machineIdsSize == deregister) {
                 IProgress *progress = NULL;
-
+#if VBOX_API_VERSION >= 4002
+                if (flagDeleteOrClose & VBOX_STORAGE_CLOSE_FLAG) {
+                    rc = hardDisk->vtbl->Close(hardDisk);
+                    if (NS_SUCCEEDED(rc)) {
+                        DEBUGIID("HardDisk closed, UUID", hddIID.value);
+                        ret = 0;
+                    }
+                }
+#endif
+                if (flagDeleteOrClose & VBOX_STORAGE_DELETE_FLAG){
                 rc = hardDisk->vtbl->DeleteStorage(hardDisk, &progress);
+                }
 
                 if (NS_SUCCEEDED(rc) && progress) {
                     progress->vtbl->WaitForCompletion(progress, -1);
@@ -8838,6 +9234,12 @@ static int vboxStorageVolDelete(virStorageVolPtr vol,
     return ret;
 }
 
+static int vboxStorageVolDelete(virStorageVolPtr vol,
+                                unsigned int flags)
+{
+    return vboxStorageDeleteOrClose(vol, flags, VBOX_STORAGE_DELETE_FLAG);
+}
+
 static int vboxStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info) {
     VBOX_OBJECT_CHECK(vol->conn, int, -1);
     IHardDisk *hardDisk  = NULL;
-- 
1.7.10.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]