VirtualBox

Changeset 18388 in vbox for trunk/src


Ignore:
Timestamp:
Mar 27, 2009 1:11:42 PM (16 years ago)
Author:
vboxsync
Message:

API/HardDisk: merge the functionality of cloneTo and flattenTo, and extend the existing flattenTo code to do the job.

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp

    r18177 r18388  
    543543
    544544        ComPtr<IProgress> progress;
    545         CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, DiskVariant, progress.asOutParam()));
     545        CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, DiskVariant, NULL, progress.asOutParam()));
    546546
    547547        showProgress(progress);
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r18376 r18388  
    21812181                            if (FAILED(rc)) throw rc;
    21822182                            /* Clone the source disk image */
    2183                             rc = srcHdVBox->CloneTo(dstHdVBox, HardDiskVariant_Standard, pProgress2.asOutParam());
     2183                            rc = srcHdVBox->CloneTo(dstHdVBox, HardDiskVariant_Standard, NULL, pProgress2.asOutParam());
    21842184                            if (FAILED(rc)) throw rc;
    21852185
     
    30713071            {
    30723072                // create a flat copy of the source disk image
    3073                 rc = pSourceDisk->FlattenTo(pTargetDisk, HardDiskVariant_VmdkStreamOptimized, pProgress2.asOutParam());
     3073                rc = pSourceDisk->CloneTo(pTargetDisk, HardDiskVariant_VmdkStreamOptimized, NULL, pProgress2.asOutParam());
    30743074                if (FAILED(rc)) throw rc;
    30753075
  • trunk/src/VBox/Main/HardDiskImpl.cpp

    r18313 r18388  
    5959{
    6060    enum Operation { CreateBase, CreateDiff,
    61                      Merge, Clone, Flatten, Delete, Reset };
     61                     Merge, Clone, Delete, Reset };
    6262
    6363    HardDisk *that;
     
    8585    }
    8686
     87    void setData (HardDisk *aTarget, HardDisk *aParent)
     88    {
     89        d.target = aTarget;
     90        HRESULT rc = d.target->addCaller();
     91        AssertComRC (rc);
     92        d.parentDisk = aParent;
     93        if (aParent)
     94        {
     95            rc = d.parentDisk->addCaller();
     96            AssertComRC (rc);
     97        }
     98    }
     99
    87100    void setData (MergeChain *aChain)
    88101    {
     
    91104    }
    92105
    93     void setData (CloneChain *aChain)
    94     {
    95         AssertReturnVoid (aChain != NULL);
    96         d.source.reset (aChain);
     106    void setData (CloneChain *aSrcChain, CloneChain *aParentChain)
     107    {
     108        AssertReturnVoid (aSrcChain != NULL);
     109        AssertReturnVoid (aParentChain != NULL);
     110        d.source.reset (aSrcChain);
     111        d.parent.reset (aParentChain);
    97112    }
    98113
     
    112127        HardDiskVariant_T variant;
    113128
    114         /* CreateDiff, Flatten */
     129        /* CreateDiff, Clone */
    115130
    116131        ComObjPtr<HardDisk> target;
    117132
    118         /* Flatten */
     133        /* Clone */
    119134
    120135        /** Hard disks to open, in {parent,child} order */
    121136        std::auto_ptr <CloneChain> source;
     137        /** Hard disks which are parent of target, in {parent,child} order */
     138        std::auto_ptr <CloneChain> parent;
     139        /** The to-be parent hard disk object */
     140        ComObjPtr<HardDisk> parentDisk;
    122141
    123142        /* Merge */
     
    14371456STDMETHODIMP HardDisk::CloneTo (IHardDisk *aTarget,
    14381457                                HardDiskVariant_T aVariant,
     1458                                IHardDisk *aParent,
    14391459                                IProgress **aProgress)
    14401460{
     
    14481468    HRESULT rc = mVirtualBox->cast (aTarget, target);
    14491469    CheckComRCReturnRC (rc);
    1450 
    1451     AutoMultiWriteLock2 alock (this, target);
    1452 
    1453     /* We want to be locked for reading as long as the clone hard disk is
    1454      * being created. */
    1455     rc = LockRead (NULL);
    1456     CheckComRCReturnRC (rc);
     1470    ComObjPtr <HardDisk> parent;
     1471    if (aParent)
     1472    {
     1473        rc = mVirtualBox->cast (aParent, parent);
     1474        CheckComRCReturnRC (rc);
     1475    }
     1476
     1477    AutoMultiWriteLock3 alock (this, target, parent);
    14571478
    14581479    ComObjPtr <Progress> progress;
     
    14621483        if (target->m.state != MediaState_NotCreated)
    14631484            throw target->setStateError();
     1485
     1486        /** @todo separate out creating/locking an image chain from
     1487         * SessionMachine::lockMedia and use it from here too.
     1488         * logically this belongs into HardDisk functionality. */
     1489
     1490        /* Build the source chain and lock images in the proper order. */
     1491        std::auto_ptr <CloneChain> srcChain (new CloneChain ());
     1492
     1493        /* we walk the source tree */
     1494        AutoReadLock srcTreeLock (this->treeLock());
     1495        for (HardDisk *hd = this; hd; hd = hd->mParent)
     1496        {
     1497            rc = srcChain->addImage(hd);
     1498            CheckComRCThrowRC (rc);
     1499        }
     1500        rc = srcChain->lockImagesRead();
     1501        CheckComRCThrowRC (rc);
     1502
     1503        /* Build the parent chain and lock images in the proper order. */
     1504        std::auto_ptr <CloneChain> parentChain (new CloneChain ());
     1505
     1506        /* we walk the future parent tree */
     1507        AutoReadLock parentTreeLock;
     1508        if (parent)
     1509            parentTreeLock.attach(parent->treeLock());
     1510        for (HardDisk *hd = parent; hd; hd = hd->mParent)
     1511        {
     1512            rc = parentChain->addImage(hd);
     1513            CheckComRCThrowRC (rc);
     1514        }
     1515        rc = parentChain->lockImagesRead();
     1516        CheckComRCThrowRC (rc);
    14641517
    14651518        progress.createObject();
     
    14761529        AssertComRCThrowRC (task->autoCaller.rc());
    14771530
    1478         task->setData (target);
     1531        task->setData (target, parent);
    14791532        task->d.variant = aVariant;
     1533        task->setData (srcChain.release(), parentChain.release());
    14801534
    14811535        rc = task->startThread();
     
    14931547    }
    14941548
    1495     if (FAILED (rc))
    1496     {
    1497         HRESULT rc2 = UnlockRead (NULL);
    1498         AssertComRC (rc2);
    1499         /* Note: on success, taskThread() will unlock this */
    1500     }
    1501     else
    1502     {
    1503         /* return progress to the caller */
    1504         progress.queryInterfaceTo (aProgress);
    1505     }
    1506 
    1507     return rc;
    1508 }
    1509 
    1510 STDMETHODIMP HardDisk::FlattenTo (IHardDisk *aTarget,
    1511                                   HardDiskVariant_T aVariant,
    1512                                   IProgress **aProgress)
    1513 {
    1514     CheckComArgNotNull (aTarget);
    1515     CheckComArgOutPointerValid (aProgress);
    1516 
    1517     AutoCaller autoCaller (this);
    1518     CheckComRCReturnRC (autoCaller.rc());
    1519 
    1520     ComObjPtr <HardDisk> target;
    1521     HRESULT rc = mVirtualBox->cast (aTarget, target);
    1522     CheckComRCReturnRC (rc);
    1523 
    1524     AutoMultiWriteLock2 alock (this, target);
    1525 
    1526     ComObjPtr <Progress> progress;
    1527 
    1528     try
    1529     {
    1530         if (target->m.state != MediaState_NotCreated)
    1531             throw target->setStateError();
    1532 
    1533         /** @todo separate out creating/locking an image chain from
    1534          * SessionMachine::lockMedia and use it from here too.
    1535          * logically this belongs into HardDisk functionality. */
    1536 
    1537         /* we walk the tree */
    1538         AutoReadLock treeLock (this->treeLock());
    1539 
    1540         /* Build the chain and at the end lock images in the proper order. */
    1541         std::auto_ptr <CloneChain> chain (new CloneChain ());
    1542         HardDisk *hd = this;
    1543         do
    1544         {
    1545             rc = chain->addImage(hd);
    1546             CheckComRCThrowRC (rc);
    1547 
    1548             hd = hd->mParent;
    1549         } while (hd);
    1550         rc = chain->lockImagesRead();
    1551         CheckComRCThrowRC (rc);
    1552 
    1553         progress.createObject();
    1554         rc = progress->init (mVirtualBox, static_cast <IHardDisk *> (this),
    1555             BstrFmt (tr ("Creating flattened clone hard disk '%ls'"),
    1556                      target->m.locationFull.raw()),
    1557             TRUE /* aCancelable */);
    1558         CheckComRCThrowRC (rc);
    1559 
    1560         /* setup task object and thread to carry out the operation
    1561          * asynchronously */
    1562 
    1563         std::auto_ptr <Task> task (new Task (this, progress, Task::Flatten));
    1564         AssertComRCThrowRC (task->autoCaller.rc());
    1565 
    1566         task->setData (target);
    1567         task->d.variant = aVariant;
    1568         task->setData (chain.release());
    1569 
    1570         rc = task->startThread();
    1571         CheckComRCThrowRC (rc);
    1572 
    1573         /* go to Creating state before leaving the lock */
    1574         target->m.state = MediaState_Creating;
    1575 
    1576         /* task is now owned (or already deleted) by taskThread() so release it */
    1577         task.release();
    1578     }
    1579     catch (HRESULT aRC)
    1580     {
    1581         rc = aRC;
    1582     }
    1583 
    1584     if (FAILED (rc))
    1585     {
    1586         HRESULT rc2 = UnlockRead (NULL);
    1587         AssertComRC (rc2);
    1588         /* Note: on success, taskThread() will unlock this */
    1589     }
    1590     else
     1549    if (SUCCEEDED (rc))
    15911550    {
    15921551        /* return progress to the caller */
     
    41364095        {
    41374096            ComObjPtr<HardDisk> &target = task->d.target;
    4138 
    4139             /* Lock both in {parent,child} order. The lock is also used as a
     4097            ComObjPtr<HardDisk> &parent = task->d.parentDisk;
     4098
     4099            /* Lock all in {parent,child} order. The lock is also used as a
    41404100             * signal from the task initiator (which releases it only after
    41414101             * RTThreadCreate()) that we can start the job. */
    4142             AutoMultiWriteLock2 thatLock (that, target);
     4102            AutoMultiWriteLock3 thatLock (that, target, parent);
     4103
     4104            CloneChain *srcChain = task->d.source.get();
     4105            CloneChain *parentChain = task->d.parent.get();
    41434106
    41444107            uint64_t size = 0, logicalSize = 0;
     
    41614124                ComAssertRCThrow (vrc, E_FAIL);
    41624125
    4163                 Utf8Str format (that->mm.format);
    4164                 Utf8Str location (that->m.locationFull);
    4165 
    4166                 Utf8Str targetFormat (target->mm.format);
    4167                 Utf8Str targetLocation (target->m.locationFull);
    4168 
    4169                 Assert (target->m.state == MediaState_Creating);
    4170 
    4171                 Assert (that->m.state == MediaState_LockedRead);
    4172 
    4173                 /* unlock before the potentially lengthy operation */
    4174                 thatLock.leave();
    4175 
    41764126                try
    41774127                {
    4178                     vrc = VDOpen (hdd, format, location,
    4179                                   VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO,
    4180                                   that->mm.vdDiskIfaces);
    4181                     if (RT_FAILURE (vrc))
    4182                     {
    4183                         throw setError (E_FAIL,
    4184                             tr ("Could not open the hard disk storage "
    4185                                 "unit '%s'%s"),
    4186                             location.raw(), that->vdError (vrc).raw());
    4187                     }
    4188 
    4189                     /* ensure the target directory exists */
    4190                     rc = VirtualBox::ensureFilePathExists (targetLocation);
    4191                     CheckComRCThrowRC (rc);
    4192 
    4193                     /* needed for vdProgressCallback */
    4194                     that->mm.vdProgress = task->progress;
    4195 
    4196                     PVBOXHDD targetHdd;
    4197                     int vrc = VDCreate (that->mm.vdDiskIfaces, &targetHdd);
    4198                     ComAssertRCThrow (vrc, E_FAIL);
    4199 
    4200                     vrc = VDCopy (hdd, 0, targetHdd, targetFormat,
    4201                                   targetLocation, false, 0, task->d.variant,
    4202                                   targetId.raw(), NULL,
    4203                                   target->mm.vdDiskIfaces,
    4204                                   that->mm.vdDiskIfaces);
    4205 
    4206                     that->mm.vdProgress = NULL;
    4207 
    4208                     if (RT_FAILURE (vrc))
    4209                     {
    4210                         VDDestroy (targetHdd);
    4211 
    4212                         throw setError (E_FAIL,
    4213                             tr ("Could not create the clone hard disk "
    4214                                 "'%s'%s"),
    4215                             targetLocation.raw(), that->vdError (vrc).raw());
    4216                     }
    4217 
    4218                     size = VDGetFileSize (targetHdd, 0);
    4219                     logicalSize = VDGetSize (targetHdd, 0) / _1M;
    4220 
    4221                     VDDestroy (targetHdd);
    4222                 }
    4223                 catch (HRESULT aRC) { rc = aRC; }
    4224 
    4225                 VDDestroy (hdd);
    4226             }
    4227             catch (HRESULT aRC) { rc = aRC; }
    4228 
    4229             if (SUCCEEDED (rc))
    4230             {
    4231                 /* we set mParent & children() (note that thatLock is released
    4232                  * here), but lock VirtualBox first to follow the rule */
    4233                 AutoMultiWriteLock2 alock (that->mVirtualBox->lockHandle(),
    4234                                            that->treeLock());
    4235 
    4236                 Assert (target->mParent.isNull());
    4237 
    4238                 if (!that->mParent.isNull())
    4239                 {
    4240                     /* associate the clone with the original's parent and
    4241                      * deassociate from VirtualBox */
    4242                     target->mParent = that->mParent;
    4243                     that->mParent->addDependentChild (target);
    4244                     target->mVirtualBox->removeDependentChild (target);
    4245 
    4246                     /* register with mVirtualBox as the last step and move to
    4247                      * Created state only on success (leaving an orphan file is
    4248                      * better than breaking media registry consistency) */
    4249                     rc = that->mVirtualBox->registerHardDisk(target);
    4250 
    4251                     if (FAILED (rc))
    4252                     {
    4253                         /* break the parent association on failure to register */
    4254                         target->mVirtualBox->addDependentChild (target);
    4255                         that->mParent->removeDependentChild (target);
    4256                         target->mParent.setNull();
    4257                     }
    4258                 }
    4259                 else
    4260                 {
    4261                     /* just register  */
    4262                     rc = that->mVirtualBox->registerHardDisk(target);
    4263                 }
    4264             }
    4265 
    4266             thatLock.maybeEnter();
    4267 
    4268             if (SUCCEEDED (rc))
    4269             {
    4270                 target->m.state = MediaState_Created;
    4271 
    4272                 target->m.size = size;
    4273                 target->mm.logicalSize = logicalSize;
    4274             }
    4275             else
    4276             {
    4277                 /* back to NotCreated on failure */
    4278                 target->m.state = MediaState_NotCreated;
    4279 
    4280                 /* reset UUID to prevent it from being reused next time */
    4281                 if (generateUuid)
    4282                     unconst (target->m.id).clear();
    4283             }
    4284 
    4285             if (isAsync)
    4286             {
    4287                 /* unlock ourselves when done (unless in MediaState_LockedWrite
    4288                  * state because of taking the online snapshot*/
    4289                 if (that->m.state != MediaState_LockedWrite)
    4290                 {
    4291                     HRESULT rc2 = that->UnlockRead (NULL);
    4292                     AssertComRC (rc2);
    4293                 }
    4294             }
    4295 
    4296             /* Note that in sync mode, it's the caller's responsibility to
    4297              * unlock the hard disk */
    4298 
    4299             break;
    4300         }
    4301 
    4302         ////////////////////////////////////////////////////////////////////////
    4303 
    4304         case Task::Flatten:
    4305         {
    4306             ComObjPtr<HardDisk> &target = task->d.target;
    4307 
    4308             /* Lock both in {parent,child} order. The lock is also used as a
    4309              * signal from the task initiator (which releases it only after
    4310              * RTThreadCreate()) that we can start the job. */
    4311             AutoMultiWriteLock2 thatLock (that, target);
    4312 
    4313             CloneChain *chain = task->d.source.get();
    4314 
    4315             uint64_t size = 0, logicalSize = 0;
    4316 
    4317             /* The object may request a specific UUID (through a special form of
    4318              * the setLocation() argument). Otherwise we have to generate it */
    4319             Guid targetId = target->m.id;
    4320             bool generateUuid = targetId.isEmpty();
    4321             if (generateUuid)
    4322             {
    4323                 targetId.create();
    4324                 /* VirtualBox::registerHardDisk() will need UUID */
    4325                 unconst (target->m.id) = targetId;
    4326             }
    4327 
    4328             try
    4329             {
    4330                 PVBOXHDD hdd;
    4331                 int vrc = VDCreate (that->mm.vdDiskIfaces, &hdd);
    4332                 ComAssertRCThrow (vrc, E_FAIL);
    4333 
    4334                 try
    4335                 {
    4336                     /* Open all hard disk images in the chain. */
    4337                     for (List::const_iterator it = chain->begin();
    4338                          it != chain->end(); ++ it)
     4128                    /* Open all hard disk images in the source chain. */
     4129                    for (List::const_iterator it = srcChain->begin();
     4130                         it != srcChain->end(); ++ it)
    43394131                    {
    43404132                        /* sanity check */
    43414133                        Assert ((*it)->m.state == MediaState_LockedRead);
    43424134
    4343                         /** Open all diff images in read-only mode. */
     4135                        /** Open all images in read-only mode. */
    43444136                        vrc = VDOpen (hdd, Utf8Str ((*it)->mm.format),
    43454137                                      Utf8Str ((*it)->m.locationFull),
     
    43634155
    43644156                    Assert (target->m.state == MediaState_Creating);
     4157                    Assert (that->m.state == MediaState_LockedRead);
     4158                    Assert (parent.isNull() || parent->m.state == MediaState_LockedRead);
    43654159
    43664160                    /* ensure the target directory exists */
     
    43754169                    ComAssertRCThrow (vrc, E_FAIL);
    43764170
    4377                     vrc = VDCopy (hdd, VD_LAST_IMAGE, targetHdd, targetFormat,
    4378                                   targetLocation, false, 0, task->d.variant,
    4379                                   targetId.raw(), NULL,
    4380                                   target->mm.vdDiskIfaces,
    4381                                   that->mm.vdDiskIfaces);
    4382 
    4383                     that->mm.vdProgress = NULL;
    4384 
    4385                     if (RT_FAILURE (vrc))
     4171                    try
    43864172                    {
    4387                         VDDestroy (targetHdd);
    4388 
    4389                         throw setError (E_FAIL,
    4390                             tr ("Could not create the flattened hard disk "
    4391                                 "'%s'%s"),
    4392                             targetLocation.raw(), that->vdError (vrc).raw());
     4173                        /* Open all hard disk images in the parent chain. */
     4174                        for (List::const_iterator it = parentChain->begin();
     4175                             it != parentChain->end(); ++ it)
     4176                        {
     4177                            /* sanity check */
     4178                            Assert ((*it)->m.state == MediaState_LockedRead);
     4179
     4180                            /** Open all images in read-only mode. */
     4181                            vrc = VDOpen (hdd, Utf8Str ((*it)->mm.format),
     4182                                          Utf8Str ((*it)->m.locationFull),
     4183                                          VD_OPEN_FLAGS_READONLY,
     4184                                          (*it)->mm.vdDiskIfaces);
     4185                            if (RT_FAILURE (vrc))
     4186                            {
     4187                                throw setError (E_FAIL,
     4188                                    tr ("Could not open the hard disk storage "
     4189                                        "unit '%s'%s"),
     4190                                    Utf8Str ((*it)->m.locationFull).raw(),
     4191                                    that->vdError (vrc).raw());
     4192                            }
     4193                        }
     4194
     4195                        vrc = VDCopy (hdd, VD_LAST_IMAGE, targetHdd,
     4196                                      targetFormat, targetLocation, false, 0,
     4197                                      task->d.variant, targetId.raw(), NULL,
     4198                                      target->mm.vdDiskIfaces,
     4199                                      that->mm.vdDiskIfaces);
     4200
     4201                        that->mm.vdProgress = NULL;
     4202
     4203                        if (RT_FAILURE (vrc))
     4204                        {
     4205                            throw setError (E_FAIL,
     4206                                tr ("Could not create the clone hard disk "
     4207                                    "'%s'%s"),
     4208                                targetLocation.raw(), that->vdError (vrc).raw());
     4209                        }
     4210                        size = VDGetFileSize (targetHdd, 0);
     4211                        logicalSize = VDGetSize (targetHdd, 0) / _1M;
    43934212                    }
    4394 
    4395                     size = VDGetFileSize (targetHdd, 0);
    4396                     logicalSize = VDGetSize (targetHdd, 0) / _1M;
     4213                    catch (HRESULT aRC) { rc = aRC; }
    43974214
    43984215                    VDDestroy (targetHdd);
     
    44064223            if (SUCCEEDED (rc))
    44074224            {
     4225                /* we set mParent & children() (note that thatLock is released
     4226                 * here), but lock VirtualBox first to follow the rule */
     4227                AutoMultiWriteLock2 alock (that->mVirtualBox->lockHandle(),
     4228                                           that->treeLock());
     4229
    44084230                Assert (target->mParent.isNull());
    44094231
    4410                 /* just register  */
    4411                 rc = that->mVirtualBox->registerHardDisk(target);
     4232                if (parent)
     4233                {
     4234                    /* associate the clone with the parent and deassociate
     4235                     * from VirtualBox */
     4236                    target->mParent = parent;
     4237                    parent->addDependentChild (target);
     4238                    target->mVirtualBox->removeDependentChild (target);
     4239
     4240                    /* register with mVirtualBox as the last step and move to
     4241                     * Created state only on success (leaving an orphan file is
     4242                     * better than breaking media registry consistency) */
     4243                    rc = parent->mVirtualBox->registerHardDisk(target);
     4244
     4245                    if (FAILED (rc))
     4246                    {
     4247                        /* break parent association on failure to register */
     4248                        target->mVirtualBox->addDependentChild (target);
     4249                        parent->removeDependentChild (target);
     4250                        target->mParent.setNull();
     4251                    }
     4252                }
     4253                else
     4254                {
     4255                    /* just register  */
     4256                    rc = that->mVirtualBox->registerHardDisk(target);
     4257                }
    44124258            }
    44134259
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r18311 r18388  
    88018801  <interface
    88028802    name="IHardDisk" extends="IMedium"
    8803     uuid="3498d065-dee6-48bf-bcc5-47018fee4f42"
     8803    uuid="91648dc6-bb19-46bf-9e1c-4bf5b960c8e2"
    88048804    wsmap="managed"
    88058805  >
     
    95359535    </method>
    95369536
    9537     <!-- clone methods -->
     9537    <!-- clone method -->
    95389538
    95399539    <method name="cloneTo">
     
    95459545        state (i.e. must not have an existing storage unit). Upon successful
    95469546        completion, the cloned hard disk will contain exactly the same sector
    9547         data as the hard disk being cloned, except that a new UUID for the clone
    9548         will be randomly generated.
     9547        data as the hard disk being cloned, except that a new UUID for the
     9548        clone will be randomly generated.
     9549
     9550        The @a parent argument defines which hard disk will be the parent
     9551        of the clone. Passing a NULL reference indicates that the clone will
     9552        be a base image, i.e. completely independent. It is possible to specify
     9553        an arbitrary hard disk for this parameter, including the parent of the
     9554        hard disk which is being cloned. Even cloning to a child of the source
     9555        hard disk is possible.
    95499556
    95509557        After the returned progress object reports that the operation is
     
    95539560
    95549561        <note>
    9555           If the cloned hard disk is a differencing hard disk, it will inherit
    9556           parent dependency of the original hard disk.
    9557         </note>
    9558         <note>
    95599562          This hard disk will be placed to <link to="MediaState_LockedRead"/>
    95609563          state for the duration of this operation.
     
    95679570        <desc>Exact image variant which should be created.</desc>
    95689571      </param>
    9569       <param name="progress" type="IProgress" dir="return">
    9570         <desc>Progress object to track the operation completion.</desc>
    9571       </param>
    9572     </method>
    9573 
    9574     <method name="flattenTo">
    9575       <desc>
    9576         Starts creating a deep (independent) clone of this hard disk in the
    9577         format and at the location defined by the @a target argument.
    9578 
    9579         This operation is similar to <link to="#cloneTo"/> except that when
    9580         applied to a differencing hard disk, it will also copy missing hard disk
    9581         data from all parent hard disks it is linked to. This will make the
    9582         created clone an independent base hard disk that contains all hard disk
    9583         data and does not need any other hard disks to operate.
    9584 
    9585         After the returned progress object reports that the operation is
    9586         successfully complete, the target hard disk gets remembered by this
    9587         VirtualBox installation and may be attached to virtual machines.
    9588 
    9589         <note>
    9590           For base hard disks, this operation is identical to
    9591           <link to="#cloneTo"/>.
    9592         </note>
    9593         <note>
    9594           This hard disk and all its parent hard disks will be placed to <link
    9595           to="MediaState_LockedRead"/> state for the duration of this
    9596           operation.
    9597         </note>
    9598       </desc>
    9599       <param name="target" type="IHardDisk" dir="in">
    9600         <desc>Target hard disk.</desc>
    9601       </param>
    9602       <param name="variant" type="HardDiskVariant" dir="in">
    9603         <desc>Exact image variant which should be created.</desc>
     9572      <param name="parent" type="IHardDisk" dir="in">
     9573        <desc>Parent of the cloned hard disk.</desc>
    96049574      </param>
    96059575      <param name="progress" type="IProgress" dir="return">
  • trunk/src/VBox/Main/include/HardDiskImpl.h

    r18313 r18388  
    126126    STDMETHOD(MergeTo) (IN_GUID aTargetId, IProgress **aProgress);
    127127    STDMETHOD(CloneTo) (IHardDisk *aTarget, HardDiskVariant_T aVariant,
    128                         IProgress **aProgress);
    129     STDMETHOD(FlattenTo) (IHardDisk *aTarget, HardDiskVariant_T aVariant,
    130                           IProgress **aProgress);
     128                        IHardDisk *aParent, IProgress **aProgress);
    131129    STDMETHOD(Compact) (IProgress **aProgress);
    132130    STDMETHOD(Reset) (IProgress **aProgress);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette