[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