~ubuntu-branches/ubuntu/lucid/rsyslog/lucid-updates

« back to all changes in this revision

Viewing changes to action.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2009-06-23 12:12:43 UTC
  • mfrom: (1.1.11 upstream) (3.2.8 sid)
  • Revision ID: james.westby@ubuntu.com-20090623121243-d2fejarzidywnn17
Tags: 4.2.0-1
* New upstream release of the now stable v4 branch.
  - Fix warnings when /etc/rsyslog.d/ is empty. Closes: #530228
* debian/patches/imudp_multiple_udp_sockets.patch
  - Removed, merged upstream.
* debian/rsyslog.default
  - Set default compat mode to '4'.
* debian/rsyslog.logcheck.ignore.server
  - Update logcheck rules files to also ignore rsyslogd and imklog stop
    messages.
* debian/control
  - Bump Standards-Version to 3.8.2. No further changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
static time_t iActExecEveryNthOccurTO = 0; /* timeout for n-occurence setting (in seconds, 0=never) */
59
59
static int glbliActionResumeInterval = 30;
60
60
int glbliActionResumeRetryCount = 0;            /* how often should suspended actions be retried? */
 
61
static int bActionRepMsgHasMsg = 0;             /* last messsage repeated... has msg fragment in it */
61
62
 
62
63
/* main message queue and its configuration parameters */
63
64
static queueType_t ActionQueType = QUEUETYPE_DIRECT;            /* type of the main message queue above */
179
180
        ASSERT(pThis != NULL);
180
181
 
181
182
        if(pThis->pQueue != NULL) {
182
 
                queueDestruct(&pThis->pQueue);
 
183
                qqueueDestruct(&pThis->pQueue);
183
184
        }
184
185
 
185
186
        if(pThis->pMod != NULL)
254
255
         * to be run on multiple threads. So far, this is forbidden by the interface
255
256
         * spec. -- rgerhards, 2008-01-30
256
257
         */
257
 
        CHKiRet(queueConstruct(&pThis->pQueue, ActionQueType, 1, iActionQueueSize, (rsRetVal (*)(void*,void*))actionCallDoAction));
 
258
        CHKiRet(qqueueConstruct(&pThis->pQueue, ActionQueType, 1, iActionQueueSize, (rsRetVal (*)(void*,void*))actionCallDoAction));
258
259
        obj.SetName((obj_t*) pThis->pQueue, pszQName);
259
260
 
260
261
        /* ... set some properties ... */
267
268
                errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \
268
269
        }
269
270
 
270
 
        queueSetpUsr(pThis->pQueue, pThis);
271
 
        setQPROP(queueSetsizeOnDiskMax, "$ActionQueueMaxDiskSpace", iActionQueMaxDiskSpace);
272
 
        setQPROP(queueSetMaxFileSize, "$ActionQueueFileSize", iActionQueMaxFileSize);
273
 
        setQPROPstr(queueSetFilePrefix, "$ActionQueueFileName", pszActionQFName);
274
 
        setQPROP(queueSetiPersistUpdCnt, "$ActionQueueCheckpointInterval", iActionQPersistUpdCnt);
275
 
        setQPROP(queueSettoQShutdown, "$ActionQueueTimeoutShutdown", iActionQtoQShutdown );
276
 
        setQPROP(queueSettoActShutdown, "$ActionQueueTimeoutActionCompletion", iActionQtoActShutdown);
277
 
        setQPROP(queueSettoWrkShutdown, "$ActionQueueWorkerTimeoutThreadShutdown", iActionQtoWrkShutdown);
278
 
        setQPROP(queueSettoEnq, "$ActionQueueTimeoutEnqueue", iActionQtoEnq);
279
 
        setQPROP(queueSetiHighWtrMrk, "$ActionQueueHighWaterMark", iActionQHighWtrMark);
280
 
        setQPROP(queueSetiLowWtrMrk, "$ActionQueueLowWaterMark", iActionQLowWtrMark);
281
 
        setQPROP(queueSetiDiscardMrk, "$ActionQueueDiscardMark", iActionQDiscardMark);
282
 
        setQPROP(queueSetiDiscardSeverity, "$ActionQueueDiscardSeverity", iActionQDiscardSeverity);
283
 
        setQPROP(queueSetiMinMsgsPerWrkr, "$ActionQueueWorkerThreadMinimumMessages", iActionQWrkMinMsgs);
284
 
        setQPROP(queueSetbSaveOnShutdown, "$ActionQueueSaveOnShutdown", bActionQSaveOnShutdown);
285
 
        setQPROP(queueSetiDeqSlowdown,    "$ActionQueueDequeueSlowdown", iActionQueueDeqSlowdown);
286
 
        setQPROP(queueSetiDeqtWinFromHr,  "$ActionQueueDequeueTimeBegin", iActionQueueDeqtWinFromHr);
287
 
        setQPROP(queueSetiDeqtWinToHr,    "$ActionQueueDequeueTimeEnd", iActionQueueDeqtWinToHr);
 
271
        qqueueSetpUsr(pThis->pQueue, pThis);
 
272
        setQPROP(qqueueSetsizeOnDiskMax, "$ActionQueueMaxDiskSpace", iActionQueMaxDiskSpace);
 
273
        setQPROP(qqueueSetMaxFileSize, "$ActionQueueFileSize", iActionQueMaxFileSize);
 
274
        setQPROPstr(qqueueSetFilePrefix, "$ActionQueueFileName", pszActionQFName);
 
275
        setQPROP(qqueueSetiPersistUpdCnt, "$ActionQueueCheckpointInterval", iActionQPersistUpdCnt);
 
276
        setQPROP(qqueueSettoQShutdown, "$ActionQueueTimeoutShutdown", iActionQtoQShutdown );
 
277
        setQPROP(qqueueSettoActShutdown, "$ActionQueueTimeoutActionCompletion", iActionQtoActShutdown);
 
278
        setQPROP(qqueueSettoWrkShutdown, "$ActionQueueWorkerTimeoutThreadShutdown", iActionQtoWrkShutdown);
 
279
        setQPROP(qqueueSettoEnq, "$ActionQueueTimeoutEnqueue", iActionQtoEnq);
 
280
        setQPROP(qqueueSetiHighWtrMrk, "$ActionQueueHighWaterMark", iActionQHighWtrMark);
 
281
        setQPROP(qqueueSetiLowWtrMrk, "$ActionQueueLowWaterMark", iActionQLowWtrMark);
 
282
        setQPROP(qqueueSetiDiscardMrk, "$ActionQueueDiscardMark", iActionQDiscardMark);
 
283
        setQPROP(qqueueSetiDiscardSeverity, "$ActionQueueDiscardSeverity", iActionQDiscardSeverity);
 
284
        setQPROP(qqueueSetiMinMsgsPerWrkr, "$ActionQueueWorkerThreadMinimumMessages", iActionQWrkMinMsgs);
 
285
        setQPROP(qqueueSetbSaveOnShutdown, "$ActionQueueSaveOnShutdown", bActionQSaveOnShutdown);
 
286
        setQPROP(qqueueSetiDeqSlowdown,    "$ActionQueueDequeueSlowdown", iActionQueueDeqSlowdown);
 
287
        setQPROP(qqueueSetiDeqtWinFromHr,  "$ActionQueueDequeueTimeBegin", iActionQueueDeqtWinFromHr);
 
288
        setQPROP(qqueueSetiDeqtWinToHr,    "$ActionQueueDequeueTimeEnd", iActionQueueDeqtWinToHr);
288
289
 
289
290
#       undef setQPROP
290
291
#       undef setQPROPstr
293
294
                   bActionQSaveOnShutdown, iActionQueMaxDiskSpace);
294
295
        
295
296
 
296
 
        CHKiRet(queueStart(pThis->pQueue));
 
297
        CHKiRet(qqueueStart(pThis->pQueue));
297
298
        dbgprintf("Action %p: queue %p created\n", pThis, pThis->pQueue);
298
299
        
299
300
        /* and now reset the queue params (see comment in its function header!) */
352
353
 
353
354
        ASSERT(pThis != NULL);
354
355
 
355
 
        ttNow = getActNow(pThis); /* cache "now" */
 
356
        /* for resume handling, we must always obtain a fresh timestamp. We used
 
357
         * to use the action timestamp, but in this case we will never reach a
 
358
         * point where a resumption is actually tried, because the action timestamp
 
359
         * is always in the past. So we can not avoid doing a fresh time() call
 
360
         * here. -- rgerhards, 2009-03-18
 
361
         */
 
362
        time(&ttNow); /* cache "now" */
356
363
 
357
364
        /* first check if it is time for a re-try */
358
365
        if(ttNow > pThis->ttResumeRtry) {
418
425
        DEFiRet;
419
426
        int iRetries;
420
427
        int i;
 
428
        int iArr;
421
429
        int iSleepPeriod;
422
430
        int bCallAction;
423
431
        int iCancelStateSave;
432
440
 
433
441
        /* here we must loop to process all requested strings */
434
442
        for(i = 0 ; i < pAction->iNumTpls ; ++i) {
435
 
                CHKiRet(tplToString(pAction->ppTpl[i], pMsg, &(ppMsgs[i])));
 
443
                switch(pAction->eParamPassing) {
 
444
                        case ACT_STRING_PASSING:
 
445
                                CHKiRet(tplToString(pAction->ppTpl[i], pMsg, &(ppMsgs[i])));
 
446
                                break;
 
447
                        case ACT_ARRAY_PASSING:
 
448
                                CHKiRet(tplToArray(pAction->ppTpl[i], pMsg, (uchar***) &(ppMsgs[i])));
 
449
                                break;
 
450
                        default:assert(0); /* software bug if this happens! */
 
451
                }
436
452
        }
437
453
        iRetries = 0;
438
454
        /* We now must guard the output module against execution by multiple threads. The
488
504
        /* cleanup */
489
505
        for(i = 0 ; i < pAction->iNumTpls ; ++i) {
490
506
                if(ppMsgs[i] != NULL) {
491
 
                        d_free(ppMsgs[i]);
 
507
                        switch(pAction->eParamPassing) {
 
508
                        case ACT_ARRAY_PASSING:
 
509
                                iArr = 0;
 
510
                                while(((char **)ppMsgs[i])[iArr] != NULL)
 
511
                                        d_free(((char **)ppMsgs[i])[iArr++]);
 
512
                                d_free(ppMsgs[i]);
 
513
                                break;
 
514
                        case ACT_STRING_PASSING:
 
515
                                d_free(ppMsgs[i]);
 
516
                                break;
 
517
                        default:
 
518
                                assert(0);
 
519
                        }
492
520
                }
493
521
        }
494
522
        d_free(ppMsgs);
498
526
}
499
527
#pragma GCC diagnostic warning "-Wempty-body"
500
528
 
 
529
 
 
530
/* call the HUP handler for a given action, if such a handler is defined. The
 
531
 * action mutex is locked, because the HUP handler most probably needs to modify
 
532
 * some internal state information.
 
533
 * rgerhards, 2008-10-22
 
534
 */
 
535
#pragma GCC diagnostic ignored "-Wempty-body"
 
536
rsRetVal
 
537
actionCallHUPHdlr(action_t *pAction)
 
538
{
 
539
        DEFiRet;
 
540
        int iCancelStateSave;
 
541
 
 
542
        ASSERT(pAction != NULL);
 
543
        DBGPRINTF("Action %p checks HUP hdlr: %p\n", pAction, pAction->pMod->doHUP);
 
544
 
 
545
        if(pAction->pMod->doHUP == NULL) {
 
546
                FINALIZE;       /* no HUP handler, so we are done ;) */
 
547
        }
 
548
 
 
549
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave);
 
550
        d_pthread_mutex_lock(&pAction->mutActExec);
 
551
        pthread_cleanup_push(mutexCancelCleanup, &pAction->mutActExec);
 
552
        pthread_setcancelstate(iCancelStateSave, NULL);
 
553
        CHKiRet(pAction->pMod->doHUP(pAction->pModData));
 
554
        pthread_cleanup_pop(1); /* unlock mutex */
 
555
 
 
556
finalize_it:
 
557
        RETiRet;
 
558
}
 
559
#pragma GCC diagnostic warning "-Wempty-body"
 
560
 
 
561
 
501
562
/* set the action message queue mode
502
563
 * TODO: probably move this into queue object, merge with MainMsgQueue!
503
564
 * rgerhards, 2008-01-28
588
649
         */
589
650
        if(pAction->f_prevcount > 1) {
590
651
                msg_t *pMsg;
591
 
                uchar szRepMsg[64];
592
 
                snprintf((char*)szRepMsg, sizeof(szRepMsg), "last message repeated %d times",
593
 
                    pAction->f_prevcount);
 
652
                uchar szRepMsg[1024];
594
653
 
595
654
                if((pMsg = MsgDup(pAction->f_pMsg)) == NULL) {
596
655
                        /* it failed - nothing we can do against it... */
598
657
                        ABORT_FINALIZE(RS_RET_ERR);
599
658
                }
600
659
 
 
660
                if(pAction->bRepMsgHasMsg == 0) { /* old format repeat message? */
 
661
                        snprintf((char*)szRepMsg, sizeof(szRepMsg), "last message repeated %d times",
 
662
                            pAction->f_prevcount);
 
663
                } else {
 
664
                        snprintf((char*)szRepMsg, sizeof(szRepMsg), "message repeated %d times: [%.800s]",
 
665
                            pAction->f_prevcount, getMSG(pAction->f_pMsg));
 
666
                }
 
667
 
601
668
                /* We now need to update the other message properties.
602
669
                 * ... RAWMSG is a problem ... Please note that digital
603
670
                 * signatures inside the message are also invalidated.
604
671
                 */
605
 
                datetime.getCurrTime(&(pMsg->tRcvdAt));
 
672
                datetime.getCurrTime(&(pMsg->tRcvdAt), &(pMsg->ttGenTime));
606
673
                memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime));
607
674
                MsgSetMSG(pMsg, (char*)szRepMsg);
608
675
                MsgSetRawMsg(pMsg, (char*)szRepMsg);
625
692
                dbgprintf("action not yet ready again to be executed, onceInterval %d, tCurr %d, tNext %d\n",
626
693
                          (int) pAction->iSecsExecOnceInterval, (int) getActNow(pAction),
627
694
                          (int) (pAction->iSecsExecOnceInterval + pAction->tLastExec));
 
695
                pAction->tLastExec = getActNow(pAction); /* re-init time flags */
628
696
                FINALIZE;
629
697
        }
630
698
 
631
 
        pAction->f_time = pAction->tLastExec = getActNow(pAction); /* re-init time flags */
632
 
        /* Note: tLastExec could be set in the if block above, but f_time causes us a hard time
633
 
         * so far, I do not see a solution to getting rid of it. -- rgerhards, 2008-09-16
634
 
         */
 
699
        /* we use reception time, not dequeue time - this is considered more appropriate and also faster ;) -- rgerhards, 2008-09-17 */
 
700
        pAction->f_time = pAction->f_pMsg->ttGenTime;
635
701
 
636
702
        /* When we reach this point, we have a valid, non-disabled action.
637
703
         * So let's enqueue our message for execution. -- rgerhards, 2007-07-24
638
704
         */
639
 
        iRet = queueEnqObj(pAction->pQueue, pAction->f_pMsg->flowCtlType, (void*) MsgAddRef(pAction->f_pMsg));
 
705
        iRet = qqueueEnqObj(pAction->pQueue, pAction->f_pMsg->flowCtlType, (void*) MsgAddRef(pAction->f_pMsg));
640
706
 
641
707
        if(iRet == RS_RET_OK)
642
708
                pAction->f_prevcount = 0; /* message processed, so we start a new cycle */
785
851
        CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iActionQueueDeqtWinToHr, NULL));
786
852
        CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyeverynthtime", 0, eCmdHdlrInt, NULL, &iActExecEveryNthOccur, NULL));
787
853
        CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyeverynthtimetimeout", 0, eCmdHdlrInt, NULL, &iActExecEveryNthOccurTO, NULL));
 
854
        CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgcontainsoriginalmsg", 0, eCmdHdlrBinary, NULL, &bActionRepMsgHasMsg, NULL));
788
855
        
789
856
finalize_it:
790
857
        RETiRet;
818
885
        pAction->iSecsExecOnceInterval = iActExecOnceInterval;
819
886
        pAction->iExecEveryNthOccur = iActExecEveryNthOccur;
820
887
        pAction->iExecEveryNthOccurTO = iActExecEveryNthOccurTO;
 
888
        pAction->bRepMsgHasMsg = bActionRepMsgHasMsg;
821
889
        iActExecEveryNthOccur = 0; /* auto-reset */
822
890
        iActExecEveryNthOccurTO = 0; /* auto-reset */
823
891
 
858
926
                        ABORT_FINALIZE(RS_RET_RQD_TPLOPT_MISSING);
859
927
                }
860
928
 
 
929
                /* set parameter-passing mode */
 
930
                if(iTplOpts & OMSR_TPL_AS_ARRAY) {
 
931
                        pAction->eParamPassing = ACT_ARRAY_PASSING;
 
932
                } else {
 
933
                        pAction->eParamPassing = ACT_STRING_PASSING;
 
934
                }
 
935
 
861
936
                dbgprintf("template: '%s' assigned\n", pTplName);
862
937
        }
863
938