示例#1
0
DWORD
VmDirIndexLibInit(
    PVMDIR_MUTEX    pModMutex
    )
{
    static VDIR_DEFAULT_INDEX_CFG defIdx[] = VDIR_INDEX_INITIALIZER;

    DWORD   dwError = 0;
    DWORD   i = 0;
    PSTR    pszLastOffset = NULL;
    ENTRYID maxEId = 0;
    VDIR_BACKEND_CTX    beCtx = {0};
    BOOLEAN             bHasTxn = FALSE;
    PVDIR_INDEX_CFG     pIndexCfg = NULL;
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

    if (!pModMutex)
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // pModMutex refers to gVdirSchemaGlobals.cacheModMutex,
    // so do not free it during shutdown
    gVdirIndexGlobals.mutex = pModMutex;

    dwError = VmDirAllocateCondition(&gVdirIndexGlobals.cond);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(
            &gVdirIndexGlobals.pIndexCfgMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    beCtx.pBE = VmDirBackendSelect(NULL);

    dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = TRUE;

    // get fields to continue indexing from where it left last time
    dwError = beCtx.pBE->pfnBEUniqKeyGetValue(
            &beCtx, INDEX_LAST_OFFSET_KEY, &pszLastOffset);
    if (dwError)
    {
        dwError = beCtx.pBE->pfnBEMaxEntryId(&maxEId);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (maxEId == ENTRY_ID_SEQ_INITIAL_VALUE)
        {
            gVdirIndexGlobals.bFirstboot = TRUE;
        }
        else
        {
            gVdirIndexGlobals.bLegacyDB = TRUE;
        }

        // set index_last_offset = -1 to indicate indexing has started
        gVdirIndexGlobals.offset = -1;
        dwError = beCtx.pBE->pfnBEUniqKeySetValue(
                &beCtx, INDEX_LAST_OFFSET_KEY, "-1");
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    else
    {
        dwError = VmDirStringToINT64(pszLastOffset, NULL, &gVdirIndexGlobals.offset);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = beCtx.pBE->pfnBETxnCommit(&beCtx);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = FALSE;

    dwError = VmDirSchemaCtxAcquire(&pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // open default indices
    for (i = 0; defIdx[i].pszAttrName; i++)
    {
        dwError = VmDirDefaultIndexCfgInit(&defIdx[i], &pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);

        // update attribute types in schema cache with their index info
        dwError = VmDirSchemaAttrNameToDescriptor(
                pSchemaCtx, pIndexCfg->pszAttrName, &pATDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirIndexCfgGetAllScopesInStrArray(
                pIndexCfg, &pATDesc->ppszUniqueScopes);
        BAIL_ON_VMDIR_ERROR(dwError);

        pATDesc->dwSearchFlags |= 1;

        // for free later
        pATDesc->pLdapAt->ppszUniqueScopes = pATDesc->ppszUniqueScopes;
        pATDesc->pLdapAt->dwSearchFlags = pATDesc->dwSearchFlags;

        dwError = VmDirIndexOpen(pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);
        pIndexCfg = NULL;
    }

    // VMIT support
    dwError = VmDirIndexLibInitVMIT();
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = InitializeIndexingThread();
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    if (bHasTxn)
    {
        beCtx.pBE->pfnBETxnAbort(&beCtx);
    }
    VmDirBackendCtxContentFree(&beCtx);
    VmDirSchemaCtxRelease(pSchemaCtx);
    VMDIR_SAFE_FREE_MEMORY(pszLastOffset);
    return dwError;

error:
    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)",
            __FUNCTION__,
            dwError);

    VmDirFreeIndexCfg(pIndexCfg);
    goto cleanup;
}
示例#2
0
/*
 * merge current and patch schema
 * 1. if new schema defined in patch, copy them over to current schema
 * 2. if both current and patch schema have schema definition, use value from patch schema
 *
 * The output is merged into pCurrentEntry.
 */
static
DWORD
VmDirSchemaPatchMerge(
    PVDIR_ENTRY pCurrentEntry,
    PVDIR_ENTRY pPatchEntry
    )
{
    DWORD                   dwError = 0;
    PVDIR_SCHEMA_INSTANCE   pPatchSchema = NULL;
    PVDIR_ATTRIBUTE         pAttr = NULL;
    USHORT                  usCnt = 0;

    dwError = _VmDirSchemaEntryToInstance( pPatchEntry, &pPatchSchema);
    BAIL_ON_VMDIR_ERROR(dwError);

    pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_ATTRIBUTE_TYPES, pCurrentEntry );
    assert( pAttr );
    _VmDirSchemaNormalizeAttrValue( pAttr );
    for (usCnt = 0; usCnt < pPatchSchema->ats.usNumATs; usCnt++)
    {
        PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;
        dwError = VmDirSchemaAttrNameToDescriptor( pCurrentEntry->pSchemaCtx,
                                                   pPatchSchema->ats.pATSortName[ usCnt ].pszName,
                                                   &pATDesc);
        if ( dwError == ERROR_NO_SUCH_ATTRIBUTE )
        {
            dwError = VmDirEntryAddSingleValueStrAttribute(
                            pCurrentEntry,
                            VDIR_ATTRIBUTE_ATTRIBUTE_TYPES,
                            pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
            VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s",
                            VDIR_SAFE_STRING(pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition));
        }
        else
        {
            dwError = _VmDirSchemaAttrReplaceValue( pAttr,
                                                   pPatchSchema->ats.pATSortName[ usCnt ].pszName,
                                                   pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

    pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_OBJECT_CLASSES, pCurrentEntry );
    assert( pAttr );
    _VmDirSchemaNormalizeAttrValue( pAttr );
    for (usCnt = 0; usCnt < pPatchSchema->ocs.usNumOCs; usCnt++)
    {
        PVDIR_SCHEMA_OC_DESC    pOCDesc = NULL;

        dwError = VmDirSchemaOCNameToDescriptor( pCurrentEntry->pSchemaCtx,
                                                 pPatchSchema->ocs.pOCSortName[ usCnt ].pszName,
                                                 &pOCDesc);
        if ( dwError == ERROR_NO_SUCH_OBJECTCLASS )
        {
            dwError = VmDirEntryAddSingleValueStrAttribute(
                            pCurrentEntry,
                            VDIR_ATTRIBUTE_OBJECT_CLASSES,
                            pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
            VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s",
                            VDIR_SAFE_STRING(pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition));
        }
        else
        {
            dwError = _VmDirSchemaAttrReplaceValue( pAttr,
                                                   pPatchSchema->ocs.pOCSortName[ usCnt ].pszName,
                                                   pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

    pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_DIT_CONTENTRULES, pCurrentEntry );
    assert ( pAttr );
    _VmDirSchemaNormalizeAttrValue( pAttr );
    for (usCnt = 0; pAttr && usCnt < pPatchSchema->contentRules.usNumContents; usCnt++)
    {
        PVDIR_SCHEMA_CR_DESC    pCRDesc = NULL;

        dwError = VmDirSchemaCRNameToDescriptor( pCurrentEntry->pSchemaCtx,
                                                 pPatchSchema->contentRules.pContentSortName[ usCnt ].pszName,
                                                 &pCRDesc);
        if ( dwError == ERROR_NO_SUCH_DITCONTENTRULES )
        {
            dwError = VmDirEntryAddSingleValueStrAttribute(
                            pCurrentEntry,
                            VDIR_ATTRIBUTE_DIT_CONTENTRULES,
                            pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
            VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s",
                            VDIR_SAFE_STRING(pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition));
        }
        else
        {
            dwError = _VmDirSchemaAttrReplaceValue( pAttr,
                                                   pPatchSchema->contentRules.pContentSortName[ usCnt ].pszName,
                                                   pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:

    if ( pPatchSchema )
    {
        VdirSchemaInstanceFree(pPatchSchema);
    }

    return dwError;

error:

    goto cleanup;
}