[libvirt] [PATCHv2 RESEND 3/5] vbox_tmpl.c: Better XML description for snapshots
Guido Günther
agx at sigxcpu.org
Tue Sep 3 09:34:03 UTC 2013
Hi,
On Mon, Sep 02, 2013 at 06:05:51PM +0200, Manuel VIVES wrote:
> It will be needed for the futur patches because we will
> redefine snapshots
> ---
> src/conf/domain_conf.c | 20 ++-
> src/vbox/vbox_tmpl.c | 427 ++++++++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 427 insertions(+), 20 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index f1623f1..c98ff63 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -16810,15 +16810,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) {
Maybe I'm missing something but this looks like:
if (STREQ_NULLABLE(def->os.type, "hvm") &&
def->nconsoles == 0 &&
def->nserials > 0) {
is simpler.
Cheers,
-- Guido
> + 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..ded179f 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) {
> @@ -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,344 @@ 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;
> + size_t i = 0;
> + 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 (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 (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];
> + size_t j = 0;
> + size_t k = 0;
> + 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 (j = 0; j < children.count; ++j) {
> + IMedium *child = children.items[j];
> + for (k = 0; k < snapshotIids.count; ++k) {
> + PRUnichar *diskSnapId = snapshotIids.items[k];
> + 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 (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 +6367,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 +6385,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 +6483,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 +7189,8 @@ cleanup:
> return ret;
> }
>
> +
> +
> static int
> vboxDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
> unsigned int flags)
> @@ -6839,8 +7226,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 +9050,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 +9207,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 +9237,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
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>
More information about the libvir-list
mailing list