VirtualBox

Changeset 28110 in vbox for trunk


Ignore:
Timestamp:
Apr 8, 2010 6:07:13 PM (15 years ago)
Author:
vboxsync
Message:

Main: more Machine::init() work to get OVF vbox:Machine import running; works now for machines without media attachments

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

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

    r28098 r28110  
    3434#include "GuestOSTypeImpl.h"
    3535#include "ProgressImpl.h"
     36#include "MachineImpl.h"
    3637
    3738#include "AutoCaller.h"
     
    11211122
    11221123            if (vsdescThis->m->pConfig)
    1123                 importVBoxMachine(*vsdescThis->m->pConfig, pNewMachine, stack);
     1124                importVBoxMachine(vsdescThis, pNewMachine, stack);
    11241125            else
    11251126                importMachineGeneric(vsysThis, vsdescThis, pNewMachine, stack);
    11261127        }
    1127         catch(HRESULT aRC)
     1128        catch (HRESULT aRC)
    11281129        {
    11291130            rc = aRC;
     
    13671368        size_t a = 0;
    13681369        for (nwIt = vsdeNW.begin();
    1369                 (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
    1370                 ++nwIt, ++a)
     1370             (nwIt != vsdeNW.end() && a < SchemaDefs::NetworkAdapterCount);
     1371             ++nwIt, ++a)
    13711372        {
    13721373            const VirtualSystemDescriptionEntry* pvsys = *nwIt;
     
    15291530    if (FAILED(rc)) throw rc;
    15301531
     1532    // store new machine for roll-back in case of errors
    15311533    Bstr bstrNewMachineId;
    15321534    rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam());
    15331535    if (FAILED(rc)) throw rc;
    1534 
    1535     // store new machine for roll-back in case of errors
    15361536    stack.llMachinesRegistered.push_back(bstrNewMachineId);
    15371537
     
    18621862 * @param stack
    18631863 */
    1864 void Appliance::importVBoxMachine(const settings::MachineConfigFile &config,
    1865                                   ComPtr<IMachine> &pNewMachine,
     1864void Appliance::importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis,
     1865                                  ComPtr<IMachine> &pReturnNewMachine,
    18661866                                  ImportStack &stack)
    18671867{
     1868    Assert(vsdescThis->m->pConfig);
     1869    const settings::MachineConfigFile &config = *vsdescThis->m->pConfig;
     1870
     1871    // use the name that we computed in the OVF fields to avoid duplicates
     1872    std::list<VirtualSystemDescriptionEntry*> vsdeName = vsdescThis->findByType(VirtualSystemDescriptionType_Name);
     1873    if (vsdeName.size() < 1)
     1874        throw setError(VBOX_E_FILE_ERROR,
     1875                        tr("Missing VM name"));
     1876    const Utf8Str &strNameVBox = vsdeName.front()->strVbox;
     1877
     1878    ComObjPtr<Machine> pNewMachine;
     1879    HRESULT rc = pNewMachine.createObject();
     1880    if (FAILED(rc)) throw rc;
     1881    rc = pNewMachine->init(mVirtualBox, strNameVBox, config);
     1882    if (FAILED(rc)) throw rc;
     1883
     1884    IMachine *p;
     1885    rc = pNewMachine.queryInterfaceTo(&p);
     1886    if (FAILED(rc)) throw rc;
     1887
     1888    pReturnNewMachine = p;
     1889
     1890    rc = mVirtualBox->RegisterMachine(pNewMachine);
     1891    if (FAILED(rc)) throw rc;
     1892
     1893    // store new machine for roll-back in case of errors
     1894    Bstr bstrNewMachineId;
     1895    rc = pNewMachine->COMGETTER(Id)(bstrNewMachineId.asOutParam());
     1896    if (FAILED(rc)) throw rc;
     1897    stack.llMachinesRegistered.push_back(bstrNewMachineId);
    18681898}
    18691899
  • trunk/src/VBox/Main/MachineImpl.cpp

    r28098 r28110  
    296296    if (FAILED(rc)) return rc;
    297297
     298    rc = tryCreateMachineConfigFile(aOverride);
     299    if (FAILED(rc)) return rc;
     300
     301    if (SUCCEEDED(rc))
     302    {
     303        // create an empty machine config
     304        mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);
     305
     306        rc = initDataAndChildObjects();
     307    }
     308
     309    if (SUCCEEDED(rc))
     310    {
     311        // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
     312        mData->mAccessible = TRUE;
     313
     314        unconst(mData->mUuid) = aId;
     315
     316        mUserData->mName = strName;
     317        mUserData->mNameSync = aNameSync;
     318
     319        /* initialize the default snapshots folder
     320         * (note: depends on the name value set above!) */
     321        rc = COMSETTER(SnapshotFolder)(NULL);
     322        AssertComRC(rc);
     323
     324        if (aOsType)
     325        {
     326            /* Store OS type */
     327            mUserData->mOSTypeId = aOsType->id();
     328
     329            /* Apply BIOS defaults */
     330            mBIOSSettings->applyDefaults(aOsType);
     331
     332            /* Apply network adapters defaults */
     333            for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot)
     334                mNetworkAdapters[slot]->applyDefaults(aOsType);
     335
     336            /* Apply serial port defaults */
     337            for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
     338                mSerialPorts[slot]->applyDefaults(aOsType);
     339        }
     340
     341        /* commit all changes made during the initialization */
     342        commit();
     343    }
     344
     345    /* Confirm a successful initialization when it's the case */
     346    if (SUCCEEDED(rc))
     347    {
     348        if (mData->mAccessible)
     349            autoInitSpan.setSucceeded();
     350        else
     351            autoInitSpan.setLimited();
     352    }
     353
     354    LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool, rc=%08X\n",
     355                     !!mUserData ? mUserData->mName.raw() : NULL,
     356                     mData->mRegistered,
     357                     mData->mAccessible,
     358                     rc));
     359
     360    LogFlowThisFuncLeave();
     361
     362    return rc;
     363}
     364
     365/**
     366 *  Initializes a new instance with data from machine XML (formerly Init_Registered).
     367 *  Gets called in two modes:
     368 *      -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the
     369 *         UUID is specified and we mark the machine as "registered";
     370 *      -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL
     371 *         and the machine remains unregistered until RegisterMachine() is called.
     372 *
     373 *  @param aParent      Associated parent object
     374 *  @param aConfigFile  Local file system path to the VM settings file (can
     375 *                      be relative to the VirtualBox config directory).
     376 *  @param aId          UUID of the machine or NULL (see above).
     377 *
     378 *  @return  Success indicator. if not S_OK, the machine object is invalid
     379 */
     380HRESULT Machine::init(VirtualBox *aParent,
     381                      const Utf8Str &strConfigFile,
     382                      const Guid *aId)
     383{
     384    LogFlowThisFuncEnter();
     385    LogFlowThisFunc(("(Init_Registered) aConfigFile='%s\n", strConfigFile.raw()));
     386
     387    /* Enclose the state transition NotReady->InInit->Ready */
     388    AutoInitSpan autoInitSpan(this);
     389    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     390
     391    HRESULT rc = initImpl(aParent, strConfigFile);
     392    if (FAILED(rc)) return rc;
     393
     394    if (aId)
     395    {
     396        // loading a registered VM:
     397        unconst(mData->mUuid) = *aId;
     398        mData->mRegistered = TRUE;
     399        // now load the settings from XML:
     400        rc = registeredInit();
     401            // this calls initDataAndChildObjects() and loadSettings()
     402    }
     403    else
     404    {
     405        // opening an unregistered VM (VirtualBox::OpenMachine()):
     406        rc = initDataAndChildObjects();
     407
     408        if (SUCCEEDED(rc))
     409        {
     410            // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
     411            mData->mAccessible = TRUE;
     412
     413            try
     414            {
     415                // load and parse machine XML; this will throw on XML or logic errors
     416                mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull);
     417
     418                // use UUID from machine config
     419                unconst(mData->mUuid) = mData->pMachineConfigFile->uuid;
     420
     421                rc = loadMachineDataFromSettings(*mData->pMachineConfigFile);
     422                if (FAILED(rc)) throw rc;
     423
     424                commit();
     425            }
     426            catch (HRESULT err)
     427            {
     428                /* we assume that error info is set by the thrower */
     429                rc = err;
     430            }
     431            catch (...)
     432            {
     433                rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
     434            }
     435        }
     436    }
     437
     438    /* Confirm a successful initialization when it's the case */
     439    if (SUCCEEDED(rc))
     440    {
     441        if (mData->mAccessible)
     442            autoInitSpan.setSucceeded();
     443        else
     444            autoInitSpan.setLimited();
     445    }
     446
     447    LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
     448                      "rc=%08X\n",
     449                      !!mUserData ? mUserData->mName.raw() : NULL,
     450                      mData->mRegistered, mData->mAccessible, rc));
     451
     452    LogFlowThisFuncLeave();
     453
     454    return rc;
     455}
     456
     457/**
     458 *  Initializes a new instance from a machine config that is already in memory
     459 *  (import OVF import case). Since we are importing, the UUID in the machine
     460 *  config is ignored and we always generate a fresh one.
     461 *
     462 *  @param strName  Name for the new machine; this overrides what is specified in config and is used
     463 *                  for the settings file as well.
     464 *  @param config   Machine configuration loaded and parsed from XML.
     465 *
     466 *  @return  Success indicator. if not S_OK, the machine object is invalid
     467 */
     468HRESULT Machine::init(VirtualBox *aParent,
     469                      const Utf8Str &strName,
     470                      const settings::MachineConfigFile &config)
     471{
     472    LogFlowThisFuncEnter();
     473
     474    /* Enclose the state transition NotReady->InInit->Ready */
     475    AutoInitSpan autoInitSpan(this);
     476    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     477
     478    Utf8Str strConfigFile(aParent->getDefaultMachineFolder());
     479    strConfigFile.append(Utf8StrFmt("%c%s%c%s.xml",
     480                                    RTPATH_DELIMITER,
     481                                    strName.c_str(),
     482                                    RTPATH_DELIMITER,
     483                                    strName.c_str()));
     484
     485    HRESULT rc = initImpl(aParent, strConfigFile);
     486    if (FAILED(rc)) return rc;
     487
     488    rc = tryCreateMachineConfigFile(FALSE /* aOverride */);
     489    if (FAILED(rc)) return rc;
     490
     491    rc = initDataAndChildObjects();
     492
     493    if (SUCCEEDED(rc))
     494    {
     495        // set to true now to cause uninit() to call uninitDataAndChildObjects() on failure
     496        mData->mAccessible = TRUE;
     497
     498        // create empty machine config for instance data
     499        mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);
     500
     501        // generate fresh UUID, ignore machine config
     502        unconst(mData->mUuid).create();
     503
     504        rc = loadMachineDataFromSettings(config);
     505
     506        // override VM name as well, it may be different
     507        mUserData->mName = strName;
     508
     509        /* commit all changes made during the initialization */
     510        if (SUCCEEDED(rc))
     511            commit();
     512    }
     513
     514    /* Confirm a successful initialization when it's the case */
     515    if (SUCCEEDED(rc))
     516    {
     517        if (mData->mAccessible)
     518            autoInitSpan.setSucceeded();
     519        else
     520            autoInitSpan.setLimited();
     521    }
     522
     523    LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
     524                     "rc=%08X\n",
     525                      !!mUserData ? mUserData->mName.raw() : NULL,
     526                      mData->mRegistered, mData->mAccessible, rc));
     527
     528    LogFlowThisFuncLeave();
     529
     530    return rc;
     531}
     532
     533/**
     534 * Shared code between the various init() implementations.
     535 * @param aParent
     536 * @return
     537 */
     538HRESULT Machine::initImpl(VirtualBox *aParent,
     539                          const Utf8Str &strConfigFile)
     540{
     541    LogFlowThisFuncEnter();
     542
     543    AssertReturn(aParent, E_INVALIDARG);
     544    AssertReturn(!strConfigFile.isEmpty(), E_INVALIDARG);
     545
     546    HRESULT rc = S_OK;
     547
     548    /* share the parent weakly */
     549    unconst(mParent) = aParent;
     550
     551    /* allocate the essential machine data structure (the rest will be
     552     * allocated later by initDataAndChildObjects() */
     553    mData.allocate();
     554
     555    /* memorize the config file name (as provided) */
     556    mData->m_strConfigFile = strConfigFile;
     557
     558    /* get the full file name */
     559    int vrc1 = mParent->calculateFullPath(strConfigFile, mData->m_strConfigFileFull);
     560    if (RT_FAILURE(vrc1))
     561        return setError(VBOX_E_FILE_ERROR,
     562                        tr("Invalid machine settings file name '%s' (%Rrc)"),
     563                        strConfigFile.raw(),
     564                        vrc1);
     565
     566    LogFlowThisFuncLeave();
     567
     568    return rc;
     569}
     570
     571/**
     572 * Tries to create a machine settings file in the path stored in the machine
     573 * instance data. Used when a new machine is created to fail gracefully if
     574 * the settings file could not be written (e.g. because machine dir is read-only).
     575 * @return
     576 */
     577HRESULT Machine::tryCreateMachineConfigFile(BOOL aOverride)
     578{
     579    HRESULT rc = S_OK;
     580
    298581    // when we create a new machine, we must be able to create the settings file
    299582    RTFILE f = NIL_RTFILE;
     
    327610                      mData->m_strConfigFileFull.raw(),
    328611                      vrc);
    329 
    330     if (SUCCEEDED(rc))
    331     {
    332         // create an empty machine config
    333         mData->pMachineConfigFile = new settings::MachineConfigFile(NULL);
    334 
    335         rc = initDataAndChildObjects();
    336     }
    337 
    338     if (SUCCEEDED(rc))
    339     {
    340         /* set to true now to cause uninit() to call
    341          * uninitDataAndChildObjects() on failure */
    342         mData->mAccessible = TRUE;
    343 
    344         unconst(mData->mUuid) = aId;
    345 
    346         mUserData->mName = strName;
    347         mUserData->mNameSync = aNameSync;
    348 
    349         /* initialize the default snapshots folder
    350          * (note: depends on the name value set above!) */
    351         rc = COMSETTER(SnapshotFolder)(NULL);
    352         AssertComRC(rc);
    353 
    354         if (aOsType)
    355         {
    356             /* Store OS type */
    357             mUserData->mOSTypeId = aOsType->id();
    358 
    359             /* Apply BIOS defaults */
    360             mBIOSSettings->applyDefaults(aOsType);
    361 
    362             /* Apply network adapters defaults */
    363             for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot)
    364                 mNetworkAdapters[slot]->applyDefaults(aOsType);
    365 
    366             /* Apply serial port defaults */
    367             for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
    368                 mSerialPorts[slot]->applyDefaults(aOsType);
    369         }
    370 
    371         /* commit all changes made during the initialization */
    372         commit();
    373     }
    374 
    375     /* Confirm a successful initialization when it's the case */
    376     if (SUCCEEDED(rc))
    377     {
    378         if (mData->mAccessible)
    379             autoInitSpan.setSucceeded();
    380         else
    381             autoInitSpan.setLimited();
    382     }
    383 
    384     LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool, rc=%08X\n",
    385                      !!mUserData ? mUserData->mName.raw() : NULL,
    386                      mData->mRegistered,
    387                      mData->mAccessible,
    388                      rc));
    389 
    390     LogFlowThisFuncLeave();
    391 
    392     return rc;
    393 }
    394 
    395 /**
    396  *  Initializes a new instance with data from machine XML (formerly Init_Registered).
    397  *  Gets called in two modes:
    398  *      -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the
    399  *         UUID is specified and we mark the machine as "registered";
    400  *      -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL
    401  *         and the machine remains unregistered until RegisterMachine() is called.
    402  *
    403  *  @param aParent      Associated parent object
    404  *  @param aConfigFile  Local file system path to the VM settings file (can
    405  *                      be relative to the VirtualBox config directory).
    406  *  @param aId          UUID of the machine or NULL (see above).
    407  *
    408  *  @return  Success indicator. if not S_OK, the machine object is invalid
    409  */
    410 HRESULT Machine::init(VirtualBox *aParent,
    411                       const Utf8Str &strConfigFile,
    412                       const Guid *aId)
    413 {
    414     LogFlowThisFuncEnter();
    415     LogFlowThisFunc(("(Init_Registered) aConfigFile='%s\n", strConfigFile.raw()));
    416 
    417     /* Enclose the state transition NotReady->InInit->Ready */
    418     AutoInitSpan autoInitSpan(this);
    419     AssertReturn(autoInitSpan.isOk(), E_FAIL);
    420 
    421     HRESULT rc = initImpl(aParent, strConfigFile);
    422     if (FAILED(rc)) return rc;
    423 
    424     if (aId)
    425     {
    426         // loading a registered VM:
    427         unconst(mData->mUuid) = *aId;
    428         mData->mRegistered = TRUE;
    429         // now load the settings from XML:
    430         rc = registeredInit();
    431             // this calls initDataAndChildObjects() and loadSettings()
    432     }
    433     else
    434     {
    435         // opening an unregistered VM (VirtualBox::OpenMachine()):
    436         rc = initDataAndChildObjects();
    437 
    438         if (SUCCEEDED(rc))
    439         {
    440             /* set to true now to cause uninit() to call
    441              * uninitDataAndChildObjects() on failure */
    442             mData->mAccessible = TRUE;
    443 
    444             rc = loadSettings(false /* aRegistered */);
    445 
    446             /* commit all changes made during the initialization */
    447             if (SUCCEEDED(rc))
    448                 commit();
    449         }
    450     }
    451 
    452     /* Confirm a successful initialization when it's the case */
    453     if (SUCCEEDED(rc))
    454     {
    455         if (mData->mAccessible)
    456             autoInitSpan.setSucceeded();
    457         else
    458             autoInitSpan.setLimited();
    459     }
    460 
    461     LogFlowThisFunc(("mName='%ls', mRegistered=%RTbool, mAccessible=%RTbool "
    462                       "rc=%08X\n",
    463                       !!mUserData ? mUserData->mName.raw() : NULL,
    464                       mData->mRegistered, mData->mAccessible, rc));
    465 
    466     LogFlowThisFuncLeave();
    467 
    468     return rc;
    469 }
    470 
    471 /**
    472  * Shared code between the various init() implementation.s
    473  * @param aParent
    474  * @return
    475  */
    476 HRESULT Machine::initImpl(VirtualBox *aParent,
    477                           const Utf8Str &strConfigFile)
    478 {
    479     LogFlowThisFuncEnter();
    480 
    481     AssertReturn(aParent, E_INVALIDARG);
    482     AssertReturn(!strConfigFile.isEmpty(), E_INVALIDARG);
    483 
    484     HRESULT rc = S_OK;
    485 
    486     /* share the parent weakly */
    487     unconst(mParent) = aParent;
    488 
    489     /* allocate the essential machine data structure (the rest will be
    490      * allocated later by initDataAndChildObjects() */
    491     mData.allocate();
    492 
    493     /* memorize the config file name (as provided) */
    494     mData->m_strConfigFile = strConfigFile;
    495 
    496     /* get the full file name */
    497     int vrc1 = mParent->calculateFullPath(strConfigFile, mData->m_strConfigFileFull);
    498     if (RT_FAILURE(vrc1))
    499         return setError(VBOX_E_FILE_ERROR,
    500                         tr("Invalid machine settings file name '%s' (%Rrc)"),
    501                         strConfigFile.raw(),
    502                         vrc1);
    503 
    504     LogFlowThisFuncLeave();
    505 
    506612    return rc;
    507613}
     
    535641        mData->mRegistered = FALSE;
    536642
    537         rc = loadSettings(true /* aRegistered */);
     643        try
     644        {
     645            // load and parse machine XML; this will throw on XML or logic errors
     646            mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull);
     647
     648            if (mData->mUuid != mData->pMachineConfigFile->uuid)
     649                throw setError(E_FAIL,
     650                               tr("Machine UUID {%RTuuid} in '%s' doesn't match its UUID {%s} in the registry file '%s'"),
     651                               mData->pMachineConfigFile->uuid.raw(),
     652                               mData->m_strConfigFileFull.raw(),
     653                               mData->mUuid.toString().raw(),
     654                               mParent->settingsFilePath().raw());
     655
     656            rc = loadMachineDataFromSettings(*mData->pMachineConfigFile);
     657            if (FAILED(rc)) throw rc;
     658        }
     659        catch (HRESULT err)
     660        {
     661            /* we assume that error info is set by the thrower */
     662            rc = err;
     663        }
     664        catch (...)
     665        {
     666            rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
     667        }
    538668
    539669        /* Restore the registered flag (even on failure) */
     
    63106440
    63116441/**
    6312  *  Loads all the VM settings by walking down the <Machine> node.
    6313  *
    6314  *  @param aRegistered  true when the machine is being loaded on VirtualBox
    6315  *                      startup
    6316  *
    6317  *  @note This method is intended to be called only from init(), so it assumes
    6318  *  all machine data fields have appropriate default values when it is called.
    6319  *
    6320  *  @note Doesn't lock any objects.
     6442 * Initializes all machine instance data from the given settings structures
     6443 * from XML. The exception is the machine UUID which needs special handling
     6444 * depending on the caller's use case, so the caller needs to set that herself.
     6445 *
     6446 * @param config
     6447 * @param fAllowStorage
    63216448 */
    6322 HRESULT Machine::loadSettings(bool aRegistered)
    6323 {
    6324     LogFlowThisFuncEnter();
    6325     AssertReturn(getClassID() == clsidMachine, E_FAIL);
    6326 
    6327     AutoCaller autoCaller(this);
    6328     AssertReturn(autoCaller.state() == InInit, E_FAIL);
    6329 
    6330     HRESULT rc = S_OK;
    6331 
    6332     try
    6333     {
    6334         Assert(mData->pMachineConfigFile == NULL);
    6335 
    6336         // load and parse machine XML; this will throw on XML or logic errors
    6337         mData->pMachineConfigFile = new settings::MachineConfigFile(&mData->m_strConfigFileFull);
    6338 
    6339         /* If the stored UUID is not empty, it means the registered machine
    6340          * is being loaded. Compare the loaded UUID with the stored one taken
    6341          * from the global registry. */
    6342         if (!mData->mUuid.isEmpty())
    6343         {
    6344             if (mData->mUuid != mData->pMachineConfigFile->uuid)
    6345             {
    6346                 throw setError(E_FAIL,
    6347                                tr("Machine UUID {%RTuuid} in '%s' doesn't match its UUID {%s} in the registry file '%s'"),
    6348                                mData->pMachineConfigFile->uuid.raw(),
    6349                                mData->m_strConfigFileFull.raw(),
    6350                                mData->mUuid.toString().raw(),
    6351                                mParent->settingsFilePath().raw());
    6352             }
    6353         }
    6354         else
    6355             unconst(mData->mUuid) = mData->pMachineConfigFile->uuid;
    6356 
    6357         /* name (required) */
    6358         mUserData->mName = mData->pMachineConfigFile->strName;
    6359 
    6360         /* nameSync (optional, default is true) */
    6361         mUserData->mNameSync = mData->pMachineConfigFile->fNameSync;
    6362 
    6363         mUserData->mDescription = mData->pMachineConfigFile->strDescription;
    6364 
    6365         // guest OS type
    6366         mUserData->mOSTypeId = mData->pMachineConfigFile->strOsType;
    6367         /* look up the object by Id to check it is valid */
    6368         ComPtr<IGuestOSType> guestOSType;
    6369         rc = mParent->GetGuestOSType(mUserData->mOSTypeId,
    6370                                      guestOSType.asOutParam());
    6371         if (FAILED(rc)) throw rc;
    6372 
    6373         // stateFile (optional)
    6374         if (mData->pMachineConfigFile->strStateFile.isEmpty())
    6375             mSSData->mStateFilePath.setNull();
    6376         else
    6377         {
    6378             Utf8Str stateFilePathFull(mData->pMachineConfigFile->strStateFile);
    6379             int vrc = calculateFullPath(stateFilePathFull, stateFilePathFull);
    6380             if (RT_FAILURE(vrc))
    6381                 throw setError(E_FAIL,
    6382                                 tr("Invalid saved state file path '%s' (%Rrc)"),
    6383                                 mData->pMachineConfigFile->strStateFile.raw(),
    6384                                 vrc);
    6385             mSSData->mStateFilePath = stateFilePathFull;
    6386         }
    6387 
    6388         /* snapshotFolder (optional) */
    6389         rc = COMSETTER(SnapshotFolder)(Bstr(mData->pMachineConfigFile->strSnapshotFolder));
    6390         if (FAILED(rc)) throw rc;
    6391 
    6392         /* currentStateModified (optional, default is true) */
    6393         mData->mCurrentStateModified = mData->pMachineConfigFile->fCurrentStateModified;
    6394 
    6395         mData->mLastStateChange = mData->pMachineConfigFile->timeLastStateChange;
    6396 
    6397         /* teleportation */
    6398         mUserData->mTeleporterEnabled  = mData->pMachineConfigFile->fTeleporterEnabled;
    6399         mUserData->mTeleporterPort     = mData->pMachineConfigFile->uTeleporterPort;
    6400         mUserData->mTeleporterAddress  = mData->pMachineConfigFile->strTeleporterAddress;
    6401         mUserData->mTeleporterPassword = mData->pMachineConfigFile->strTeleporterPassword;
    6402 
    6403         /* RTC */
    6404         mUserData->mRTCUseUTC = mData->pMachineConfigFile->fRTCUseUTC;
    6405 
    6406         /*
    6407          *  note: all mUserData members must be assigned prior this point because
    6408          *  we need to commit changes in order to let mUserData be shared by all
    6409          *  snapshot machine instances.
    6410          */
    6411         mUserData.commitCopy();
    6412 
    6413         /* Snapshot node (optional) */
    6414         size_t cRootSnapshots;
    6415         if ((cRootSnapshots = mData->pMachineConfigFile->llFirstSnapshot.size()))
    6416         {
    6417             // there must be only one root snapshot
    6418             Assert(cRootSnapshots == 1);
    6419 
    6420             settings::Snapshot &snap = mData->pMachineConfigFile->llFirstSnapshot.front();
    6421 
    6422             rc = loadSnapshot(snap,
    6423                               mData->pMachineConfigFile->uuidCurrentSnapshot,
    6424                               NULL);        // no parent == first snapshot
    6425             if (FAILED(rc)) throw rc;
    6426         }
    6427 
    6428         /* Hardware node (required) */
    6429         rc = loadHardware(mData->pMachineConfigFile->hardwareMachine);
    6430         if (FAILED(rc)) throw rc;
    6431 
    6432         /* Load storage controllers */
    6433         rc = loadStorageControllers(mData->pMachineConfigFile->storageMachine, aRegistered);
    6434         if (FAILED(rc)) throw rc;
    6435 
    6436         /*
    6437          *  NOTE: the assignment below must be the last thing to do,
    6438          *  otherwise it will be not possible to change the settings
    6439          *  somewehere in the code above because all setters will be
    6440          *  blocked by checkStateDependency(MutableStateDep).
    6441          */
    6442 
    6443         /* set the machine state to Aborted or Saved when appropriate */
    6444         if (mData->pMachineConfigFile->fAborted)
    6445         {
    6446             Assert(!mSSData->mStateFilePath.isEmpty());
    6447             mSSData->mStateFilePath.setNull();
    6448 
    6449             /* no need to use setMachineState() during init() */
    6450             mData->mMachineState = MachineState_Aborted;
    6451         }
    6452         else if (!mSSData->mStateFilePath.isEmpty())
    6453         {
    6454             /* no need to use setMachineState() during init() */
    6455             mData->mMachineState = MachineState_Saved;
    6456         }
    6457 
    6458         // after loading settings, we are no longer different from the XML on disk
    6459         mData->flModifications = 0;
    6460     }
    6461     catch (HRESULT err)
    6462     {
    6463         /* we assume that error info is set by the thrower */
    6464         rc = err;
    6465     }
    6466     catch (...)
    6467     {
    6468         rc = VirtualBox::handleUnexpectedExceptions(RT_SRC_POS);
    6469     }
    6470 
    6471     LogFlowThisFuncLeave();
    6472     return rc;
     6449HRESULT Machine::loadMachineDataFromSettings(const settings::MachineConfigFile &config)
     6450{
     6451    /* name (required) */
     6452    mUserData->mName = config.strName;
     6453
     6454    /* nameSync (optional, default is true) */
     6455    mUserData->mNameSync = config.fNameSync;
     6456
     6457    mUserData->mDescription = config.strDescription;
     6458
     6459    // guest OS type
     6460    mUserData->mOSTypeId = config.strOsType;
     6461    /* look up the object by Id to check it is valid */
     6462    ComPtr<IGuestOSType> guestOSType;
     6463    HRESULT rc = mParent->GetGuestOSType(mUserData->mOSTypeId,
     6464                                         guestOSType.asOutParam());
     6465    if (FAILED(rc)) return rc;
     6466
     6467    // stateFile (optional)
     6468    if (config.strStateFile.isEmpty())
     6469        mSSData->mStateFilePath.setNull();
     6470    else
     6471    {
     6472        Utf8Str stateFilePathFull(config.strStateFile);
     6473        int vrc = calculateFullPath(stateFilePathFull, stateFilePathFull);
     6474        if (RT_FAILURE(vrc))
     6475            return setError(E_FAIL,
     6476                            tr("Invalid saved state file path '%s' (%Rrc)"),
     6477                            config.strStateFile.raw(),
     6478                            vrc);
     6479        mSSData->mStateFilePath = stateFilePathFull;
     6480    }
     6481
     6482    /* snapshotFolder (optional) */
     6483    rc = COMSETTER(SnapshotFolder)(Bstr(config.strSnapshotFolder));
     6484    if (FAILED(rc)) return rc;
     6485
     6486    /* currentStateModified (optional, default is true) */
     6487    mData->mCurrentStateModified = config.fCurrentStateModified;
     6488
     6489    mData->mLastStateChange = config.timeLastStateChange;
     6490
     6491    /* teleportation */
     6492    mUserData->mTeleporterEnabled  = config.fTeleporterEnabled;
     6493    mUserData->mTeleporterPort     = config.uTeleporterPort;
     6494    mUserData->mTeleporterAddress  = config.strTeleporterAddress;
     6495    mUserData->mTeleporterPassword = config.strTeleporterPassword;
     6496
     6497    /* RTC */
     6498    mUserData->mRTCUseUTC = config.fRTCUseUTC;
     6499
     6500    /*
     6501     *  note: all mUserData members must be assigned prior this point because
     6502     *  we need to commit changes in order to let mUserData be shared by all
     6503     *  snapshot machine instances.
     6504     */
     6505    mUserData.commitCopy();
     6506
     6507    /* Snapshot node (optional) */
     6508    size_t cRootSnapshots;
     6509    if ((cRootSnapshots = config.llFirstSnapshot.size()))
     6510    {
     6511        // there must be only one root snapshot
     6512        Assert(cRootSnapshots == 1);
     6513
     6514        const settings::Snapshot &snap = config.llFirstSnapshot.front();
     6515
     6516        rc = loadSnapshot(snap,
     6517                          config.uuidCurrentSnapshot,
     6518                          NULL);        // no parent == first snapshot
     6519        if (FAILED(rc)) return rc;
     6520    }
     6521
     6522    /* Hardware node (required) */
     6523    rc = loadHardware(config.hardwareMachine);
     6524    if (FAILED(rc)) return rc;
     6525
     6526    /* Load storage controllers */
     6527    rc = loadStorageControllers(config.storageMachine);
     6528    if (FAILED(rc)) return rc;
     6529
     6530    /*
     6531        *  NOTE: the assignment below must be the last thing to do,
     6532        *  otherwise it will be not possible to change the settings
     6533        *  somewehere in the code above because all setters will be
     6534        *  blocked by checkStateDependency(MutableStateDep).
     6535        */
     6536
     6537    /* set the machine state to Aborted or Saved when appropriate */
     6538    if (config.fAborted)
     6539    {
     6540        Assert(!mSSData->mStateFilePath.isEmpty());
     6541        mSSData->mStateFilePath.setNull();
     6542
     6543        /* no need to use setMachineState() during init() */
     6544        mData->mMachineState = MachineState_Aborted;
     6545    }
     6546    else if (!mSSData->mStateFilePath.isEmpty())
     6547    {
     6548        /* no need to use setMachineState() during init() */
     6549        mData->mMachineState = MachineState_Saved;
     6550    }
     6551
     6552    // after loading settings, we are no longer different from the XML on disk
     6553    mData->flModifications = 0;
     6554
     6555    return S_OK;
    64736556}
    64746557
     
    67616844   */
    67626845HRESULT Machine::loadStorageControllers(const settings::Storage &data,
    6763                                         bool aRegistered,
    67646846                                        const Guid *aSnapshotId /* = NULL */)
    67656847{
     
    68116893        rc = loadStorageDevices(pCtl,
    68126894                                ctlData,
    6813                                 aRegistered,
    68146895                                aSnapshotId);
    68156896        if (FAILED(rc)) return rc;
     
    68216902/**
    68226903 * @param aNode        <HardDiskAttachments> node.
    6823  * @param aRegistered  true when the machine is being loaded on VirtualBox
    6824  *                     startup, or when a snapshot is being loaded (which
    6825  *                     currently can happen on startup only)
     6904 * @param fAllowStorage if false, we produce an error if the config requests media attachments
     6905 *                      (used with importing unregistered machines which cannot have media attachments)
    68266906 * @param aSnapshotId  pointer to the snapshot ID if this is a snapshot machine
    68276907 *
     
    68306910HRESULT Machine::loadStorageDevices(StorageController *aStorageController,
    68316911                                    const settings::StorageController &data,
    6832                                     bool aRegistered,
    68336912                                    const Guid *aSnapshotId /*= NULL*/)
    68346913{
     
    68386917
    68396918    HRESULT rc = S_OK;
    6840 
    6841     if (!aRegistered && data.llAttachedDevices.size() > 0)
    6842         /* when the machine is being loaded (opened) from a file, it cannot
    6843          * have hard disks attached (this should not happen normally,
    6844          * because we don't allow to attach hard disks to an unregistered
    6845          * VM at all */
    6846         return setError(E_FAIL,
    6847                         tr("Unregistered machine '%ls' cannot have storage devices attached (found %d attachments)"),
    6848                         mUserData->mName.raw(),
    6849                         data.llAttachedDevices.size());
    68506919
    68516920    /* paranoia: detect duplicate attachments */
  • trunk/src/VBox/Main/SnapshotImpl.cpp

    r28091 r28110  
    10191019    HRESULT rc = loadHardware(hardware);
    10201020    if (SUCCEEDED(rc))
    1021         rc = loadStorageControllers(storage, true /* aRegistered */, &mSnapshotId);
     1021        rc = loadStorageControllers(storage, &mSnapshotId);
    10221022
    10231023    if (SUCCEEDED(rc))
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r28098 r28110  
    148148    HRESULT importFS(const LocationInfo &locInfo, ComObjPtr<Progress> &aProgress);
    149149    struct ImportStack;
    150     void importVBoxMachine(const settings::MachineConfigFile &config,
     150    void importVBoxMachine(ComObjPtr<VirtualSystemDescription> &vsdescThis,
    151151                           ComPtr<IMachine> &pNewMachine,
    152152                           ImportStack &stack);
  • trunk/src/VBox/Main/include/MachineImpl.h

    r28091 r28110  
    364364                 const Guid *aId);
    365365
     366    // initializer for machine config in memory (OVF import)
     367    HRESULT init(VirtualBox *aParent,
     368                 const Utf8Str &strName,
     369                 const settings::MachineConfigFile &config);
     370
    366371    void uninit();
    367372
     
    370375                     const Utf8Str &strConfigFile);
    371376    HRESULT initDataAndChildObjects();
     377    HRESULT registeredInit();
     378    HRESULT tryCreateMachineConfigFile(BOOL aOverride);
    372379    void uninitDataAndChildObjects();
    373380
     
    703710protected:
    704711
    705     HRESULT registeredInit();
    706 
    707712    HRESULT checkStateDependency(StateDependency aDepType);
    708713
     
    718723
    719724    HRESULT loadSettings(bool aRegistered);
     725    HRESULT loadMachineDataFromSettings(const settings::MachineConfigFile &config);
    720726    HRESULT loadSnapshot(const settings::Snapshot &data,
    721727                         const Guid &aCurSnapshotId,
     
    723729    HRESULT loadHardware(const settings::Hardware &data);
    724730    HRESULT loadStorageControllers(const settings::Storage &data,
    725                                    bool aRegistered,
    726731                                   const Guid *aSnapshotId = NULL);
    727732    HRESULT loadStorageDevices(StorageController *aStorageController,
    728733                               const settings::StorageController &data,
    729                                bool aRegistered,
    730734                               const Guid *aSnapshotId = NULL);
    731735
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