syslog-ng source
logpipe.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2012 Balabit
3  * Copyright (c) 1998-2012 Balázs Scheidler
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * As an additional exemption you are allowed to compile & link against the
20  * OpenSSL libraries as published by the OpenSSL project. See the file
21  * COPYING for details.
22  *
23  */
24 
25 #ifndef LOGPIPE_H_INCLUDED
26 #define LOGPIPE_H_INCLUDED
27 
28 #include "syslog-ng.h"
29 #include "logmsg/logmsg.h"
30 #include "cfg.h"
31 #include "atomic.h"
32 #include "messages.h"
33 
34 /* notify code values */
35 #define NC_CLOSE 1
36 #define NC_READ_ERROR 2
37 #define NC_WRITE_ERROR 3
38 #define NC_FILE_MOVED 4
39 #define NC_FILE_EOF 5
40 #define NC_REOPEN_REQUIRED 6
41 #define NC_FILE_DELETED 7
42 #define NC_FILE_MODIFIED 8
43 #define NC_AGAIN 9
44 #define NC_LOGROTATE 10
45 
46 /* notify result mask values */
47 #define NR_OK 0x0000
48 #define NR_ERROR 0x0001
49 #define NR_STOP_ON_EOF 0x0002
50 
51 /* indicates that the LogPipe was initialized */
52 #define PIF_INITIALIZED 0x0001
53 /* indicates that this LogPipe got cloned into the tree already */
54 #define PIF_INLINED 0x0002
55 
56 /* this pipe is a source for messages, it is not meant to be used to
57  * forward messages, syslog-ng will only use these pipes for the
58  * left-hand side of the processing graph, e.g. no other pipes may be
59  * sending messages to these pipes and these are expected to generate
60  * messages "automatically". */
61 
62 #define PIF_SOURCE 0x0004
63 
64 /* log statement flags that are copied to the head of a branch */
65 #define PIF_BRANCH_FINAL 0x0008
66 #define PIF_BRANCH_FALLBACK 0x0010
67 #define PIF_BRANCH_PROPERTIES (PIF_BRANCH_FINAL + PIF_BRANCH_FALLBACK)
68 
69 /* branch starting with this pipe wants hard flow control */
70 #define PIF_HARD_FLOW_CONTROL 0x0020
71 
72 /* LogPipe right after the filter in an "if (filter)" expression */
73 #define PIF_CONDITIONAL_MIDPOINT 0x0040
74 
75 /* LogPipe as the joining element of a junction */
76 #define PIF_JUNCTION_END 0x0080
77 
78 /* node created directly by the user */
79 #define PIF_CONFIG_RELATED 0x0100
80 
81 /* private flags range, to be used by other LogPipe instances for their own purposes */
82 
83 #define PIF_PRIVATE(x) ((x) << 16)
84 
197 {
198  /* an acknowledgement is "passed" to this path, an ACK is still
199  * needed to close the window slot. This was called "flow-control"
200  * and meant both of these things: the user requested
201  * flags(flow-control), _AND_ an acknowledgement was needed. With
202  * the latest change, the one below specifies the user option,
203  * while the "ack is still needed" condition is stored in
204  * ack_needed.
205  */
206 
207  gboolean ack_needed;
208 
209  /* The user has requested flow-control on this processing path,
210  * which means that the destination should invoke log_msg_ack()
211  * after it has completed processing it (e.g. after sending to the
212  * actual destination, possibly after confirmation if the transport
213  * supports that). If flow-control is not requested, destinations
214  * are permitted to call log_msg_ack() early (e.g. at queue time).
215  *
216  * This is initially FALSE and can be set to TRUE anywhere _before_
217  * the destination driver, which will actually carry out the
218  * required action.
219  */
220 
222 
223  gboolean *matched;
224  const LogPathOptions *lpo_parent_junction;
225 };
226 
227 #define LOG_PATH_OPTIONS_INIT { TRUE, FALSE, NULL, NULL }
228 #define LOG_PATH_OPTIONS_INIT_NOACK { FALSE, FALSE, NULL, NULL }
229 
230 /*
231  * Embed a step in our LogPathOptions chain.
232  */
233 static inline LogPathOptions *
234 log_path_options_chain(LogPathOptions *local_path_options, const LogPathOptions *lpo_previous_hop)
235 {
236  *local_path_options = *lpo_previous_hop;
237  return local_path_options;
238 }
239 
240 /* LogPathOptions are chained up at the start of a junction and teared down
241  * at the end (see log_path_options_pop_junction().
242  *
243  * The "matched" value is kept separate on the parent level and the junction
244  * level. This way the junction can separately act on matching/non-matching
245  * messages and potentially propagate it to the parent (or not), see
246  * logmpx.c for details.
247  * */
248 static inline void
249 log_path_options_push_junction(LogPathOptions *local_path_options,
250  gboolean *matched,
251  const LogPathOptions *lpo_parent_junction)
252 {
253  *local_path_options = *lpo_parent_junction;
254  local_path_options->matched = matched;
255  local_path_options->lpo_parent_junction = lpo_parent_junction;
256 }
257 
258 /* Part of the junction related state needs to be "popped" once the
259  * conditional decision is concluded. This happens in the `if (filter)`
260  * form, once the filter is evaluated, or at the end of the junction. This
261  * basically resets the "matched" pointer to that of the parent junction.
262  */
263 static inline void
264 log_path_options_pop_conditional(LogPathOptions *local_path_options)
265 {
266  if (local_path_options->lpo_parent_junction)
267  local_path_options->matched = local_path_options->lpo_parent_junction->matched;
268 }
269 
270 /*
271  * Tear down the embedded junction related state from the LogPathOptions
272  * chain. This implies log_path_options_pop_conditional() as well, which
273  * will do nothing if there was a conditional midpoint (e.g. `if
274  * (filter)`).
275  *
276  * NOTE: we need to be optional about ->parent being set, as synthetic
277  * messages (e.g. the likes emitted by db-parser/grouping-by() may arrive
278  * at the end of a junction without actually crossing the beginning of the
279  * same junction. But this is ok, in these cases we don't need to propagate
280  * our matched state to anywhere, we can assume that the synthetic message
281  * will just follow the same route as the one it was created from.
282  */
283 static inline void
284 log_path_options_pop_junction(LogPathOptions *local_path_options)
285 {
286  log_path_options_pop_conditional(local_path_options);
287 
288  if (local_path_options->lpo_parent_junction)
289  local_path_options->lpo_parent_junction = local_path_options->lpo_parent_junction->lpo_parent_junction;
290 }
291 
292 typedef struct _LogPipeOptions LogPipeOptions;
293 
295 {
296  gboolean internal;
297 };
298 
299 struct _LogPipe
300 {
302  gint32 flags;
303 
304  void (*queue)(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options);
305 
306  GlobalConfig *cfg;
307  LogExprNode *expr_node;
308  LogPipe *pipe_next;
310  const gchar *persist_name;
311  gchar *plugin_name;
312  LogPipeOptions options;
313 
314  gboolean (*pre_init)(LogPipe *self);
315  gboolean (*init)(LogPipe *self);
316  gboolean (*deinit)(LogPipe *self);
317  void (*post_deinit)(LogPipe *self);
318 
319  gboolean (*pre_config_init)(LogPipe *self);
320  /* this event function is used to perform necessary operation, such as
321  * starting worker thread, and etc. therefore, syslog-ng will terminate if
322  * return value is false.
323  */
324  gboolean (*post_config_init)(LogPipe *self);
325 
326  const gchar *(*generate_persist_name)(const LogPipe *self);
327  GList *(*arcs)(LogPipe *self);
328 
329  /* clone this pipe when used in multiple locations in the processing
330  * pipe-line. If it contains state, it should behave as if it was
331  * the same instance, otherwise it can be a copy.
332  */
333  LogPipe *(*clone)(LogPipe *self);
334 
335  void (*free_fn)(LogPipe *self);
336  gint (*notify)(LogPipe *self, gint notify_code, gpointer user_data);
337  GList *info;
338 };
339 
340 /*
341  cpu-cache optimization: queue method should be as close as possible to flags.
342 
343  Rationale: the pointer pointing to this LogPipe instance is
344  resolved right before calling queue and the colocation of flags and
345  the queue pointer ensures that they are on the same cache line. The
346  queue method is probably the single most often called virtual method
347  */
348 G_STATIC_ASSERT(G_STRUCT_OFFSET(LogPipe, queue) - G_STRUCT_OFFSET(LogPipe, flags) <= 4);
349 
350 extern gboolean (*pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const LogPathOptions *path_options);
351 
352 LogPipe *log_pipe_ref(LogPipe *self);
353 gboolean log_pipe_unref(LogPipe *self);
354 LogPipe *log_pipe_new(GlobalConfig *cfg);
355 void log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg);
356 void log_pipe_clone_method(LogPipe *dst, const LogPipe *src);
357 void log_pipe_forward_notify(LogPipe *self, gint notify_code, gpointer user_data);
358 EVTTAG *log_pipe_location_tag(LogPipe *pipe);
359 void log_pipe_attach_expr_node(LogPipe *self, LogExprNode *expr_node);
360 void log_pipe_detach_expr_node(LogPipe *self);
361 
362 static inline GlobalConfig *
363 log_pipe_get_config(LogPipe *s)
364 {
365  g_assert(s->cfg);
366  return s->cfg;
367 }
368 
369 static inline void
370 log_pipe_set_config(LogPipe *s, GlobalConfig *cfg)
371 {
372  s->cfg = cfg;
373 }
374 
375 static inline void
376 log_pipe_reset_config(LogPipe *s)
377 {
378  log_pipe_set_config(s, NULL);
379 }
380 
381 static inline gboolean
382 log_pipe_init(LogPipe *s)
383 {
384  if (!(s->flags & PIF_INITIALIZED))
385  {
386  if (s->pre_init && !s->pre_init(s))
387  return FALSE;
388  if (!s->init || s->init(s))
389  {
390  s->flags |= PIF_INITIALIZED;
391  if (s->cfg)
392  cfg_tree_register_initialized_pipe(&s->cfg->tree, s);
393  return TRUE;
394  }
395  return FALSE;
396  }
397  return TRUE;
398 }
399 
400 static inline gboolean
401 log_pipe_deinit(LogPipe *s)
402 {
403  if ((s->flags & PIF_INITIALIZED))
404  {
405  if (!s->deinit || s->deinit(s))
406  {
407  s->flags &= ~PIF_INITIALIZED;
408 
409  if (s->post_deinit)
410  s->post_deinit(s);
411  if (s->cfg)
412  cfg_tree_deregister_initialized_pipe(&s->cfg->tree, s);
413  return TRUE;
414  }
415  return FALSE;
416  }
417  return TRUE;
418 }
419 
420 static inline gboolean
421 log_pipe_pre_config_init(LogPipe *s)
422 {
423  if (s->pre_config_init)
424  return s->pre_config_init(s);
425  return TRUE;
426 }
427 
428 static inline gboolean
429 log_pipe_post_config_init(LogPipe *s)
430 {
431  if (s->post_config_init)
432  return s->post_config_init(s);
433  return TRUE;
434 }
435 
436 static inline LogPipe *
437 log_pipe_clone(LogPipe *self)
438 {
439  g_assert(NULL != self->clone);
440  return self->clone(self);
441 }
442 
443 static inline gint
444 log_pipe_notify(LogPipe *s, gint notify_code, gpointer user_data)
445 {
446  if (s->notify)
447  return s->notify(s, notify_code, user_data);
448  return NR_OK;
449 }
450 
451 static inline void
452 log_pipe_append(LogPipe *s, LogPipe *next)
453 {
454  s->pipe_next = next;
455 }
456 
457 void log_pipe_set_persist_name(LogPipe *self, const gchar *persist_name);
458 const gchar *log_pipe_get_persist_name(const LogPipe *self);
459 
460 void log_pipe_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options);
461 void log_pipe_forward_msg(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options);
462 
463 void log_pipe_set_options(LogPipe *self, const LogPipeOptions *options);
464 void log_pipe_set_internal(LogPipe *self, gboolean internal);
465 gboolean log_pipe_is_internal(const LogPipe *self);
466 
467 void log_pipe_free_method(LogPipe *s);
468 
469 static inline GList *
470 log_pipe_get_arcs(LogPipe *s)
471 {
472  return s->arcs(s);
473 }
474 
475 void log_pipe_add_info(LogPipe *self, const gchar *info);
476 #endif
void cfg_tree_register_initialized_pipe(CfgTree *self, LogPipe *s)
Definition: cfg-tree.c:676
void cfg_tree_deregister_initialized_pipe(CfgTree *self, LogPipe *s)
Definition: cfg-tree.c:696
void log_pipe_forward_msg(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options)
Definition: logpipe.c:32
void log_pipe_attach_expr_node(LogPipe *self, LogExprNode *expr_node)
Definition: logpipe.c:114
#define NR_OK
Definition: logpipe.h:47
LogPipe * log_pipe_new(GlobalConfig *cfg)
Definition: logpipe.c:159
void log_pipe_forward_notify(LogPipe *self, gint notify_code, gpointer user_data)
Definition: logpipe.c:211
gboolean log_pipe_is_internal(const LogPipe *self)
Definition: logpipe.c:243
const gchar * log_pipe_get_persist_name(const LogPipe *self)
Definition: logpipe.c:224
#define PIF_INITIALIZED
Definition: logpipe.h:52
G_STATIC_ASSERT(G_STRUCT_OFFSET(LogPipe, queue) - G_STRUCT_OFFSET(LogPipe, flags)<=4)
void log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)
Definition: logpipe.c:145
void log_pipe_detach_expr_node(LogPipe *self)
Definition: logpipe.c:120
void log_pipe_add_info(LogPipe *self, const gchar *info)
Definition: logpipe.c:249
gboolean(* pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const LogPathOptions *path_options)
Definition: logpipe.c:29
void log_pipe_free_method(LogPipe *s)
Definition: logpipe.c:168
LogPipe * log_pipe_ref(LogPipe *self)
Definition: logpipe.c:174
void log_pipe_set_internal(LogPipe *self, gboolean internal)
Definition: logpipe.c:237
gboolean log_pipe_unref(LogPipe *self)
Definition: logpipe.c:197
void log_pipe_set_options(LogPipe *self, const LogPipeOptions *options)
Definition: logpipe.c:231
void log_pipe_set_persist_name(LogPipe *self, const gchar *persist_name)
Definition: logpipe.c:217
EVTTAG * log_pipe_location_tag(LogPipe *pipe)
Definition: logpipe.c:108
void log_pipe_clone_method(LogPipe *dst, const LogPipe *src)
Definition: logpipe.c:138
void log_pipe_queue(LogPipe *s, LogMessage *msg, const LogPathOptions *path_options)
Definition: logpipe.c:83
#define self
Definition: rcptid.c:38
Definition: atomic.h:31
Definition: stats-counter.h:67
Definition: logpipe.h:197
gboolean ack_needed
Definition: logpipe.h:207
const LogPathOptions * lpo_parent_junction
Definition: logpipe.h:224
gboolean flow_control_requested
Definition: logpipe.h:221
gboolean * matched
Definition: logpipe.h:223
Definition: logpipe.h:295
Definition: logpipe.h:300
void(* queue)(LogPipe *self, LogMessage *msg, const LogPathOptions *path_options)
Definition: logpipe.h:304
LogPipeOptions options
Definition: logpipe.h:312
gint32 flags
Definition: logpipe.h:302
void(* free_fn)(LogPipe *self)
Definition: logpipe.h:335
void(* post_deinit)(LogPipe *self)
Definition: logpipe.h:317
GlobalConfig * cfg
Definition: logpipe.h:306
gboolean(* pre_init)(LogPipe *self)
Definition: logpipe.h:314
GAtomicCounter ref_cnt
Definition: logpipe.h:301
gchar * plugin_name
Definition: logpipe.h:311
GList * info
Definition: logpipe.h:337
gint(* notify)(LogPipe *self, gint notify_code, gpointer user_data)
Definition: logpipe.h:336
gboolean(* deinit)(LogPipe *self)
Definition: logpipe.h:316
LogExprNode * expr_node
Definition: logpipe.h:307
StatsCounterItem * discarded_messages
Definition: logpipe.h:309
const gchar * persist_name
Definition: logpipe.h:310
gboolean(* pre_config_init)(LogPipe *self)
Definition: logpipe.h:319
gboolean(* init)(LogPipe *self)
Definition: logpipe.h:315
LogPipe * pipe_next
Definition: logpipe.h:308
gboolean(* post_config_init)(LogPipe *self)
Definition: logpipe.h:324
GlobalConfig * cfg
Definition: test_batched_ack_tracker.c:34
LogMessage * msg
Definition: test_rename.c:35
LogPathOptions path_options
Definition: test_wildcard_file_reader.c:62