diff options
Diffstat (limited to 'tools/omfile.c')
-rw-r--r-- | tools/omfile.c | 281 |
1 files changed, 188 insertions, 93 deletions
diff --git a/tools/omfile.c b/tools/omfile.c index a4f010c6..a861ed0b 100644 --- a/tools/omfile.c +++ b/tools/omfile.c @@ -48,10 +48,13 @@ #include <libgen.h> #include <unistd.h> #include <sys/file.h> - #ifdef OS_SOLARIS # include <fcntl.h> #endif +#ifdef HAVE_ATOMIC_BUILTINS +# include <pthread.h> +#endif + #include "conf.h" #include "syslogd-types.h" @@ -67,6 +70,10 @@ #include "atomic.h" MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP + +/* forward definitions */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); /* internal structures */ @@ -74,12 +81,41 @@ DEF_OMOD_STATIC_DATA DEFobjCurrIf(errmsg) DEFobjCurrIf(strm) +/* for our current LRU mechanism, we need a monotonically increasing counters. We use + * it much like a "Lamport logical clock": we do not need the actual time, we just need + * to know the sequence in which files were accessed. So we use a simple counter to + * create that sequence. We use an unsigned 64 bit value which is extremely unlike to + * wrap within the lifetime of a process. If we process 1,000,000 file writes per + * second, the process could still exist over 500,000 years before a wrap to 0 happens. + * That should be sufficient (and even than, there would no really bad effect ;)). + * The variable below is the global counter/clock. + */ +#if HAVE_ATOMIC_BUILTINS_64BIT +static uint64 clockFileAccess = 0; +#else +static unsigned clockFileAccess = 0; +#endif +/* and the "tick" function */ +#ifndef HAVE_ATOMIC_BUILTINS +static pthread_mutex_t mutClock; +#endif +static inline uint64 +getClockFileAccess(void) +{ +#if HAVE_ATOMIC_BUILTINS_64BIT + return ATOMIC_INC_AND_FETCH_uint64(&clockFileAccess, &mutClock); +#else + return ATOMIC_INC_AND_FETCH_unsigned(&clockFileAccess, &mutClock); +#endif +} + + /* The following structure is a dynafile name cache entry. */ struct s_dynaFileCacheEntry { uchar *pName; /* name currently open, if dynamic name */ strm_t *pStrm; /* our output stream */ - time_t lastUsed; /* for LRU - last access */ + uint64 clkTickAccessed;/* for LRU - based on clockFileAccess */ }; typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; @@ -89,25 +125,7 @@ typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; #define USE_ASYNCWRITER_DFLT 0 /* default buffer use async writer */ #define FLUSHONTX_DFLT 1 /* default for flush on TX end */ -/* globals for default values */ -static int iDynaFileCacheSize = 10; /* max cache for dynamic files */ -static int fCreateMode = 0644; /* mode to use when creating files */ -static int fDirCreateMode = 0700; /* mode to use when creating files */ -static int bFailOnChown; /* fail if chown fails? */ -static uid_t fileUID; /* UID to be used for newly created files */ -static uid_t fileGID; /* GID to be used for newly created files */ -static uid_t dirUID; /* UID to be used for newly created directories */ -static uid_t dirGID; /* GID to be used for newly created directories */ -static int bCreateDirs = 1;/* auto-create directories for dynaFiles: 0 - no, 1 - yes */ -static int bEnableSync = 0;/* enable syncing of files (no dash in front of pathname in conf): 0 - no, 1 - yes */ -static int iZipLevel = 0; /* zip compression mode (0..9 as usual) */ -static bool bFlushOnTXEnd = FLUSHONTX_DFLT;/* flush write buffers when transaction has ended? */ -static int64 iIOBufSize = IOBUF_DFLT_SIZE; /* size of an io buffer */ -static int iFlushInterval = FLUSH_INTRVL_DFLT; /* how often flush the output buffer on inactivity? */ -static int bUseAsyncWriter = USE_ASYNCWRITER_DFLT; /* should we enable asynchronous writing? */ -uchar *pszFileDfltTplName = NULL; /* name of the default template to use */ -/* end globals for default values */ - +#define DFLT_bForceChown 0 typedef struct _instanceData { uchar f_fname[MAXFNAME];/* file or template name (display only) */ @@ -118,6 +136,7 @@ typedef struct _instanceData { int fDirCreateMode; /* creation mode for mkdir() */ int bCreateDirs; /* auto-create directories? */ int bSyncFile; /* should the file by sync()'ed? 1- yes, 0- no */ + sbool bForceChown; /* force chown() on existing files? */ uid_t fileUID; /* IDs for creation */ uid_t dirUID; gid_t fileGID; @@ -136,11 +155,40 @@ typedef struct _instanceData { int iZipLevel; /* zip mode to use for this selector */ int iIOBufSize; /* size of associated io buffer */ int iFlushInterval; /* how fast flush buffer on inactivity? */ - bool bFlushOnTXEnd; /* flush write buffers when transaction has ended? */ - bool bUseAsyncWriter; /* use async stream writer? */ + sbool bFlushOnTXEnd; /* flush write buffers when transaction has ended? */ + sbool bUseAsyncWriter; /* use async stream writer? */ } instanceData; +typedef struct configSettings_s { + int iDynaFileCacheSize; /* max cache for dynamic files */ + int fCreateMode; /* mode to use when creating files */ + int fDirCreateMode; /* mode to use when creating files */ + int bFailOnChown; /* fail if chown fails? */ + int bForceChown; /* Force chown() on existing files? */ + uid_t fileUID; /* UID to be used for newly created files */ + uid_t fileGID; /* GID to be used for newly created files */ + uid_t dirUID; /* UID to be used for newly created directories */ + uid_t dirGID; /* GID to be used for newly created directories */ + int bCreateDirs;/* auto-create directories for dynaFiles: 0 - no, 1 - yes */ + int bEnableSync;/* enable syncing of files (no dash in front of pathname in conf): 0 - no, 1 - yes */ + int iZipLevel; /* zip compression mode (0..9 as usual) */ + sbool bFlushOnTXEnd;/* flush write buffers when transaction has ended? */ + int64 iIOBufSize; /* size of an io buffer */ + int iFlushInterval; /* how often flush the output buffer on inactivity? */ + int bUseAsyncWriter; /* should we enable asynchronous writing? */ + EMPTY_STRUCT +} configSettings_t; +uchar *pszFileDfltTplName; /* name of the default template to use */ + +SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */ + +BEGINinitConfVars /* (re)set config variables to default values */ +CODESTARTinitConfVars + pszFileDfltTplName = NULL; /* make sure this can be free'ed! */ + iRet = resetConfigVariables(NULL, NULL); /* params are dummies */ +ENDinitConfVars + BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature if(eFeat == sFEATURERepeatedMsgReduction) @@ -163,8 +211,9 @@ CODESTARTdbgPrintInstInfo dbgprintf("\tflush interval=%d\n", pData->iFlushInterval); dbgprintf("\tfile cache size=%d\n", pData->iDynaFileCacheSize); dbgprintf("\tcreate directories: %s\n", pData->bCreateDirs ? "yes" : "no"); - dbgprintf("\tfile owner %d, group %d\n", pData->fileUID, pData->fileGID); - dbgprintf("\tdirectory owner %d, group %d\n", pData->dirUID, pData->dirGID); + dbgprintf("\tfile owner %d, group %d\n", (int) pData->fileUID, (int) pData->fileGID); + dbgprintf("\tforce chown() for all files: %s\n", pData->bForceChown ? "yes" : "no"); + dbgprintf("\tdirectory owner %d, group %d\n", (int) pData->dirUID, (int) pData->dirGID); dbgprintf("\tdir create mode 0%3.3o, file create mode 0%3.3o\n", pData->fDirCreateMode, pData->fCreateMode); dbgprintf("\tfail if owner/group can not be set: %s\n", pData->bFailOnChown ? "yes" : "no"); @@ -195,7 +244,7 @@ rsRetVal setDynaFileCacheSize(void __attribute__((unused)) *pVal, int iNewVal) iNewVal = 1000; } - iDynaFileCacheSize = iNewVal; + cs.iDynaFileCacheSize = iNewVal; DBGPRINTF("DynaFileCacheSize changed to %d.\n", iNewVal); RETiRet; @@ -351,7 +400,22 @@ prepareFile(instanceData *pData, uchar *newFileName) int fd; DEFiRet; - if(access((char*)newFileName, F_OK) != 0) { + if(access((char*)newFileName, F_OK) == 0) { + if(pData->bForceChown) { + /* Try to fix wrong ownership set by someone else. Note that this code + * will no longer work once we have made the $PrivDrop code fully secure. + * This change is based on an idea of Michael Terry, provided as part of + * the effort to make rsyslogd the Ubuntu default syslogd. + * rgerhards, 2009-09-11 + */ + if(chown((char*)newFileName, pData->fileUID, pData->fileGID) != 0) { + if(pData->bFailOnChown) { + int eSave = errno; + errno = eSave; + } + } + } + } else { /* file does not exist, create it (and eventually parent directories */ if(pData->bCreateDirs) { /* We first need to create parent dirs if they are missing. @@ -371,7 +435,7 @@ prepareFile(instanceData *pData, uchar *newFileName) pData->fCreateMode); if(fd != -1) { /* check and set uid/gid */ - if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) { + if(pData->bForceChown || pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) { /* we need to set owner/group */ if(fchown(fd, pData->fileUID, pData->fileGID) != 0) { if(pData->bFailOnChown) { @@ -406,7 +470,7 @@ prepareFile(instanceData *pData, uchar *newFileName) CHKiRet(strm.SetiZipLevel(pData->pStrm, pData->iZipLevel)); CHKiRet(strm.SetsIOBufSize(pData->pStrm, (size_t) pData->iIOBufSize)); CHKiRet(strm.SettOperationsMode(pData->pStrm, STREAMMODE_WRITE_APPEND)); - CHKiRet(strm.SettOpenMode(pData->pStrm, fCreateMode)); + CHKiRet(strm.SettOpenMode(pData->pStrm, cs.fCreateMode)); CHKiRet(strm.SetbSync(pData->pStrm, pData->bSyncFile)); CHKiRet(strm.SetsType(pData->pStrm, pData->strmType)); CHKiRet(strm.SetiSizeLimit(pData->pStrm, pData->iSizeLimit)); @@ -436,7 +500,7 @@ finalize_it: static inline rsRetVal prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) { - time_t ttOldest; /* timestamp of oldest element */ + uint64 ctOldest; /* "timestamp" of oldest element */ int iOldest; int i; int iFirstFree; @@ -455,7 +519,7 @@ prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) if( (pData->iCurrElt != -1) && !ustrcmp(newFileName, pCache[pData->iCurrElt]->pName)) { /* great, we are all set */ - pCache[pData->iCurrElt]->lastUsed = time(NULL); /* update timestamp for LRU */ // TODO: optimize time call! + pCache[pData->iCurrElt]->clkTickAccessed = getClockFileAccess(); // LRU needs only a strictly monotonically increasing counter, so such a one could do FINALIZE; } @@ -466,7 +530,7 @@ prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) pData->iCurrElt = -1; /* invalid current element pointer */ iFirstFree = -1; /* not yet found */ iOldest = 0; /* we assume the first element to be the oldest - that will change as we loop */ - ttOldest = time(NULL) + 1; /* there must always be an older one */ + ctOldest = getClockFileAccess(); /* there must always be an older one */ for(i = 0 ; i < pData->iCurrCacheSize ; ++i) { if(pCache[i] == NULL || pCache[i]->pName == NULL) { if(iFirstFree == -1) @@ -476,12 +540,12 @@ prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) /* we found our element! */ pData->pStrm = pCache[i]->pStrm; pData->iCurrElt = i; - pCache[i]->lastUsed = time(NULL); /* update timestamp for LRU */ + pCache[i]->clkTickAccessed = getClockFileAccess(); /* update "timestamp" for LRU */ FINALIZE; } /* did not find it - so lets keep track of the counters for LRU */ - if(pCache[i]->lastUsed < ttOldest) { - ttOldest = pCache[i]->lastUsed; + if(pCache[i]->clkTickAccessed < ctOldest) { + ctOldest = pCache[i]->clkTickAccessed; iOldest = i; } } @@ -507,7 +571,6 @@ prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) iFirstFree = pData->iCurrCacheSize++; } -// RG: this is the begin of a potential problem area /* Note that the following code sequence does not work with the cache entry itself, * but rather with pData->pStrm, the (sole) stream pointer in the non-dynafile case. * The cache array is only updated after the open was successful. -- rgerhards, 2010-03-21 @@ -545,7 +608,7 @@ prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsgOpts) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pCache[iFirstFree]->pStrm = pData->pStrm; - pCache[iFirstFree]->lastUsed = time(NULL); + pCache[iFirstFree]->clkTickAccessed = getClockFileAccess(); pData->iCurrElt = iFirstFree; DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName); @@ -566,7 +629,7 @@ doWrite(instanceData *pData, uchar *pszBuf, int lenBuf) ASSERT(pData != NULL); ASSERT(pszBuf != NULL); -dbgprintf("doWrite, pData->pStrm %p, lenBuf %d\n", pData->pStrm, lenBuf); +dbgprintf("write to stream, pData->pStrm %p, lenBuf %d\n", pData->pStrm, lenBuf); if(pData->pStrm != NULL){ CHKiRet(strm.Write(pData->pStrm, pszBuf, lenBuf)); FINALIZE; @@ -632,15 +695,31 @@ BEGINtryResume CODESTARTtryResume ENDtryResume +BEGINbeginTransaction +CODESTARTbeginTransaction + /* we have nothing to do to begin a transaction */ +ENDbeginTransaction + + +BEGINendTransaction +CODESTARTendTransaction + if(pData->bFlushOnTXEnd) { + CHKiRet(strm.Flush(pData->pStrm)); + } +finalize_it: +ENDendTransaction + + BEGINdoAction CODESTARTdoAction DBGPRINTF("file to log to: %s\n", pData->f_fname); CHKiRet(writeFile(ppString, iMsgOpts, pData)); - if(pData->bFlushOnTXEnd) { - /* TODO v5: do this in endTransaction only! */ + if(!bCoreSupportsBatching && pData->bFlushOnTXEnd) { CHKiRet(strm.Flush(pData->pStrm)); } finalize_it: + if(iRet == RS_RET_OK) + iRet = RS_RET_DEFER_COMMIT; ENDdoAction @@ -653,7 +732,14 @@ CODESTARTparseSelectorAct */ if(!strncmp((char*) p, ":omfile:", sizeof(":omfile:") - 1)) { p += sizeof(":omfile:") - 1; - } + } else { + if(*p == '$') { + errmsg.LogError(0, RS_RET_OUTDATED_STMT, + "action '%s' treated as ':omfile:%s' - please " + "change syntax, '%s' will not be supported in " + "rsyslog v6 and above.", p, p, p); + } + } if(!(*p == '$' || *p == '?' || *p == '/' || *p == '.' || *p == '-')) ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); @@ -663,7 +749,7 @@ CODESTARTparseSelectorAct pData->bSyncFile = 0; p++; } else { - pData->bSyncFile = bEnableSync; + pData->bSyncFile = cs.bEnableSync; } pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ @@ -697,7 +783,7 @@ CODESTARTparseSelectorAct pData->iCurrElt = -1; /* no current element */ /* we now allocate the cache table */ CHKmalloc(pData->dynCache = (dynaFileCacheEntry**) - calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); + calloc(cs.iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); break; /* case '|': while pipe support has been removed, I leave the code in in case we @@ -726,20 +812,21 @@ CODESTARTparseSelectorAct } /* freeze current paremeters for this action */ - pData->iDynaFileCacheSize = iDynaFileCacheSize; - pData->fCreateMode = fCreateMode; - pData->fDirCreateMode = fDirCreateMode; - pData->bCreateDirs = bCreateDirs; - pData->bFailOnChown = bFailOnChown; - pData->fileUID = fileUID; - pData->fileGID = fileGID; - pData->dirUID = dirUID; - pData->dirGID = dirGID; - pData->iZipLevel = iZipLevel; - pData->bFlushOnTXEnd = bFlushOnTXEnd; - pData->iIOBufSize = (int) iIOBufSize; - pData->iFlushInterval = iFlushInterval; - pData->bUseAsyncWriter = bUseAsyncWriter; + pData->iDynaFileCacheSize = cs.iDynaFileCacheSize; + pData->fCreateMode = cs.fCreateMode; + pData->fDirCreateMode = cs.fDirCreateMode; + pData->bCreateDirs = cs.bCreateDirs; + pData->bFailOnChown = cs.bFailOnChown; + pData->bForceChown = cs.bForceChown; + pData->fileUID = cs.fileUID; + pData->fileGID = cs.fileGID; + pData->dirUID = cs.dirUID; + pData->dirGID = cs.dirGID; + pData->iZipLevel = cs.iZipLevel; + pData->bFlushOnTXEnd = cs.bFlushOnTXEnd; + pData->iIOBufSize = (int) cs.iIOBufSize; + pData->iFlushInterval = cs.iFlushInterval; + pData->bUseAsyncWriter = cs.bUseAsyncWriter; if(pData->bDynamicName == 0) { /* try open and emit error message if not possible. At this stage, we ignore the @@ -761,25 +848,24 @@ ENDparseSelectorAct */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - fileUID = -1; - fileGID = -1; - dirUID = -1; - dirGID = -1; - bFailOnChown = 1; - iDynaFileCacheSize = 10; - fCreateMode = 0644; - fDirCreateMode = 0700; - bCreateDirs = 1; - bEnableSync = 0; - iZipLevel = 0; - bFlushOnTXEnd = FLUSHONTX_DFLT; - iIOBufSize = IOBUF_DFLT_SIZE; - iFlushInterval = FLUSH_INTRVL_DFLT; - bUseAsyncWriter = USE_ASYNCWRITER_DFLT; - if(pszFileDfltTplName != NULL) { - free(pszFileDfltTplName); - pszFileDfltTplName = NULL; - } + cs.fileUID = -1; + cs.fileGID = -1; + cs.dirUID = -1; + cs.dirGID = -1; + cs.bFailOnChown = 1; + cs.bForceChown = DFLT_bForceChown; + cs.iDynaFileCacheSize = 10; + cs.fCreateMode = 0644; + cs.fDirCreateMode = 0700; + cs.bCreateDirs = 1; + cs.bEnableSync = 0; + cs.iZipLevel = 0; + cs.bFlushOnTXEnd = FLUSHONTX_DFLT; + cs.iIOBufSize = IOBUF_DFLT_SIZE; + cs.iFlushInterval = FLUSH_INTRVL_DFLT; + cs.bUseAsyncWriter = USE_ASYNCWRITER_DFLT; + free(pszFileDfltTplName); + pszFileDfltTplName = NULL; return RS_RET_OK; } @@ -803,12 +889,14 @@ CODESTARTmodExit objRelease(errmsg, CORE_COMPONENT); objRelease(strm, CORE_COMPONENT); free(pszFileDfltTplName); + DESTROY_ATOMIC_HELPER_MUT(mutClock); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_TXIF_OMOD_QUERIES /* we support the transactional interface! */ CODEqueryEtryPt_doHUP ENDqueryEtryPt @@ -817,25 +905,32 @@ BEGINmodInit(File) CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr +SCOPINGmodInit CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(strm, CORE_COMPONENT)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"dynafilecachesize", 0, eCmdHdlrInt, (void*) setDynaFileCacheSize, NULL, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileziplevel", 0, eCmdHdlrInt, NULL, &iZipLevel, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushinterval", 0, eCmdHdlrInt, NULL, &iFlushInterval, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileasyncwriting", 0, eCmdHdlrBinary, NULL, &bUseAsyncWriter, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushontxend", 0, eCmdHdlrBinary, NULL, &bFlushOnTXEnd, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileiobuffersize", 0, eCmdHdlrSize, NULL, &iIOBufSize, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirowner", 0, eCmdHdlrUID, NULL, &dirUID, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroup", 0, eCmdHdlrGID, NULL, &dirGID, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileowner", 0, eCmdHdlrUID, NULL, &fileUID, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroup", 0, eCmdHdlrGID, NULL, &fileGID, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"dircreatemode", 0, eCmdHdlrFileCreateMode, NULL, &fDirCreateMode, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &fCreateMode, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &bCreateDirs, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &bFailOnChown, STD_LOADABLE_MODULE_ID)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &bEnableSync, STD_LOADABLE_MODULE_ID)); - CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszFileDfltTplName, NULL)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); + + INIT_ATOMIC_HELPER_MUT(mutClock); + + INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); + DBGPRINTF("omfile: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dynafilecachesize", 0, eCmdHdlrInt, (void*) setDynaFileCacheSize, NULL, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileziplevel", 0, eCmdHdlrInt, NULL, &cs.iZipLevel, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushinterval", 0, eCmdHdlrInt, NULL, &cs.iFlushInterval, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileasyncwriting", 0, eCmdHdlrBinary, NULL, &cs.bUseAsyncWriter, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushontxend", 0, eCmdHdlrBinary, NULL, &cs.bFlushOnTXEnd, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileiobuffersize", 0, eCmdHdlrSize, NULL, &cs.iIOBufSize, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirowner", 0, eCmdHdlrUID, NULL, &cs.dirUID, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroup", 0, eCmdHdlrGID, NULL, &cs.dirGID, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileowner", 0, eCmdHdlrUID, NULL, &cs.fileUID, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroup", 0, eCmdHdlrGID, NULL, &cs.fileGID, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dircreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fDirCreateMode, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fCreateMode, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &cs.bCreateDirs, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileForceChown", 0, eCmdHdlrBinary, NULL, &cs.bForceChown, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, STD_LOADABLE_MODULE_ID, eConfObjAction)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszFileDfltTplName, NULL, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjAction)); ENDmodInit /* vi:set ai: */ |