From: Michal Privoznik <mpriv...@redhat.com>

There's too much happening inside of vboxSnapshotRedefine(). Not
only it makes the function hard to read, but it also increases
stack size of the function. Move one part into a separate
function: vboxSnapshotCreateFakeDiffStorage()

Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
 src/vbox/vbox_common.c | 288 ++++++++++++++++++++++-------------------
 1 file changed, 157 insertions(+), 131 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 9ed972e52e..349ac832dc 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -4903,6 +4903,157 @@ vboxSnapshotAddRWDisks(struct _vboxDriver *data,
 }
 
 
+static int
+vboxSnapshotCreateFakeDiffStorage(struct _vboxDriver *data,
+                                  virDomainSnapshotDef *def,
+                                  char *machineLocationPath,
+                                  virVBoxSnapshotConfMachine 
*snapshotMachineDesc)
+{
+    virVBoxSnapshotConfHardDisk *newHardDisk = NULL;
+    int it;
+    int ret = -1;
+
+    for (it = 0; it < def->parent.dom->ndisks; it++) {
+        IMedium *medium = NULL;
+        PRUnichar *locationUtf16 = NULL;
+        char *parentUuid = NULL;
+        IMedium *newMedium = NULL;
+        PRUnichar *formatUtf16 = NULL;
+        PRUnichar *newLocation = NULL;
+        char *newLocationUtf8 = NULL;
+        resultCodeUnion resultCode;
+        char *uuid = NULL;
+        char *format = NULL;
+        char *tmp = NULL;
+        vboxIID iid, parentiid;
+        IProgress *progress = NULL;
+        PRUint32 tab[1];
+        nsresult rc;
+        g_auto(GStrv) searchResultTab = NULL;
+        ssize_t resultSize = 0;
+
+        VBOX_IID_INITIALIZE(&iid);
+        VBOX_IID_INITIALIZE(&parentiid);
+        VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, 
&locationUtf16);
+        rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
+                                              locationUtf16,
+                                              DeviceType_HardDisk,
+                                              AccessMode_ReadWrite,
+                                              &medium);
+        if (NS_FAILED(rc)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to open HardDisk"));
+            VBOX_UTF16_FREE(locationUtf16);
+            goto cleanup;
+        }
+        VBOX_UTF16_FREE(locationUtf16);
+
+        rc = gVBoxAPI.UIMedium.GetId(medium, &parentiid);
+        if (NS_FAILED(rc)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to get hard disk id"));
+            goto cleanup;
+        }
+        gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
+        vboxIIDUnalloc(&parentiid);
+        VBOX_UTF8_TO_UTF16("VDI", &formatUtf16);
+
+        newLocationUtf8 = g_strdup_printf("%sfakedisk-%d.vdi",
+                                          machineLocationPath, it);
+        VBOX_UTF8_TO_UTF16(newLocationUtf8, &newLocation);
+        rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj,
+                                                  formatUtf16,
+                                                  newLocation,
+                                                  &newMedium);
+        VBOX_UTF16_FREE(newLocation);
+        VBOX_UTF16_FREE(formatUtf16);
+        if (NS_FAILED(rc)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to create HardDisk"));
+            goto cleanup;
+        }
+
+        tab[0] = MediumVariant_Diff;
+        gVBoxAPI.UIMedium.CreateDiffStorage(medium, newMedium, 1, tab, 
&progress);
+
+        gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
+        gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
+        if (RC_FAILED(resultCode)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Error while creating diff storage, rc=%1$08x"),
+                            resultCode.uResultCode);
+            goto cleanup;
+        }
+        VBOX_RELEASE(progress);
+        /*
+         * The differential newHardDisk is created, we add it to the
+         * media registry and the machine storage controllers.
+         */
+
+        newHardDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
+
+        rc = gVBoxAPI.UIMedium.GetId(newMedium, &iid);
+        if (NS_FAILED(rc)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to get medium uuid"));
+            goto cleanup;
+        }
+        gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
+        newHardDisk->uuid = uuid;
+        vboxIIDUnalloc(&iid);
+
+        newHardDisk->location = g_strdup(newLocationUtf8);
+
+        rc = gVBoxAPI.UIMedium.GetFormat(newMedium, &formatUtf16);
+        VBOX_UTF16_TO_UTF8(formatUtf16, &format);
+        newHardDisk->format = format;
+        VBOX_UTF16_FREE(formatUtf16);
+
+        if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(newHardDisk,
+                                                          
snapshotMachineDesc->mediaRegistry,
+                                                          parentUuid) < 0) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to add hard disk to the media 
registry"));
+            goto cleanup;
+        }
+        newHardDisk = NULL;  /* Consumed by above */
+        /* Adding the fake disk to the machine storage controllers */
+
+        resultSize = virStringSearch(snapshotMachineDesc->storageController,
+                                     VBOX_UUID_REGEX,
+                                     it + 1,
+                                     &searchResultTab);
+        if (resultSize != it + 1) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR,
+                            _("Unable to find UUID %1$s"), 
searchResultTab[it]);
+            goto cleanup;
+        }
+
+        tmp = virStringReplace(snapshotMachineDesc->storageController,
+                               searchResultTab[it],
+                               uuid);
+        VIR_FREE(snapshotMachineDesc->storageController);
+        if (!tmp)
+            goto cleanup;
+        snapshotMachineDesc->storageController = g_strdup(tmp);
+
+        VIR_FREE(tmp);
+        /* Closing the "fake" disk */
+        rc = gVBoxAPI.UIMedium.Close(newMedium);
+        if (NS_FAILED(rc)) {
+            vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to close the new medium"));
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+ cleanup:
+    virVboxSnapshotConfHardDiskFree(newHardDisk);
+    return ret;
+}
+
+
 static int
 vboxSnapshotRedefine(virDomainPtr dom,
                      virDomainSnapshotDef *def,
@@ -4950,7 +5101,6 @@ vboxSnapshotRedefine(virDomainPtr dom,
     unsigned char snapshotUuid[VIR_UUID_BUFLEN];
     virVBoxSnapshotConfHardDisk **hardDiskToOpen = NULL;
     size_t hardDiskToOpenSize = 0;
-    virVBoxSnapshotConfHardDisk *newHardDisk = NULL;
     g_auto(GStrv) searchResultTab = NULL;
     ssize_t resultSize = 0;
     int it = 0;
@@ -5224,137 +5374,14 @@ vboxSnapshotRedefine(virDomainPtr dom,
         }
     } else {
         char *snapshotContent;
+
         /* Create a "fake" disk to avoid corrupting children snapshot disks. */
-        for (it = 0; it < def->parent.dom->ndisks; it++) {
-            IMedium *medium = NULL;
-            PRUnichar *locationUtf16 = NULL;
-            char *parentUuid = NULL;
-            IMedium *newMedium = NULL;
-            PRUnichar *formatUtf16 = NULL;
-            PRUnichar *newLocation = NULL;
-            char *newLocationUtf8 = NULL;
-            resultCodeUnion resultCode;
-            char *uuid = NULL;
-            char *format = NULL;
-            char *tmp = NULL;
-            vboxIID iid, parentiid;
-            IProgress *progress = NULL;
-            PRUint32 tab[1];
-
-            VBOX_IID_INITIALIZE(&iid);
-            VBOX_IID_INITIALIZE(&parentiid);
-            VBOX_UTF8_TO_UTF16(def->parent.dom->disks[it]->src->path, 
&locationUtf16);
-            rc = gVBoxAPI.UIVirtualBox.OpenMedium(data->vboxObj,
-                                                  locationUtf16,
-                                                  DeviceType_HardDisk,
-                                                  AccessMode_ReadWrite,
-                                                  &medium);
-            if (NS_FAILED(rc)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to open HardDisk"));
-                VBOX_UTF16_FREE(locationUtf16);
-                goto cleanup;
-            }
-            VBOX_UTF16_FREE(locationUtf16);
-
-            rc = gVBoxAPI.UIMedium.GetId(medium, &parentiid);
-            if (NS_FAILED(rc)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to get hard disk id"));
-                goto cleanup;
-            }
-            gVBoxAPI.UIID.vboxIIDToUtf8(data, &parentiid, &parentUuid);
-            vboxIIDUnalloc(&parentiid);
-            VBOX_UTF8_TO_UTF16("VDI", &formatUtf16);
-
-            newLocationUtf8 = g_strdup_printf("%sfakedisk-%d.vdi",
-                                              machineLocationPath, it);
-            VBOX_UTF8_TO_UTF16(newLocationUtf8, &newLocation);
-            rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj,
-                                                      formatUtf16,
-                                                      newLocation,
-                                                      &newMedium);
-            VBOX_UTF16_FREE(newLocation);
-            VBOX_UTF16_FREE(formatUtf16);
-            if (NS_FAILED(rc)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to create HardDisk"));
-                goto cleanup;
-            }
-
-            tab[0] = MediumVariant_Diff;
-            gVBoxAPI.UIMedium.CreateDiffStorage(medium, newMedium, 1, tab, 
&progress);
-
-            gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
-            gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
-            if (RC_FAILED(resultCode)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Error while creating diff storage, 
rc=%1$08x"),
-                                resultCode.uResultCode);
-                goto cleanup;
-            }
-            VBOX_RELEASE(progress);
-            /*
-             * The differential newHardDisk is created, we add it to the
-             * media registry and the machine storage controllers.
-             */
-
-            newHardDisk = g_new0(virVBoxSnapshotConfHardDisk, 1);
-
-            rc = gVBoxAPI.UIMedium.GetId(newMedium, &iid);
-            if (NS_FAILED(rc)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to get medium uuid"));
-                goto cleanup;
-            }
-            gVBoxAPI.UIID.vboxIIDToUtf8(data, &iid, &uuid);
-            newHardDisk->uuid = uuid;
-            vboxIIDUnalloc(&iid);
-
-            newHardDisk->location = g_strdup(newLocationUtf8);
-
-            rc = gVBoxAPI.UIMedium.GetFormat(newMedium, &formatUtf16);
-            VBOX_UTF16_TO_UTF8(formatUtf16, &format);
-            newHardDisk->format = format;
-            VBOX_UTF16_FREE(formatUtf16);
-
-            if (virVBoxSnapshotConfAddHardDiskToMediaRegistry(newHardDisk,
-                                           snapshotMachineDesc->mediaRegistry,
-                                           parentUuid) < 0) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to add hard disk to the media 
registry"));
-                goto cleanup;
-            }
-            newHardDisk = NULL;  /* Consumed by above */
-            /* Adding the fake disk to the machine storage controllers */
-
-            resultSize = 
virStringSearch(snapshotMachineDesc->storageController,
-                                         VBOX_UUID_REGEX,
-                                         it + 1,
-                                         &searchResultTab);
-            if (resultSize != it + 1) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("Unable to find UUID %1$s"), 
searchResultTab[it]);
-                goto cleanup;
-            }
-
-            tmp = virStringReplace(snapshotMachineDesc->storageController,
-                                   searchResultTab[it],
-                                   uuid);
-            VIR_FREE(snapshotMachineDesc->storageController);
-            if (!tmp)
-                goto cleanup;
-            snapshotMachineDesc->storageController = g_strdup(tmp);
-
-            VIR_FREE(tmp);
-            /* Closing the "fake" disk */
-            rc = gVBoxAPI.UIMedium.Close(newMedium);
-            if (NS_FAILED(rc)) {
-                vboxReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                                _("Unable to close the new medium"));
-                goto cleanup;
-            }
+        if (vboxSnapshotCreateFakeDiffStorage(data, def,
+                                              machineLocationPath,
+                                              snapshotMachineDesc) < 0) {
+            goto cleanup;
         }
+
         /*
          * We save the snapshot xml file to retrieve the real read-write disk 
during the
          * next define. This file is saved as 
"'machineLocation'/snapshot-'uuid'.xml"
@@ -5443,7 +5470,6 @@ vboxSnapshotRedefine(virDomainPtr dom,
     VIR_FREE(currentSnapshotXmlFilePath);
     VBOX_UTF16_FREE(machineNameUtf16);
     VBOX_UTF8_FREE(machineName);
-    virVboxSnapshotConfHardDiskFree(newHardDisk);
     VIR_FREE(hardDiskToOpen);
     VIR_FREE(newSnapshotPtr);
     VIR_FREE(machineLocationPath);
-- 
2.49.0

Reply via email to