VirtualBox

Changeset 38469 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Aug 16, 2011 10:34:32 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73520
Message:

VD: Interface cleanup. Merge the two involved structures (generic interface descriptor and callback table) into one, remove the duplicated interface wrappers in the backends and move the interface definitions into separate headers separating public and private interfaces.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r37641 r38469  
    8585    /** Pointer to list of VD interfaces. Per-image. */
    8686    PVDINTERFACE       pVDIfsImage;
    87     /** Common structure for the configuration information interface. */
    88     VDINTERFACE        VDIConfig;
    89     /** Common structure for the supported TCP network stack interface. */
    90     VDINTERFACE        VDITcpNet;
    91     /** Common structure for the supported I/O interface. */
    92     VDINTERFACE        VDIIO;
     87    /** Configuration information interface. */
     88    VDINTERFACECONFIG  VDIfConfig;
     89    /** TCP network stack interface. */
     90    VDINTERFACETCPNET  VDIfTcpNet;
     91    /** I/O interface. */
     92    VDINTERFACEIO      VDIfIo;
    9393} VBOXIMAGE, *PVBOXIMAGE;
    9494
     
    125125{
    126126    /** The VBox disk container. */
    127     PVBOXHDD           pDisk;
     127    PVBOXHDD                 pDisk;
    128128    /** The media interface. */
    129     PDMIMEDIA          IMedia;
     129    PDMIMEDIA                IMedia;
    130130    /** Media port. */
    131     PPDMIMEDIAPORT     pDrvMediaPort;
     131    PPDMIMEDIAPORT           pDrvMediaPort;
    132132    /** Pointer to the driver instance. */
    133     PPDMDRVINS         pDrvIns;
     133    PPDMDRVINS               pDrvIns;
    134134    /** Flag whether suspend has changed image open mode to read only. */
    135     bool               fTempReadOnly;
     135    bool                     fTempReadOnly;
    136136    /** Flag whether to use the runtime (true) or startup error facility. */
    137     bool               fErrorUseRuntime;
     137    bool                     fErrorUseRuntime;
    138138    /** Pointer to list of VD interfaces. Per-disk. */
    139     PVDINTERFACE       pVDIfsDisk;
    140     /** Common structure for the supported error interface. */
    141     VDINTERFACE        VDIError;
    142     /** Callback table for error interface. */
    143     VDINTERFACEERROR   VDIErrorCallbacks;
    144     /** Common structure for the supported thread synchronization interface. */
    145     VDINTERFACE        VDIThreadSync;
    146     /** Callback table for thread synchronization interface. */
    147     VDINTERFACETHREADSYNC VDIThreadSyncCallbacks;
    148 
    149     /** Callback table for the configuration information interface. */
    150     VDINTERFACECONFIG  VDIConfigCallbacks;
    151     /** Callback table for TCP network stack interface. */
    152     VDINTERFACETCPNET  VDITcpNetCallbacks;
    153     /** Callback table for I/O interface. */
    154     VDINTERFACEIO      VDIIOCallbacks;
     139    PVDINTERFACE             pVDIfsDisk;
     140    /** Error interface. */
     141    VDINTERFACEERROR         VDIfError;
     142    /** Thread synchronization interface. */
     143    VDINTERFACETHREADSYNC    VDIfThreadSync;
    155144
    156145    /** Flag whether opened disk supports async I/O operations. */
    157     bool               fAsyncIOSupported;
     146    bool                     fAsyncIOSupported;
    158147    /** The async media interface. */
    159148    PDMIMEDIAASYNC           IMediaAsync;
     
    163152    PVBOXIMAGE               pImages;
    164153    /** Flag whether the media should allow concurrent open for writing. */
    165     bool                fShareable;
     154    bool                     fShareable;
    166155    /** Flag whether a merge operation has been set up. */
    167     bool                fMergePending;
     156    bool                     fMergePending;
    168157    /** Synchronization to prevent destruction before merge finishes. */
    169     RTSEMFASTMUTEX      MergeCompleteMutex;
     158    RTSEMFASTMUTEX           MergeCompleteMutex;
    170159    /** Synchronization between merge and other image accesses. */
    171     RTSEMRW             MergeLock;
     160    RTSEMRW                  MergeLock;
    172161    /** Source image index for merging. */
    173     unsigned            uMergeSource;
     162    unsigned                 uMergeSource;
    174163    /** Target image index for merging. */
    175     unsigned            uMergeTarget;
     164    unsigned                 uMergeTarget;
    176165
    177166    /** Flag whether boot acceleration is enabled. */
    178     bool                fBootAccelEnabled;
     167    bool                     fBootAccelEnabled;
    179168    /** Flag whether boot acceleration is currently active. */
    180     bool                fBootAccelActive;
     169    bool                     fBootAccelActive;
    181170    /** Size of the disk, used for read truncation. */
    182     size_t              cbDisk;
     171    size_t                   cbDisk;
    183172    /** Size of the configured buffer. */
    184     size_t              cbBootAccelBuffer;
     173    size_t                   cbBootAccelBuffer;
    185174    /** Start offset for which the buffer holds data. */
    186     uint64_t            offDisk;
     175    uint64_t                 offDisk;
    187176    /** Number of valid bytes in the buffer. */
    188     size_t              cbDataValid;
     177    size_t                   cbDataValid;
    189178    /** The disk buffer. */
    190     uint8_t            *pbData;
     179    uint8_t                 *pbData;
    191180    /** Bandwidth group the disk is assigned to. */
    192     char               *pszBwGroup;
     181    char                    *pszBwGroup;
    193182    /** Flag whether async I/O using the host cache is enabled. */
    194     bool                fAsyncIoWithHostCache;
     183    bool                     fAsyncIoWithHostCache;
    195184
    196185    /** I/O interface for a cache image. */
    197     VDINTERFACE         VDIIOCache;
     186    VDINTERFACEIO            VDIfIoCache;
    198187    /** Interface list for the cache image. */
    199     PVDINTERFACE        pVDIfsCache;
     188    PVDINTERFACE             pVDIfsCache;
    200189
    201190    /** The block cache handle if configured. */
    202     PPDMBLKCACHE        pBlkCache;
     191    PPDMBLKCACHE             pBlkCache;
    203192} VBOXDISK, *PVBOXDISK;
    204193
     
    15561545        /** @todo maybe introduce a conversion which limits update frequency. */
    15571546        PVDINTERFACE pVDIfsOperation = NULL;
    1558         VDINTERFACE VDIProgress;
    1559         VDINTERFACEPROGRESS VDIProgressCallbacks;
    1560         VDIProgressCallbacks.cbSize       = sizeof(VDINTERFACEPROGRESS);
    1561         VDIProgressCallbacks.enmInterface = VDINTERFACETYPE_PROGRESS;
    1562         VDIProgressCallbacks.pfnProgress  = pfnProgress;
    1563         rc2 = VDInterfaceAdd(&VDIProgress, "DrvVD_VDIProgress", VDINTERFACETYPE_PROGRESS,
    1564                              &VDIProgressCallbacks, pvUser, &pVDIfsOperation);
     1547        VDINTERFACEPROGRESS VDIfProgress;
     1548        VDIfProgress.pfnProgress  = pfnProgress;
     1549        rc2 = VDInterfaceAdd(&VDIfProgress.Core, "DrvVD_VDIProgress", VDINTERFACETYPE_PROGRESS,
     1550                             pvUser, sizeof(VDINTERFACEPROGRESS), &pVDIfsOperation);
    15651551        AssertRC(rc2);
    15661552        pThis->fMergePending = false;
     
    20822068    pThis->pVDIfsDisk = NULL;
    20832069
    2084     pThis->VDIErrorCallbacks.cbSize       = sizeof(VDINTERFACEERROR);
    2085     pThis->VDIErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
    2086     pThis->VDIErrorCallbacks.pfnError     = drvvdErrorCallback;
    2087     pThis->VDIErrorCallbacks.pfnMessage   = NULL;
    2088 
    2089     rc = VDInterfaceAdd(&pThis->VDIError, "DrvVD_VDIError", VDINTERFACETYPE_ERROR,
    2090                         &pThis->VDIErrorCallbacks, pDrvIns, &pThis->pVDIfsDisk);
     2070    pThis->VDIfError.pfnError     = drvvdErrorCallback;
     2071    pThis->VDIfError.pfnMessage   = NULL;
     2072    rc = VDInterfaceAdd(&pThis->VDIfError.Core, "DrvVD_VDIError", VDINTERFACETYPE_ERROR,
     2073                        pDrvIns, sizeof(VDINTERFACEERROR), &pThis->pVDIfsDisk);
    20912074    AssertRC(rc);
    2092 
    2093     /* This is just prepared here, the actual interface is per-image, so it's
    2094      * added later. No need to have separate callback tables. */
    2095     pThis->VDIConfigCallbacks.cbSize                = sizeof(VDINTERFACECONFIG);
    2096     pThis->VDIConfigCallbacks.enmInterface          = VDINTERFACETYPE_CONFIG;
    2097     pThis->VDIConfigCallbacks.pfnAreKeysValid       = drvvdCfgAreKeysValid;
    2098     pThis->VDIConfigCallbacks.pfnQuerySize          = drvvdCfgQuerySize;
    2099     pThis->VDIConfigCallbacks.pfnQuery              = drvvdCfgQuery;
    21002075
    21012076    /* List of images is empty now. */
     
    23132288    if (RT_SUCCESS(rc))
    23142289    {
     2290        /*
     2291         * The image has a bandwidth group but the host cache is enabled.
     2292         * Use the async I/O framework but tell it to enable the host cache.
     2293         */
     2294        if (!fUseNewIo && pThis->pszBwGroup)
     2295        {
     2296            pThis->fAsyncIoWithHostCache = true;
     2297            fUseNewIo = true;
     2298        }
     2299
     2300        /** @todo quick hack to work around problems in the async I/O
     2301         * implementation (rw semaphore thread ownership problem)
     2302         * while a merge is running. Remove once this is fixed. */
     2303        if (pThis->fMergePending)
     2304            fUseNewIo = false;
     2305
     2306        if (RT_SUCCESS(rc) && pThis->fMergePending)
     2307        {
     2308            rc = RTSemFastMutexCreate(&pThis->MergeCompleteMutex);
     2309            if (RT_SUCCESS(rc))
     2310                rc = RTSemRWCreate(&pThis->MergeLock);
     2311            if (RT_SUCCESS(rc))
     2312            {
     2313                pThis->VDIfThreadSync.pfnStartRead   = drvvdThreadStartRead;
     2314                pThis->VDIfThreadSync.pfnFinishRead  = drvvdThreadFinishRead;
     2315                pThis->VDIfThreadSync.pfnStartWrite  = drvvdThreadStartWrite;
     2316                pThis->VDIfThreadSync.pfnFinishWrite = drvvdThreadFinishWrite;
     2317
     2318                rc = VDInterfaceAdd(&pThis->VDIfThreadSync.Core, "DrvVD_ThreadSync", VDINTERFACETYPE_THREADSYNC,
     2319                                    pThis, sizeof(VDINTERFACETHREADSYNC), &pThis->pVDIfsDisk);
     2320            }
     2321            else
     2322            {
     2323                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2324                                      N_("DrvVD: Failed to create semaphores for \"MergePending\""));
     2325            }
     2326        }
     2327
     2328        if (RT_SUCCESS(rc))
     2329        {
     2330            rc = VDCreate(pThis->pVDIfsDisk, enmType, &pThis->pDisk);
     2331            /* Error message is already set correctly. */
     2332        }
     2333    }
     2334
     2335    if (pThis->pDrvMediaAsyncPort && fUseNewIo)
     2336        pThis->fAsyncIOSupported = true;
     2337
     2338    unsigned iImageIdx = 0;
     2339    while (pCurNode && RT_SUCCESS(rc))
     2340    {
     2341        /* Allocate per-image data. */
     2342        PVBOXIMAGE pImage = drvvdNewImage(pThis);
     2343        if (!pImage)
     2344        {
     2345            rc = VERR_NO_MEMORY;
     2346            break;
     2347        }
     2348
     2349        /*
     2350         * Read the image configuration.
     2351         */
     2352        rc = CFGMR3QueryStringAlloc(pCurNode, "Path", &pszName);
     2353        if (RT_FAILURE(rc))
     2354        {
     2355            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2356                                  N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
     2357            break;
     2358        }
     2359
     2360        rc = CFGMR3QueryStringAlloc(pCurNode, "Format", &pszFormat);
     2361        if (RT_FAILURE(rc))
     2362        {
     2363            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2364                                  N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
     2365            break;
     2366        }
     2367
     2368        bool fMergeSource;
     2369        rc = CFGMR3QueryBoolDef(pCurNode, "MergeSource", &fMergeSource, false);
     2370        if (RT_FAILURE(rc))
     2371        {
     2372            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2373                                  N_("DrvVD: Configuration error: Querying \"MergeSource\" as boolean failed"));
     2374            break;
     2375        }
     2376        if (fMergeSource)
     2377        {
     2378            if (pThis->uMergeSource == VD_LAST_IMAGE)
     2379                pThis->uMergeSource = iImageIdx;
     2380            else
     2381            {
     2382                rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
     2383                                      N_("DrvVD: Configuration error: Multiple \"MergeSource\" occurrences"));
     2384                break;
     2385            }
     2386        }
     2387
     2388        bool fMergeTarget;
     2389        rc = CFGMR3QueryBoolDef(pCurNode, "MergeTarget", &fMergeTarget, false);
     2390        if (RT_FAILURE(rc))
     2391        {
     2392            rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2393                                  N_("DrvVD: Configuration error: Querying \"MergeTarget\" as boolean failed"));
     2394            break;
     2395        }
     2396        if (fMergeTarget)
     2397        {
     2398            if (pThis->uMergeTarget == VD_LAST_IMAGE)
     2399                pThis->uMergeTarget = iImageIdx;
     2400            else
     2401            {
     2402                rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
     2403                                      N_("DrvVD: Configuration error: Multiple \"MergeTarget\" occurrences"));
     2404                break;
     2405            }
     2406        }
     2407
     2408        PCFGMNODE pCfgVDConfig = CFGMR3GetChild(pCurNode, "VDConfig");
     2409        pImage->VDIfConfig.pfnAreKeysValid = drvvdCfgAreKeysValid;
     2410        pImage->VDIfConfig.pfnQuerySize    = drvvdCfgQuerySize;
     2411        pImage->VDIfConfig.pfnQuery        = drvvdCfgQuery;
     2412        rc = VDInterfaceAdd(&pImage->VDIfConfig.Core, "DrvVD_Config", VDINTERFACETYPE_CONFIG,
     2413                            pCfgVDConfig, sizeof(VDINTERFACECONFIG), &pImage->pVDIfsImage);
     2414        AssertRC(rc);
     2415
     2416        /* Unconditionally insert the TCPNET interface, don't bother to check
     2417         * if an image really needs it. Will be ignored. Since the TCPNET
     2418         * interface is per image we could make this more flexible in the
     2419         * future if we want to. */
    23152420        /* Construct TCPNET callback table depending on the config. This is
    23162421         * done unconditionally, as uninterested backends will ignore it. */
    23172422        if (fHostIP)
    23182423        {
    2319             pThis->VDITcpNetCallbacks.cbSize = sizeof(VDINTERFACETCPNET);
    2320             pThis->VDITcpNetCallbacks.enmInterface = VDINTERFACETYPE_TCPNET;
    2321             pThis->VDITcpNetCallbacks.pfnSocketCreate = drvvdTcpSocketCreate;
    2322             pThis->VDITcpNetCallbacks.pfnSocketDestroy = drvvdTcpSocketDestroy;
    2323             pThis->VDITcpNetCallbacks.pfnClientConnect = drvvdTcpClientConnect;
    2324             pThis->VDITcpNetCallbacks.pfnIsClientConnected = drvvdTcpIsClientConnected;
    2325             pThis->VDITcpNetCallbacks.pfnClientClose = drvvdTcpClientClose;
    2326             pThis->VDITcpNetCallbacks.pfnSelectOne = drvvdTcpSelectOne;
    2327             pThis->VDITcpNetCallbacks.pfnRead = drvvdTcpRead;
    2328             pThis->VDITcpNetCallbacks.pfnWrite = drvvdTcpWrite;
    2329             pThis->VDITcpNetCallbacks.pfnSgWrite = drvvdTcpSgWrite;
    2330             pThis->VDITcpNetCallbacks.pfnReadNB = drvvdTcpReadNB;
    2331             pThis->VDITcpNetCallbacks.pfnWriteNB = drvvdTcpWriteNB;
    2332             pThis->VDITcpNetCallbacks.pfnSgWriteNB = drvvdTcpSgWriteNB;
    2333             pThis->VDITcpNetCallbacks.pfnFlush = drvvdTcpFlush;
    2334             pThis->VDITcpNetCallbacks.pfnSetSendCoalescing = drvvdTcpSetSendCoalescing;
    2335             pThis->VDITcpNetCallbacks.pfnGetLocalAddress = drvvdTcpGetLocalAddress;
    2336             pThis->VDITcpNetCallbacks.pfnGetPeerAddress = drvvdTcpGetPeerAddress;
     2424            pImage->VDIfTcpNet.pfnSocketCreate = drvvdTcpSocketCreate;
     2425            pImage->VDIfTcpNet.pfnSocketDestroy = drvvdTcpSocketDestroy;
     2426            pImage->VDIfTcpNet.pfnClientConnect = drvvdTcpClientConnect;
     2427            pImage->VDIfTcpNet.pfnIsClientConnected = drvvdTcpIsClientConnected;
     2428            pImage->VDIfTcpNet.pfnClientClose = drvvdTcpClientClose;
     2429            pImage->VDIfTcpNet.pfnSelectOne = drvvdTcpSelectOne;
     2430            pImage->VDIfTcpNet.pfnRead = drvvdTcpRead;
     2431            pImage->VDIfTcpNet.pfnWrite = drvvdTcpWrite;
     2432            pImage->VDIfTcpNet.pfnSgWrite = drvvdTcpSgWrite;
     2433            pImage->VDIfTcpNet.pfnReadNB = drvvdTcpReadNB;
     2434            pImage->VDIfTcpNet.pfnWriteNB = drvvdTcpWriteNB;
     2435            pImage->VDIfTcpNet.pfnSgWriteNB = drvvdTcpSgWriteNB;
     2436            pImage->VDIfTcpNet.pfnFlush = drvvdTcpFlush;
     2437            pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdTcpSetSendCoalescing;
     2438            pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdTcpGetLocalAddress;
     2439            pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdTcpGetPeerAddress;
    23372440
    23382441            /*
     
    23512454            {
    23522455                LogRel(("VD: Detected Windows XP, disabled poll based waiting for TCP\n"));
    2353                 pThis->VDITcpNetCallbacks.pfnSelectOneEx = drvvdTcpSelectOneExNoPoll;
     2456                pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExNoPoll;
    23542457            }
    23552458            else
    2356                 pThis->VDITcpNetCallbacks.pfnSelectOneEx = drvvdTcpSelectOneExPoll;
    2357 
    2358             pThis->VDITcpNetCallbacks.pfnPoke = drvvdTcpPoke;
     2459                pImage->VDIfTcpNet.pfnSelectOneEx = drvvdTcpSelectOneExPoll;
     2460
     2461            pImage->VDIfTcpNet.pfnPoke = drvvdTcpPoke;
    23592462        }
    23602463        else
     
    23642467                                     RT_SRC_POS, N_("DrvVD: Configuration error: TCP over Internal Networking not compiled in"));
    23652468#else /* VBOX_WITH_INIP */
    2366             pThis->VDITcpNetCallbacks.cbSize = sizeof(VDINTERFACETCPNET);
    2367             pThis->VDITcpNetCallbacks.enmInterface = VDINTERFACETYPE_TCPNET;
    2368             pThis->VDITcpNetCallbacks.pfnSocketCreate = drvvdINIPSocketCreate;
    2369             pThis->VDITcpNetCallbacks.pfnSocketDestroy = drvvdINIPSocketDestroy;
    2370             pThis->VDITcpNetCallbacks.pfnClientConnect = drvvdINIPClientConnect;
    2371             pThis->VDITcpNetCallbacks.pfnClientClose = drvvdINIPClientClose;
    2372             pThis->VDITcpNetCallbacks.pfnIsClientConnected = drvvdINIPIsClientConnected;
    2373             pThis->VDITcpNetCallbacks.pfnSelectOne = drvvdINIPSelectOne;
    2374             pThis->VDITcpNetCallbacks.pfnRead = drvvdINIPRead;
    2375             pThis->VDITcpNetCallbacks.pfnWrite = drvvdINIPWrite;
    2376             pThis->VDITcpNetCallbacks.pfnSgWrite = drvvdINIPSgWrite;
    2377             pThis->VDITcpNetCallbacks.pfnFlush = drvvdINIPFlush;
    2378             pThis->VDITcpNetCallbacks.pfnSetSendCoalescing = drvvdINIPSetSendCoalescing;
    2379             pThis->VDITcpNetCallbacks.pfnGetLocalAddress = drvvdINIPGetLocalAddress;
    2380             pThis->VDITcpNetCallbacks.pfnGetPeerAddress = drvvdINIPGetPeerAddress;
    2381             pThis->VDITcpNetCallbacks.pfnSelectOneEx = drvvdINIPSelectOneEx;
    2382             pThis->VDITcpNetCallbacks.pfnPoke = drvvdINIPPoke;
     2469            pImage->VDIfTcpNet.pfnSocketCreate = drvvdINIPSocketCreate;
     2470            pImage->VDIfTcpNet.pfnSocketDestroy = drvvdINIPSocketDestroy;
     2471            pImage->VDIfTcpNet.pfnClientConnect = drvvdINIPClientConnect;
     2472            pImage->VDIfTcpNet.pfnClientClose = drvvdINIPClientClose;
     2473            pImage->VDIfTcpNet.pfnIsClientConnected = drvvdINIPIsClientConnected;
     2474            pImage->VDIfTcpNet.pfnSelectOne = drvvdINIPSelectOne;
     2475            pImage->VDIfTcpNet.pfnRead = drvvdINIPRead;
     2476            pImage->VDIfTcpNet.pfnWrite = drvvdINIPWrite;
     2477            pImage->VDIfTcpNet.pfnSgWrite = drvvdINIPSgWrite;
     2478            pImage->VDIfTcpNet.pfnFlush = drvvdINIPFlush;
     2479            pImage->VDIfTcpNet.pfnSetSendCoalescing = drvvdINIPSetSendCoalescing;
     2480            pImage->VDIfTcpNet.pfnGetLocalAddress = drvvdINIPGetLocalAddress;
     2481            pImage->VDIfTcpNet.pfnGetPeerAddress = drvvdINIPGetPeerAddress;
     2482            pImage->VDIfTcpNet.pfnSelectOneEx = drvvdINIPSelectOneEx;
     2483            pImage->VDIfTcpNet.pfnPoke = drvvdINIPPoke;
    23832484#endif /* VBOX_WITH_INIP */
    23842485        }
    2385 
    2386         /*
    2387          * The image has a bandwidth group but the host cache is enabled.
    2388          * Use the async I/O framework but tell it to enable the host cache.
    2389          */
    2390         if (!fUseNewIo && pThis->pszBwGroup)
    2391         {
    2392             pThis->fAsyncIoWithHostCache = true;
    2393             fUseNewIo = true;
    2394         }
    2395 
    2396         /** @todo quick hack to work around problems in the async I/O
    2397          * implementation (rw semaphore thread ownership problem)
    2398          * while a merge is running. Remove once this is fixed. */
    2399         if (pThis->fMergePending)
    2400             fUseNewIo = false;
    2401 
    2402         if (RT_SUCCESS(rc) && fUseNewIo)
     2486        rc = VDInterfaceAdd(&pImage->VDIfTcpNet.Core, "DrvVD_TCPNET",
     2487                            VDINTERFACETYPE_TCPNET, NULL,
     2488                            sizeof(VDINTERFACETCPNET), &pImage->pVDIfsImage);
     2489        AssertRC(rc);
     2490
     2491        /* Insert the custom I/O interface only if we're told to use new IO.
     2492         * Since the I/O interface is per image we could make this more
     2493         * flexible in the future if we want to. */
     2494        if (fUseNewIo)
    24032495        {
    24042496#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
    2405             pThis->VDIIOCallbacks.cbSize        = sizeof(VDINTERFACEIO);
    2406             pThis->VDIIOCallbacks.enmInterface  = VDINTERFACETYPE_IO;
    2407             pThis->VDIIOCallbacks.pfnOpen       = drvvdAsyncIOOpen;
    2408             pThis->VDIIOCallbacks.pfnClose      = drvvdAsyncIOClose;
    2409             pThis->VDIIOCallbacks.pfnGetSize    = drvvdAsyncIOGetSize;
    2410             pThis->VDIIOCallbacks.pfnSetSize    = drvvdAsyncIOSetSize;
    2411             pThis->VDIIOCallbacks.pfnReadSync   = drvvdAsyncIOReadSync;
    2412             pThis->VDIIOCallbacks.pfnWriteSync  = drvvdAsyncIOWriteSync;
    2413             pThis->VDIIOCallbacks.pfnFlushSync  = drvvdAsyncIOFlushSync;
    2414             pThis->VDIIOCallbacks.pfnReadAsync  = drvvdAsyncIOReadAsync;
    2415             pThis->VDIIOCallbacks.pfnWriteAsync = drvvdAsyncIOWriteAsync;
    2416             pThis->VDIIOCallbacks.pfnFlushAsync = drvvdAsyncIOFlushAsync;
     2497            pImage->VDIfIo.pfnOpen       = drvvdAsyncIOOpen;
     2498            pImage->VDIfIo.pfnClose      = drvvdAsyncIOClose;
     2499            pImage->VDIfIo.pfnGetSize    = drvvdAsyncIOGetSize;
     2500            pImage->VDIfIo.pfnSetSize    = drvvdAsyncIOSetSize;
     2501            pImage->VDIfIo.pfnReadSync   = drvvdAsyncIOReadSync;
     2502            pImage->VDIfIo.pfnWriteSync  = drvvdAsyncIOWriteSync;
     2503            pImage->VDIfIo.pfnFlushSync  = drvvdAsyncIOFlushSync;
     2504            pImage->VDIfIo.pfnReadAsync  = drvvdAsyncIOReadAsync;
     2505            pImage->VDIfIo.pfnWriteAsync = drvvdAsyncIOWriteAsync;
     2506            pImage->VDIfIo.pfnFlushAsync = drvvdAsyncIOFlushAsync;
    24172507#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
    24182508            rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
    24192509                                     RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
    24202510#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
    2421         }
    2422 
    2423         if (RT_SUCCESS(rc) && pThis->fMergePending)
    2424         {
    2425             rc = RTSemFastMutexCreate(&pThis->MergeCompleteMutex);
    24262511            if (RT_SUCCESS(rc))
    2427                 rc = RTSemRWCreate(&pThis->MergeLock);
    2428             if (RT_SUCCESS(rc))
    2429             {
    2430                 pThis->VDIThreadSyncCallbacks.cbSize        = sizeof(VDINTERFACETHREADSYNC);
    2431                 pThis->VDIThreadSyncCallbacks.enmInterface  = VDINTERFACETYPE_THREADSYNC;
    2432                 pThis->VDIThreadSyncCallbacks.pfnStartRead  = drvvdThreadStartRead;
    2433                 pThis->VDIThreadSyncCallbacks.pfnFinishRead = drvvdThreadFinishRead;
    2434                 pThis->VDIThreadSyncCallbacks.pfnStartWrite = drvvdThreadStartWrite;
    2435                 pThis->VDIThreadSyncCallbacks.pfnFinishWrite = drvvdThreadFinishWrite;
    2436 
    2437                 rc = VDInterfaceAdd(&pThis->VDIThreadSync, "DrvVD_ThreadSync", VDINTERFACETYPE_THREADSYNC,
    2438                                     &pThis->VDIThreadSyncCallbacks, pThis, &pThis->pVDIfsDisk);
    2439             }
    2440             else
    2441             {
    2442                 rc = PDMDRV_SET_ERROR(pDrvIns, rc,
    2443                                       N_("DrvVD: Failed to create semaphores for \"MergePending\""));
    2444             }
    2445         }
    2446 
    2447         if (RT_SUCCESS(rc))
    2448         {
    2449             rc = VDCreate(pThis->pVDIfsDisk, enmType, &pThis->pDisk);
    2450             /* Error message is already set correctly. */
    2451         }
    2452     }
    2453 
    2454     if (pThis->pDrvMediaAsyncPort && fUseNewIo)
    2455         pThis->fAsyncIOSupported = true;
    2456 
    2457     unsigned iImageIdx = 0;
    2458     while (pCurNode && RT_SUCCESS(rc))
    2459     {
    2460         /* Allocate per-image data. */
    2461         PVBOXIMAGE pImage = drvvdNewImage(pThis);
    2462         if (!pImage)
    2463         {
    2464             rc = VERR_NO_MEMORY;
    2465             break;
    2466         }
    2467 
    2468         /*
    2469          * Read the image configuration.
    2470          */
    2471         rc = CFGMR3QueryStringAlloc(pCurNode, "Path", &pszName);
    2472         if (RT_FAILURE(rc))
    2473         {
    2474             rc = PDMDRV_SET_ERROR(pDrvIns, rc,
    2475                                   N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
    2476             break;
    2477         }
    2478 
    2479         rc = CFGMR3QueryStringAlloc(pCurNode, "Format", &pszFormat);
    2480         if (RT_FAILURE(rc))
    2481         {
    2482             rc = PDMDRV_SET_ERROR(pDrvIns, rc,
    2483                                   N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
    2484             break;
    2485         }
    2486 
    2487         bool fMergeSource;
    2488         rc = CFGMR3QueryBoolDef(pCurNode, "MergeSource", &fMergeSource, false);
    2489         if (RT_FAILURE(rc))
    2490         {
    2491             rc = PDMDRV_SET_ERROR(pDrvIns, rc,
    2492                                   N_("DrvVD: Configuration error: Querying \"MergeSource\" as boolean failed"));
    2493             break;
    2494         }
    2495         if (fMergeSource)
    2496         {
    2497             if (pThis->uMergeSource == VD_LAST_IMAGE)
    2498                 pThis->uMergeSource = iImageIdx;
    2499             else
    2500             {
    2501                 rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
    2502                                       N_("DrvVD: Configuration error: Multiple \"MergeSource\" occurrences"));
    2503                 break;
    2504             }
    2505         }
    2506 
    2507         bool fMergeTarget;
    2508         rc = CFGMR3QueryBoolDef(pCurNode, "MergeTarget", &fMergeTarget, false);
    2509         if (RT_FAILURE(rc))
    2510         {
    2511             rc = PDMDRV_SET_ERROR(pDrvIns, rc,
    2512                                   N_("DrvVD: Configuration error: Querying \"MergeTarget\" as boolean failed"));
    2513             break;
    2514         }
    2515         if (fMergeTarget)
    2516         {
    2517             if (pThis->uMergeTarget == VD_LAST_IMAGE)
    2518                 pThis->uMergeTarget = iImageIdx;
    2519             else
    2520             {
    2521                 rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
    2522                                       N_("DrvVD: Configuration error: Multiple \"MergeTarget\" occurrences"));
    2523                 break;
    2524             }
    2525         }
    2526 
    2527         PCFGMNODE pCfgVDConfig = CFGMR3GetChild(pCurNode, "VDConfig");
    2528         rc = VDInterfaceAdd(&pImage->VDIConfig, "DrvVD_Config", VDINTERFACETYPE_CONFIG,
    2529                             &pThis->VDIConfigCallbacks, pCfgVDConfig, &pImage->pVDIfsImage);
    2530         AssertRC(rc);
    2531 
    2532         /* Unconditionally insert the TCPNET interface, don't bother to check
    2533          * if an image really needs it. Will be ignored. Since the TCPNET
    2534          * interface is per image we could make this more flexible in the
    2535          * future if we want to. */
    2536         rc = VDInterfaceAdd(&pImage->VDITcpNet, "DrvVD_TCPNET",
    2537                             VDINTERFACETYPE_TCPNET, &pThis->VDITcpNetCallbacks,
    2538                             NULL, &pImage->pVDIfsImage);
    2539         AssertRC(rc);
    2540 
    2541         /* Insert the custom I/O interface only if we're told to use new IO.
    2542          * Since the I/O interface is per image we could make this more
    2543          * flexible in the future if we want to. */
    2544         if (fUseNewIo)
    2545         {
    2546             rc = VDInterfaceAdd(&pImage->VDIIO, "DrvVD_IO", VDINTERFACETYPE_IO,
    2547                                 &pThis->VDIIOCallbacks, pThis,
    2548                                 &pImage->pVDIfsImage);
     2512                rc = VDInterfaceAdd(&pImage->VDIfIo.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
     2513                                    pThis, sizeof(VDINTERFACEIO), &pImage->pVDIfsImage);
    25492514            AssertRC(rc);
    25502515        }
     
    26202585        if (fUseNewIo)
    26212586        {
    2622             rc = VDInterfaceAdd(&pThis->VDIIOCache, "DrvVD_IO", VDINTERFACETYPE_IO,
    2623                                 &pThis->VDIIOCallbacks, pThis,
    2624                                 &pThis->pVDIfsCache);
     2587#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
     2588            pThis->VDIfIoCache.pfnOpen       = drvvdAsyncIOOpen;
     2589            pThis->VDIfIoCache.pfnClose      = drvvdAsyncIOClose;
     2590            pThis->VDIfIoCache.pfnGetSize    = drvvdAsyncIOGetSize;
     2591            pThis->VDIfIoCache.pfnSetSize    = drvvdAsyncIOSetSize;
     2592            pThis->VDIfIoCache.pfnReadSync   = drvvdAsyncIOReadSync;
     2593            pThis->VDIfIoCache.pfnWriteSync  = drvvdAsyncIOWriteSync;
     2594            pThis->VDIfIoCache.pfnFlushSync  = drvvdAsyncIOFlushSync;
     2595            pThis->VDIfIoCache.pfnReadAsync  = drvvdAsyncIOReadAsync;
     2596            pThis->VDIfIoCache.pfnWriteAsync = drvvdAsyncIOWriteAsync;
     2597            pThis->VDIfIoCache.pfnFlushAsync = drvvdAsyncIOFlushAsync;
     2598#else /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
     2599            rc = PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
     2600                                     RT_SRC_POS, N_("DrvVD: Configuration error: Async Completion Framework not compiled in"));
     2601#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
     2602            if (RT_SUCCESS(rc))
     2603                rc = VDInterfaceAdd(&pThis->VDIfIoCache.Core, "DrvVD_IO", VDINTERFACETYPE_IO,
     2604                                    pThis, sizeof(VDINTERFACEIO), &pThis->pVDIfsCache);
    26252605            AssertRC(rc);
    26262606        }
Note: See TracChangeset for help on using the changeset viewer.

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