- Timestamp:
- Jan 26, 2007 10:49:57 AM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 17908
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HardDiskImpl.cpp
r132 r351 67 67 ComObjPtr <Progress> progress; 68 68 69 / / for CreateDynamic, CreateStatic69 /* for CreateDynamic, CreateStatic */ 70 70 uint64_t size; 71 71 72 / / for CloneToImage72 /* for CloneToImage */ 73 73 ComObjPtr <HardDisk> source; 74 74 }; … … 84 84 Progress *progress = static_cast <Progress *> (pvUser); 85 85 86 / / update the progress object86 /* update the progress object */ 87 87 if (progress) 88 88 progress->notifyProgress (uPercent); … … 172 172 Assert (isReady()); 173 173 174 / / uninit all children174 /* uninit all children */ 175 175 uninitDependentChildren(); 176 176 … … 332 332 HRESULT rc = S_OK; 333 333 334 / / check the accessibility state of all ancestors334 /* check the accessibility state of all ancestors */ 335 335 ComObjPtr <HardDisk> parent = (HardDisk *) mParent; 336 336 while (parent) … … 413 413 HRESULT rc = S_OK; 414 414 415 / / create a project object415 /* create a project object */ 416 416 ComObjPtr <Progress> progress; 417 417 progress.createObject(); … … 421 421 CheckComRCReturnRC (rc); 422 422 423 / / create an imageless resulting object423 /* create an imageless resulting object */ 424 424 ComObjPtr <HVirtualDiskImage> image; 425 425 image.createObject(); … … 427 427 CheckComRCReturnRC (rc); 428 428 429 / / append the default path if only a name is given429 /* append the default path if only a name is given */ 430 430 Bstr path = aFilePath; 431 431 { … … 441 441 } 442 442 443 / / set the desired path443 /* set the desired path */ 444 444 rc = image->setFilePath (path); 445 445 CheckComRCReturnRC (rc); 446 446 447 / / ensure the directory exists447 /* ensure the directory exists */ 448 448 { 449 449 Utf8Str imageDir = image->filePath(); … … 462 462 } 463 463 464 / /mark as busy (being created)465 // (VDI task thread will unmark it)464 /* mark as busy (being created) 465 * (VDI task thread will unmark it) */ 466 466 image->setBusy(); 467 467 468 / / fill in a VDI task data468 /* fill in a VDI task data */ 469 469 VDITask *task = new VDITask (VDITask::CloneToImage, image, progress); 470 470 task->source = this; 471 471 472 / /increase readers until finished473 // (VDI task thread will decrease them)472 /* increase readers until finished 473 * (VDI task thread will decrease them) */ 474 474 addReader(); 475 475 476 / / create the hard disk creation thread, pass operation data476 /* create the hard disk creation thread, pass operation data */ 477 477 int vrc = RTThreadCreate (NULL, HVirtualDiskImage::vdiTaskThread, 478 478 (void *) task, 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, … … 487 487 } 488 488 489 / / return interfaces to the caller489 /* return interfaces to the caller */ 490 490 image.queryInterfaceTo (aImage); 491 491 progress.queryInterfaceTo (aProgress); … … 706 706 AssertReturn (!mMachineId.isEmpty(), false); 707 707 708 / / check all children708 /* check all children */ 709 709 AutoLock chLock (childrenLock()); 710 710 for (HardDiskList::const_iterator it = children().begin(); … … 746 746 if (child->mReaders > 0 || child->mBusy) 747 747 { 748 / / reset the busy flag of all previous children748 /* reset the busy flag of all previous children */ 749 749 while (it != children().begin()) 750 750 (*(-- it))->clearBusy(); … … 906 906 aFolder.raw(), RTPATH_DELIMITER, id.ptr()); 907 907 908 / / try to make the path relative to the vbox home dir908 /* try to make the path relative to the vbox home dir */ 909 909 const char *filePathToRel = filePathTo; 910 910 { … … 914 914 } 915 915 916 / / first ensure the directory exists916 /* first ensure the directory exists */ 917 917 { 918 918 Utf8Str dir = aFolder; … … 932 932 alock.leave(); 933 933 934 / / call storage type specific diff creation method934 /* call storage type specific diff creation method */ 935 935 HRESULT rc = createDiffImage (id, filePathTo, aProgress); 936 936 … … 945 945 CheckComRCReturnRC (rc); 946 946 947 / / associate the created hard disk with the given machine947 /* associate the created hard disk with the given machine */ 948 948 vdi->setMachineId (aMachineId); 949 949 … … 1011 1011 AssertReturn (aHDNode, E_FAIL); 1012 1012 1013 Guid uuid; / / uuid (required)1013 Guid uuid; /* uuid (required) */ 1014 1014 CFGLDRQueryUUID (aHDNode, "uuid", uuid.ptr()); 1015 1015 mId = uuid; … … 1017 1017 if (!isDifferencing()) 1018 1018 { 1019 Bstr type; / / type (required for <HardDisk> nodes only)1019 Bstr type; /* type (required for <HardDisk> nodes only) */ 1020 1020 CFGLDRQueryBSTR (aHDNode, "type", type.asOutParam()); 1021 1021 if (type == L"normal") … … 1036 1036 return rc; 1037 1037 1038 / / load all children1038 /* load all children */ 1039 1039 unsigned count = 0; 1040 1040 CFGLDRCountChildren (aHDNode, "DiffHardDisk", &count); … … 1083 1083 AssertReturn (aHDNode, E_FAIL); 1084 1084 1085 / / uuid (required)1085 /* uuid (required) */ 1086 1086 CFGLDRSetUUID (aHDNode, "uuid", mId.ptr()); 1087 1087 1088 1088 if (!isDifferencing()) 1089 1089 { 1090 / / type (required)1090 /* type (required) */ 1091 1091 const char *type = NULL; 1092 1092 switch (mType) … … 1107 1107 HRESULT rc = S_OK; 1108 1108 1109 / / save all children1109 /* save all children */ 1110 1110 AutoLock chLock (childrenLock()); 1111 1111 for (HardDiskList::const_iterator it = children().begin(); … … 1152 1152 1153 1153 mState = NotCreated; 1154 1155 mStateCheckSem = NIL_RTSEMEVENTMULTI; 1156 mStateCheckWaiters = 0; 1154 1157 1155 1158 mSize = 0; … … 1347 1350 CHECK_READY(); 1348 1351 1349 / / only a non-differencing image knows the logical size1352 /* only a non-differencing image knows the logical size */ 1350 1353 if (isDifferencing()) 1351 1354 return root()->COMGETTER(Size) (aSize); … … 1521 1524 CHECK_READY(); 1522 1525 1523 // check the basic accessibility 1526 if (mStateCheckSem != NIL_RTSEMEVENTMULTI) 1527 { 1528 /* An accessibility check in progress on some other thread, 1529 * wait for it to finish. */ 1530 1531 ComAssertRet (mStateCheckWaiters != ~0, E_FAIL); 1532 ++ mStateCheckWaiters; 1533 alock.leave(); 1534 1535 int vrc = RTSemEventMultiWait (mStateCheckSem, RT_INDEFINITE_WAIT); 1536 1537 alock.enter(); 1538 AssertReturn (mStateCheckWaiters != 0, E_FAIL); 1539 -- mStateCheckWaiters; 1540 if (mStateCheckWaiters == 0) 1541 { 1542 RTSemEventMultiDestroy (mStateCheckSem); 1543 mStateCheckSem = NIL_RTSEMEVENTMULTI; 1544 } 1545 1546 /* don't touch aAccessError, it has been already set */ 1547 return S_OK; 1548 } 1549 1550 /* check the basic accessibility */ 1524 1551 HRESULT rc = HardDisk::getAccessible (aAccessError); 1525 1552 if (FAILED (rc) || !aAccessError.isNull()) … … 1529 1556 { 1530 1557 return queryInformation (&aAccessError); 1531 / /if we fail here, this means something like UUID mismatch.1532 //Do nothing, just return the failure (error info is already1533 //set by queryInformation()), in hope that one of subsequent1534 // attempts to check for acessibility will succeed1558 /* if we fail here, this means something like UUID mismatch. 1559 * Do nothing, just return the failure (error info is already 1560 * set by queryInformation()), in hope that one of subsequent 1561 * attempts to check for acessibility will succeed */ 1535 1562 } 1536 1563 … … 1703 1730 releaseReader(); 1704 1731 1705 / / update the UUID to correspond to the file name1732 /* update the UUID to correspond to the file name */ 1706 1733 if (VBOX_SUCCESS (vrc)) 1707 1734 vrc = VDISetImageUUIDs (aTargetPath, aId, NULL, NULL, NULL); … … 1757 1784 aFolder.raw(), RTPATH_DELIMITER, id.ptr()); 1758 1785 1759 / / try to make the path relative to the vbox home dir1786 /* try to make the path relative to the vbox home dir */ 1760 1787 const char *filePathToRel = filePathTo; 1761 1788 { … … 1765 1792 } 1766 1793 1767 / / first ensure the directory exists1794 /* first ensure the directory exists */ 1768 1795 { 1769 1796 Utf8Str dir = aFolder; … … 1791 1818 alock.enter(); 1792 1819 1793 / / get modification and parent UUIDs of this image1820 /* get modification and parent UUIDs of this image */ 1794 1821 RTUUID modUuid, parentUuid, parentModUuid; 1795 1822 if (VBOX_SUCCESS (vrc)) … … 1815 1842 return rc; 1816 1843 1817 / / associate the created hard disk with the given machine1844 /* associate the created hard disk with the given machine */ 1818 1845 vdi->setMachineId (aMachineId); 1819 1846 … … 1900 1927 AutoLock childLock (child); 1901 1928 1902 / / reparent the child1929 /* reparent the child */ 1903 1930 child->mParent = mParent; 1904 1931 if (mParent) 1905 1932 mParent->addDependentChild (child); 1906 1933 1907 / / change the parent UUID in the image as well1934 /* change the parent UUID in the image as well */ 1908 1935 RTUUID parentUuid, parentModUuid; 1909 1936 vrc = VDIGetImageUUIDs (Utf8Str (mParent->asVDI()->mFilePathFull), … … 1933 1960 } 1934 1961 1935 / / detach all our children to avoid their uninit in #uninit()1962 /* detach all our children to avoid their uninit in #uninit() */ 1936 1963 removeDependentChildren(); 1937 1964 … … 1977 2004 CHECK_READY(); 1978 2005 1979 / / this must be a diff image2006 /* this must be a diff image */ 1980 2007 AssertReturn (isDifferencing(), E_FAIL); 1981 2008 … … 1991 2018 AutoLock chLock (childrenLock()); 1992 2019 1993 / / iterate over a copy since we will modify the list2020 /* iterate over a copy since we will modify the list */ 1994 2021 HardDiskList list = children(); 1995 2022 … … 2023 2050 } 2024 2051 2025 / / reparent the child2052 /* reparent the child */ 2026 2053 child->mParent = mParent; 2027 2054 if (mParent) 2028 2055 mParent->addDependentChild (child); 2029 2056 2030 / / change the parent UUID in the image as well2057 /* change the parent UUID in the image as well */ 2031 2058 RTUUID parentUuid, parentModUuid; 2032 2059 vrc = VDIGetImageUUIDs (Utf8Str (mParent->asVDI()->mFilePathFull), … … 2051 2078 } 2052 2079 2053 / / detach child to avoid its uninit in #uninit()2080 /* detach child to avoid its uninit in #uninit() */ 2054 2081 removeDependentChild (child); 2055 2082 2056 / / remove the busy flag2083 /* remove the busy flag */ 2057 2084 child->clearBusy(); 2058 2085 } … … 2094 2121 Utf8Str (mParent->asVDI()->mFilePathFull), 2095 2122 NULL, NULL, NULL); 2096 / / update the UUID to correspond to the file name2123 /* update the UUID to correspond to the file name */ 2097 2124 if (VBOX_SUCCESS (vrc)) 2098 2125 vrc = VDISetImageUUIDs (filePathFull, mId, NULL, NULL, NULL); … … 2120 2147 if (aFilePath && *aFilePath) 2121 2148 { 2122 / / get the full file name2149 /* get the full file name */ 2123 2150 char filePathFull [RTPATH_MAX]; 2124 2151 int vrc = RTPathAbsEx (mVirtualBox->homeDir(), Utf8Str (aFilePath), … … 2141 2168 2142 2169 /** 2143 * Helper to query information about the VDI hard disk 2170 * Helper to query information about the VDI hard disk. 2144 2171 * 2145 2172 * @param aAccessError not used when NULL, otherwise see #getAccessible() 2146 * @note 2147 * Must be called from under the object's lock! 2173 * 2174 * @note Must be called from under the object's lock, only after 2175 * CHECK_BUSY_AND_READERS() succeeds. 2148 2176 */ 2149 2177 HRESULT HVirtualDiskImage::queryInformation (Bstr *aAccessError) 2150 2178 { 2179 AssertReturn (isLockedOnCurrentThread(), E_FAIL); 2180 2181 /* create a lock object to completely release it later */ 2182 AutoLock alock (this); 2183 2184 AssertReturn (mStateCheckWaiters == 0, E_FAIL); 2185 2151 2186 ComAssertRet (mState >= Created, E_FAIL); 2152 2187 … … 2154 2189 int vrc = VINF_SUCCESS; 2155 2190 2156 /* stupid-stupid-stupid code. VBoxVHDD management is sick. 2157 * we're opening a file three times to get three bits of information */ 2191 /* lazily create a semaphore */ 2192 vrc = RTSemEventMultiCreate (&mStateCheckSem); 2193 ComAssertRCRet (vrc, E_FAIL); 2194 2195 /* go to Busy state to prevent any concurrent modifications 2196 * after releasing the lock below (to unblock getters before 2197 * a lengthy operation) */ 2198 setBusy(); 2199 2200 alock.leave(); 2201 2202 /* VBoxVHDD management interface needs to be optimized: we're opening a 2203 * file three times in a raw to get three bits of information. */ 2158 2204 2159 2205 Utf8Str filePath = mFilePathFull; … … 2165 2211 vrc = VDICheckImage (filePath, NULL, NULL, NULL, 2166 2212 id.ptr(), parentId.ptr(), NULL, 0); 2213 2167 2214 if (VBOX_FAILURE (vrc)) 2168 2215 { … … 2252 2299 break; 2253 2300 } 2254 2255 if (aAccessError)2256 aAccessError->setNull();2257 2258 mState = Accessible;2259 2301 } 2260 2302 while (0); 2261 2303 2304 /* enter the lock again */ 2305 alock.enter(); 2306 2307 /* remove the busy flag */ 2308 clearBusy(); 2309 2262 2310 if (VBOX_FAILURE (vrc) || FAILED (rc)) 2263 2311 { … … 2274 2322 mState = Created; 2275 2323 } 2324 else 2325 { 2326 if (aAccessError) 2327 aAccessError->setNull(); 2328 2329 mState = Accessible; 2330 } 2331 2332 /* inform waiters if there are any */ 2333 if (mStateCheckWaiters > 0) 2334 { 2335 RTSemEventMultiSignal (mStateCheckSem); 2336 } 2337 else 2338 { 2339 /* delete the semaphore ourselves */ 2340 RTSemEventMultiDestroy (mStateCheckSem); 2341 mStateCheckSem = NIL_RTSEMEVENTMULTI; 2342 } 2276 2343 2277 2344 return rc; … … 2302 2369 mFilePathFull.raw()); 2303 2370 2304 / / first ensure the directory exists2371 /* first ensure the directory exists */ 2305 2372 { 2306 2373 Utf8Str imageDir = mFilePathFull; … … 2319 2386 } 2320 2387 2321 / / check whether the given file exists or not2388 /* check whether the given file exists or not */ 2322 2389 RTFILE file; 2323 2390 int vrc = RTFileOpen (&file, Utf8Str (mFilePathFull), … … 2341 2408 } 2342 2409 2343 / / check VDI size limits2410 /* check VDI size limits */ 2344 2411 { 2345 2412 HRESULT rc; … … 2359 2426 HRESULT rc; 2360 2427 2361 / / create a project object2428 /* create a project object */ 2362 2429 ComObjPtr <Progress> progress; 2363 2430 progress.createObject(); … … 2370 2437 } 2371 2438 2372 / /mark as busy (being created)2373 // (VDI task thread will unmark it)2439 /* mark as busy (being created) 2440 * (VDI task thread will unmark it) */ 2374 2441 setBusy(); 2375 2442 2376 / / fill in a VDI task data2443 /* fill in VDI task data */ 2377 2444 VDITask *task = new VDITask (aDynamic ? VDITask::CreateDynamic 2378 2445 : VDITask::CreateStatic, 2379 2446 this, progress); 2380 2447 task->size = aSize; 2381 task->size *= 1024 * 1024; / / convert to bytes2382 2383 / / create the hard disk creation thread, pass operation data2448 task->size *= 1024 * 1024; /* convert to bytes */ 2449 2450 /* create the hard disk creation thread, pass operation data */ 2384 2451 vrc = RTThreadCreate (NULL, vdiTaskThread, (void *) task, 0, 2385 2452 RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, "VDITask"); … … 2393 2460 else 2394 2461 { 2395 / / get one interface for the caller2462 /* get one interface for the caller */ 2396 2463 progress.queryInterfaceTo (aProgress); 2397 2464 } … … 2400 2467 } 2401 2468 2402 / / static2469 /* static */ 2403 2470 DECLCALLBACK(int) HVirtualDiskImage::vdiTaskThread (RTTHREAD thread, void *pvUser) 2404 2471 { … … 2431 2498 task->progress); 2432 2499 2433 / / release reader added in HardDisk::CloneToImage()2500 /* release reader added in HardDisk::CloneToImage() */ 2434 2501 task->source->releaseReader(); 2435 2502 } … … 2444 2511 if (VBOX_SUCCESS (vrc) && task->vdi->id()) 2445 2512 { 2446 / / we have a non-null UUID, update the created image2513 /* we have a non-null UUID, update the created image */ 2447 2514 vrc = VDISetImageUUIDs (Utf8Str (task->vdi->filePathFull()), 2448 2515 task->vdi->id().raw(), NULL, NULL, NULL); … … 2462 2529 AutoLock alock (task->vdi); 2463 2530 2464 / /clear busy set in in HardDisk::CloneToImage() or2465 // in HVirtualDiskImage::createImage()2531 /* clear busy set in in HardDisk::CloneToImage() or 2532 * in HVirtualDiskImage::createImage() */ 2466 2533 task->vdi->clearBusy(); 2467 2534 … … 2469 2536 { 2470 2537 task->vdi->mState = HVirtualDiskImage::Created; 2471 / / update VDI data fields2538 /* update VDI data fields */ 2472 2539 rc = task->vdi->queryInformation (NULL); 2473 / / complete the progress object2540 /* complete the progress object */ 2474 2541 task->progress->notifyComplete (rc); 2475 2542 } … … 2480 2547 2481 2548 task->vdi->mState = HVirtualDiskImage::NotCreated; 2482 / / complete the progress object2549 /* complete the progress object */ 2483 2550 if (errorMsg) 2484 2551 task->progress->notifyComplete ( … … 2554 2621 CheckComRCBreakRC (rc); 2555 2622 2556 / / set ready to let protectedUninit() be called on failure2623 /* set ready to let protectedUninit() be called on failure */ 2557 2624 setReady (true); 2558 2625 2559 / / server (required)2626 /* server (required) */ 2560 2627 CFGLDRQueryBSTR (aISCSINode, "server", mServer.asOutParam()); 2561 / / target (required)2628 /* target (required) */ 2562 2629 CFGLDRQueryBSTR (aISCSINode, "target", mTarget.asOutParam()); 2563 2630 2564 / / port (optional)2631 /* port (optional) */ 2565 2632 CFGLDRQueryUInt16 (aISCSINode, "port", &mPort); 2566 / / lun (optional)2633 /* lun (optional) */ 2567 2634 CFGLDRQueryUInt64 (aISCSINode, "lun", &mLun); 2568 / / userName (optional)2635 /* userName (optional) */ 2569 2636 CFGLDRQueryBSTR (aISCSINode, "userName", mUserName.asOutParam()); 2570 / / password (optional)2637 /* password (optional) */ 2571 2638 CFGLDRQueryBSTR (aISCSINode, "password", mPassword.asOutParam()); 2572 2639 … … 2575 2642 mLun)); 2576 2643 2577 / / load basic settings and children2644 /* load basic settings and children */ 2578 2645 rc = loadSettings (aHDNode); 2579 2646 CheckComRCBreakRC (rc); … … 2618 2685 CheckComRCBreakRC (rc); 2619 2686 2620 / / set ready to let protectedUninit() be called on failure2687 /* set ready to let protectedUninit() be called on failure */ 2621 2688 setReady (true); 2622 2689 2623 / / we have to generate a new UUID2690 /* we have to generate a new UUID */ 2624 2691 mId.create(); 2625 2692 mType = HardDiskType_WritethroughHardDisk; … … 2922 2989 CHECK_READY(); 2923 2990 2924 / / check the basic accessibility2991 /* check the basic accessibility */ 2925 2992 HRESULT rc = HardDisk::getAccessible (aAccessError); 2926 2993 if (FAILED (rc) || !aAccessError.isNull()) … … 2944 3011 CHECK_READY(); 2945 3012 2946 / / server (required)3013 /* server (required) */ 2947 3014 CFGLDRSetBSTR (aStorageNode, "server", mServer); 2948 / / target (required)3015 /* target (required) */ 2949 3016 CFGLDRSetBSTR (aStorageNode, "target", mTarget); 2950 3017 2951 / / port (optional)3018 /* port (optional) */ 2952 3019 if (mPort != 0) 2953 3020 CFGLDRSetUInt16 (aStorageNode, "port", mPort); 2954 3021 else 2955 3022 CFGLDRDeleteAttribute (aStorageNode, "port"); 2956 / / lun (optional)3023 /* lun (optional) */ 2957 3024 if (mLun != 0) 2958 3025 CFGLDRSetUInt64 (aStorageNode, "lun", mLun); 2959 3026 else 2960 3027 CFGLDRDeleteAttribute (aStorageNode, "lun"); 2961 / / userName (optional)3028 /* userName (optional) */ 2962 3029 if (!mUserName.isNull()) 2963 3030 CFGLDRSetBSTR (aStorageNode, "userName", mUserName); 2964 3031 else 2965 3032 CFGLDRDeleteAttribute (aStorageNode, "userName"); 2966 / / password (optional)3033 /* password (optional) */ 2967 3034 if (!mPassword.isNull()) 2968 3035 CFGLDRSetBSTR (aStorageNode, "password", mPassword); … … 2970 3037 CFGLDRDeleteAttribute (aStorageNode, "password"); 2971 3038 2972 / / save basic settings and children3039 /* save basic settings and children */ 2973 3040 return HardDisk::saveSettings (aHDNode); 2974 3041 } -
trunk/src/VBox/Main/ProgressImpl.cpp
r1 r351 393 393 return rc; 394 394 395 mCompletedSem = NIL_RTSEMEVENT ;395 mCompletedSem = NIL_RTSEMEVENTMULTI; 396 396 mWaitersCount = 0; 397 397 -
trunk/src/VBox/Main/include/HardDiskImpl.h
r132 r351 28 28 #include <VBox/cfgldr.h> 29 29 30 #include <iprt/semaphore.h> 31 30 32 #include <list> 31 33 … … 61 63 HRESULT FinalConstruct(); 62 64 void FinalRelease(); 63 64 /// @todo (dmik) remove65 enum InitMode { Init_New, Init_Existing, Init_Registered };66 65 67 66 protected: … … 168 167 void updatePaths (const char *aOldPath, const char *aNewPath); 169 168 170 bool isBusy() { AutoLock alock (this); return mBusy; } 171 unsigned readers() { AutoLock alock (this); return mReaders; } 169 /* these must be are called from under the lock */ 170 bool isBusy() { isLockedOnCurrentThread(); return mBusy; } 171 unsigned readers() { isLockedOnCurrentThread(); return mReaders; } 172 172 173 173 // for VirtualBoxSupportErrorInfoImpl … … 295 295 NotCreated, 296 296 Created, 297 Accessible, // must be greater than Created 297 /* the following must be greater than Created */ 298 Accessible, 298 299 }; 299 300 300 301 State mState; 302 303 RTSEMEVENTMULTI mStateCheckSem; 304 ULONG mStateCheckWaiters; 301 305 302 306 Bstr mDescription;
Note:
See TracChangeset
for help on using the changeset viewer.