VirtualBox

Ignore:
Timestamp:
Jun 29, 2009 3:26:13 PM (15 years ago)
Author:
vboxsync
Message:

API/HardDisk: implementation for cloning to existing image

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/HardDiskImpl.cpp

    r20977 r21031  
    423423            {
    424424                return setError (E_FAIL,
    425                     tr ("Hard disk '%ls' involved in the merge operation "
    426                         "has more than one child hard disk (%d)"),
     425                    tr ("Hard disk '%ls' involved in the merge operation has more than one child hard disk (%d)"),
    427426                    aHardDisk->m.locationFull.raw(),
    428427                    aHardDisk->children().size());
     
    14591458        &&  !(mm.formatObj->capabilities() & HardDiskFormatCapabilities_CreateDynamic))
    14601459        return setError (VBOX_E_NOT_SUPPORTED,
    1461             tr ("Hard disk format '%ls' does not support dynamic storage "
    1462                 "creation"), mm.format.raw());
     1460            tr ("Hard disk format '%ls' does not support dynamic storage creation"),
     1461            mm.format.raw());
    14631462    if (    (aVariant & HardDiskVariant_Fixed)
    14641463        &&  !(mm.formatObj->capabilities() & HardDiskFormatCapabilities_CreateDynamic))
    14651464        return setError (VBOX_E_NOT_SUPPORTED,
    1466             tr ("Hard disk format '%ls' does not support fixed storage "
    1467                 "creation"), mm.format.raw());
     1465            tr ("Hard disk format '%ls' does not support fixed storage creation"),
     1466            mm.format.raw());
    14681467
    14691468    switch (m.state)
     
    16111610            throw target->setStateError();
    16121611
    1613         /** @todo implement the cloning to existing media */
    1614         if (target->m.state == MediaState_Created)
    1615             throw setError (E_NOTIMPL, tr ("This cloning variant is not implemented"));
    1616 
    16171612        /** @todo separate out creating/locking an image chain from
    16181613         * SessionMachine::lockMedia and use it from here too.
     
    16441639            CheckComRCThrowRC (rc);
    16451640        }
    1646         rc = parentChain->lockImagesRead();
    1647         CheckComRCThrowRC (rc);
     1641        if (target->m.state == MediaState_Created)
     1642        {
     1643            /* If we're cloning to an existing image the parent chain also
     1644             * contains the target image, and it gets locked for writing. */
     1645            rc = parentChain->addImage(target);
     1646            CheckComRCThrowRC (rc);
     1647            rc = parentChain->lockImagesReadAndLastWrite();
     1648            CheckComRCThrowRC (rc);
     1649        }
     1650        else
     1651        {
     1652            rc = parentChain->lockImagesRead();
     1653            CheckComRCThrowRC (rc);
     1654        }
    16481655
    16491656        progress.createObject();
     
    16671674        CheckComRCThrowRC (rc);
    16681675
    1669         /* go to Creating state before leaving the lock */
    1670         target->m.state = MediaState_Creating;
     1676        if (target->m.state == MediaState_NotCreated)
     1677        {
     1678            /* go to Creating state before leaving the lock */
     1679            target->m.state = MediaState_Creating;
     1680        }
    16711681
    16721682        /* task is now owned (or already deleted) by taskThread() so release it */
     
    25912601            {
    25922602                return setError (VBOX_E_INVALID_OBJECT_STATE,
    2593                     tr ("Hard disk '%ls' is attached to a virtual machine "
    2594                         "with UUID {%RTuuid}. No differencing hard disks "
    2595                         "based on it may be created until it is detached"),
     2603                    tr ("Hard disk '%ls' is attached to a virtual machine with UUID {%RTuuid}. No differencing hard disks based on it may be created until it is detached"),
    25962604                    m.locationFull.raw(), it->machineId.raw());
    25972605            }
     
    29832991
    29842992                ComAssertMsgRet (!mm.formatObj->fileExtensions().empty(),
    2985                                  ("Must be at least one extension if it is "
    2986                                   "HardDiskFormatCapabilities_File\n"),
     2993                                 ("Must be at least one extension if it is HardDiskFormatCapabilities_File\n"),
    29872994                                 E_FAIL);
    29882995
     
    30443051                if (vrc == VERR_FILE_NOT_FOUND || vrc == VERR_PATH_NOT_FOUND)
    30453052                    return setError (VBOX_E_FILE_ERROR,
    3046                         tr ("Could not find file for the hard disk "
    3047                             "'%s' (%Rrc)"), locationFull.raw(), vrc);
     3053                        tr ("Could not find file for the hard disk '%s' (%Rrc)"),
     3054                        locationFull.raw(), vrc);
    30483055                else
    30493056                    return setError (VBOX_E_IPRT_ERROR,
    3050                         tr ("Could not get the storage format of the hard disk "
    3051                             "'%s' (%Rrc)"), locationFull.raw(), vrc);
     3057                        tr ("Could not get the storage format of the hard disk '%s' (%Rrc)"),
     3058                        locationFull.raw(), vrc);
    30523059            }
    30533060
     
    32973304                    {
    32983305                        lastAccessError = Utf8StrFmt (
    3299                             tr ("UUID {%RTuuid} of the hard disk '%ls' does "
    3300                                 "not match the value {%RTuuid} stored in the "
    3301                                 "media registry ('%ls')"),
     3306                            tr ("UUID {%RTuuid} of the hard disk '%ls' does not match the value {%RTuuid} stored in the media registry ('%ls')"),
    33023307                            &uuid, m.locationFull.raw(), m.id.raw(),
    33033308                            mVirtualBox->settingsFileName().raw());
     
    33493354                    {
    33503355                        lastAccessError = Utf8StrFmt (
    3351                             tr ("Parent hard disk with UUID {%RTuuid} of the "
    3352                                 "hard disk '%ls' is not found in the media "
    3353                                 "registry ('%ls')"),
     3356                            tr ("Parent hard disk with UUID {%RTuuid} of the hard disk '%ls' is not found in the media registry ('%ls')"),
    33543357                            &parentId, m.locationFull.raw(),
    33553358                            mVirtualBox->settingsFileName().raw());
     
    33803383                    {
    33813384                        lastAccessError = Utf8StrFmt (
    3382                             tr ("Hard disk '%ls' is differencing but it is not "
    3383                                 "associated with any parent hard disk in the "
    3384                                 "media registry ('%ls')"),
     3385                            tr ("Hard disk '%ls' is differencing but it is not associated with any parent hard disk in the media registry ('%ls')"),
    33853386                            m.locationFull.raw(),
    33863387                            mVirtualBox->settingsFileName().raw());
     
    33933394                    {
    33943395                        lastAccessError = Utf8StrFmt (
    3395                             tr ("Parent UUID {%RTuuid} of the hard disk '%ls' "
    3396                                 "does not match UUID {%RTuuid} of its parent "
    3397                                 "hard disk stored in the media registry ('%ls')"),
     3396                            tr ("Parent UUID {%RTuuid} of the hard disk '%ls' does not match UUID {%RTuuid} of its parent hard disk stored in the media registry ('%ls')"),
    33983397                            &parentId, m.locationFull.raw(),
    33993398                            mParent->id().raw(),
     
    34333432    {
    34343433        m.lastAccessError = lastAccessError;
    3435         LogWarningFunc (("'%ls' is not accessible (error='%ls', "
    3436                          "rc=%Rhrc, vrc=%Rrc)\n",
     3434        LogWarningFunc (("'%ls' is not accessible (error='%ls', rc=%Rhrc, vrc=%Rrc)\n",
    34373435                         m.locationFull.raw(), m.lastAccessError.raw(),
    34383436                         rc, vrc));
     
    34973495    if (mm.numCreateDiffTasks > 0)
    34983496        return setError (E_FAIL,
    3499             tr ("One or more differencing child hard disks are "
    3500                 "being created for the hard disk '%ls' (%u)"),
     3497            tr ("One or more differencing child hard disks are being created for the hard disk '%ls' (%u)"),
    35013498            m.locationFull.raw(), mm.numCreateDiffTasks);
    35023499
     
    37943791                    {
    37953792                        throw setError (E_FAIL,
    3796                             tr ("Could not create the hard disk storage "
    3797                                 "unit '%s'%s"),
     3793                            tr ("Could not create the hard disk storage unit '%s'%s"),
    37983794                            location.raw(), that->vdError (vrc).raw());
    37993795                    }
     
    38933889                    {
    38943890                        throw setError (E_FAIL,
    3895                             tr ("Could not open the hard disk storage "
    3896                                 "unit '%s'%s"),
     3891                            tr ("Could not open the hard disk storage unit '%s'%s"),
    38973892                            location.raw(), that->vdError (vrc).raw());
    38983893                    }
     
    39183913                    {
    39193914                        throw setError (E_FAIL,
    3920                             tr ("Could not create the differencing hard disk "
    3921                                 "storage unit '%s'%s"),
     3915                            tr ("Could not create the differencing hard disk storage unit '%s'%s"),
    39223916                            targetLocation.raw(), that->vdError (vrc).raw());
    39233917                    }
     
    43604354                        {
    43614355                            throw setError (E_FAIL,
    4362                                 tr ("Could not open the hard disk storage "
    4363                                     "unit '%s'%s"),
     4356                                tr ("Could not open the hard disk storage unit '%s'%s"),
    43644357                                Utf8Str ((*it)->m.locationFull).raw(),
    43654358                                that->vdError (vrc).raw());
     
    43734366                    Utf8Str targetLocation (target->m.locationFull);
    43744367
    4375                     Assert (target->m.state == MediaState_Creating);
     4368                    Assert (    target->m.state == MediaState_Creating
     4369                            ||  target->m.state == MediaState_LockedWrite);
    43764370                    Assert (that->m.state == MediaState_LockedRead);
    43774371                    Assert (parent.isNull() || parent->m.state == MediaState_LockedRead);
     
    43954389                        {
    43964390                            /* sanity check */
    4397                             Assert ((*it)->m.state == MediaState_LockedRead);
    4398 
    4399                             /** Open all images in read-only mode. */
    4400                             vrc = VDOpen (hdd, Utf8Str ((*it)->mm.format),
     4391                            Assert (    (*it)->m.state == MediaState_LockedRead
     4392                                    ||  (*it)->m.state == MediaState_LockedWrite);
     4393
     4394                            /* Open all images in appropriate mode. */
     4395                            vrc = VDOpen (targetHdd, Utf8Str ((*it)->mm.format),
    44014396                                          Utf8Str ((*it)->m.locationFull),
    4402                                           VD_OPEN_FLAGS_READONLY,
     4397                                          ((*it)->m.state == MediaState_LockedWrite) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY,
    44034398                                          (*it)->mm.vdDiskIfaces);
    44044399                            if (RT_FAILURE (vrc))
    44054400                            {
    44064401                                throw setError (E_FAIL,
    4407                                     tr ("Could not open the hard disk storage "
    4408                                         "unit '%s'%s"),
     4402                                    tr ("Could not open the hard disk storage unit '%s'%s"),
    44094403                                    Utf8Str ((*it)->m.locationFull).raw(),
    44104404                                    that->vdError (vrc).raw());
     
    44134407
    44144408                        vrc = VDCopy (hdd, VD_LAST_IMAGE, targetHdd,
    4415                                       targetFormat, targetLocation, false, 0,
     4409                                      targetFormat,
     4410                                      target->m.state == MediaState_Creating ? targetLocation.raw() : (char *)NULL,
     4411                                      false, 0,
    44164412                                      task->d.variant, targetId.raw(), NULL,
    44174413                                      target->mm.vdDiskIfaces,
     
    44234419                        {
    44244420                            throw setError (E_FAIL,
    4425                                 tr ("Could not create the clone hard disk "
    4426                                     "'%s'%s"),
     4421                                tr ("Could not create the clone hard disk '%s'%s"),
    44274422                                targetLocation.raw(), that->vdError (vrc).raw());
    44284423                        }
     
    44404435            catch (HRESULT aRC) { rc = aRC; }
    44414436
    4442             if (SUCCEEDED (rc))
     4437            /* Only do the parent changes for newly created images. */
     4438            if (target->m.state == MediaState_Creating)
    44434439            {
    4444                 /* we set mParent & children() (note that thatLock is released
    4445                  * here), but lock VirtualBox first to follow the rule */
    4446                 AutoMultiWriteLock2 alock (that->mVirtualBox->lockHandle(),
    4447                                            that->treeLock());
    4448 
    4449                 Assert (target->mParent.isNull());
    4450 
    4451                 if (parent)
     4440                if (SUCCEEDED (rc))
    44524441                {
    4453                     /* associate the clone with the parent and deassociate
    4454                      * from VirtualBox */
    4455                     target->mParent = parent;
    4456                     parent->addDependentChild (target);
    4457                     target->mVirtualBox->removeDependentChild (target);
    4458 
    4459                     /* register with mVirtualBox as the last step and move to
    4460                      * Created state only on success (leaving an orphan file is
    4461                      * better than breaking media registry consistency) */
    4462                     rc = parent->mVirtualBox->registerHardDisk(target);
    4463 
    4464                     if (FAILED (rc))
     4442                    /* we set mParent & children() (note that thatLock is released
     4443                     * here), but lock VirtualBox first to follow the rule */
     4444                    AutoMultiWriteLock2 alock (that->mVirtualBox->lockHandle(),
     4445                                               that->treeLock());
     4446
     4447                    Assert (target->mParent.isNull());
     4448
     4449                    if (parent)
    44654450                    {
    4466                         /* break parent association on failure to register */
    4467                         target->mVirtualBox->addDependentChild (target);
    4468                         parent->removeDependentChild (target);
    4469                         target->mParent.setNull();
     4451                        /* associate the clone with the parent and deassociate
     4452                         * from VirtualBox */
     4453                        target->mParent = parent;
     4454                        parent->addDependentChild (target);
     4455                        target->mVirtualBox->removeDependentChild (target);
     4456
     4457                        /* register with mVirtualBox as the last step and move to
     4458                         * Created state only on success (leaving an orphan file is
     4459                         * better than breaking media registry consistency) */
     4460                        rc = parent->mVirtualBox->registerHardDisk(target);
     4461
     4462                        if (FAILED (rc))
     4463                        {
     4464                            /* break parent association on failure to register */
     4465                            target->mVirtualBox->addDependentChild (target);
     4466                            parent->removeDependentChild (target);
     4467                            target->mParent.setNull();
     4468                        }
    44704469                    }
     4470                    else
     4471                    {
     4472                        /* just register  */
     4473                        rc = that->mVirtualBox->registerHardDisk(target);
     4474                    }
     4475                }
     4476            }
     4477
     4478            thatLock.maybeEnter();
     4479
     4480            if (target->m.state == MediaState_Creating)
     4481            {
     4482                if (SUCCEEDED (rc))
     4483                {
     4484                    target->m.state = MediaState_Created;
     4485
     4486                    target->m.size = size;
     4487                    target->mm.logicalSize = logicalSize;
    44714488                }
    44724489                else
    44734490                {
    4474                     /* just register  */
    4475                     rc = that->mVirtualBox->registerHardDisk(target);
     4491                    /* back to NotCreated on failure */
     4492                    target->m.state = MediaState_NotCreated;
     4493
     4494                    /* reset UUID to prevent it from being reused next time */
     4495                    if (generateUuid)
     4496                        unconst (target->m.id).clear();
    44764497                }
    4477             }
    4478 
    4479             thatLock.maybeEnter();
    4480 
    4481             if (SUCCEEDED (rc))
    4482             {
    4483                 target->m.state = MediaState_Created;
    4484 
    4485                 target->m.size = size;
    4486                 target->mm.logicalSize = logicalSize;
    4487             }
    4488             else
    4489             {
    4490                 /* back to NotCreated on failure */
    4491                 target->m.state = MediaState_NotCreated;
    4492 
    4493                 /* reset UUID to prevent it from being reused next time */
    4494                 if (generateUuid)
    4495                     unconst (target->m.id).clear();
    44964498            }
    44974499
     
    45384540                    {
    45394541                        throw setError (E_FAIL,
    4540                             tr ("Could not delete the hard disk storage "
    4541                                 "unit '%s'%s"),
     4542                            tr ("Could not delete the hard disk storage unit '%s'%s"),
    45424543                            location.raw(), that->vdError (vrc).raw());
    45434544                    }
     
    46074608                    {
    46084609                        throw setError (E_FAIL,
    4609                             tr ("Could not delete the hard disk storage "
    4610                                 "unit '%s'%s"),
     4610                            tr ("Could not delete the hard disk storage unit '%s'%s"),
    46114611                            location.raw(), that->vdError (vrc).raw());
    46124612                    }
     
    46194619                    {
    46204620                        throw setError (E_FAIL,
    4621                             tr ("Could not open the hard disk storage "
    4622                                 "unit '%s'%s"),
     4621                            tr ("Could not open the hard disk storage unit '%s'%s"),
    46234622                            parentLocation.raw(), that->vdError (vrc).raw());
    46244623                    }
     
    46414640                    {
    46424641                        throw setError (E_FAIL,
    4643                             tr ("Could not create the differencing hard disk "
    4644                                 "storage unit '%s'%s"),
     4642                            tr ("Could not create the differencing hard disk storage unit '%s'%s"),
    46454643                            location.raw(), that->vdError (vrc).raw());
    46464644                    }
     
    47124710                        {
    47134711                            throw setError (E_FAIL,
    4714                                 tr ("Could not open the hard disk storage "
    4715                                     "unit '%s'%s"),
     4712                                tr ("Could not open the hard disk storage unit '%s'%s"),
    47164713                                Utf8Str ((*it)->m.locationFull).raw(),
    47174714                                that->vdError (vrc).raw());
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