VirtualBox

Changeset 37591 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Jun 22, 2011 3:58:22 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72437
Message:

RTLog,VMM,Main,SUPDrv: Restrict VM release logging by group - major support driver version change.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/log/log.cpp

    r36679 r37591  
    7272{
    7373    /** The logger instance. */
    74     PRTLOGGER   pLogger;
     74    PRTLOGGER               pLogger;
    7575    /** The flags. (used for prefixing.) */
    76     unsigned    fFlags;
     76    unsigned                fFlags;
    7777    /** The group. (used for prefixing.) */
    78     unsigned    iGroup;
     78    unsigned                iGroup;
    7979} RTLOGOUTPUTPREFIXEDARGS, *PRTLOGOUTPUTPREFIXEDARGS;
    8080
    81 #ifdef IN_RING3
    82 /**
    83  * File logging bits for the logger.
    84  */
    85 typedef struct RTLOGGERFILE
    86 {
     81/**
     82 * Internal logger data.
     83 *
     84 * @remarks Don't make casual changes to this structure.
     85 */
     86typedef struct RTLOGGERINTERNAL
     87{
     88    /** The structure revision (RTLOGGERINTERNAL_REV). */
     89    uint32_t                uRevision;
     90    /** The size of the internal logger structure. */
     91    uint32_t                cbSelf;
     92
     93    /** Spinning mutex semaphore.  Can be NIL. */
     94    RTSEMSPINMUTEX          hSpinMtx;
     95    /** Pointer to the flush function. */
     96    PFNRTLOGFLUSH           pfnFlush;
     97
     98    /** Custom prefix callback. */
     99    PFNRTLOGPREFIX          pfnPrefix;
     100    /** Prefix callback argument. */
     101    void                   *pvPrefixUserArg;
     102    /** This is set if a prefix is pending. */
     103    bool                    fPendingPrefix;
     104    /** Alignment padding. */
     105    bool                    afPadding1[3];
     106
     107    /** The max number of groups that there is room for in afGroups and papszGroups.
     108     * Used by RTLogCopyGroupAndFlags(). */
     109    uint32_t                cMaxGroups;
     110    /** Pointer to the group name array.
     111     * (The data is readonly and provided by the user.) */
     112    const char * const     *papszGroups;
     113
     114    /** The number of log entries per group.  NULL if
     115     * RTLOGFLAGS_RESTRICT_GROUPS is not specified. */
     116    uint32_t               *pacEntriesPerGroup;
     117    /** The max number of entries per group. */
     118    uint32_t                cMaxEntriesPerGroup;
     119    /** Padding.  */
     120    uint32_t                u32Padding2;
     121
     122#ifdef IN_RING3 /* Note! Must be at the end! */
     123    /** @name File logging bits for the logger.
     124     * @{ */
    87125    /** Pointer to the function called when starting logging, and when
    88126     * ending or starting a new log file as part of history rotation.
    89127     * This can be NULL. */
    90128    PFNRTLOGPHASE           pfnPhase;
     129
    91130    /** Handle to log file (if open). */
    92     RTFILE                  File;
    93     /** Pointer to filename.
    94      * (The memory is allocated in the same block as RTLOGGER.) */
    95     char                   *pszFilename;
    96     /** Log file history settings: number of older files to keep.
    97      * 0 means no history. */
    98     uint32_t                cHistory;
     131    union
     132    {
     133        RTFILE              hFile;
     134        RTHCUINTPTR         uPaddingForNewRTFILE;
     135    } u;
     136# if ARCH_BITS == 32
     137    /** Alignment padding.  */
     138    uint32_t                u32Padding;
     139# endif
    99140    /** Log file history settings: maximum amount of data to put in a file. */
    100141    uint64_t                cbHistoryFileMax;
     
    105146    /** Log file history settings: in what time slot was the file created. */
    106147    uint32_t                uHistoryTimeSlotStart;
    107 } RTLOGGERFILE;
     148    /** Log file history settings: number of older files to keep.
     149     * 0 means no history. */
     150    uint32_t                cHistory;
     151    /** Pointer to filename. */
     152    char                    szFilename[RTPATH_MAX];
     153    /** @} */
    108154#endif /* IN_RING3 */
    109 
     155} RTLOGGERINTERNAL;
     156
     157/** The revision of the internal logger structure. */
     158#define RTLOGGERINTERNAL_REV    UINT32_C(9)
     159
     160#ifdef IN_RING3
     161/** The size of the RTLOGGERINTERNAL structure in ring-0.  */
     162# define RTLOGGERINTERNAL_R0_SIZE       RT_OFFSETOF(RTLOGGERINTERNAL, pfnPhase)
     163AssertCompileMemberAlignment(RTLOGGERINTERNAL, u.hFile, sizeof(void *));
     164AssertCompileMemberAlignment(RTLOGGERINTERNAL, cbHistoryFileMax, sizeof(uint64_t));
     165#endif
    110166
    111167/*******************************************************************************
     
    126182static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars);
    127183static void rtlogLoggerExVLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
     184static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
    128185
    129186
     
    142199static uint32_t volatile            g_cLoggerLockCount;
    143200#endif
     201
    144202#ifdef IN_RING0
    145203/** Number of per-thread loggers. */
     
    210268    { "tsc",          sizeof("tsc"         ) - 1,   RTLOGFLAGS_PREFIX_TSC,          false }, /* before ts! */
    211269    { "ts",           sizeof("ts"          ) - 1,   RTLOGFLAGS_PREFIX_TS,           false },
     270    /* We intentionally omit RTLOGFLAGS_RESTRICT_GROUPS. */
    212271};
    213272
     
    244303{
    245304#ifndef IN_RC
    246     if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX)
    247     {
    248         int rc = RTSemSpinMutexRequest(pLogger->hSpinMtx);
     305    PRTLOGGERINTERNAL pInt = pLogger->pInt;
     306    AssertMsgReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, ("%#x != %#x\n", pInt->uRevision, RTLOGGERINTERNAL_REV),
     307                    VERR_LOG_REVISION_MISMATCH);
     308    AssertMsgReturn(pInt->cbSelf == sizeof(*pInt), ("%#x != %#x\n", pInt->cbSelf, sizeof(*pInt)),
     309                    VERR_LOG_REVISION_MISMATCH);
     310    if (pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
     311    {
     312        int rc = RTSemSpinMutexRequest(pInt->hSpinMtx);
    249313        if (RT_FAILURE(rc))
    250314            return rc;
     
    262326{
    263327#ifndef IN_RC
    264     if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX)
    265         RTSemSpinMutexRelease(pLogger->hSpinMtx);
     328    if (pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX)
     329        RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
    266330#endif
    267331    return;
     
    281345{
    282346    PRTLOGGER pLogger = (PRTLOGGER)pvArg;
    283     RTFileWrite(pLogger->pFile->File, pachChars, cbChars, NULL);
     347    RTFileWrite(pLogger->pInt->u.hFile, pachChars, cbChars, NULL);
    284348    return cbChars;
    285349}
     
    325389    va_list args;
    326390    AssertPtrReturnVoid(pLogger);
    327     AssertPtrReturnVoid(pLogger->pFile);
    328     Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX);
     391    AssertPtrReturnVoid(pLogger->pInt);
     392    Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    329393
    330394    va_start(args, pszFormat);
     
    345409    va_list args;
    346410    AssertPtrReturnVoid(pLogger);
    347     AssertPtrReturnVoid(pLogger->pFile);
    348     Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX);
     411    AssertPtrReturnVoid(pLogger->pInt);
     412    Assert(pLogger->pInt->hSpinMtx != NIL_RTSEMSPINMUTEX);
    349413
    350414    va_start(args, pszFormat);
     
    356420
    357421RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
    358                            const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
     422                           const char *pszEnvVarBase, unsigned cGroups, const char * const *papszGroups,
    359423                           uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
    360424                           uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
    361425                           char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args)
    362426{
    363     int        rc;
    364     size_t     cb;
    365     PRTLOGGER  pLogger;
     427    int         rc;
     428    size_t      offInternal;
     429    size_t      cbLogger;
     430    PRTLOGGER   pLogger;
    366431
    367432    /*
     
    384449     * Allocate a logger instance.
    385450     */
    386     cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups + 1]) + RTPATH_MAX;
    387 #ifdef IN_RING3
    388     cb += sizeof(RTLOGGERFILE);
    389 #endif
    390     pLogger = (PRTLOGGER)RTMemAllocZVar(cb);
     451    offInternal = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
     452    offInternal = RT_ALIGN_Z(offInternal, sizeof(uint64_t));
     453    cbLogger = offInternal;
     454    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     455        cbLogger += cGroups * sizeof(uint32_t);
     456    pLogger = (PRTLOGGER)RTMemAllocZVar(offInternal + sizeof(RTLOGGERINTERNAL));
    391457    if (pLogger)
    392458    {
    393 #if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
     459# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
    394460        uint8_t *pu8Code;
    395 #endif
    396 
    397         pLogger->u32Magic    = RTLOGGER_MAGIC;
    398         pLogger->papszGroups = papszGroups;
    399         pLogger->cMaxGroups  = cGroups;
    400         pLogger->cGroups     = cGroups;
    401 #ifdef IN_RING3
    402         pLogger->pFile       = (PRTLOGGERFILE)((char *)&pLogger->afGroups[cGroups + 1] + RTPATH_MAX);
    403         pLogger->pFile->File        = NIL_RTFILE;
    404         pLogger->pFile->pszFilename = (char *)&pLogger->afGroups[cGroups + 1];
    405         pLogger->pFile->pfnPhase    = pfnPhase;
    406         pLogger->pFile->cHistory    = cHistory;
     461# endif
     462        pLogger->u32Magic       = RTLOGGER_MAGIC;
     463        pLogger->cGroups        = cGroups;
     464        pLogger->fFlags         = fFlags;
     465        pLogger->fDestFlags     = fDestFlags;
     466        pLogger->pInt           = (PRTLOGGERINTERNAL)((uintptr_t)pLogger + offInternal);
     467        pLogger->pInt->uRevision                = RTLOGGERINTERNAL_REV;
     468        pLogger->pInt->cbSelf                   = sizeof(RTLOGGERINTERNAL);
     469        pLogger->pInt->hSpinMtx                 = NIL_RTSEMSPINMUTEX;
     470        pLogger->pInt->pfnFlush                 = NULL;
     471        pLogger->pInt->pfnPrefix                = NULL;
     472        pLogger->pInt->pvPrefixUserArg          = NULL;
     473        pLogger->pInt->afPadding1[0]            = false;
     474        pLogger->pInt->afPadding1[1]            = false;
     475        pLogger->pInt->afPadding1[2]            = false;
     476        pLogger->pInt->cMaxGroups               = cGroups;
     477        pLogger->pInt->papszGroups              = papszGroups;
     478        if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     479            pLogger->pInt->pacEntriesPerGroup   = (uint32_t *)(pLogger->pInt + 1);
     480        else
     481            pLogger->pInt->pacEntriesPerGroup   = NULL;
     482        pLogger->pInt->cMaxEntriesPerGroup      = UINT32_MAX;
     483# ifdef IN_RING3
     484        pLogger->pInt->pfnPhase                 = pfnPhase;
     485        pLogger->pInt->u.hFile                  = NIL_RTFILE;
     486        pLogger->pInt->cHistory                 = cHistory;
    407487        if (cbHistoryFileMax == 0)
    408             pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
     488            pLogger->pInt->cbHistoryFileMax    = UINT64_MAX;
    409489        else
    410             pLogger->pFile->cbHistoryFileMax = cbHistoryFileMax;
     490            pLogger->pInt->cbHistoryFileMax    = cbHistoryFileMax;
    411491        if (cSecsHistoryTimeSlot == 0)
    412             pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
     492            pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
    413493        else
    414             pLogger->pFile->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
    415 #else  /* !IN_RING3 */
    416         pLogger->pFile       = NULL;
    417 #endif /* !IN_RING3 */
    418         pLogger->fFlags      = fFlags;
    419         pLogger->fDestFlags  = fDestFlags;
    420         pLogger->fPendingPrefix = true;
     494            pLogger->pInt->cSecsHistoryTimeSlot = cSecsHistoryTimeSlot;
     495# endif  /* IN_RING3 */
    421496        if (pszGroupSettings)
    422497            RTLogGroupSettings(pLogger, pszGroupSettings);
    423498
    424 #if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
     499# if defined(RT_ARCH_X86) && (!defined(LOG_USE_C99) || !defined(RT_WITHOUT_EXEC_ALLOC))
    425500        /*
    426501         * Emit wrapper code.
     
    447522        else
    448523        {
    449 # ifdef RT_OS_LINUX
     524#  ifdef RT_OS_LINUX
    450525            if (pszErrorMsg) /* Most probably SELinux causing trouble since the larger RTMemAlloc succeeded. */
    451526                RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("mmap(PROT_WRITE | PROT_EXEC) failed -- SELinux?"));
    452 # endif
     527#  endif
    453528            rc = VERR_NO_MEMORY;
    454529        }
    455530        if (RT_SUCCESS(rc))
    456 #endif /* X86 wrapper code*/
    457         {
    458 #ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */
     531# endif /* X86 wrapper code*/
     532        {
     533# ifdef IN_RING3 /* files and env.vars. are only accessible when in R3 at the present time. */
    459534            /*
    460535             * Format the filename.
     
    463538            {
    464539                /** @todo validate the length, fail on overflow. */
    465                 RTStrPrintfV(pLogger->pFile->pszFilename, RTPATH_MAX, pszFilenameFmt, args);
     540                RTStrPrintfV(pLogger->pInt->szFilename, sizeof(pLogger->pInt->szFilename), pszFilenameFmt, args);
    466541                pLogger->fDestFlags |= RTLOGDEST_FILE;
    467542            }
     
    501576                    RTLogGroupSettings(pLogger, pszVar);
    502577            }
    503 #endif /* IN_RING3 */
     578# endif /* IN_RING3 */
    504579
    505580            /*
     
    507582             */
    508583            rc = VINF_SUCCESS;
    509 #ifdef IN_RING3
     584# ifdef IN_RING3
    510585            if (pLogger->fDestFlags & RTLOGDEST_FILE)
    511586            {
     
    521596                {
    522597                    /* Force rotation if it is configured. */
    523                     pLogger->pFile->cbHistoryFileWritten = UINT64_MAX;
     598                    pLogger->pInt->cbHistoryFileWritten = UINT64_MAX;
    524599                    rtlogRotate(pLogger, 0, true /* fFirst */);
    525600
    526601                    /* If the file is not open then rotation is not set up. */
    527                     if (pLogger->pFile->File == NIL_RTFILE)
     602                    if (pLogger->pInt->u.hFile == NIL_RTFILE)
    528603                    {
    529                         pLogger->pFile->cbHistoryFileWritten = 0;
     604                        pLogger->pInt->cbHistoryFileWritten = 0;
    530605                        rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg);
    531606                    }
    532607                }
    533608            }
    534 #endif  /* IN_RING3 */
     609# endif  /* IN_RING3 */
    535610
    536611            /*
     
    540615            if (RT_SUCCESS(rc))
    541616            {
    542                 rc = RTSemSpinMutexCreate(&pLogger->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
     617                rc = RTSemSpinMutexCreate(&pLogger->pInt->hSpinMtx, RTSEMSPINMUTEX_FLAGS_IRQ_SAFE);
    543618                if (RT_SUCCESS(rc))
    544619                {
    545 #ifdef IN_RING3 /** @todo do counters in ring-0 too? */
     620# ifdef IN_RING3 /** @todo do counters in ring-0 too? */
    546621                    RTTHREAD Thread = RTThreadSelf();
    547622                    if (Thread != NIL_RTTHREAD)
    548623                    {
    549624                        int32_t c = RTLockValidatorWriteLockGetCount(Thread);
    550                         RTSemSpinMutexRequest(pLogger->hSpinMtx);
     625                        RTSemSpinMutexRequest(pLogger->pInt->hSpinMtx);
    551626                        c = RTLockValidatorWriteLockGetCount(Thread) - c;
    552                         RTSemSpinMutexRelease(pLogger->hSpinMtx);
     627                        RTSemSpinMutexRelease(pLogger->pInt->hSpinMtx);
    553628                        ASMAtomicWriteU32(&g_cLoggerLockCount, c);
    554629                    }
    555630
    556631                    /* Use the callback to generate some initial log contents. */
    557                     Assert(VALID_PTR(pLogger->pFile->pfnPhase) || pLogger->pFile->pfnPhase == NULL);
    558                     if (pLogger->pFile->pfnPhase)
    559                         pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
    560 #endif
     632                    Assert(VALID_PTR(pLogger->pInt->pfnPhase) || pLogger->pInt->pfnPhase == NULL);
     633                    if (pLogger->pInt->pfnPhase)
     634                        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal);
     635# endif
    561636                    *ppLogger = pLogger;
    562637                    return VINF_SUCCESS;
     
    566641                    RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("failed to create semaphore"));
    567642            }
    568 #ifdef IN_RING3
    569             RTFileClose(pLogger->pFile->File);
    570 #endif
    571 #if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
     643# ifdef IN_RING3
     644            RTFileClose(pLogger->pInt->u.hFile);
     645# endif
     646# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    572647            RTMemFree(*(void **)&pLogger->pfnLogger);
    573 #else
     648# else
    574649            RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
    575 #endif
     650# endif
    576651        }
    577652        RTMemFree(pLogger);
     
    640715    if (!pLogger)
    641716        return VINF_SUCCESS;
    642     AssertReturn(VALID_PTR(pLogger), VERR_INVALID_POINTER);
     717    AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
    643718    AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     719    AssertPtrReturn(pLogger->pInt, VERR_INVALID_POINTER);
    644720
    645721    /*
     
    659735    rtlogFlush(pLogger);
    660736
    661 #ifdef IN_RING3
     737# ifdef IN_RING3
    662738    /*
    663739     * Add end of logging message.
    664740     */
    665741    if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
    666         && pLogger->pFile->File != NIL_RTFILE)
    667         pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
     742        && pLogger->pInt->u.hFile != NIL_RTFILE)
     743        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked);
    668744
    669745    /*
    670746     * Close output stuffs.
    671747     */
    672     if (pLogger->pFile->File != NIL_RTFILE)
    673     {
    674         int rc2 = RTFileClose(pLogger->pFile->File);
     748    if (pLogger->pInt->u.hFile != NIL_RTFILE)
     749    {
     750        int rc2 = RTFileClose(pLogger->pInt->u.hFile);
    675751        AssertRC(rc2);
    676752        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    677753            rc = rc2;
    678         pLogger->pFile->File = NIL_RTFILE;
    679     }
    680 #endif
     754        pLogger->pInt->u.hFile = NIL_RTFILE;
     755    }
     756# endif
    681757
    682758    /*
    683759     * Free the mutex, the wrapper and the instance memory.
    684760     */
    685     hSpinMtx = pLogger->hSpinMtx;
    686     pLogger->hSpinMtx = NIL_RTSEMSPINMUTEX;
     761    hSpinMtx = pLogger->pInt->hSpinMtx;
     762    pLogger->pInt->hSpinMtx = NIL_RTSEMSPINMUTEX;
    687763    if (hSpinMtx != NIL_RTSEMSPINMUTEX)
    688764    {
     
    697773    if (pLogger->pfnLogger)
    698774    {
    699 #if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
     775# if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC)
    700776        RTMemFree(*(void **)&pLogger->pfnLogger);
    701 #else
     777# else
    702778        RTMemExecFree(*(void **)&pLogger->pfnLogger, 64);
    703 #endif
     779# endif
    704780        pLogger->pfnLogger = NULL;
    705781    }
     
    772848    {
    773849        AssertMsgFailed(("%d req=%d cGroups=%d\n", cbLoggerRC, RT_OFFSETOF(RTLOGGERRC, afGroups[pLogger->cGroups]), pLogger->cGroups));
    774         return VERR_INVALID_PARAMETER;
     850        return VERR_BUFFER_OVERFLOW;
    775851    }
    776852    memcpy(&pLoggerRC->afGroups[0], &pLogger->afGroups[0], pLogger->cGroups * sizeof(pLoggerRC->afGroups[0]));
     
    780856     * Copy bits from the HC instance.
    781857     */
    782     pLoggerRC->fPendingPrefix = pLogger->fPendingPrefix;
     858    pLoggerRC->fPendingPrefix = pLogger->pInt->fPendingPrefix;
    783859    pLoggerRC->fFlags |= pLogger->fFlags;
    784860
     
    851927RT_EXPORT_SYMBOL(RTLogFlushRC);
    852928
    853 
    854 #ifdef IN_RING3
    855 /**
    856  * Create a logger instance for singled threaded ring-0 usage.
    857  *
    858  * @returns iprt status code.
    859  *
    860  * @param   pLogger             Where to create the logger instance.
    861  * @param   cbLogger            The amount of memory available for the logger instance.
    862  * @param   pfnLogger           Pointer to logger wrapper function for the clone.
    863  * @param   pfnFlush            Pointer to flush function for the clone.
    864  * @param   fFlags              Logger instance flags for the clone, a combination of the RTLOGFLAGS_* values.
    865  * @param   fDestFlags          The destination flags.
    866  */
    867 RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger, PFNRTLOGGER pfnLogger, PFNRTLOGFLUSH pfnFlush,
     929# ifdef IN_RING3
     930
     931RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
     932                             RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
    868933                             uint32_t fFlags, uint32_t fDestFlags)
    869934{
     
    872937     */
    873938    AssertPtrReturn(pLogger, VERR_INVALID_PARAMETER);
    874     AssertReturn(cbLogger >= sizeof(*pLogger), VERR_INVALID_PARAMETER);
    875     AssertReturn(pfnLogger, VERR_INVALID_PARAMETER);
    876     AssertReturn(pfnFlush, VERR_INVALID_PARAMETER);
     939    size_t const cbRequired = sizeof(*pLogger) + RTLOGGERINTERNAL_R0_SIZE;
     940    AssertReturn(cbLogger >= cbRequired, VERR_BUFFER_OVERFLOW);
     941    AssertReturn(pLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
     942    AssertReturn(pfnLoggerR0Ptr != NIL_RTR0PTR, VERR_INVALID_PARAMETER);
    877943
    878944    /*
    879945     * Initialize the ring-0 instance.
    880946     */
    881     pLogger->offScratch   = 0;
    882     pLogger->fPendingPrefix = false;
    883     pLogger->pfnLogger    = pfnLogger;
    884     pLogger->pfnFlush     = pfnFlush;
    885     pLogger->hSpinMtx     = NIL_RTSEMSPINMUTEX; /* Not serialized. */
    886     pLogger->u32Magic     = RTLOGGER_MAGIC;
    887     pLogger->fFlags       = fFlags;
    888     pLogger->fDestFlags   = fDestFlags & ~RTLOGDEST_FILE;
    889     pLogger->pFile        = NULL;
    890     pLogger->papszGroups  = NULL;
    891     pLogger->cMaxGroups   = (uint32_t)((cbLogger - RT_OFFSETOF(RTLOGGER, afGroups[0])) / sizeof(pLogger->afGroups[0]));
    892     pLogger->cGroups      = 1;
    893     pLogger->afGroups[0]  = 0;
     947    pLogger->achScratch[0]  = 0;
     948    pLogger->offScratch     = 0;
     949    pLogger->pfnLogger      = (PFNRTLOGGER)pfnLoggerR0Ptr;
     950    pLogger->fFlags         = fFlags;
     951    pLogger->fDestFlags     = fDestFlags & ~RTLOGDEST_FILE;
     952    pLogger->pInt           = NULL;
     953    pLogger->cGroups        = 1;
     954    pLogger->afGroups[0]    = 0;
     955
     956    uint32_t cMaxGroups     = (uint32_t)((cbLogger - cbRequired) / sizeof(pLogger->afGroups[0]));
     957    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     958        cMaxGroups /= 2;
     959    PRTLOGGERINTERNAL pInt;
     960    for (;;)
     961    {
     962        AssertReturn(cMaxGroups > 0, VERR_BUFFER_OVERFLOW);
     963        pInt = (PRTLOGGERINTERNAL)&pLogger->afGroups[cMaxGroups];
     964        if (!((uintptr_t)pInt & (sizeof(uint64_t) - 1)))
     965            break;
     966        cMaxGroups--;
     967    }
     968    pLogger->pInt               = (PRTLOGGERINTERNAL)(pLoggerR0Ptr + (uintptr_t)pInt - (uintptr_t)pLogger);
     969    pInt->uRevision             = RTLOGGERINTERNAL_REV;
     970    pInt->cbSelf                = RTLOGGERINTERNAL_R0_SIZE;
     971    pInt->hSpinMtx              = NIL_RTSEMSPINMUTEX; /* Not serialized. */
     972    pInt->pfnFlush              = (PFNRTLOGFLUSH)pfnFlushR0Ptr;
     973    pInt->pfnPrefix             = NULL;
     974    pInt->pvPrefixUserArg       = NULL;
     975    pInt->fPendingPrefix        = false;
     976    pInt->cMaxGroups            = cMaxGroups;
     977    pInt->papszGroups           = NULL;
     978    pInt->cMaxEntriesPerGroup   = UINT32_MAX;
     979    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     980    {
     981        memset(pInt + 1, 0, sizeof(uint32_t) * cMaxGroups);
     982        pInt->pacEntriesPerGroup= (uint32_t *)(pLogger->pInt + 1);
     983    }
     984    else
     985        pInt->pacEntriesPerGroup= NULL;
     986
     987    pLogger->u32Magic           = RTLOGGER_MAGIC;
    894988    return VINF_SUCCESS;
    895989}
    896990RT_EXPORT_SYMBOL(RTLogCreateForR0);
    897 #endif /* IN_RING3 */
    898 
    899 
    900 /**
    901  * Copies the group settings and flags from logger instance to another.
    902  *
    903  * @returns IPRT status code.
    904  * @param   pDstLogger      The destination logger instance.
    905  * @param   pSrcLogger      The source logger instance. If NULL the default one is used.
    906  * @param   fFlagsOr        OR mask for the flags.
    907  * @param   fFlagsAnd       AND mask for the flags.
    908  */
    909 RTDECL(int) RTLogCopyGroupsAndFlags(PRTLOGGER pDstLogger, PCRTLOGGER pSrcLogger, unsigned fFlagsOr, unsigned fFlagsAnd)
    910 {
    911     int      rc;
    912     unsigned cGroups;
    913 
     991
     992
     993RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags)
     994{
     995    size_t cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups]);
     996    cb = RT_ALIGN_Z(cb, sizeof(uint64_t));
     997    cb += sizeof(RTLOGGERINTERNAL);
     998    if (fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     999        cb += sizeof(uint32_t) * cGroups;
     1000    return cb;
     1001}
     1002RT_EXPORT_SYMBOL(RTLogCalcSizeForR0);
     1003
     1004
     1005RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr,
     1006                                         PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd)
     1007{
    9141008    /*
    9151009     * Validate input.
     
    9261020        if (!pSrcLogger)
    9271021        {
    928             pDstLogger->fFlags |= RTLOGFLAGS_DISABLED;
     1022            pDstLogger->fFlags |= RTLOGFLAGS_DISABLED | fFlagsOr;
    9291023            pDstLogger->cGroups = 1;
    9301024            pDstLogger->afGroups[0] = 0;
     
    9361030     * Copy flags and group settings.
    9371031     */
    938     pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd) | fFlagsOr;
    939 
    940     rc = VINF_SUCCESS;
    941     cGroups = pSrcLogger->cGroups;
    942     if (cGroups < pDstLogger->cMaxGroups)
    943     {
    944         AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstLogger->cMaxGroups,
    945                          pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups])));
     1032    pDstLogger->fFlags = (pSrcLogger->fFlags & fFlagsAnd & ~RTLOGFLAGS_RESTRICT_GROUPS) | fFlagsOr;
     1033
     1034    PRTLOGGERINTERNAL   pDstInt = (PRTLOGGERINTERNAL)((uintptr_t)pDstLogger->pInt - pDstLoggerR0Ptr + (uintptr_t)pDstLogger);
     1035    int                 rc      = VINF_SUCCESS;
     1036    uint32_t            cGroups = pSrcLogger->cGroups;
     1037    if (cGroups > pDstInt->cMaxGroups)
     1038    {
     1039        AssertMsgFailed(("cMaxGroups=%zd cGroups=%zd (min size %d)\n", pDstInt->cMaxGroups,
     1040                         pSrcLogger->cGroups, RT_OFFSETOF(RTLOGGER, afGroups[pSrcLogger->cGroups]) + RTLOGGERINTERNAL_R0_SIZE));
    9461041        rc = VERR_INVALID_PARAMETER;
    947         cGroups = pDstLogger->cMaxGroups;
     1042        cGroups = pDstInt->cMaxGroups;
    9481043    }
    9491044    memcpy(&pDstLogger->afGroups[0], &pSrcLogger->afGroups[0], cGroups * sizeof(pDstLogger->afGroups[0]));
     
    9521047    return rc;
    9531048}
    954 RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlags);
     1049RT_EXPORT_SYMBOL(RTLogCopyGroupsAndFlagsForR0);
     1050
     1051
     1052RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr,
     1053                                              RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr)
     1054{
     1055    AssertPtrReturn(pLogger, VERR_INVALID_POINTER);
     1056    AssertReturn(pLogger->u32Magic == RTLOGGER_MAGIC, VERR_INVALID_MAGIC);
     1057
     1058    /*
     1059     * Do the work.
     1060     */
     1061    PRTLOGGERINTERNAL pInt = (PRTLOGGERINTERNAL)((uintptr_t)pLogger->pInt - pLoggerR0Ptr + (uintptr_t)pLogger);
     1062    AssertReturn(pInt->uRevision == RTLOGGERINTERNAL_REV, VERR_LOG_REVISION_MISMATCH);
     1063    pInt->pvPrefixUserArg = (void *)pvUserR0Ptr;
     1064    pInt->pfnPrefix       = (PFNRTLOGPREFIX)pfnCallbackR0Ptr;
     1065
     1066    return VINF_SUCCESS;
     1067}
     1068RT_EXPORT_SYMBOL(RTLogSetCustomPrefixCallbackForR0);
     1069
     1070# endif /* IN_RING3 */
    9551071
    9561072
     
    10501166     */
    10511167    rtlogLock(pLogger);
    1052     pLogger->pvPrefixUserArg = pvUser;
    1053     pLogger->pfnPrefix       = pfnCallback;
     1168    pLogger->pInt->pvPrefixUserArg = pvUser;
     1169    pLogger->pInt->pfnPrefix       = pfnCallback;
    10541170    rtlogUnlock(pLogger);
    10551171
     
    12191335            {
    12201336                const char *psz2 = (const char*)pszStart;
    1221                 if (rtlogIsGroupMatching(pLogger->papszGroups[i], &psz2, cch))
     1337                if (rtlogIsGroupMatching(pLogger->pInt->papszGroups[i], &psz2, cch))
    12221338                {
    12231339                    unsigned fFlags = RTLOGGRPFLAGS_ENABLED | RTLOGGRPFLAGS_LEVEL_1;
     
    12791395            { "f",          RTLOGGRPFLAGS_FLOW },
    12801396            { "flow",       RTLOGGRPFLAGS_FLOW },
     1397            { "restrict",   RTLOGGRPFLAGS_RESTRICT },
    12811398
    12821399            { "lelik",      RTLOGGRPFLAGS_LELIK },
    12831400            { "michael",    RTLOGGRPFLAGS_MICHAEL },
    1284             { "dmik",       RTLOGGRPFLAGS_DMIK },
    12851401            { "sunlover",   RTLOGGRPFLAGS_SUNLOVER },
    12861402            { "achim",      RTLOGGRPFLAGS_ACHIM },
     
    13441460static int rtLogGetGroupSettingsAddOne(const char *pszName, uint32_t fGroup, char **ppszBuf, size_t *pcchBuf, bool *pfNotFirst)
    13451461{
    1346 #define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
    1347 #define APPEND_SZ(sz)       APPEND_PSZ(sz, sizeof(sz) - 1)
    1348 #define APPEND_CH(ch)       do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
     1462# define APPEND_PSZ(psz,cch) do { memcpy(*ppszBuf, (psz), (cch)); *ppszBuf += (cch); *pcchBuf -= (cch); } while (0)
     1463# define APPEND_SZ(sz)       APPEND_PSZ(sz, sizeof(sz) - 1)
     1464# define APPEND_CH(ch)       do { **ppszBuf = (ch); *ppszBuf += 1; *pcchBuf -= 1; } while (0)
    13491465
    13501466    /*
     
    13821498        return VERR_BUFFER_OVERFLOW;
    13831499
    1384 #undef APPEND_PSZ
    1385 #undef APPEND_SZ
    1386 #undef APPEND_CH
     1500# undef APPEND_PSZ
     1501# undef APPEND_SZ
     1502# undef APPEND_CH
    13871503    return VINF_SUCCESS;
    13881504}
     
    14431559            if (fGroup)
    14441560            {
    1445                 const char *pszName = pLogger->papszGroups[i];
     1561                const char *pszName = pLogger->pInt->papszGroups[i];
    14461562                if (pszName)
    14471563                {
     
    14581574}
    14591575RT_EXPORT_SYMBOL(RTLogGetGroupSettings);
     1576
    14601577#endif /* !IN_RC */
    1461 
    14621578
    14631579/**
     
    15881704RT_EXPORT_SYMBOL(RTLogSetBuffering);
    15891705
     1706
     1707#ifdef IN_RING3
     1708RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup)
     1709{
     1710    /*
     1711     * Resolve the logger instance.
     1712     */
     1713    if (!pLogger)
     1714    {
     1715        pLogger = RTLogDefaultInstance();
     1716        if (!pLogger)
     1717            return UINT32_MAX;
     1718    }
     1719
     1720    rtlogLock(pLogger);
     1721    uint32_t cOld = pLogger->pInt->cMaxEntriesPerGroup;
     1722    pLogger->pInt->cMaxEntriesPerGroup = cMaxEntriesPerGroup;
     1723    rtlogUnlock(pLogger);
     1724
     1725    return cOld;
     1726}
     1727#endif
     1728
    15901729#ifndef IN_RC
    15911730
     
    17221861                    if (i == 0 /* file */ && !fNo)
    17231862                    {
    1724                         AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE);
    1725                         memcpy(pLogger->pFile->pszFilename, pszVar, cch);
    1726                         pLogger->pFile->pszFilename[cch] = '\0';
     1863                        AssertReturn(cch < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
     1864                        memcpy(pLogger->pInt->szFilename, pszVar, cch);
     1865                        pLogger->pInt->szFilename[cch] = '\0';
    17271866                    }
    17281867                    /* log directory */
    17291868                    else if (i == 1 /* dir */ && !fNo)
    17301869                    {
    1731                         char        szTmp[RTPATH_MAX];
    1732                         const char *pszFile = RTPathFilename(pLogger->pFile->pszFilename);
     1870                        char        szTmp[sizeof(pLogger->pInt->szFilename)];
     1871                        const char *pszFile = RTPathFilename(pLogger->pInt->szFilename);
    17331872                        size_t      cchFile = pszFile ? strlen(pszFile) : 0;
    1734                         AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE);
     1873                        AssertReturn(cchFile + cch + 1 < sizeof(pLogger->pInt->szFilename), VERR_OUT_OF_RANGE);
    17351874                        memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1);
    17361875
    1737                         memcpy(pLogger->pFile->pszFilename, pszVar, cch);
    1738                         pLogger->pFile->pszFilename[cch] = '\0';
    1739                         RTPathStripTrailingSlash(pLogger->pFile->pszFilename);
    1740 
    1741                         cch = strlen(pLogger->pFile->pszFilename);
    1742                         pLogger->pFile->pszFilename[cch++] = '/';
    1743                         memcpy(&pLogger->pFile->pszFilename[cch], szTmp, cchFile);
    1744                         pLogger->pFile->pszFilename[cch+cchFile] = '\0';
     1876                        memcpy(pLogger->pInt->szFilename, pszVar, cch);
     1877                        pLogger->pInt->szFilename[cch] = '\0';
     1878                        RTPathStripTrailingSlash(pLogger->pInt->szFilename);
     1879
     1880                        cch = strlen(pLogger->pInt->szFilename);
     1881                        pLogger->pInt->szFilename[cch++] = '/';
     1882                        memcpy(&pLogger->pInt->szFilename[cch], szTmp, cchFile);
     1883                        pLogger->pInt->szFilename[cch + cchFile] = '\0';
    17451884                    }
    17461885                    else if (i == 2 /* history */)
     
    17541893                                rc = RTStrToUInt32Full(szTmp, 0, &cHistory);
    17551894                            AssertMsgReturn(RT_SUCCESS(rc) && cHistory < _1M, ("Invalid history value %s (%Rrc)!\n", szTmp, rc), rc);
    1756                             pLogger->pFile->cHistory = cHistory;
     1895                            pLogger->pInt->cHistory = cHistory;
    17571896                        }
    17581897                        else
    1759                             pLogger->pFile->cHistory = 0;
     1898                            pLogger->pInt->cHistory = 0;
    17601899                    }
    17611900                    else if (i == 3 /* histsize */)
     
    17661905                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch);
    17671906                            if (RT_SUCCESS(rc))
    1768                                 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pFile->cbHistoryFileMax);
     1907                                rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pInt->cbHistoryFileMax);
    17691908                            AssertMsgRCReturn(rc, ("Invalid history file size value %s (%Rrc)!\n", szTmp, rc), rc);
    1770                             if (pLogger->pFile->cbHistoryFileMax == 0)
    1771                                 pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
     1909                            if (pLogger->pInt->cbHistoryFileMax == 0)
     1910                                pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
    17721911                        }
    17731912                        else
    1774                             pLogger->pFile->cbHistoryFileMax = UINT64_MAX;
     1913                            pLogger->pInt->cbHistoryFileMax = UINT64_MAX;
    17751914                    }
    17761915                    else if (i == 4 /* histtime */)
     
    17811920                            int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch);
    17821921                            if (RT_SUCCESS(rc))
    1783                                 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pFile->cSecsHistoryTimeSlot);
     1922                                rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pInt->cSecsHistoryTimeSlot);
    17841923                            AssertMsgRCReturn(rc, ("Invalid history time slot value %s (%Rrc)!\n", szTmp, rc), rc);
    1785                             if (pLogger->pFile->cSecsHistoryTimeSlot == 0)
    1786                                 pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
     1924                            if (pLogger->pInt->cSecsHistoryTimeSlot == 0)
     1925                                pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
    17871926                        }
    17881927                        else
    1789                             pLogger->pFile->cSecsHistoryTimeSlot = UINT32_MAX;
     1928                            pLogger->pInt->cSecsHistoryTimeSlot = UINT32_MAX;
    17901929                    }
    17911930                    else
     
    18632002        }
    18642003
    1865 #ifdef IN_RING3
     2004# ifdef IN_RING3
    18662005    /*
    18672006     * Add the filename.
    18682007     */
    1869     if (    (fDestFlags & RTLOGDEST_FILE)
    1870         &&  VALID_PTR(pLogger->pFile->pszFilename))
     2008    if (fDestFlags & RTLOGDEST_FILE)
    18712009    {
    18722010        rc = RTStrCopyP(&pszBuf, &cchBuf, fNotFirst ? " file=" : "file=");
    18732011        if (RT_FAILURE(rc))
    18742012            return rc;
    1875         rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pFile->pszFilename);
     2013        rc = RTStrCopyP(&pszBuf, &cchBuf, pLogger->pInt->szFilename);
    18762014        if (RT_FAILURE(rc))
    18772015            return rc;
     
    18822020    {
    18832021        char szNum[32];
    1884         if (pLogger->pFile->cHistory)
    1885         {
    1886             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->pFile->cHistory);
     2022        if (pLogger->pInt->cHistory)
     2023        {
     2024            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "history=%u" : " history=%u", pLogger->pInt->cHistory);
    18872025            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    18882026            if (RT_FAILURE(rc))
    18892027                return rc;
    18902028        }
    1891         if (pLogger->pFile->cbHistoryFileMax != UINT64_MAX)
    1892         {
    1893             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->pFile->cbHistoryFileMax);
     2029        if (pLogger->pInt->cbHistoryFileMax != UINT64_MAX)
     2030        {
     2031            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histsize=%llu" : " histsize=%llu", pLogger->pInt->cbHistoryFileMax);
    18942032            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    18952033            if (RT_FAILURE(rc))
    18962034                return rc;
    18972035        }
    1898         if (pLogger->pFile->cSecsHistoryTimeSlot != UINT32_MAX)
    1899         {
    1900             RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->pFile->cSecsHistoryTimeSlot);
     2036        if (pLogger->pInt->cSecsHistoryTimeSlot != UINT32_MAX)
     2037        {
     2038            RTStrPrintf(szNum, sizeof(szNum), fNotFirst ? "histtime=%llu" : " histtime=%llu", pLogger->pInt->cSecsHistoryTimeSlot);
    19012039            rc = RTStrCopyP(&pszBuf, &cchBuf, szNum);
    19022040            if (RT_FAILURE(rc))
     
    19042042        }
    19052043    }
    1906 #endif /* IN_RING3 */
     2044# endif /* IN_RING3 */
    19072045
    19082046    return VINF_SUCCESS;
     
    21312269}
    21322270RT_EXPORT_SYMBOL(RTLogSetDefaultInstanceThread);
    2133 #endif
     2271#endif /* IN_RING0 */
    21342272
    21352273
     
    22092347
    22102348    /*
    2211      * Call worker.
    2212      */
    2213     rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
     2349     * Check restrictions and call worker.
     2350     */
     2351#ifndef IN_RC
     2352    if (RT_UNLIKELY(   (pLogger->fFlags & RTLOGFLAGS_RESTRICT_GROUPS)
     2353                    && iGroup < pLogger->cGroups
     2354                    && (pLogger->afGroups[iGroup] & RTLOGGRPFLAGS_RESTRICT)
     2355                    && ++pLogger->pInt->pacEntriesPerGroup[iGroup] >= pLogger->pInt->cMaxEntriesPerGroup ))
     2356    {
     2357        uint32_t cEntries = pLogger->pInt->pacEntriesPerGroup[iGroup];
     2358        if (cEntries > pLogger->pInt->cMaxEntriesPerGroup)
     2359            pLogger->pInt->pacEntriesPerGroup[iGroup] = cEntries - 1;
     2360        else
     2361        {
     2362            rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
     2363            if (   pLogger->pInt->papszGroups
     2364                && pLogger->pInt->papszGroups[iGroup])
     2365                rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group %s (#%u), muting it.\n",
     2366                                     cEntries, pLogger->pInt->papszGroups[iGroup], iGroup);
     2367            else
     2368                rtlogLoggerExFLocked(pLogger, fFlags, iGroup, "%u messages from group #%u, muting it.\n",
     2369                                     cEntries, iGroup);
     2370        }
     2371    }
     2372    else
     2373#endif
     2374        rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, args);
    22142375
    22152376    /*
     
    22612422        RTLogWriteStdErr(pThis->achScratch, pThis->offScratch);
    22622423
    2263 #ifndef LOG_NO_COM
     2424# ifndef LOG_NO_COM
    22642425    if (pThis->fDestFlags & RTLOGDEST_COM)
    22652426        RTLogWriteCom(pThis->achScratch, pThis->offScratch);
    2266 #endif
     2427# endif
    22672428
    22682429    /* empty the buffer. */
     
    24012562        fOpen |= RTFILE_O_WRITE_THROUGH;
    24022563
    2403     int rc = RTFileOpen(&pLogger->pFile->File, pLogger->pFile->pszFilename, fOpen);
     2564    int rc = RTFileOpen(&pLogger->pInt->u.hFile, pLogger->pInt->szFilename, fOpen);
    24042565    if (RT_FAILURE(rc))
    24052566    {
    2406         pLogger->pFile->File = NIL_RTFILE;
     2567        pLogger->pInt->u.hFile = NIL_RTFILE;
    24072568        if (pszErrorMsg)
    2408             RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pFile->pszFilename, fOpen);
     2569            RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pInt->szFilename, fOpen);
    24092570    }
    24102571    else
    24112572    {
    2412         rc = RTFileGetSize(pLogger->pFile->File, &pLogger->pFile->cbHistoryFileWritten);
     2573        rc = RTFileGetSize(pLogger->pInt->u.hFile, &pLogger->pInt->cbHistoryFileWritten);
    24132574        if (RT_FAILURE(rc))
    24142575        {
    24152576            /* Don't complain if this fails, assume the file is empty. */
    2416             pLogger->pFile->cbHistoryFileWritten = 0;
     2577            pLogger->pInt->cbHistoryFileWritten = 0;
    24172578            rc = VINF_SUCCESS;
    24182579        }
     
    24362597{
    24372598    /* Suppress rotating empty log files simply because the time elapsed. */
    2438     if (RT_UNLIKELY(!pLogger->pFile->cbHistoryFileWritten))
    2439         pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot;
     2599    if (RT_UNLIKELY(!pLogger->pInt->cbHistoryFileWritten))
     2600        pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
    24402601
    24412602    /* Check rotation condition: file still small enough and not too old? */
    2442     if (RT_LIKELY(   pLogger->pFile->cbHistoryFileWritten < pLogger->pFile->cbHistoryFileMax
    2443                   && uTimeSlot == pLogger->pFile->uHistoryTimeSlotStart))
     2603    if (RT_LIKELY(   pLogger->pInt->cbHistoryFileWritten < pLogger->pInt->cbHistoryFileMax
     2604                  && uTimeSlot == pLogger->pInt->uHistoryTimeSlotStart))
    24442605        return;
    24452606
     
    24562617     * chatty phase logging we could run into endless rotation.
    24572618     */
    2458     uint32_t const cSavedHistory = pLogger->pFile->cHistory;
    2459     pLogger->pFile->cHistory = 0;
     2619    uint32_t const cSavedHistory = pLogger->pInt->cHistory;
     2620    pLogger->pInt->cHistory = 0;
    24602621
    24612622    /*
    24622623     * Close the old log file.
    24632624     */
    2464     if (pLogger->pFile->File != NIL_RTFILE)
     2625    if (pLogger->pInt->u.hFile != NIL_RTFILE)
    24652626    {
    24662627        /* Use the callback to generate some final log contents, but only if
    24672628         * this is a rotation with a fully set up logger. Leave the other case
    24682629         * to the RTLogCreateExV function. */
    2469         if (pLogger->pFile->pfnPhase && !fFirst)
     2630        if (pLogger->pInt->pfnPhase && !fFirst)
    24702631        {
    24712632            uint32_t fODestFlags = pLogger->fDestFlags;
    24722633            pLogger->fDestFlags &= RTLOGDEST_FILE;
    2473             pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
     2634            pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked);
    24742635            pLogger->fDestFlags = fODestFlags;
    24752636        }
    2476         RTFileClose(pLogger->pFile->File);
    2477         pLogger->pFile->File = NIL_RTFILE;
     2637        RTFileClose(pLogger->pInt->u.hFile);
     2638        pLogger->pInt->u.hFile = NIL_RTFILE;
    24782639    }
    24792640
     
    24852646        for (uint32_t i = cSavedHistory - 1; i + 1 > 0; i--)
    24862647        {
    2487             char szOldName[RTPATH_MAX];
     2648            char szOldName[sizeof(pLogger->pInt->szFilename) + 32];
    24882649            if (i > 0)
    2489                 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pFile->pszFilename, i);
     2650                RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pInt->szFilename, i);
    24902651            else
    2491                 RTStrCopy(szOldName, sizeof(szOldName), pLogger->pFile->pszFilename);
    2492             char szNewName[RTPATH_MAX];
    2493             RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pFile->pszFilename, i + 1);
    2494             if (RTFileRename(szOldName, szNewName,
    2495                              RTFILEMOVE_FLAGS_REPLACE) == VERR_FILE_NOT_FOUND)
     2652                RTStrCopy(szOldName, sizeof(szOldName), pLogger->pInt->szFilename);
     2653
     2654            char szNewName[sizeof(pLogger->pInt->szFilename) + 32];
     2655            RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pInt->szFilename, i + 1);
     2656            if (   RTFileRename(szOldName, szNewName, RTFILEMOVE_FLAGS_REPLACE)
     2657                == VERR_FILE_NOT_FOUND)
    24962658                RTFileDelete(szNewName);
    24972659        }
     
    25022664        for (uint32_t i = cSavedHistory + 1; ; i++)
    25032665        {
    2504             char szExcessName[RTPATH_MAX];
    2505             RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pFile->pszFilename, i);
     2666            char szExcessName[sizeof(pLogger->pInt->szFilename) + 32];
     2667            RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pInt->szFilename, i);
    25062668            int rc = RTFileDelete(szExcessName);
    25072669            if (RT_FAILURE(rc))
     
    25132675     * Update logger state and create new log file.
    25142676     */
    2515     pLogger->pFile->cbHistoryFileWritten = 0;
    2516     pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot;
     2677    pLogger->pInt->cbHistoryFileWritten = 0;
     2678    pLogger->pInt->uHistoryTimeSlotStart = uTimeSlot;
    25172679    rtlogFileOpen(pLogger, NULL, 0);
    25182680
     
    25222684     * RTLogCreateExV function.
    25232685     */
    2524     if (pLogger->pFile->pfnPhase && !fFirst)
     2686    if (pLogger->pInt->pfnPhase && !fFirst)
    25252687    {
    25262688        uint32_t const fSavedDestFlags = pLogger->fDestFlags;
    25272689        pLogger->fDestFlags &= RTLOGDEST_FILE;
    2528         pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
     2690        pLogger->pInt->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked);
    25292691        pLogger->fDestFlags = fSavedDestFlags;
    25302692    }
    25312693
    25322694    /* Restore saved values. */
    2533     pLogger->pFile->cHistory = cSavedHistory;
     2695    pLogger->pInt->cHistory = cSavedHistory;
    25342696    pLogger->fFlags          = fSavedFlags;
    25352697}
     
    25592721    if (pLogger->fDestFlags & RTLOGDEST_FILE)
    25602722    {
    2561         if (pLogger->pFile->File != NIL_RTFILE)
    2562         {
    2563             RTFileWrite(pLogger->pFile->File, pLogger->achScratch, pLogger->offScratch, NULL);
     2723        if (pLogger->pInt->u.hFile != NIL_RTFILE)
     2724        {
     2725            RTFileWrite(pLogger->pInt->u.hFile, pLogger->achScratch, pLogger->offScratch, NULL);
    25642726            if (pLogger->fFlags & RTLOGFLAGS_FLUSH)
    2565                 RTFileFlush(pLogger->pFile->File);
    2566         }
    2567         if (pLogger->pFile->cHistory)
    2568             pLogger->pFile->cbHistoryFileWritten += pLogger->offScratch;
     2727                RTFileFlush(pLogger->pInt->u.hFile);
     2728        }
     2729        if (pLogger->pInt->cHistory)
     2730            pLogger->pInt->cbHistoryFileWritten += pLogger->offScratch;
    25692731    }
    25702732# endif
     
    25822744#endif /* !IN_RC */
    25832745
     2746#ifdef IN_RC
    25842747    if (pLogger->pfnFlush)
    25852748        pLogger->pfnFlush(pLogger);
     2749#else
     2750    if (pLogger->pInt->pfnFlush)
     2751        pLogger->pInt->pfnFlush(pLogger);
     2752#endif
    25862753
    25872754    /* empty the buffer. */
     
    25952762     */
    25962763    if (   (pLogger->fDestFlags & RTLOGDEST_FILE)
    2597         && pLogger->pFile->cHistory)
    2598         rtlogRotate(pLogger,
    2599                     RTTimeProgramSecTS() / pLogger->pFile->cSecsHistoryTimeSlot,
    2600                     false /* fFirst */);
     2764        && pLogger->pInt->cHistory)
     2765        rtlogRotate(pLogger, RTTimeProgramSecTS() / pLogger->pInt->cSecsHistoryTimeSlot, false /* fFirst */);
    26012766#endif
    26022767}
     
    26782843        for (;;)
    26792844        {
    2680             size_t cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
    2681             char *psz;
     2845            size_t      cb = sizeof(pLogger->achScratch) - pLogger->offScratch - 1;
    26822846            const char *pszNewLine;
     2847            char       *psz;
     2848#ifdef IN_RC
     2849            bool       *pfPendingPrefix = &pLogger->fPendingPrefix;
     2850#else
     2851            bool       *pfPendingPrefix = &pLogger->pInt->fPendingPrefix;
     2852#endif
    26832853
    26842854            /*
    26852855             * Pending prefix?
    26862856             */
    2687             if (pLogger->fPendingPrefix)
     2857            if (*pfPendingPrefix)
    26882858            {
    2689                 pLogger->fPendingPrefix = false;
     2859                *pfPendingPrefix = false;
    26902860
    26912861#if defined(DEBUG) && defined(IN_RING3)
     
    28803050#ifndef IN_RC
    28813051                if (    (pLogger->fFlags & RTLOGFLAGS_PREFIX_CUSTOM)
    2882                     &&  pLogger->pfnPrefix)
     3052                    &&  pLogger->pInt->pfnPrefix)
    28833053                {
    2884                     psz += pLogger->pfnPrefix(pLogger, psz, 31, pLogger->pvPrefixUserArg);
     3054                    psz += pLogger->pInt->pfnPrefix(pLogger, psz, 31, pLogger->pInt->pvPrefixUserArg);
    28853055                    *psz++ = ' ';                                                               /* +32 */
    28863056                }
     
    29173087                {
    29183088#ifdef IN_RING3
    2919                     const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->papszGroups[pArgs->iGroup] : NULL;
     3089                    const char *pszGroup = pArgs->iGroup != ~0U ? pLogger->pInt->papszGroups[pArgs->iGroup] : NULL;
    29203090#else
    29213091                    const char *pszGroup = NULL;
     
    29663136                        case RTLOGGRPFLAGS_LELIK:       pszGroup = "lelik"   ;  cch = sizeof("lelik"   ) - 1; break;
    29673137                        case RTLOGGRPFLAGS_MICHAEL:     pszGroup = "Michael" ;  cch = sizeof("Michael" ) - 1; break;
    2968                         case RTLOGGRPFLAGS_DMIK:        pszGroup = "dmik"    ;  cch = sizeof("dmik"    ) - 1; break;
    29693138                        case RTLOGGRPFLAGS_SUNLOVER:    pszGroup = "sunlover";  cch = sizeof("sunlover") - 1; break;
    29703139                        case RTLOGGRPFLAGS_ACHIM:       pszGroup = "Achim"   ;  cch = sizeof("Achim"   ) - 1; break;
     
    30243193                {
    30253194                    cb = pszNewLine - pachChars + 1;
    3026                     pLogger->fPendingPrefix = true;
     3195                    *pfPendingPrefix = true;
    30273196                }
    30283197            }
     
    30453214                cbChars--;
    30463215                cb++;
    3047                 pLogger->fPendingPrefix = true;
     3216                *pfPendingPrefix = true;
    30483217            }
    30493218
     
    31023271}
    31033272
     3273
     3274/**
     3275 * For calling rtlogLoggerExVLocked.
     3276 *
     3277 * @param   pLogger     The logger.
     3278 * @param   fFlags      The logging flags.
     3279 * @param   iGroup      The group.
     3280 *                      The value ~0U is reserved for compatibility with RTLogLogger[V] and is
     3281 *                      only for internal usage!
     3282 * @param   pszFormat   Format string.
     3283 * @param   ...         Format arguments.
     3284 */
     3285static void rtlogLoggerExFLocked(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...)
     3286{
     3287    va_list va;
     3288    va_start(va, pszFormat);
     3289    rtlogLoggerExVLocked(pLogger, fFlags, iGroup, pszFormat, va);
     3290    va_end(va);
     3291}
     3292
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