VirtualBox

Changeset 3317 in vbox for trunk/src


Ignore:
Timestamp:
Jun 27, 2007 2:45:20 PM (18 years ago)
Author:
vboxsync
Message:

Main: Improved error handling when opening hard disks using the generic IVirtualBox::openHardDisk() call (#2017).

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

Legend:

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

    r3093 r3317  
    3333#include <iprt/cpputils.h>
    3434#include <VBox/VBoxHDD.h>
    35 #include <VBox/VBoxHDD-new.h>
    3635#include <VBox/err.h>
    3736
     
    485484
    486485    /* create the hard disk creation thread, pass operation data */
    487     int vrc = RTThreadCreate (NULL, HVirtualDiskImage::vdiTaskThread,
     486    int vrc = RTThreadCreate (NULL, HVirtualDiskImage::VDITaskThread,
    488487                              (void *) task, 0, RTTHREADTYPE_MAIN_HEAVY_WORKER,
    489488                              0, "VDITask");
     
    10621061    AssertReturn (*aLocation, E_INVALIDARG);
    10631062
    1064     HRESULT rc = S_OK;
     1063    static const struct
     1064    {
     1065        HardDiskStorageType_T type;
     1066        const char *ext;
     1067    }
     1068    storageTypes[] =
     1069    {
     1070        { HardDiskStorageType_VMDKImage, ".vmdk" },
     1071        { HardDiskStorageType_VirtualDiskImage, ".vdi" },
     1072    };
    10651073
    10661074    /* try to guess the probe order by extension */
     1075    size_t first = -1;
    10671076    Utf8Str loc = aLocation;
    10681077    char *ext = RTPathExt (loc);
    10691078
    1070     HardDiskStorageType_T order [2];
    1071     size_t cOrder = ELEMENTS (order);
    1072 
    1073     if (RTPathCompare (ext, ".vmdk") == 0)
    1074     {
    1075         /// @todo This is a hack. The proper solution would be to save the
    1076         /// error info from the first try and restore that if everything fails.
    1077         /// That way a non-working VMDK will get a proper VMDK diagnostics
    1078         /// message and not some incomprehensible VDI error.
    1079         order [0] = HardDiskStorageType_VMDKImage;
    1080         cOrder = 1;
    1081     }
    1082     else
    1083     {
    1084         order [0] = HardDiskStorageType_VirtualDiskImage;
    1085         order [1] = HardDiskStorageType_VMDKImage;
    1086     }
    1087 
    1088     for (size_t i = 0; i < cOrder; ++ i)
    1089     {
    1090         switch (order [i])
     1079    for (size_t i = 0; i < ELEMENTS (storageTypes); ++ i)
     1080    {
     1081        if (RTPathCompare (ext, storageTypes [i].ext) == 0)
     1082        {
     1083            first = i;
     1084            break;
     1085        }
     1086    }
     1087
     1088    HRESULT rc = S_OK;
     1089
     1090    HRESULT firstRC = S_OK;
     1091    com::ErrorInfoKeeper firstErr (true /* aIsNull */);
     1092
     1093    for (size_t i = 0; i < ELEMENTS (storageTypes); ++ i)
     1094    {
     1095        size_t j = first == -1 ? i : i == 0 ? first : i == first ? 0 : i;
     1096        switch (storageTypes [j].type)
    10911097        {
    10921098            case HardDiskStorageType_VirtualDiskImage:
     
    11181124            default:
    11191125            {
    1120                 ComAssertComRCRetRC (E_FAIL);
     1126                AssertComRCReturnRC (E_FAIL);
    11211127            }
    11221128        }
    1123     }
    1124 
    1125     return rc;
     1129
     1130        Assert (FAILED (rc));
     1131
     1132        /* remember the first encountered error */
     1133        if (j == first)
     1134        {
     1135            firstRC = rc;
     1136            firstErr.fetch();
     1137        }
     1138    }
     1139
     1140    if (first != -1)
     1141    {
     1142        Assert (FAILED (firstRC));
     1143        /* firstErr will restore the error info upon destruction */
     1144        return firstRC;
     1145    }
     1146
     1147    /* There was no exact extension match; chances are high that an error we
     1148     * got after probing is useless. Use a generic error message instead. */
     1149
     1150    firstErr.forget();
     1151
     1152    return setError (E_FAIL,
     1153        tr ("Could not recognize the format of the hard disk '%ls'. "
     1154            "Either the given format is not supported or hard disk data "
     1155            "is corrupt"),
     1156        aLocation);
    11261157}
    11271158
     
    25992630
    26002631    /* create the hard disk creation thread, pass operation data */
    2601     vrc = RTThreadCreate (NULL, vdiTaskThread, (void *) task, 0,
     2632    vrc = RTThreadCreate (NULL, VDITaskThread, (void *) task, 0,
    26022633                          RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, "VDITask");
    26032634    ComAssertMsgRC (vrc, ("Could not create a thread (%Vrc)", vrc));
     
    26182649
    26192650/* static */
    2620 DECLCALLBACK(int) HVirtualDiskImage::vdiTaskThread (RTTHREAD thread, void *pvUser)
     2651DECLCALLBACK(int) HVirtualDiskImage::VDITaskThread (RTTHREAD thread, void *pvUser)
    26212652{
    26222653    VDITask *task = static_cast <VDITask *> (pvUser);
    26232654    AssertReturn (task, VERR_GENERAL_FAILURE);
    26242655
    2625     LogFlow (("vdiTaskThread(): operation=%d, size=%llu\n",
    2626               task->operation, task->size));
     2656    LogFlowFunc (("operation=%d, size=%llu\n", task->operation, task->size));
    26272657
    26282658    VDIIMAGETYPE type = (VDIIMAGETYPE) 0;
     
    26752705    }
    26762706
    2677     LogFlow (("vdiTaskThread(): rc=%08X\n", rc));
     2707    LogFlowFunc (("rc=%08X\n", rc));
    26782708
    26792709    AutoLock alock (task->vdi);
     
    33133343    mActualSize = 0;
    33143344
     3345    /* initialize the container */
     3346    int vrc = VDCreate ("VMDK", VDError, this, &mContainer);
     3347    ComAssertRCRet (vrc, E_FAIL);
     3348
    33153349    return S_OK;
    33163350}
     
    33183352void HVMDKImage::FinalRelease()
    33193353{
     3354    if (mContainer != NULL)
     3355        VDDestroy (mContainer);
     3356
    33203357    HardDisk::FinalRelease();
    33213358}
     
    39183955}
    39193956
    3920 DECLCALLBACK(void) VDError (void *pvUser, int rc, RT_SRC_POS_DECL,
    3921                             const char *pszFormat, va_list va)
    3922 {
    3923     /// @todo pass the error message to the operation initiator
    3924 }
    3925 
    39263957/**
    39273958 *  Helper to query information about the VDI hard disk.
     
    39633994    Bstr errMsg;
    39643995
    3965     PVBOXHDD hdd = NULL;
     3996    /* reset any previous error report from VDError() */
     3997    mLastVDError.setNull();
    39663998
    39673999    do
    39684000    {
    39694001        Guid id, parentId;
    3970 
    3971         /// @todo make PVBOXHDD a member variable and init/destroy it upon
    3972         /// image creation/deletion instead of doing that here every time.
    3973 
    3974         vrc = VDCreate ("VMDK", VDError, NULL, &hdd);
    3975         if (VBOX_FAILURE (vrc))
    3976             break;
    39774002
    39784003        /// @todo changed from VD_OPEN_FLAGS_READONLY to VD_OPEN_FLAGS_NORMAL,
     
    39814006        /// obviously. This of course changes locking behavior, but for now
    39824007        /// this is acceptable. A better solution needs to be found later.
    3983         vrc = VDOpen (hdd, filePath, VD_OPEN_FLAGS_NORMAL);
     4008        vrc = VDOpen (mContainer, filePath, VD_OPEN_FLAGS_NORMAL);
    39844009        if (VBOX_FAILURE (vrc))
    39854010            break;
    39864011
    3987         vrc = VDGetUuid (hdd, 0, id.ptr());
     4012        vrc = VDGetUuid (mContainer, 0, id.ptr());
    39884013        if (VBOX_FAILURE (vrc))
    39894014            break;
    3990         vrc = VDGetParentUuid (hdd, 0, parentId.ptr());
     4015        vrc = VDGetParentUuid (mContainer, 0, parentId.ptr());
    39914016        if (VBOX_FAILURE (vrc))
    39924017            break;
     
    40554080        if (!mParent)
    40564081        {
    4057             uint64_t size = VDGetSize (hdd);
     4082            uint64_t size = VDGetSize (mContainer);
    40584083            /* convert to MBytes */
    40594084            mSize = size / 1024 / 1024;
     
    40624087    while (0);
    40634088
    4064     if (hdd)
    4065         VDDestroy (hdd);
     4089    VDCloseAll (mContainer);
    40664090
    40674091    /* enter the lock again */
     
    40814105            if (!errMsg.isNull())
    40824106                *aAccessError = errMsg;
     4107            else if (!mLastVDError.isNull())
     4108                *aAccessError = mLastVDError;
    40834109            else if (VBOX_FAILURE (vrc))
    40844110                *aAccessError = Utf8StrFmt (
     
    41104136    }
    41114137
     4138    /* cleanup the last error report from VDError() */
     4139    mLastVDError.setNull();
     4140
    41124141    return rc;
    41134142}
     
    41314160
    41324161/* static */
    4133 DECLCALLBACK(int) HVMDKImage::vdiTaskThread (RTTHREAD thread, void *pvUser)
     4162DECLCALLBACK(int) HVMDKImage::VDITaskThread (RTTHREAD thread, void *pvUser)
    41344163{
    41354164    AssertMsgFailed (("Not implemented"));
     
    41374166
    41384167/// @todo (r=dmik) later
    4139 //  Use code from HVirtualDiskImage::vdiTaskThread as an example.
    4140 }
     4168//  Use code from HVirtualDiskImage::VDITaskThread as an example.
     4169}
     4170
     4171/* static */
     4172DECLCALLBACK(void) HVMDKImage::VDError (void *pvUser, int rc, RT_SRC_POS_DECL,
     4173                                        const char *pszFormat, va_list va)
     4174{
     4175    HVMDKImage *that = static_cast <HVMDKImage *> (pvUser);
     4176    AssertReturnVoid (that != NULL);
     4177
     4178    /// @todo pass the error message to the operation initiator
     4179    Utf8Str err = Utf8StrFmt (pszFormat, va);
     4180    if (VBOX_FAILURE (rc))
     4181        err = Utf8StrFmt ("%s (%Vrc)", err.raw(), rc);
     4182
     4183    if (that->mLastVDError.isNull())
     4184        that->mLastVDError = err;
     4185    else
     4186        that->mLastVDError = Utf8StrFmt
     4187            ("%s.\n%s", that->mLastVDError.raw(), err.raw());
     4188}
     4189
  • trunk/src/VBox/Main/include/HardDiskImpl.h

    r2981 r3317  
    2727
    2828#include <VBox/cfgldr.h>
     29#include <VBox/VBoxHDD-new.h>
    2930
    3031#include <iprt/semaphore.h>
     
    296297
    297298    /** VDI asynchronous operation thread function */
    298     static DECLCALLBACK(int) vdiTaskThread (RTTHREAD thread, void *pvUser);
     299    static DECLCALLBACK(int) VDITaskThread (RTTHREAD thread, void *pvUser);
    299300
    300301    enum State
     
    508509
    509510    /** VDI asynchronous operation thread function */
    510     static DECLCALLBACK(int) vdiTaskThread (RTTHREAD thread, void *pvUser);
     511    static DECLCALLBACK(int) VDITaskThread (RTTHREAD thread, void *pvUser);
     512
     513    static DECLCALLBACK(void) VDError (void *pvUser, int rc, RT_SRC_POS_DECL,
     514                                       const char *pszFormat, va_list va);
    511515
    512516    enum State
     
    531535    Bstr mFilePathFull;
    532536
     537    PVBOXHDD mContainer;
     538
     539    Utf8Str mLastVDError;
     540
    533541    friend class HardDisk;
    534542};
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