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