/
githubmirror
/
rsyslog
Обзор
Документация
Войти
/
githubmirror
/
rsyslog
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
runtime/queue.h
329 строк
16 KB
Rainer Gerhards
queue: clarify DA transfer worker role
19 июл 2026, 12:40
19 июл 2026, 12:40
60361d4
Код
Авторство
О чём код?
/* Definition of the queue support module. * * Copyright 2008-2026 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>. * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ /** * @file queue.h * @brief Public interface and data structures for the rsyslog queue subsystem. * * This header defines the primary functions and data structures needed to * interact with rsyslog queues (in-memory, disk, and disk-assisted). It serves * as the main entry point for developers looking to understand how to use and * interact with the queueing mechanism. * * For a detailed discussion of the architectural principles, especially * concerning disk queues, their "Limited Duplication" guarantee, and a * comparison to Write-Ahead Logs (WALs), please see the extensive header * comment in queue.c. * * @see queue.c */ #ifndef QUEUE_H_INCLUDED #define QUEUE_H_INCLUDED #include <pthread.h> #include "obj.h" #include "wtp.h" #include "batch.h" #include "stream.h" #include "statsobj.h" #include "cryprov.h" #include "queue_da.h" #include "segdisk_store.h" /* support for the toDelete list */ typedef struct toDeleteLst_s toDeleteLst_t; struct toDeleteLst_s { qDeqID deqID; int nElemDeq; /* numbe of elements that were dequeued and as such must now be discarded */ struct toDeleteLst_s *pNext; }; /* queue types */ typedef enum { QUEUETYPE_FIXED_ARRAY = 0, /* a simple queue made out of a fixed (initially malloced) array fast but memoryhog */ QUEUETYPE_LINKEDLIST = 1, /* linked list used as buffer, lower fixed memory overhead but slower */ QUEUETYPE_DISK = 2, /* disk files used as buffer */ QUEUETYPE_DIRECT = 3, /* no queuing happens, consumer is directly called */ QUEUETYPE_SEGMENTED_DISK = 4 /* log-structured segmented disk queue */ } queueType_t; /* queue recovery modes */ typedef enum { QUEUE_ON_CORRUPTION_SAFE_MODE = 0, QUEUE_ON_CORRUPTION_IN_MEMORY = 1, QUEUE_ON_CORRUPTION_IGNORE = 2 } queueOnCorruption_t; /* list member definition for linked list types of queues: */ typedef struct qLinkedList_S { struct qLinkedList_S *pNext; smsg_t *pMsg; } qLinkedList_t; /** * @brief The "queue object for the queueing subsystem". * * This structure holds the runtime state for a queue instance, especially a * disk-based one. It contains the core pointers that define the Bounded Queue. * * Note on naming: This is named `qqueue` due to historical symbol clashes with * system libraries on some platforms (e.g., AIX). See queue.c for details. */ struct queue_s { BEGINobjInstance ; queueType_t qType; int nLogDeq; /* number of elements currently logically dequeued */ int bShutdownImmediate; /* should all workers cease processing messages? */ DEF_ATOMIC_HELPER_MUT(mutShutdownImmediate); sbool bEnqOnly; /* does queue run in enqueue-only mode (1) or not (0)? */ sbool bSaveOnShutdown; /* persists everthing on shutdown (if DA!)? 1-yes, 0-no */ sbool bQueueStarted; /* has queueStart() been called on this queue? 1-yes, 0-no */ sbool takeFlowCtlFromMsg; /* override enq flow ctl by message property? */ int iQueueSize; /* Current number of elements in the queue */ int iMaxQueueSize; /* how large can the queue grow? */ int iNumWorkerThreads; /* number of worker threads to use */ int iCurNumWrkThrd; /* current number of active worker threads */ int iMinMsgsPerWrkr; /* minimum nbr of msgs per worker thread, if more, a new worker is started until max wrkrs */ wtp_t *pWtpDA; /* single-worker DA transfer pool, not the DA disk queue child consumer pool */ wtp_t *pWtpReg; action_t *pAction; /* for action queues, ptr to action object; for main queues unused */ int iUpdsSincePersist; /* nbr of queue updates since the last persist call */ int iPersistUpdCnt; /* persits queue info after this nbr of updates - 0 -> persist only on shutdown */ sbool bSyncQueueFiles; /* if working with files, sync them after each write? */ int iHighWtrMrk; /* high water mark for disk-assisted memory queues */ int iLowWtrMrk; /* low water mark for disk-assisted memory queues */ int iDiscardMrk; /* if the queue is above this mark, low-severity messages are discarded */ int iFullDlyMrk; /* if the queue is above this mark, FULL_DELAYable message are put on hold */ int iLightDlyMrk; /* if the queue is above this mark, LIGHT_DELAYable message are put on hold */ int iDiscardSeverity; /* messages of this severity above are discarded on too-full queue */ sbool bNeedDelQIF; /* does the QIF file need to be deleted when queue becomes empty? */ queueOnCorruption_t onCorruption; /* what to do on queue corruption */ int toQShutdown; /* timeout for regular queue shutdown in ms */ int toActShutdown; /* timeout for long-running action shutdown in ms */ int toWrkShutdown; /* timeout for idle workers in ms, -1 means indefinite (0 is immediate) */ toDeleteLst_t *toDeleteLst; /* this queue's to-delete list */ int toEnq; /* enqueue timeout */ int iDeqBatchSize; /* max number of elements that shall be dequeued at once */ int iMinDeqBatchSize; /* min number of elements that shall be dequeued at once */ int toMinDeqBatchSize; /* timeout for MinDeqBatchSize, in ms */ /* rate limiting settings (will be expanded) */ int iDeqSlowdown; /* slow down dequeue by specified nbr of microseconds */ /* end rate limiting */ /* dequeue time window settings (may also be expanded) */ int iDeqtWinFromHr; /* begin of dequeue time window (hour only) */ int iDeqtWinToHr; /* end of dequeue time window (hour only), set to 25 to disable deq window! */ /* note that begin and end have specific semantics. It is a big difference if we have * begin 4, end 22 or begin 22, end 4. In the later case, dequeuing will run from 10p, * throughout the night and stop at 4 in the morning. In the first case, it will start * at 4am, run throughout the day, and stop at 10 in the evening! So far, not logic is * applied to detect user configuration errors (and tell me how should we detect what * the user really wanted...). -- rgerhards, 2008-04-02 */ /* end dequeue time window */ rsRetVal (*pConsumer)(void *, batch_t *, wti_t *); /* user-supplied consumer function for dequeued messages */ /* calling interface for pConsumer: arg1 is the global user pointer from this structure, arg2 is the * user pointer array that was dequeued (actual sample: for actions, arg1 is the pAction and arg2 * is pointer to an array of message message pointers) */ /* type-specific handlers (set during construction) */ rsRetVal (*qConstruct)(struct queue_s *pThis); rsRetVal (*qDestruct)(struct queue_s *pThis); rsRetVal (*qAdd)(struct queue_s *pThis, smsg_t *pMsg); rsRetVal (*qDeq)(struct queue_s *pThis, smsg_t **ppMsg); rsRetVal (*qDel)(struct queue_s *pThis); rsRetVal (*qDeqBatch)(struct queue_s *pThis, batch_t *batch, int max, int *skipped); rsRetVal (*qCompleteBatch)(struct queue_s *pThis, batch_t *batch, int *committed, int *retried); /* end type-specific handler */ /* public entry points (set during construction, permit to set best algorithm for params selected) */ rsRetVal (*MultiEnq)(qqueue_t *pThis, multi_submit_t *pMultiSub); /* end public entry points */ /* synchronization variables */ pthread_mutex_t mutThrdMgmt; /* mutex for the queue's thread management */ pthread_mutex_t *mut; /* mutex for enqueing and dequeueing messages */ pthread_cond_t notFull; pthread_cond_t belowFullDlyWtrMrk; /* below eFLOWCTL_FULL_DELAY watermark */ pthread_cond_t belowLightDlyWtrMrk; /* below eFLOWCTL_FULL_DELAY watermark */ int bThrdStateChanged; /* at least one thread state has changed if 1 */ /* end sync variables */ /* the following variables are always present, because they * are not only used for the "disk" queueing mode but also for * any other queueing mode if it is set to "disk assisted". * rgerhards, 2008-01-09 */ uchar *pszSpoolDir; size_t lenSpoolDir; uchar *pszFilePrefix; size_t lenFilePrefix; uchar *pszQIFNam; /* full .qi file name, based on parts above */ size_t lenQIFNam; int iNumberFiles; /* how many files make up the queue? */ int64 iMaxFileSize; /* max size for a single queue file */ int64 sizeOnDiskMax; /* maximum size on disk allowed */ qDeqID deqIDAdd; /* next dequeue ID to use during add to queue store */ qDeqID deqIDDel; /* queue store delete position */ int bIsDA; /* is this queue disk assisted? */ qda_engine_mode_t diskQueueType; /* configured DA disk child selection */ qda_engine_mode_t effectiveDiskQueueType; /* selected DA disk child engine */ sbool diskQueueAutoUpgrade; /* move a drained auto-selected classic child to segmented */ int diskQueueIdleTimeout; /* segmented DA child idle dematerialization timeout */ sbool diskQueueTypeSet; sbool diskQueueAutoUpgradeSet; sbool diskQueueIdleTimeoutSet; sbool segdiskLazyCreate; /* create a fresh segmented store on first append */ sbool segdiskDAChild; /* segmented child of an in-memory DA parent */ sbool daEngineMarkerPending; /* publish the selected DA engine before first append */ uint64_t daActivityGeneration; /* parent enqueue generation for the idle grace period */ uint64_t segdiskIdleObservedActivity; struct queue_s *pqDA; /* queue for disk-assisted modes */ struct queue_s *pqParent; /* pointer to the parent (if this is a child queue) */ int bDAEnqOnly; /* EnqOnly setting for DA queue */ /* now follow queueing mode specific data elements */ // union { /* different data elements based on queue type (qType) */ struct { /* different data elements based on queue type (qType) */ struct { long deqhead, head, tail; void **pBuf; /* the queued user data structure */ } farray; struct { qLinkedList_t *pDeqRoot; qLinkedList_t *pDelRoot; qLinkedList_t *pLast; } linklist; struct { int64 sizeOnDisk; /* current amount of disk space used */ int64 deqOffs; /* offset after dequeue batch - used for file deleter */ int deqFileNumIn; /* same for the circular file numbers, mainly for */ int deqFileNumOut; /* deleting finished files */ strm_t *pWrite; /* current file to be written */ strm_t *pReadDeq; /* current file for dequeueing */ strm_t *pReadDel; /* current file for deleting */ int nForcePersist; /* force persist of .qi file the next "n" times */ int pendingCorruptRet; /* deferred dequeue-time corruption result to recover on next batch */ sbool runtimeCorruptionSkip; /* skipped messages in current batch due to runtime corruption */ } disk; segdisk_store_t *segdisk; } tVars; sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ uchar *cryprovName; /* crypto provider to use */ cryprov_if_t cryprov; /* ptr to crypto provider interface */ void *cryprovData; /* opaque data ptr for provider use */ uchar *cryprovNameFull; /* full internal crypto provider name */ DEF_ATOMIC_HELPER_MUT(mutQueueSize); DEF_ATOMIC_HELPER_MUT(mutLogDeq); /* for statistics subsystem */ statsobj_t *statsobj; STATSCOUNTER_DEF(ctrEnqueued, mutCtrEnqueued) STATSCOUNTER_DEF(ctrSizeEnqueued, mutCtrSizeEnqueued) /* cumulative bytes enqueued */ STATSCOUNTER_DEF(ctrFull, mutCtrFull) STATSCOUNTER_DEF(ctrFDscrd, mutCtrFDscrd) STATSCOUNTER_DEF(ctrNFDscrd, mutCtrNFDscrd) int ctrMaxqsize; /* NOT guarded by a mutex */ int segdiskBytes; int segdiskSegments; int segdiskCheckpoints; int segdiskReplayed; int segdiskCorruptionEvents; int segdiskCorruptionBytes; int segdiskCorruptionRecords; int segdiskRetryOverageBytes; int segdiskRetryOverageMaxBytes; int segdiskStateWrites; int segdiskForcedStateWrites; int segdiskRecoveryPending; int segdiskRecoveryBytes; int segdiskRecoveryRecords; int segdiskStartupPayloadBytes; int segdiskStartupSegmentFilesProbed; int segdiskCorruptionSegments; int segdiskMaterializations; int segdiskDematerializations; int segdiskIdleCleanupFailures; int iSmpInterval; /* line interval of sampling logs */ int isRunning; }; /* the define below is an "eternal" timeout for the timeout settings which require a value. * It is one day, which is not really eternal, but comes close to it if we think about * rsyslog (e.g.: do you want to wait on shutdown for more than a day? ;)) * rgerhards, 2008-01-17 */ #define QUEUE_TIMEOUT_ETERNAL 24 * 60 * 60 * 1000 /* prototypes */ rsRetVal qqueueDestruct(qqueue_t **ppThis); rsRetVal qqueueEnqMsg(qqueue_t *pThis, flowControl_t flwCtlType, smsg_t *pMsg); rsRetVal qqueueStart(rsconf_t *cnf, qqueue_t *pThis); rsRetVal qqueueSetMaxFileSize(qqueue_t *pThis, size_t iMaxFileSize); rsRetVal qqueueSetFilePrefix(qqueue_t *pThis, uchar *pszPrefix, size_t iLenPrefix); rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThreads, int iMaxQueueSize, rsRetVal (*pConsumer)(void *, batch_t *, wti_t *)); int queueCnfParamsSet(struct nvlst *lst); rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst); void qqueueSetDefaultsRulesetQueue(qqueue_t *pThis); void qqueueSetDefaultsActionQueue(qqueue_t *pThis); void qqueueDbgPrint(qqueue_t *pThis); rsRetVal qqueueShutdownWorkers(qqueue_t *pThis); void qqueueDoneLoadCnf(void); int queuesEqual(qqueue_t *pOld, qqueue_t *pNew); void qqueueCorrectParams(qqueue_t *pThis); PROTOTYPEObjClassInit(qqueue); PROTOTYPEpropSetMeth(qqueue, iPersistUpdCnt, int); PROTOTYPEpropSetMeth(qqueue, bSyncQueueFiles, int); PROTOTYPEpropSetMeth(qqueue, iDeqtWinFromHr, int); PROTOTYPEpropSetMeth(qqueue, iDeqtWinToHr, int); PROTOTYPEpropSetMeth(qqueue, toQShutdown, long); PROTOTYPEpropSetMeth(qqueue, toActShutdown, long); PROTOTYPEpropSetMeth(qqueue, toWrkShutdown, long); PROTOTYPEpropSetMeth(qqueue, toEnq, long); PROTOTYPEpropSetMeth(qqueue, iLightDlyMrk, int); PROTOTYPEpropSetMeth(qqueue, iHighWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iLowWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iDiscardMrk, int); PROTOTYPEpropSetMeth(qqueue, iDiscardSeverity, int); PROTOTYPEpropSetMeth(qqueue, iMinMsgsPerWrkr, int); PROTOTYPEpropSetMeth(qqueue, iNumWorkerThreads, int); PROTOTYPEpropSetMeth(qqueue, bSaveOnShutdown, int); PROTOTYPEpropSetMeth(qqueue, pAction, action_t *); PROTOTYPEpropSetMeth(qqueue, iDeqSlowdown, int); PROTOTYPEpropSetMeth(qqueue, sizeOnDiskMax, int64); PROTOTYPEpropSetMeth(qqueue, iDeqBatchSize, int); PROTOTYPEpropSetMeth(qqueue, iMinDeqBatchSize, int); PROTOTYPEpropSetMeth(qqueue, iSmpInterval, int); #define qqueueGetID(pThis) ((unsigned long)pThis) #ifdef ENABLE_IMDIAG extern unsigned int iOverallQueueSize; rsRetVal qqueueSetSegDiskTestFault(qqueue_t *pThis, const char *point, unsigned int hit_count); rsRetVal qqueueClearSegDiskTestFault(qqueue_t *pThis); #endif #endif /* #ifndef QUEUE_H_INCLUDED */