1
/* rsyslog.c - the main entry point into rsyslog's runtime library (RTL)
3
* This module contains all function which work on a RTL global level. It's
4
* name is abbreviated to "rsrt" (rsyslog runtime).
6
* Please note that the runtime library tends to be plugin-safe. That is, it must be
7
* initialized by calling a global initialization function. However, that
8
* function checks if the library is already initialized and, if so, does
9
* nothing except incrementing a refeence count. Similarly, the deinit
10
* function does nothing as long as there are still other users (which
11
* is tracked via the refcount). As such, it is safe to call init and
12
* exit multiple times, as long as this are always matching calls. This
13
* capability is needed for a plugin system, where one plugin never
14
* knows what the other did. HOWEVER, as of this writing, not all runtime
15
* library objects may work cleanly without static global data (the
16
* debug system is a very good example of this). So while we aim at the
17
* ability to work well in a plugin environment, things may not really work
18
* out. If you intend to use the rsyslog runtime library inside plugins,
19
* you should investigate the situation in detail. Please note that the
20
* rsyslog project itself does not yet need this functionality - thus you
21
* can safely assume it is totally untested ;).
23
* rgerhards, 2008-04-17: I have now once again checked on the plugin-safety.
24
* Unfortunately, there is currently no hook at all with which we could
25
* abstract a global data instance class. As such, we can NOT make the
26
* runtime plugin-safe in the above-described sense. As the rsyslog
27
* project itself does not need this functionality (and it is quesationable
28
* if someone else ever will), we do currently do not make an effort to
29
* support it. So if you intend to use rsyslog runtime inside a non-rsyslog
30
* plugin system, be careful!
32
* The rsyslog runtime library is in general reentrant and thread-safe. There
33
* are some intentional exceptions (e.g. inside the msg object). These are
34
* documented. Any other threading and reentrency issue can be considered a bug.
36
* Module begun 2008-04-16 by Rainer Gerhards
38
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
40
* This file is part of the rsyslog runtime library.
42
* The rsyslog runtime library is free software: you can redistribute it and/or modify
43
* it under the terms of the GNU Lesser General Public License as published by
44
* the Free Software Foundation, either version 3 of the License, or
45
* (at your option) any later version.
47
* The rsyslog runtime library is distributed in the hope that it will be useful,
48
* but WITHOUT ANY WARRANTY; without even the implied warranty of
49
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50
* GNU Lesser General Public License for more details.
52
* You should have received a copy of the GNU Lesser General Public License
53
* along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
55
* A copy of the GPL can be found in the file "COPYING" in this distribution.
56
* A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
67
#include "stringbuf.h"
81
/* forward definitions */
82
static rsRetVal dfltErrLogger(int, uchar *errMsg);
84
/* globally visible static data - see comment in rsyslog.h for details */
85
uchar *glblModPath; /* module load path */
86
rsRetVal (*glblErrLogger)(int, uchar*) = dfltErrLogger; /* the error logger to use by the errmsg module */
89
static int iRefCount = 0; /* our refcount - it MUST exist only once inside a process (not thread)
90
thus it is perfectly OK to use a static. MUST be initialized to 0! */
92
/* This is the default instance of the error logger. It simply writes the message
93
* to stderr. It is expected that this is replaced by the runtime user very early
94
* during startup (at least if the default is unsuitable). However, we provide a
95
* default so that we can log errors during the intial phase, most importantly
96
* during initialization. -- rgerhards. 2008-04-17
98
static rsRetVal dfltErrLogger(int iErr, uchar *errMsg)
101
fprintf(stderr, "rsyslog runtime error(%d): %s\n", iErr, errMsg);
106
/* set the error log function
107
* rgerhards, 2008-04-18
110
rsrtSetErrLogger(rsRetVal (*errLogger)(int, uchar*))
113
assert(errLogger != NULL);
114
glblErrLogger = errLogger;
119
/* globally initialze the runtime system
120
* NOTE: this is NOT thread safe and must not be called concurrently. If that
121
* ever poses a problem, we may use proper mutex calls - not considered needed yet.
122
* If ppErrObj is provided, it receives a char pointer to the name of the object that
123
* caused the problem (if one occured). The caller must never free this pointer. If
124
* ppErrObj is NULL, no such information will be provided. pObjIF is the pointer to
125
* the "obj" object interface, which may be used to query any other rsyslog objects.
126
* rgerhards, 2008-04-16
129
rsrtInit(char **ppErrObj, obj_if_t *pObjIF)
134
/* init runtime only if not yet done */
135
if(ppErrObj != NULL) *ppErrObj = "obj";
136
CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */
137
CHKiRet(objGetObjInterface(pObjIF)); /* this provides the root pointer for all other queries */
139
/* initialize core classes. We must be very careful with the order of events. Some
140
* classes use others and if we do not initialize them in the right order, we may end
141
* up with an invalid call. The most important thing that can happen is that an error
142
* is detected and needs to be logged, wich in turn requires a broader number of classes
143
* to be available. The solution is that we take care in the order of calls AND use a
144
* class immediately after it is initialized. And, of course, we load those classes
145
* first that we use ourselfs... -- rgerhards, 2008-03-07
147
if(ppErrObj != NULL) *ppErrObj = "glbl";
148
CHKiRet(glblClassInit(NULL));
149
if(ppErrObj != NULL) *ppErrObj = "datetime";
150
CHKiRet(datetimeClassInit(NULL));
151
if(ppErrObj != NULL) *ppErrObj = "msg";
152
CHKiRet(msgClassInit(NULL));
153
if(ppErrObj != NULL) *ppErrObj = "str,";
154
CHKiRet(strmClassInit(NULL));
155
if(ppErrObj != NULL) *ppErrObj = "wti";
156
CHKiRet(wtiClassInit(NULL));
157
if(ppErrObj != NULL) *ppErrObj = "wtp";
158
CHKiRet(wtpClassInit(NULL));
159
if(ppErrObj != NULL) *ppErrObj = "queue";
160
CHKiRet(queueClassInit(NULL));
161
if(ppErrObj != NULL) *ppErrObj = "vmstk";
162
CHKiRet(vmstkClassInit(NULL));
163
if(ppErrObj != NULL) *ppErrObj = "sysvar";
164
CHKiRet(sysvarClassInit(NULL));
165
if(ppErrObj != NULL) *ppErrObj = "vm";
166
CHKiRet(vmClassInit(NULL));
167
if(ppErrObj != NULL) *ppErrObj = "vmop";
168
CHKiRet(vmopClassInit(NULL));
169
if(ppErrObj != NULL) *ppErrObj = "vmprg";
170
CHKiRet(vmprgClassInit(NULL));
171
if(ppErrObj != NULL) *ppErrObj = "ctok_token";
172
CHKiRet(ctok_tokenClassInit(NULL));
173
if(ppErrObj != NULL) *ppErrObj = "ctok";
174
CHKiRet(ctokClassInit(NULL));
175
if(ppErrObj != NULL) *ppErrObj = "expr";
176
CHKiRet(exprClassInit(NULL));
177
if(ppErrObj != NULL) *ppErrObj = "conf";
178
CHKiRet(confClassInit(NULL));
180
/* dummy "classes" */
181
if(ppErrObj != NULL) *ppErrObj = "str";
186
dbgprintf("rsyslog runtime initialized, version %s, current users %d\n", VERSION, iRefCount);
193
/* globally de-initialze the runtime system
194
* NOTE: this is NOT thread safe and must not be called concurrently. If that
195
* ever poses a problem, we may use proper mutex calls - not considered needed yet.
196
* This function must be provided with the caller's obj object pointer. This is
197
* automatically deinitialized by the runtime system.
198
* rgerhards, 2008-04-16
206
/* do actual de-init only if we are the last runtime user */
209
objClassExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
213
/* TODO we must deinit this pointer! pObjIF = NULL; / * no longer exists for this caller */
215
dbgprintf("rsyslog runtime de-initialized, current users %d\n", iRefCount);
221
/* returns 0 if the rsyslog runtime is not initialized and another value
222
* if it is. This function is primarily meant to be used by runtime functions
223
* itself. However, it is safe to call it before initializing the runtime.
224
* Plugins should NOT rely on this function. The reason is that another caller
225
* may have already initialized it but deinits it before this plugin is done.
226
* So for plugins and like architectures, the right course of action is to
227
* call rsrtInit() and rsrtExit(), which can be called by multiple callers.
228
* rgerhards, 2008-04-16