summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--action.c41
-rw-r--r--grammar/rainerscript.c79
-rw-r--r--runtime/modules.h2
-rw-r--r--runtime/queue.c124
-rw-r--r--runtime/rsconf.c9
5 files changed, 152 insertions, 103 deletions
diff --git a/action.c b/action.c
index 6997f46d..8a3d8920 100644
--- a/action.c
+++ b/action.c
@@ -289,6 +289,11 @@ rsRetVal actionDestruct(action_t *pThis)
DEFiRet;
ASSERT(pThis != NULL);
+ if(!strcmp((char*)modGetName(pThis->pMod), "builtin:omdiscard")) {
+ /* discard actions will be optimized out */
+ FINALIZE;
+ }
+
if(pThis->pQueue != NULL) {
qqueueDestruct(&pThis->pQueue);
}
@@ -310,8 +315,8 @@ rsRetVal actionDestruct(action_t *pThis)
d_free(pThis->pszName);
d_free(pThis->ppTpl);
+finalize_it:
d_free(pThis);
-
RETiRet;
}
@@ -362,6 +367,10 @@ actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams)
ASSERT(pThis != NULL);
+ if(!strcmp((char*)modGetName(pThis->pMod), "builtin:omdiscard")) {
+ /* discard actions will be optimized out */
+ FINALIZE;
+ }
/* generate a friendly name for us action stats */
if(pThis->pszName == NULL) {
snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "action %d", iActionNbr);
@@ -1607,7 +1616,8 @@ DEFFUNC_llExecFunc(doActivateActions)
}
actionDisable(pThis);
}
- DBGPRINTF("Action %p: queue %p started\n", pThis, pThis->pQueue);
+ DBGPRINTF("Action %s[%p]: queue %p started\n", modGetName(pThis->pMod),
+ pThis, pThis->pQueue);
ENDfunc
return RS_RET_OK; /* we ignore errors, we can not do anything either way */
}
@@ -2086,33 +2096,6 @@ finalize_it:
RETiRet;
}
-
-/* Process a rsyslog v6 action config object (the now-primary config method).
- * rgerhards, 2011-07-19
- */
-rsRetVal
-actionProcessCnf(struct cnfobj *o)
-{
- DEFiRet;
-#if 0 /* we need to check if we actually need this functionality -- later! */
-// This is for STAND-ALONE actions at the conf file TOP level
- struct cnfparamvals *paramvals;
-
- paramvals = nvlstGetParams(o->nvlst, &pblk, NULL);
- if(paramvals == NULL) {
- iRet = RS_RET_ERR;
- goto finalize_it;
- }
- DBGPRINTF("action param blk after actionProcessCnf:\n");
- cnfparamsPrint(&pblk, paramvals);
-
- /* now find module to activate */
-finalize_it:
-#endif
- RETiRet;
-}
-
-
/* TODO: we are not yet a real object, the ClassInit here just looks like it is..
*/
rsRetVal actionClassInit(void)
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 199aaa97..90bbb335 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -45,11 +45,13 @@
#include "srUtils.h"
#include "regexp.h"
#include "obj.h"
+#include "modules.h"
DEFobjCurrIf(obj)
DEFobjCurrIf(regexp)
void cnfexprOptimize(struct cnfexpr *expr);
+static void cnfstmtOptimizePRIFilt(struct cnfstmt *stmt);
char*
getFIOPName(unsigned iFIOP)
@@ -1628,7 +1630,7 @@ cnfstmtPrint(struct cnfstmt *root, int indent)
doIndent(indent); dbgprintf("STOP\n");
break;
case S_ACT:
- doIndent(indent); dbgprintf("ACTION %p (%s)\n", stmt->d.act, stmt->printable);
+ doIndent(indent); dbgprintf("ACTION %p [%s]\n", stmt->d.act, stmt->printable);
break;
case S_IF:
doIndent(indent); dbgprintf("IF\n");
@@ -1845,6 +1847,7 @@ struct cnfstmt *
cnfstmtNewAct(struct nvlst *lst)
{
struct cnfstmt* cnfstmt;
+ char namebuf[256];
if((cnfstmt = cnfstmtNew(S_ACT)) == NULL)
goto done;
if(actionNewInst(lst, &cnfstmt->d.act) != RS_RET_OK) {
@@ -1854,7 +1857,10 @@ cnfstmtNewAct(struct nvlst *lst)
cnfstmt->nodetype = S_NOP; /* disable action! */
goto done;
}
- cnfstmt->printable = (uchar*)strdup("action()");
+ snprintf(namebuf, sizeof(namebuf)-1, "action(type=\"%s\" ...)",
+ modGetName(cnfstmt->d.act->pMod));
+ namebuf[255] = '\0'; /* be on safe side */
+ cnfstmt->printable = (uchar*)strdup(namebuf);
done: return cnfstmt;
}
@@ -2071,7 +2077,7 @@ cnfstmtOptimizeIf(struct cnfstmt *stmt)
if(stmt->d.s_if.expr->nodetype == 'F') {
func = (struct cnffunc*)expr;
if(func->fID == CNFFUNC_PRIFILT) {
- DBGPRINTF("optimize IF to PRIFILT\n");
+ DBGPRINTF("optimizer: change IF to PRIFILT\n");
t_then = stmt->d.s_if.t_then;
t_else = stmt->d.s_if.t_else;
stmt->nodetype = S_PRIFILT;
@@ -2083,10 +2089,66 @@ cnfstmtOptimizeIf(struct cnfstmt *stmt)
stmt->printable = (uchar*)
es_str2cstr(((struct cnfstringval*)func->expr[0])->estr, NULL);
cnfexprDestruct(expr);
+ cnfstmtOptimizePRIFilt(stmt);
}
}
}
+static inline void
+cnfstmtOptimizeAct(struct cnfstmt *stmt)
+{
+ action_t *pAct;
+
+ pAct = stmt->d.act;
+ if(!strcmp((char*)modGetName(stmt->d.act->pMod), "builtin:omdiscard")) {
+ DBGPRINTF("optimizer: replacing omdiscard by STOP\n");
+ actionDestruct(stmt->d.act);
+ stmt->nodetype = S_STOP;
+ }
+}
+
+static void
+cnfstmtOptimizePRIFilt(struct cnfstmt *stmt)
+{
+ int i;
+ int isAlways = 1;
+ struct cnfstmt *subroot, *last;
+
+ stmt->d.s_prifilt.t_then = removeNOPs(stmt->d.s_prifilt.t_then);
+ cnfstmtOptimize(stmt->d.s_prifilt.t_then);
+
+ for(i = 0; i <= LOG_NFACILITIES; i++)
+ if(stmt->d.s_prifilt.pmask[i] != 0xff) {
+ isAlways = 0;
+ break;
+ }
+ if(!isAlways)
+ goto done;
+
+ DBGPRINTF("optimizer: removing always-true PRIFILT %p\n", stmt);
+ if(stmt->d.s_prifilt.t_else != NULL) {
+ parser_errmsg("error: always-true PRI filter has else part!\n");
+ cnfstmtDestruct(stmt->d.s_prifilt.t_else);
+ }
+ free(stmt->printable);
+ stmt->printable = NULL;
+ subroot = stmt->d.s_prifilt.t_then;
+ if(subroot == NULL) {
+ /* very strange, we set it to NOP, best we can do
+ * This case is NOT expected in practice
+ */
+ stmt->nodetype = S_NOP;
+ goto done;
+ }
+ for(last = subroot ; last->next != NULL ; last = last->next)
+ /* find last node in subtree */;
+ last->next = stmt->next;
+ memcpy(stmt, subroot, sizeof(struct cnfstmt));
+ free(subroot);
+
+done: return;
+}
+
/* (recursively) optimize a statement */
void
cnfstmtOptimize(struct cnfstmt *root)
@@ -2100,8 +2162,7 @@ dbgprintf("RRRR: stmtOptimize: stmt %p, nodetype %u\n", stmt, stmt->nodetype);
cnfstmtOptimizeIf(stmt);
break;
case S_PRIFILT:
- stmt->d.s_prifilt.t_then = removeNOPs(stmt->d.s_prifilt.t_then);
- cnfstmtOptimize(stmt->d.s_prifilt.t_then);
+ cnfstmtOptimizePRIFilt(stmt);
break;
case S_PROPFILT:
stmt->d.s_propfilt.t_then = removeNOPs(stmt->d.s_propfilt.t_then);
@@ -2110,9 +2171,11 @@ dbgprintf("RRRR: stmtOptimize: stmt %p, nodetype %u\n", stmt, stmt->nodetype);
case S_SET:
cnfexprOptimize(stmt->d.s_set.expr);
break;
+ case S_ACT:
+ cnfstmtOptimizeAct(stmt);
+ break;
case S_STOP:
- case S_UNSET:
- case S_ACT: /* nothing to do */
+ case S_UNSET: /* nothing to do */
break;
case S_NOP:
DBGPRINTF("optimizer error: we see a NOP, how come?\n");
@@ -2123,7 +2186,7 @@ dbgprintf("RRRR: stmtOptimize: stmt %p, nodetype %u\n", stmt, stmt->nodetype);
break;
}
}
-done: /*EMPTY*/;
+done: return;
}
diff --git a/runtime/modules.h b/runtime/modules.h
index 5041e439..16425beb 100644
--- a/runtime/modules.h
+++ b/runtime/modules.h
@@ -189,6 +189,8 @@ ENDinterface(module)
PROTOTYPEObj(module);
/* in v6, we go back to in-core static link for core objects, at least those
* that are not called from plugins.
+ * ... and we need to know that none of the module functions are called from plugins!
+ * rgerhards, 2012-09-24
*/
rsRetVal modulesProcessCnf(struct cnfobj *o);
uchar *modGetName(modInfo_t *pThis);
diff --git a/runtime/queue.c b/runtime/queue.c
index 90ffc0a0..0cd33701 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -2079,6 +2079,7 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */
pThis->pqParent == NULL ? 0 : 1, pThis->iFullDlyMrk, pThis->iLightDlyMrk,
pThis->iDeqBatchSize);
+ pThis->bQueueStarted = 1;
if(pThis->qType == QUEUETYPE_DIRECT)
FINALIZE; /* with direct queues, we are already finished... */
@@ -2109,7 +2110,6 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */
* the case when a disk queue has been loaded. If we did not start it here, it would never start.
*/
qqueueAdviseMaxWorkers(pThis);
- pThis->bQueueStarted = 1;
/* support statistics gathering */
qName = obj.GetName((obj_t*)pThis);
@@ -2307,73 +2307,75 @@ DoSaveOnShutdown(qqueue_t *pThis)
/* destructor for the queue object */
BEGINobjDestruct(qqueue) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(qqueue)
- /* shut down all workers
- * We do not need to shutdown workers when we are in enqueue-only mode or we are a
- * direct queue - because in both cases we have none... ;)
- * with a child! -- rgerhards, 2008-01-28
- */
- if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL
- && pThis->pWtpReg != NULL)
- ShutdownWorkers(pThis);
+ if(pThis->bQueueStarted) {
+ /* shut down all workers
+ * We do not need to shutdown workers when we are in enqueue-only mode or we are a
+ * direct queue - because in both cases we have none... ;)
+ * with a child! -- rgerhards, 2008-01-28
+ */
+ if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL
+ && pThis->pWtpReg != NULL)
+ ShutdownWorkers(pThis);
- if(pThis->bIsDA && getPhysicalQueueSize(pThis) > 0 && pThis->bSaveOnShutdown) {
- CHKiRet(DoSaveOnShutdown(pThis));
- }
+ if(pThis->bIsDA && getPhysicalQueueSize(pThis) > 0 && pThis->bSaveOnShutdown) {
+ CHKiRet(DoSaveOnShutdown(pThis));
+ }
- /* finally destruct our (regular) worker thread pool
- * Note: currently pWtpReg is never NULL, but if we optimize our logic, this may happen,
- * e.g. when they are not created in enqueue-only mode. We already check the condition
- * as this may otherwise be very hard to find once we optimize (and have long forgotten
- * about this condition here ;)
- * rgerhards, 2008-01-25
- */
- if(pThis->qType != QUEUETYPE_DIRECT && pThis->pWtpReg != NULL) {
- wtpDestruct(&pThis->pWtpReg);
- }
+ /* finally destruct our (regular) worker thread pool
+ * Note: currently pWtpReg is never NULL, but if we optimize our logic, this may happen,
+ * e.g. when they are not created in enqueue-only mode. We already check the condition
+ * as this may otherwise be very hard to find once we optimize (and have long forgotten
+ * about this condition here ;)
+ * rgerhards, 2008-01-25
+ */
+ if(pThis->qType != QUEUETYPE_DIRECT && pThis->pWtpReg != NULL) {
+ wtpDestruct(&pThis->pWtpReg);
+ }
- /* Now check if we actually have a DA queue and, if so, destruct it.
- * Note that the wtp must be destructed first, it may be in cancel cleanup handler
- * *right now* and actually *need* to access the queue object to persist some final
- * data (re-queueing case). So we need to destruct the wtp first, which will make
- * sure all workers have terminated. Please note that this also generates a situation
- * where it is possible that the DA queue has a parent pointer but the parent has
- * no WtpDA associated with it - which is perfectly legal thanks to this code here.
- */
- if(pThis->pWtpDA != NULL) {
- wtpDestruct(&pThis->pWtpDA);
- }
- if(pThis->pqDA != NULL) {
- qqueueDestruct(&pThis->pqDA);
- }
+ /* Now check if we actually have a DA queue and, if so, destruct it.
+ * Note that the wtp must be destructed first, it may be in cancel cleanup handler
+ * *right now* and actually *need* to access the queue object to persist some final
+ * data (re-queueing case). So we need to destruct the wtp first, which will make
+ * sure all workers have terminated. Please note that this also generates a situation
+ * where it is possible that the DA queue has a parent pointer but the parent has
+ * no WtpDA associated with it - which is perfectly legal thanks to this code here.
+ */
+ if(pThis->pWtpDA != NULL) {
+ wtpDestruct(&pThis->pWtpDA);
+ }
+ if(pThis->pqDA != NULL) {
+ qqueueDestruct(&pThis->pqDA);
+ }
- /* persist the queue (we always do that - queuePersits() does cleanup if the queue is empty)
- * This handler is most important for disk queues, it will finally persist the necessary
- * on-disk structures. In theory, other queueing modes may implement their other (non-DA)
- * methods of persisting a queue between runs, but in practice all of this is done via
- * disk queues and DA mode. Anyhow, it doesn't hurt to know that we could extend it here
- * if need arises (what I doubt...) -- rgerhards, 2008-01-25
- */
- CHKiRet_Hdlr(qqueuePersist(pThis, QUEUE_NO_CHECKPOINT)) {
- DBGOPRINT((obj_t*) pThis, "error %d persisting queue - data lost!\n", iRet);
- }
+ /* persist the queue (we always do that - queuePersits() does cleanup if the queue is empty)
+ * This handler is most important for disk queues, it will finally persist the necessary
+ * on-disk structures. In theory, other queueing modes may implement their other (non-DA)
+ * methods of persisting a queue between runs, but in practice all of this is done via
+ * disk queues and DA mode. Anyhow, it doesn't hurt to know that we could extend it here
+ * if need arises (what I doubt...) -- rgerhards, 2008-01-25
+ */
+ CHKiRet_Hdlr(qqueuePersist(pThis, QUEUE_NO_CHECKPOINT)) {
+ DBGOPRINT((obj_t*) pThis, "error %d persisting queue - data lost!\n", iRet);
+ }
- /* finally, clean up some simple things... */
- if(pThis->pqParent == NULL) {
- /* if we are not a child, we allocated our own mutex, which we now need to destroy */
- pthread_mutex_destroy(pThis->mut);
- free(pThis->mut);
- }
- pthread_mutex_destroy(&pThis->mutThrdMgmt);
- pthread_cond_destroy(&pThis->notFull);
- pthread_cond_destroy(&pThis->notEmpty);
- pthread_cond_destroy(&pThis->belowFullDlyWtrMrk);
- pthread_cond_destroy(&pThis->belowLightDlyWtrMrk);
+ /* finally, clean up some simple things... */
+ if(pThis->pqParent == NULL) {
+ /* if we are not a child, we allocated our own mutex, which we now need to destroy */
+ pthread_mutex_destroy(pThis->mut);
+ free(pThis->mut);
+ }
+ pthread_mutex_destroy(&pThis->mutThrdMgmt);
+ pthread_cond_destroy(&pThis->notFull);
+ pthread_cond_destroy(&pThis->notEmpty);
+ pthread_cond_destroy(&pThis->belowFullDlyWtrMrk);
+ pthread_cond_destroy(&pThis->belowLightDlyWtrMrk);
- DESTROY_ATOMIC_HELPER_MUT(pThis->mutQueueSize);
- DESTROY_ATOMIC_HELPER_MUT(pThis->mutLogDeq);
+ DESTROY_ATOMIC_HELPER_MUT(pThis->mutQueueSize);
+ DESTROY_ATOMIC_HELPER_MUT(pThis->mutLogDeq);
- /* type-specific destructor */
- iRet = pThis->qDestruct(pThis);
+ /* type-specific destructor */
+ iRet = pThis->qDestruct(pThis);
+ }
free(pThis->pszFilePrefix);
free(pThis->pszSpoolDir);
diff --git a/runtime/rsconf.c b/runtime/rsconf.c
index 96118538..2cffd14c 100644
--- a/runtime/rsconf.c
+++ b/runtime/rsconf.c
@@ -360,9 +360,6 @@ void cnfDoObj(struct cnfobj *o)
case CNFOBJ_MODULE:
modulesProcessCnf(o);
break;
- case CNFOBJ_ACTION:
- actionProcessCnf(o);
- break;
case CNFOBJ_TPL:
tplProcessCnf(o);
break;
@@ -371,6 +368,10 @@ void cnfDoObj(struct cnfobj *o)
/* these types are processed at a later stage */
bChkUnuse = 0;
break;
+ default:
+ dbgprintf("cnfDoObj program error: unexpected object type %u\n",
+ o->objType);
+ break;
}
if(bChkUnuse)
nvlstChkUnused(o->nvlst);
@@ -379,8 +380,6 @@ void cnfDoObj(struct cnfobj *o)
void cnfDoScript(struct cnfstmt *script)
{
- // TODO: streamline this, call directly into ruleset from grammar.y
- // TODO: BSD-Style blocks?
dbgprintf("cnf:global:script\n");
ruleset.AddScript(ruleset.GetCurrent(loadConf), script);
}