~ubuntu-branches/ubuntu/trusty/rsyslog/trusty

« back to all changes in this revision

Viewing changes to plugins/imfile/imfile.c

  • Committer: Dave Walker (Daviey)
  • Author(s): Scott Moser
  • Date: 2011-06-17 20:59:38 UTC
  • mfrom: (36.1.8 oneiric.merge)
  • Revision ID: davewalker@ubuntu.com-20110617205938-pfkizxz2wsgzi2ot
Tags: 5.8.1-1ubuntu1
* Resynchronise with Debian (LP: #794230).  Remaining changes:
  - Run as rsyslog:rsyslog, set $FileOwner to syslog
  - Replace init script with debian/rsyslog.upstart.
  - debian/rsyslog.logrotate: Use reload command to restart rsyslog
  - debian/rsyslog.conf: enable $RepeatedMsgReduction 
    to avoid bloating the syslog file (LP #453444)
  - Add debian/rsyslog.dmesg.upstart to save initial dmesg into a file.
    Install it in debian/rules.
  - debian/50-default.conf: set of default rules for syslog (forwarded to
    Debian #603160). remove file in postrm on purge. manage with ucf.
  - debian/rules: build with LDFLAGS=""
* Dropped:
  - debian/control: Bump build-dependency on debhelper
    debian now depends on dh >= 8
* New upstream release.
* Bump Standards-Version to 3.9.2. No further changes.
* Enable and install impstats module. (Closes: #620114)
* Update logcheck rule. (Closes: #616659)
* debian/rsyslog.init: Set correct compat level (5).
* The way rsyslog processes SIGHUP has changed. It no longer does a reload
  of its configuration, but simply closes all open files. To apply a changed
  configuration, rsyslogd needs to be restarted now.
  - Drop "reload" action from debian/rsyslog.init, map "force-reload" to
    "restart". (Closes: #580897)
  - Add "rotate" action to debian/rsyslog.init which sends SIGHUP to
    rsyslogd. Use that in debian/rsyslog.logrotate. (Closes: #626365)
  - Update debian/rsyslog-mysql.postinst and rsyslog-pgsql.postinst to use
    restart instead of reload.
  - Add a NEWS file explaining the changed SIGHUP handling.
* New upstream stable release.
* New upstream release.
  - Properly handle ANSI SQL strings in ompgsql. (Closes: #600479)
* New upstream release.
* debian/patches/02-pmaixforwardedfrom_type_nokeep.patch
  - Remove, merged upstream.
* debian/patches/03-epoll_create1-fallback.patch
  - Remove, merged upstream.
* debian/patches/03-epoll_create1-fallback.patch
  - If epoll_create1() is not available during runtime, fall back to
    epoll_create(). This fixes remote syslog when runnig rsyslog on a
    lenny kernel. (Closes: #617996)
* New upstream release.
* debian/rsyslog.links
  - Create symlink for rsyslog.service in multi-user.target.wants so rsyslog
    is enabled by default when using systemd.
* debian/patches/02-pmaixforwardedfrom_type_nokeep.patch
  - Fix build failure in aixforwardedfrom parser module by setting the
    module type to NOKEEP.
* debian/rsyslog.preinst
  - Remove old rsyslog.socket symlink from sockets.target.wants on upgrades
    as rsyslog uses syslog.socket now which is provided by systemd.
* debian/rsyslog.install
  - Stop installing rsyslog.socket.
* New upstream release.
* New upstream release.
  - Fix regression in imuxsock plugin which did no longer sanitize received
    messages. This makes 02-cleanup-trailing-lf.patch obsolete and also
    fixes the SQL syntax errors in the mysql output if the input contained
    NUL bytes. Closes: #614061
* Enable and install omprog output plugin. Closes: #552095
* Improve package description. Closes: #612948
  Thanks to Justin B Rye for the patch.
* debian/patches/02-cleanup-trailing-lf.patch
  - Fix regression in imuxsock plugin which did not remove a trailing LF
    anymore. Patch cherry-picked from upstream Git. Closes: #612829
* New upstream release.
* Enable and install parser modules.
* New upstream release.
* Upload to unstable.
* debian/patches/02-typo_fix_equation_sign.patch
  - Removed, merged upstream.
* debian/patches/03-atomic_operations.patch
  - Removed, merged upstream.
* debian/patches/03-atomic_operations.patch
  - Fix build failures on platforms which don't have 64 bit atomic
    operations. Patch cherry-picked from upstream Git. Closes: #600930
* New upstream development release.
* Remove patches, merged upstream
  - debian/patches/02-install_also_rsyslog_socket.patch
  - debian/patches/02-tls_loop_fix.patch
* debian/patches/02-typo_fix_equation_sign.patch
  - Fix small typo ("equation sign"). Closes: #575589
* debian/rsyslog.postinst
  - Remove pre-lenny migration code to rotate old log files from sysklogd.
* New upstream development release.
* debian/rsyslog.install
  - Install omruleset.so plugin: http://www.rsyslog.com/doc/omruleset.html
* debian/rsyslog.default
  - Start rsyslogd with native -c5 mode.
* Install systemd unit files which allow to run rsyslog in socket activation
  mode when systemd is used.
* debian/patches/02-install_also_rsyslog_socket.patch
  - When enabling rsyslog.service also enable rsyslog.socket. Patch
    cherry-picked from upstream Git.
* Bump debhelper compatibility level to 8. Update Build-Depends accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *
6
6
 * Work originally begun on 2008-02-01 by Rainer Gerhards
7
7
 *
8
 
 * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
 
8
 * Copyright 2008,2009 Rainer Gerhards and Adiscon GmbH.
9
9
 *
10
10
 * This file is part of rsyslog.
11
11
 *
47
47
#include "datetime.h"
48
48
#include "unicode-helper.h"
49
49
#include "prop.h"
 
50
#include "stringbuf.h"
 
51
#include "ruleset.h"
50
52
 
51
53
MODULE_TYPE_INPUT       /* must be present for input modules, do not remove */
 
54
MODULE_TYPE_NOKEEP
52
55
 
53
56
/* defines */
54
57
 
59
62
DEFobjCurrIf(datetime)
60
63
DEFobjCurrIf(strm)
61
64
DEFobjCurrIf(prop)
 
65
DEFobjCurrIf(ruleset)
62
66
 
63
67
typedef struct fileInfo_s {
64
68
        uchar *pszFileName;
67
71
        uchar *pszStateFile; /* file in which state between runs is to be stored */
68
72
        int iFacility;
69
73
        int iSeverity;
 
74
        int nRecords; /**< How many records did we process before persisting the stream? */
 
75
        int iPersistStateInterval; /**< how often should state be persisted? (0=on close only) */
70
76
        strm_t *pStrm;  /* its stream (NULL if not assigned) */
 
77
        int readMode;   /* which mode to use in ReadMulteLine call? */
 
78
        ruleset_t *pRuleset;    /* ruleset to bind listener to (use system default if unspecified) */
71
79
} fileInfo_t;
72
80
 
73
81
 
 
82
/* forward definitions */
 
83
static rsRetVal persistStrmState(fileInfo_t *pInfo);
 
84
 
74
85
/* config variables */
75
86
static uchar *pszFileName = NULL;
76
87
static uchar *pszFileTag = NULL;
77
88
static uchar *pszStateFile = NULL;
78
89
static int iPollInterval = 10;  /* number of seconds to sleep when there was no file activity */
 
90
static int iPersistStateInterval = 0;   /* how often if state file to be persisted? (default 0->never) */
79
91
static int iFacility = 128; /* local0 */
80
92
static int iSeverity = 5;  /* notice, as of rfc 3164 */
 
93
static int readMode = 0;  /* mode to use for ReadMultiLine call */
 
94
static ruleset_t *pBindRuleset = NULL;  /* ruleset to bind listener to (use system default if unspecified) */
81
95
 
82
96
static int iFilPtr = 0;         /* number of files to be monitored; pointer to next free spot during config */
83
97
#define MAX_INPUT_FILES 100
107
121
        MsgSetTAG(pMsg, pInfo->pszTag, pInfo->lenTag);
108
122
        pMsg->iFacility = LOG_FAC(pInfo->iFacility);
109
123
        pMsg->iSeverity = LOG_PRI(pInfo->iSeverity);
110
 
        pMsg->bParseHOSTNAME = 0;
 
124
        MsgSetRuleset(pMsg, pInfo->pRuleset);
111
125
        CHKiRet(submitMsg(pMsg));
112
126
finalize_it:
113
127
        RETiRet;
154
168
 
155
169
        CHKiRet(strm.SeekCurrOffs(pThis->pStrm));
156
170
 
157
 
        /* OK, we could successfully read the file, so we now can request that it be deleted.
158
 
         * If we need it again, it will be written on the next shutdown.
 
171
        /* note: we do not delete the state file, so that the last position remains
 
172
         * known even in the case that rsyslogd aborts for some reason (like powerfail)
159
173
         */
160
 
        psSF->bDeleteOnClose = 1;
161
174
 
162
175
finalize_it:
163
176
        if(psSF != NULL)
206
219
        }
207
220
 
208
221
        /* loop below will be exited when strmReadLine() returns EOF */
209
 
        while(1) {
210
 
                CHKiRet(strm.ReadLine(pThis->pStrm, &pCStr));
 
222
        while(glbl.GetGlobalInputTermState() == 0) {
 
223
                CHKiRet(strm.ReadLine(pThis->pStrm, &pCStr, pThis->readMode));
211
224
                *pbHadFileData = 1; /* this is just a flag, so set it and forget it */
212
225
                CHKiRet(enqLine(pThis, pCStr)); /* process line */
213
226
                rsCStrDestruct(&pCStr); /* discard string (must be done by us!) */
 
227
                if(pThis->iPersistStateInterval > 0 && pThis->nRecords++ >= pThis->iPersistStateInterval) {
 
228
                        persistStrmState(pThis);
 
229
                        pThis->nRecords = 0;
 
230
                }
214
231
        }
215
232
 
216
233
finalize_it:
217
 
        /*EMPTY - just to keep the compiler happy, do NOT remove*/;
 
234
                ; /*EMPTY STATEMENT - needed to keep compiler happy - see below! */
218
235
        /* Note: the problem above is that pthread:cleanup_pop() is a macro which
219
236
         * evaluates to something like "} while(0);". So the code would become
220
237
         * "finalize_it: }", that is a label without a statement. The C standard does
244
261
 * IMPORTANT: the calling interface of this function can NOT be modified. It actually is
245
262
 * called by pthreads. The provided argument is currently not being used.
246
263
 */
247
 
/* ------------------------------------------------------------------------------------------ *
248
 
 * DO NOT TOUCH the following code - it will soon be part of the module generation macros!    */
249
264
static void
250
265
inputModuleCleanup(void __attribute__((unused)) *arg)
251
266
{
252
267
        BEGINfunc
253
 
/* END no-touch zone                                                                          *
254
 
 * ------------------------------------------------------------------------------------------ */
255
 
 
256
 
 
257
 
 
258
 
        /* so far not needed */
259
 
 
260
 
 
261
 
 
262
 
/* ------------------------------------------------------------------------------------------ *
263
 
 * DO NOT TOUCH the following code - it will soon be part of the module generation macros!    */
264
268
        ENDfunc
265
269
}
266
 
/* END no-touch zone                                                                          *
267
 
 * ------------------------------------------------------------------------------------------ */
268
270
 
269
271
 
270
272
/* This function is called by the framework to gather the input. The module stays
292
294
        int i;
293
295
        int bHadFileData; /* were there at least one file with data during this run? */
294
296
CODESTARTrunInput
295
 
        /* ------------------------------------------------------------------------------------------ *
296
 
         * DO NOT TOUCH the following code - it will soon be part of the module generation macros!    */
297
297
        pthread_cleanup_push(inputModuleCleanup, NULL);
298
 
        while(1) { /* endless loop - do NOT break; out of it! */
299
 
        /* END no-touch zone                                                                          *
300
 
         * ------------------------------------------------------------------------------------------ */
301
 
 
302
 
        do {
303
 
                bHadFileData = 0;
304
 
                for(i = 0 ; i < iFilPtr ; ++i) {
305
 
                        pollFile(&files[i], &bHadFileData);
306
 
                }
307
 
        } while(iFilPtr > 1 && bHadFileData == 1); /* waring: do...while()! */
308
 
 
309
 
        /* Note: the additional 10ns wait is vitally important. It guards rsyslog against totally
310
 
         * hogging the CPU if the users selects a polling interval of 0 seconds. It doesn't hurt any
311
 
         * other valid scenario. So do not remove. -- rgerhards, 2008-02-14
312
 
         */
313
 
        srSleep(iPollInterval, 10);
314
 
 
315
 
        /* ------------------------------------------------------------------------------------------ *
316
 
         * DO NOT TOUCH the following code - it will soon be part of the module generation macros!    */
 
298
        while(glbl.GetGlobalInputTermState() == 0) {
 
299
                do {
 
300
                        bHadFileData = 0;
 
301
                        for(i = 0 ; i < iFilPtr ; ++i) {
 
302
                                if(glbl.GetGlobalInputTermState() == 1)
 
303
                                        break; /* terminate input! */
 
304
                                pollFile(&files[i], &bHadFileData);
 
305
                        }
 
306
                } while(iFilPtr > 1 && bHadFileData == 1 && glbl.GetGlobalInputTermState() == 0); /* warning: do...while()! */
 
307
 
 
308
                /* Note: the additional 10ns wait is vitally important. It guards rsyslog against totally
 
309
                 * hogging the CPU if the users selects a polling interval of 0 seconds. It doesn't hurt any
 
310
                 * other valid scenario. So do not remove. -- rgerhards, 2008-02-14
 
311
                 */
 
312
                if(glbl.GetGlobalInputTermState() == 0)
 
313
                        srSleep(iPollInterval, 10);
317
314
        }
318
 
        /*NOTREACHED*/
 
315
        DBGPRINTF("imfile: terminating upon request of rsyslog core\n");
319
316
        
320
317
        pthread_cleanup_pop(0); /* just for completeness, but never called... */
321
318
        RETiRet;        /* use it to make sure the housekeeping is done! */
334
331
 */
335
332
BEGINwillRun
336
333
CODESTARTwillRun
 
334
        /* free config variables we do no longer needed */
 
335
        free(pszFileName);
 
336
        free(pszFileTag);
 
337
        free(pszStateFile);
 
338
 
337
339
        if(iFilPtr == 0) {
338
340
                errmsg.LogError(0, RS_RET_NO_RUN, "No files configured to be monitored");
339
341
                ABORT_FINALIZE(RS_RET_NO_RUN);
359
361
{
360
362
        DEFiRet;
361
363
        strm_t *psSF = NULL; /* state file (stream) */
 
364
        size_t lenDir;
362
365
 
363
366
        ASSERT(pInfo != NULL);
364
367
 
365
368
        /* TODO: create a function persistObj in obj.c? */
366
369
        CHKiRet(strm.Construct(&psSF));
367
 
        CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir())));
 
370
        lenDir = ustrlen(glbl.GetWorkDir());
 
371
        if(lenDir > 0)
 
372
                CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(), lenDir));
368
373
        CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_WRITE_TRUNC));
369
374
        CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE));
370
375
        CHKiRet(strm.SetFName(psSF, pInfo->pszStateFile, strlen((char*) pInfo->pszStateFile)));
398
403
                        persistStrmState(&files[i]);
399
404
                        strm.Destruct(&(files[i].pStrm));
400
405
                }
 
406
                free(files[i].pszFileName);
 
407
                free(files[i].pszTag);
 
408
                free(files[i].pszStateFile);
401
409
        }
402
410
 
403
411
        if(pInputName != NULL)
405
413
ENDafterRun
406
414
 
407
415
 
 
416
BEGINisCompatibleWithFeature
 
417
CODESTARTisCompatibleWithFeature
 
418
        if(eFeat == sFEATURENonCancelInputTermination)
 
419
                iRet = RS_RET_OK;
 
420
ENDisCompatibleWithFeature
 
421
 
 
422
 
408
423
/* The following entry points are defined in module-template.h.
409
424
 * In general, they need to be present, but you do NOT need to provide
410
425
 * any code here.
417
432
        objRelease(glbl, CORE_COMPONENT);
418
433
        objRelease(errmsg, CORE_COMPONENT);
419
434
        objRelease(prop, CORE_COMPONENT);
 
435
        objRelease(ruleset, CORE_COMPONENT);
420
436
ENDmodExit
421
437
 
422
438
 
423
439
BEGINqueryEtryPt
424
440
CODESTARTqueryEtryPt
425
441
CODEqueryEtryPt_STD_IMOD_QUERIES
 
442
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
426
443
ENDqueryEtryPt
427
444
 
428
445
 
456
473
        iPollInterval = 10;
457
474
        iFacility = 128; /* local0 */
458
475
        iSeverity = 5;  /* notice, as of rfc 3164 */
 
476
        readMode = 0;
 
477
        pBindRuleset = NULL;
459
478
 
460
479
        RETiRet;
461
480
}
496
515
 
497
516
                pThis->iSeverity = iSeverity;
498
517
                pThis->iFacility = iFacility;
 
518
                pThis->iPersistStateInterval = iPersistStateInterval;
 
519
                pThis->nRecords = 0;
 
520
                pThis->readMode = readMode;
 
521
                pThis->pRuleset = pBindRuleset;
 
522
                iPersistStateInterval = 0;
499
523
        } else {
500
524
                errmsg.LogError(0, RS_RET_OUT_OF_DESRIPTORS, "Too many file monitors configured - ignoring this one");
501
525
                ABORT_FINALIZE(RS_RET_OUT_OF_DESRIPTORS);
510
534
        RETiRet;
511
535
}
512
536
 
 
537
 
 
538
/* accept a new ruleset to bind. Checks if it exists and complains, if not */
 
539
static rsRetVal
 
540
setRuleset(void __attribute__((unused)) *pVal, uchar *pszName)
 
541
{
 
542
        ruleset_t *pRuleset;
 
543
        rsRetVal localRet;
 
544
        DEFiRet;
 
545
 
 
546
        localRet = ruleset.GetRuleset(&pRuleset, pszName);
 
547
        if(localRet == RS_RET_NOT_FOUND) {
 
548
                errmsg.LogError(0, NO_ERRCODE, "error: ruleset '%s' not found - ignored", pszName);
 
549
        }
 
550
        CHKiRet(localRet);
 
551
        pBindRuleset = pRuleset;
 
552
        DBGPRINTF("imfile current bind ruleset %p: '%s'\n", pRuleset, pszName);
 
553
 
 
554
finalize_it:
 
555
        free(pszName); /* no longer needed */
 
556
        RETiRet;
 
557
}
 
558
 
 
559
 
513
560
/* modInit() is called once the module is loaded. It must perform all module-wide
514
561
 * initialization tasks. There are also a number of housekeeping tasks that the
515
562
 * framework requires. These are handled by the macros. Please note that the
527
574
        CHKiRet(objUse(glbl, CORE_COMPONENT));
528
575
        CHKiRet(objUse(datetime, CORE_COMPONENT));
529
576
        CHKiRet(objUse(strm, CORE_COMPONENT));
 
577
        CHKiRet(objUse(ruleset, CORE_COMPONENT));
530
578
        CHKiRet(objUse(prop, CORE_COMPONENT));
531
579
 
 
580
        DBGPRINTF("imfile: version %s initializing\n", VERSION);
532
581
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilename", 0, eCmdHdlrGetWord,
533
582
                NULL, &pszFileName, STD_LOADABLE_MODULE_ID));
534
583
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfiletag", 0, eCmdHdlrGetWord,
541
590
                NULL, &iFacility, STD_LOADABLE_MODULE_ID));
542
591
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilepollinterval", 0, eCmdHdlrInt,
543
592
                NULL, &iPollInterval, STD_LOADABLE_MODULE_ID));
 
593
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilereadmode", 0, eCmdHdlrInt,
 
594
                NULL, &readMode, STD_LOADABLE_MODULE_ID));
 
595
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilepersiststateinterval", 0, eCmdHdlrInt,
 
596
                NULL, &iPersistStateInterval, STD_LOADABLE_MODULE_ID));
 
597
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilebindruleset", 0, eCmdHdlrGetWord,
 
598
                setRuleset, NULL, STD_LOADABLE_MODULE_ID));
544
599
        /* that command ads a new file! */
545
600
        CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrunfilemonitor", 0, eCmdHdlrGetWord,
546
601
                addMonitor, NULL, STD_LOADABLE_MODULE_ID));