VirtualBox

Changeset 39854 in vbox


Ignore:
Timestamp:
Jan 24, 2012 4:39:29 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
75879
Message:

PDM: Extended the driver chain transformations with a mergeconfig action (untested). Fixed some basic bugs.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r39839 r39854  
    13811381/** Misconfigured driver chain transformation. */
    13821382#define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION   (-2889)
     1383/** The driver is already removed, not more transformations possible (at
     1384 *  present). */
     1385#define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER    (-2890)
    13831386/** @} */
    13841387
  • trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp

    r39839 r39854  
    404404                      rc == VERR_CFGM_VALUE_NOT_FOUND ? VERR_PDM_CFG_MISSING_DRIVER_NAME : rc);
    405405
     406    uint64_t    uInjectTransformationAbove = 0;
     407    if (pDrvAbove)
     408    {
     409        rc = CFGMR3QueryIntegerDef(CFGMR3GetParent(*ppNode), "InjectTransformationPtr", &uInjectTransformationAbove, 0);
     410        AssertLogRelRCReturn(rc, rc);
     411    }
     412
    406413
    407414    /*
    408415     * Enumerate possible driver chain transformations.
    409416     */
     417    unsigned cTransformations = 0;
    410418    for (; pCurTrans != NULL; pCurTrans = CFGMR3GetNextChild(pCurTrans))
    411419    {
     420        char szCurTransNm[256];
     421        rc = CFGMR3GetName(pCurTrans, szCurTransNm, sizeof(szCurTransNm));
     422        AssertLogRelRCReturn(rc, rc);
     423
    412424        /* Match against the driver multi pattern. */
    413425        char *pszMultiPat;
     
    436448
    437449        /* Match against the above-driver multi pattern. */
    438         /** @todo add some config to avoid infinie application of an
    439          * AboveDriver transformation. */
    440         rc = CFGMR3QueryStringAllocDef(pCurTrans, "AboveDriver", &pszMultiPat, "*");
    441         AssertLogRelRCReturn(rc, rc);
    442         fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszThisDrv, RTSTR_MAX, NULL);
    443         MMR3HeapFree(pszMultiPat);
    444         if (!fMatch)
    445             continue;
     450        rc = CFGMR3QueryStringAlloc(pCurTrans, "AboveDriver", &pszMultiPat);
     451        if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     452            rc = VINF_SUCCESS;
     453        else
     454        {
     455            AssertLogRelRCReturn(rc, rc);
     456            fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszThisDrv, RTSTR_MAX, NULL);
     457            MMR3HeapFree(pszMultiPat);
     458            if (!fMatch)
     459                continue;
     460            if (uInjectTransformationAbove == (uintptr_t)pCurTrans)
     461                continue;
     462        }
    446463
    447464        /*
     
    451468        rc = CFGMR3QueryStringDef(pCurTrans, "Action", szAction, sizeof(szAction), "inject");
    452469        AssertLogRelRCReturn(rc, rc);
    453         AssertLogRelMsgFailedReturn(("Action='%s', valid values are 'inject', 'replace' and 'remove'.\n",  szAction),
    454                                     VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
    455 
    456470        AssertLogRelMsgReturn(   !strcmp(szAction, "inject")
     471                              || !strcmp(szAction, "mergeconfig")
     472                              || !strcmp(szAction, "remove")
     473                              || !strcmp(szAction, "removetree")
    457474                              || !strcmp(szAction, "replace")
    458                               || !strcmp(szAction, "remove"),
    459                               ("Action='%s', valid values are 'inject', 'replace' and 'remove'.\n",  szAction),
     475                              || !strcmp(szAction, "replacetree")
     476                              ,
     477                              ("Action='%s', valid values are 'inject', 'mergeconfig', 'replace', 'replacetree', 'remove', 'removetree'.\n", szAction),
    460478                              VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
     479        LogRel(("Applying '%s' to '%s'::[%s]...'%s': %s\n", szCurTransNm, pszDevice, szLun, pszThisDrv, szAction));
     480        CFGMR3Dump(*ppNode);
     481        CFGMR3Dump(pCurTrans);
    461482
    462483        /* Get the attached driver to inject. */
    463484        PCFGMNODE pTransAttDrv = NULL;
    464         if (!strcmp(szAction, "inject") || !strcmp(szAction, "replace"))
     485        if (!strcmp(szAction, "inject") || !strcmp(szAction, "replace") || !strcmp(szAction, "replacetree"))
    465486        {
    466487            pTransAttDrv = CFGMR3GetChild(pCurTrans, "AttachedDriver");
     
    474495         * Remove the node.
    475496         */
    476         if (!strcmp(szAction, "remove"))
     497        if (!strcmp(szAction, "remove") || !strcmp(szAction, "removetree"))
    477498        {
    478499            PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
    479             if (pBelowThis)
     500            if (!pBelowThis || !strcmp(szAction, "removetree"))
    480501            {
    481                 PCFGMNODE pBelowThisCopy = CFGMR3DuplicateSubTree(pBelowThis);
    482                 AssertLogRelReturn(pBelowThisCopy, VERR_NO_MEMORY);
     502                CFGMR3RemoveNode(*ppNode);
     503                *ppNode = NULL;
     504            }
     505            else
     506            {
     507                PCFGMNODE pBelowThisCopy;
     508                rc = CFGMR3DuplicateSubTree(pBelowThis, &pBelowThisCopy);
     509                AssertLogRelRCReturn(rc, rc);
    483510
    484511                rc = CFGMR3ReplaceSubTree(*ppNode, pBelowThisCopy);
     
    489516                }
    490517            }
    491             else
    492             {
    493                 CFGMR3RemoveNode(*ppNode);
    494                 *ppNode = NULL;
    495             }
    496518        }
    497519        /*
    498520         * Replace the driver about to be instantiated.
    499521         */
    500         else if (!strcmp(szAction, "replace"))
    501         {
    502             PCFGMNODE pTransCopy = CFGMR3DuplicateSubTree(pTransAttDrv);
    503             AssertLogRelBreakStmt(pTransCopy, rc = VERR_NO_MEMORY);
    504             rc = VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION;
     522        else if (!strcmp(szAction, "replace") || !strcmp(szAction, "replacetree"))
     523        {
     524            PCFGMNODE pTransCopy;
     525            rc = CFGMR3DuplicateSubTree(pTransAttDrv, &pTransCopy);
     526            AssertLogRelRCReturn(rc, rc);
    505527
    506528            PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
    507             if (!pBelowThis)
     529            if (!pBelowThis || !strcmp(szAction, "replacetree"))
    508530                rc = VINF_SUCCESS;
    509531            else
    510532            {
    511                 PCFGMNODE pBelowThisCopy = CFGMR3DuplicateSubTree(pBelowThis);
    512                 if (pBelowThisCopy)
     533                PCFGMNODE pBelowThisCopy;
     534                rc = CFGMR3DuplicateSubTree(pBelowThis, &pBelowThisCopy);
     535                if (RT_SUCCESS(rc))
    513536                {
    514537                    rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pBelowThisCopy, NULL);
     
    528551        else if (!strcmp(szAction, "inject"))
    529552        {
    530             PCFGMNODE pTransCopy = CFGMR3DuplicateSubTree(pTransAttDrv);
    531             AssertLogRelBreakStmt(pTransCopy, rc = VERR_NO_MEMORY);
    532             rc = VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION;
    533 
    534             PCFGMNODE pThisCopy = CFGMR3DuplicateSubTree(*ppNode);
    535             if (pThisCopy)
     553            PCFGMNODE pTransCopy;
     554            rc = CFGMR3DuplicateSubTree(pTransAttDrv, &pTransCopy);
     555            AssertLogRelRCReturn(rc, rc);
     556
     557            PCFGMNODE pThisCopy;
     558            rc = CFGMR3DuplicateSubTree(*ppNode, &pThisCopy);
     559            if (RT_SUCCESS(rc))
    536560            {
    537561                rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pThisCopy, NULL);
    538                 AssertLogRelRC(rc);
    539                 if (RT_FAILURE(rc))
     562                if (RT_SUCCESS(rc))
     563                {
     564                    rc = CFGMR3InsertInteger(pTransCopy, "InjectTransformationPtr", (uintptr_t)pCurTrans);
     565                    AssertLogRelRC(rc);
     566                    rc = CFGMR3InsertString(pTransCopy, "InjectTransformationNm", szCurTransNm);
     567                    AssertLogRelRC(rc);
     568                    if (RT_SUCCESS(rc))
     569                        rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
     570                }
     571                else
     572                {
     573                    AssertLogRelRC(rc);
    540574                    CFGMR3RemoveNode(pThisCopy);
     575                }
    541576            }
    542             if (RT_SUCCESS(rc))
    543                 rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
    544577            if (RT_FAILURE(rc))
    545578                CFGMR3RemoveNode(pTransCopy);
    546579        }
     580        /*
     581         * Merge the Config node of the transformation with the one of the
     582         * current driver.
     583         */
     584        else if (!strcmp(szAction, "mergeconfig"))
     585        {
     586            PCFGMNODE pTransConfig = CFGMR3GetChild(pCurTrans, "Config");
     587            AssertLogRelReturn(pTransConfig, VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
     588
     589            PCFGMNODE pDrvConfig = CFGMR3GetChild(*ppNode, "Config");
     590            if (*ppNode)
     591                CFGMR3InsertNode(*ppNode, "Config", &pDrvConfig);
     592            AssertLogRelReturn(pDrvConfig, VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER);
     593
     594            rc = CFGMR3CopyTree(pDrvConfig, pTransConfig, CFGM_COPY_FLAGS_REPLACE_VALUES);
     595            AssertLogRelRCReturn(rc, rc);
     596        }
    547597        else
    548598            AssertFailed();
    549         break;
    550     }
     599
     600        cTransformations++;
     601        if (*ppNode)
     602            CFGMR3Dump(*ppNode);
     603        else
     604            LogRel(("The transformation removed the driver.\n"));
     605    }
     606
     607    /*
     608     * Note what happened in the release log.
     609     */
     610    if (cTransformations > 0)
     611        LogRel(("Transformations done. Applied %u driver transformations.\n", cTransformations));
    551612
    552613    return rc;
     
    572633 * @remarks Recursive calls to this function is normal as the drivers will
    573634 *          attach to anything below them during the pfnContruct call.
     635 *
     636 * @todo    Need to extend this interface a bit so that the driver
     637 *          transformation feature can attach drivers to unconfigured LUNs and
     638 *          at the end of chains.
    574639 */
    575640int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
     
    587652    if (RT_FAILURE(rc))
    588653        return rc;
     654    if (!pNode)
     655        return VERR_PDM_NO_ATTACHED_DRIVER;
    589656
    590657    /*
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