corosync  2.4.6
logsys.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2004 MontaVista Software, Inc.
3  * Copyright (c) 2006-2012 Red Hat, Inc.
4  *
5  * Author: Steven Dake (sdake@redhat.com)
6  * Author: Lon Hohberger (lhh@redhat.com)
7  * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
8  *
9  * All rights reserved.
10  *
11  * This software licensed under BSD license, the text of which follows:
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * - Redistributions of source code must retain the above copyright notice,
17  * this list of conditions and the following disclaimer.
18  * - Redistributions in binary form must reproduce the above copyright notice,
19  * this list of conditions and the following disclaimer in the documentation
20  * and/or other materials provided with the distribution.
21  * - Neither the name of the MontaVista Software, Inc. nor the names of its
22  * contributors may be used to endorse or promote products derived from this
23  * software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <config.h>
39 
40 #include <stdint.h>
41 #include <ctype.h>
42 #include <assert.h>
43 #include <stdio.h>
44 #include <string.h>
45 
46 #include <qb/qbdefs.h>
47 #include <qb/qbutil.h>
48 #include <qb/qblog.h>
49 
50 #include <corosync/list.h>
51 #include <corosync/logsys.h>
52 
53 /*
54  * syslog prioritynames, facility names to value mapping
55  * Some C libraries build this in to their headers, but it is non-portable
56  * so logsys supplies its own version.
57  */
58 struct syslog_names {
59  const char *c_name;
60  int c_val;
61 };
62 
63 static struct syslog_names prioritynames[] =
64 {
65  { "alert", LOG_ALERT },
66  { "crit", LOG_CRIT },
67  { "debug", LOG_DEBUG },
68  { "emerg", LOG_EMERG },
69  { "err", LOG_ERR },
70  { "error", LOG_ERR },
71  { "info", LOG_INFO },
72  { "notice", LOG_NOTICE },
73  { "warning", LOG_WARNING },
74  { NULL, -1 }
75 };
76 
77 #define MAX_FILES_PER_SUBSYS 32
78 #ifdef HAVE_SMALL_MEMORY_FOOTPRINT
79 #define IPC_LOGSYS_SIZE 8192*64
80 #else
81 #define IPC_LOGSYS_SIZE 8192*1024
82 #endif
83 
84 /*
85  * need unlogical order to preserve 64bit alignment
86  */
87 struct logsys_logger {
88  char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]; /* subsystem name */
89  char *logfile; /* log to file */
90  unsigned int mode; /* subsystem mode */
91  unsigned int debug; /* debug on|off|trace */
92  int syslog_priority; /* priority */
93  int logfile_priority; /* priority to file */
94  int init_status; /* internal field to handle init queues
95  for subsystems */
96  int32_t target_id;
98  int32_t file_idx;
99  int32_t dirty;
100 };
101 
102 /* values for logsys_logger init_status */
103 #define LOGSYS_LOGGER_INIT_DONE 0
104 #define LOGSYS_LOGGER_NEEDS_INIT 1
105 
106 static int logsys_system_needs_init = LOGSYS_LOGGER_NEEDS_INIT;
107 
108 static struct logsys_logger logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT + 1];
109 
110 static pthread_mutex_t logsys_config_mutex = PTHREAD_MUTEX_INITIALIZER;
111 
112 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode);
113 static void _logsys_config_apply_per_file(int32_t s, const char *filename);
114 static void _logsys_config_apply_per_subsys(int32_t s);
115 static void _logsys_subsys_filename_add (int32_t s, const char *filename);
116 static void logsys_file_format_get(char* file_format, int buf_len);
117 
118 static char *format_buffer=NULL;
119 
120 static int logsys_thread_started = 0;
121 
122 static int logsys_blackbox_enabled = 1;
123 
124 static int _logsys_config_subsys_get_unlocked (const char *subsys)
125 {
126  unsigned int i;
127 
128  if (!subsys) {
130  }
131 
132  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
133  if (strcmp (logsys_loggers[i].subsys, subsys) == 0) {
134  return i;
135  }
136  }
137 
138  return (-1);
139 }
140 
141 
142 /*
143  * we need a version that can work when somebody else is already
144  * holding a config mutex lock or we will never get out of here
145  */
146 static int logsys_config_file_set_unlocked (
147  int subsysid,
148  const char **error_string,
149  const char *file)
150 {
151  static char error_string_response[512];
152  int i;
153  char file_format[128];
154 
155  if (logsys_loggers[subsysid].target_id > 0) {
156  int32_t f;
157  for (f = 0; f < logsys_loggers[subsysid].file_idx; f++) {
158  qb_log_filter_ctl(logsys_loggers[subsysid].target_id,
159  QB_LOG_FILTER_REMOVE,
160  QB_LOG_FILTER_FILE,
161  logsys_loggers[subsysid].files[f],
162  LOG_TRACE);
163  }
164  }
165 
166  logsys_loggers[subsysid].dirty = QB_TRUE;
167  if (file == NULL) {
168  return (0);
169  }
170 
171  if (logsys_loggers[subsysid].target_id > 0 &&
172  logsys_loggers[subsysid].logfile != NULL &&
173  strcmp(file, logsys_loggers[subsysid].logfile) == 0) {
174  return (0);
175  }
176 
177  if (strlen(file) >= PATH_MAX) {
178  snprintf (error_string_response,
179  sizeof(error_string_response),
180  "%s: logfile name exceed maximum system filename length",
181  logsys_loggers[subsysid].subsys);
182  *error_string = error_string_response;
183  return (-1);
184  }
185 
186  if (logsys_loggers[subsysid].logfile != NULL) {
187  free(logsys_loggers[subsysid].logfile);
188  logsys_loggers[subsysid].logfile = NULL;
189  }
190 
191  logsys_loggers[subsysid].logfile = strdup(file);
192 
193  if (logsys_loggers[subsysid].logfile == NULL) {
194  snprintf (error_string_response,
195  sizeof(error_string_response),
196  "Unable to allocate memory for logfile '%s'",
197  file);
198  *error_string = error_string_response;
199  return (-1);
200  }
201 
202  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
203  if ((logsys_loggers[i].logfile != NULL) &&
204  (strcmp (logsys_loggers[i].logfile, file) == 0) &&
205  (i != subsysid)) {
206  /* we have found another subsys with this config file
207  * so add a filter
208  */
209  logsys_loggers[subsysid].target_id = logsys_loggers[i].target_id;
210  return (0);
211  }
212  }
213 
214  if (logsys_loggers[subsysid].target_id > 0) {
215  int num_using_current = 0;
216  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
217  if (logsys_loggers[subsysid].target_id ==
218  logsys_loggers[i].target_id) {
219  num_using_current++;
220  }
221  }
222  if (num_using_current == 1) {
223  /* no one else is using this close it */
224  qb_log_file_close(logsys_loggers[subsysid].target_id);
225  }
226  }
227 
228  logsys_loggers[subsysid].target_id = qb_log_file_open(file);
229  if (logsys_loggers[subsysid].target_id < 0) {
230  int err = -logsys_loggers[subsysid].target_id;
231  char error_str[LOGSYS_MAX_PERROR_MSG_LEN];
232  const char *error_ptr;
233  error_ptr = qb_strerror_r(err, error_str, sizeof(error_str));
234 
235  free(logsys_loggers[subsysid].logfile);
236  logsys_loggers[subsysid].logfile = NULL;
237  snprintf (error_string_response,
238  sizeof(error_string_response),
239  "Can't open logfile '%s' for reason: %s (%d)",
240  file, error_ptr, err);
241  *error_string = error_string_response;
242  return (-1);
243  }
244  logsys_file_format_get(file_format, 128);
245  qb_log_format_set(logsys_loggers[subsysid].target_id, file_format);
246 
247  qb_log_ctl(logsys_loggers[subsysid].target_id,
248  QB_LOG_CONF_ENABLED,
249  (logsys_loggers[subsysid].mode & LOGSYS_MODE_OUTPUT_FILE));
250  if (logsys_thread_started) {
251  qb_log_ctl(logsys_loggers[subsysid].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
252  }
253 
254  return (0);
255 }
256 
257 static void logsys_subsys_init (
258  const char *subsys,
259  int subsysid)
260 {
261  if (logsys_system_needs_init == LOGSYS_LOGGER_NEEDS_INIT) {
262  logsys_loggers[subsysid].init_status =
264  } else {
265  logsys_loggers[subsysid].mode = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].mode;
266  logsys_loggers[subsysid].debug = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].debug;
267  logsys_loggers[subsysid].syslog_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].syslog_priority;
268  logsys_loggers[subsysid].logfile_priority = logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT].logfile_priority;
269  logsys_loggers[subsysid].init_status = LOGSYS_LOGGER_INIT_DONE;
270  }
271  strncpy (logsys_loggers[subsysid].subsys, subsys,
272  sizeof (logsys_loggers[subsysid].subsys));
273  logsys_loggers[subsysid].subsys[
274  sizeof (logsys_loggers[subsysid].subsys) - 1] = '\0';
275  logsys_loggers[subsysid].file_idx = 0;
276 }
277 
278 static const char *_logsys_tags_stringify(uint32_t tags)
279 {
280  if (tags == QB_LOG_TAG_LIBQB_MSG) {
281  return "QB";
282  } else {
283  return logsys_loggers[tags].subsys;
284  }
285 }
286 
288 {
289  int i;
290  int f;
291  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
292  free(logsys_loggers[i].logfile);
293  for (f = 0; f < logsys_loggers[i].file_idx; f++) {
294  free(logsys_loggers[i].files[f]);
295  }
296  }
297 
298  qb_log_fini ();
299 }
300 
301 /*
302  * Internal API - exported
303  */
304 
306  const char *mainsystem,
307  unsigned int mode,
308  int syslog_facility,
309  int syslog_priority)
310 {
311  int i;
312  int32_t fidx;
313  char tempsubsys[LOGSYS_MAX_SUBSYS_NAMELEN];
314 
315  if ((mainsystem == NULL) ||
316  (strlen(mainsystem) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
317  return -1;
318  }
319 
320  /*
321  * Setup libqb as a subsys
322  */
323  i = _logsys_subsys_create ("QB", "array.c,log.c,log_syslog.c,log_blackbox.c,log_format.c,"
324  "log_file.c,log_dcs.c,log_thread.c,ipc_shm.c,ipcs.c,ipc_us.c,loop.c,"
325  "loop_poll_epoll.c,loop_job.c,loop_poll_poll.c,loop_poll_kqueue.c,"
326  "loop_timerlist.c,loop_poll.c,ringbuffer.c,ringbuffer_helper.c,trie.c,"
327  "map.c,skiplist.c,rpl_sem.c,hdb.c,unix.c,hashtable.c,strlcpy.c,ipc_socket.c,"
328  "strchrnul.c,ipc_setup.c,strlcat.c");
329  if (i < 0) {
330  return -1;
331  }
332 
333  /*
334  * name clash
335  * _logsys_subsys_filename_add (i, "util.c");
336  */
337 
338  /*
339  * This file (logsys.c) is not exactly QB. We need tag for logsys.c if flightrecorder init
340  * fails, and QB seems to be closest.
341  */
342  _logsys_subsys_filename_add (i, "logsys.c");
343 
345 
346  pthread_mutex_lock (&logsys_config_mutex);
347 
348  snprintf(logsys_loggers[i].subsys,
350  "%s", mainsystem);
351 
352  logsys_loggers[i].mode = mode;
353  logsys_loggers[i].debug = LOGSYS_DEBUG_OFF;
354  logsys_loggers[i].file_idx = 0;
355  logsys_loggers[i].logfile_priority = syslog_priority;
356  logsys_loggers[i].syslog_priority = syslog_priority;
357 
358  qb_log_init(mainsystem, syslog_facility, syslog_priority);
359  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_STDERR) {
360  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
361  } else {
362  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
363  }
364  if (logsys_loggers[i].mode & LOGSYS_MODE_OUTPUT_SYSLOG) {
365  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
366  } else {
367  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
368  }
369  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG);
370 
371  qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD,
372  QB_LOG_FILTER_FILE, "*", LOG_TRACE);
373  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, IPC_LOGSYS_SIZE);
374  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_THREADED, QB_FALSE);
375 
376  /*
377  * Blackbox is disabled at the init and enabled later based
378  * on config (logging.blackbox) value.
379  */
380  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
381 
382  if (logsys_format_set(NULL) == -1) {
383  pthread_mutex_unlock (&logsys_config_mutex);
384 
385  return -1;
386  }
387 
388  qb_log_tags_stringify_fn_set(_logsys_tags_stringify);
389 
390  logsys_loggers[i].init_status = LOGSYS_LOGGER_INIT_DONE;
391  logsys_system_needs_init = LOGSYS_LOGGER_INIT_DONE;
392 
393  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
394  if ((strcmp (logsys_loggers[i].subsys, "") != 0) &&
395  (logsys_loggers[i].init_status ==
397  fidx = logsys_loggers[i].file_idx;
398  strncpy (tempsubsys, logsys_loggers[i].subsys,
399  sizeof (tempsubsys));
400  tempsubsys[sizeof (tempsubsys) - 1] = '\0';
401  logsys_subsys_init(tempsubsys, i);
402  logsys_loggers[i].file_idx = fidx;
403  _logsys_config_mode_set_unlocked(i, logsys_loggers[i].mode);
404  _logsys_config_apply_per_subsys(i);
405  }
406  }
407 
408  pthread_mutex_unlock (&logsys_config_mutex);
409 
410  return (0);
411 }
412 
413 
414 static void _logsys_subsys_filename_add (int32_t s, const char *filename)
415 {
416  int i;
417 
418  if (filename == NULL) {
419  return;
420  }
421  assert(logsys_loggers[s].file_idx < MAX_FILES_PER_SUBSYS);
422  assert(logsys_loggers[s].file_idx >= 0);
423 
424  for (i = 0; i < logsys_loggers[s].file_idx; i++) {
425  if (strcmp(logsys_loggers[s].files[i], filename) == 0) {
426  return;
427  }
428  }
429  logsys_loggers[s].files[logsys_loggers[s].file_idx++] = strdup(filename);
430 
431  if (logsys_system_needs_init == LOGSYS_LOGGER_INIT_DONE) {
432  _logsys_config_apply_per_file(s, filename);
433  }
434 }
435 
436 int _logsys_subsys_create (const char *subsys, const char *filename)
437 {
438  int i;
439 
440  if ((subsys == NULL) ||
441  (strlen(subsys) >= LOGSYS_MAX_SUBSYS_NAMELEN)) {
442  return -1;
443  }
444 
445  pthread_mutex_lock (&logsys_config_mutex);
446 
447  i = _logsys_config_subsys_get_unlocked (subsys);
448  if ((i > -1) && (i < LOGSYS_MAX_SUBSYS_COUNT)) {
449  _logsys_subsys_filename_add(i, filename);
450  pthread_mutex_unlock (&logsys_config_mutex);
451  return i;
452  }
453 
454  for (i = 0; i < LOGSYS_MAX_SUBSYS_COUNT; i++) {
455  if (strcmp (logsys_loggers[i].subsys, "") == 0) {
456  logsys_subsys_init(subsys, i);
457  _logsys_subsys_filename_add(i, filename);
458  break;
459  }
460  }
461 
462  if (i >= LOGSYS_MAX_SUBSYS_COUNT) {
463  i = -1;
464  }
465 
466  pthread_mutex_unlock (&logsys_config_mutex);
467  return i;
468 }
469 
470 int _logsys_config_subsys_get (const char *subsys)
471 {
472  unsigned int i;
473 
474  pthread_mutex_lock (&logsys_config_mutex);
475 
476  i = _logsys_config_subsys_get_unlocked (subsys);
477 
478  pthread_mutex_unlock (&logsys_config_mutex);
479 
480  return i;
481 }
482 
483 static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode)
484 {
485  if ( logsys_loggers[subsysid].mode == new_mode) {
486  return 0;
487  }
488  if (logsys_loggers[subsysid].target_id > 0) {
489  qb_log_ctl(logsys_loggers[subsysid].target_id,
490  QB_LOG_CONF_ENABLED,
491  (new_mode & LOGSYS_MODE_OUTPUT_FILE));
492  }
493 
494  if (subsysid == LOGSYS_MAX_SUBSYS_COUNT) {
495  qb_log_ctl(QB_LOG_STDERR,
496  QB_LOG_CONF_ENABLED,
497  (new_mode & LOGSYS_MODE_OUTPUT_STDERR));
498  qb_log_ctl(QB_LOG_SYSLOG,
499  QB_LOG_CONF_ENABLED,
500  (new_mode & LOGSYS_MODE_OUTPUT_SYSLOG));
501  }
502  logsys_loggers[subsysid].mode = new_mode;
503  return 0;
504 }
505 
506 int logsys_config_mode_set (const char *subsys, unsigned int mode)
507 {
508  int i;
509 
510  pthread_mutex_lock (&logsys_config_mutex);
511  if (subsys != NULL) {
512  i = _logsys_config_subsys_get_unlocked (subsys);
513  if (i >= 0) {
514  i = _logsys_config_mode_set_unlocked(i, mode);
515  }
516  } else {
517  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
518  _logsys_config_mode_set_unlocked(i, mode);
519  }
520  i = 0;
521  }
522 
523  pthread_mutex_unlock (&logsys_config_mutex);
524 
525  return i;
526 }
527 
528 unsigned int logsys_config_mode_get (const char *subsys)
529 {
530  int i;
531 
532  i = _logsys_config_subsys_get (subsys);
533  if (i < 0) {
534  return i;
535  }
536 
537  return logsys_loggers[i].mode;
538 }
539 
541  const char *subsys,
542  const char **error_string,
543  const char *file)
544 {
545  int i;
546  int res;
547 
548  pthread_mutex_lock (&logsys_config_mutex);
549 
550  if (subsys != NULL) {
551  i = _logsys_config_subsys_get_unlocked (subsys);
552  if (i < 0) {
553  res = i;
554  } else {
555  res = logsys_config_file_set_unlocked(i, error_string, file);
556  }
557  } else {
558  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
559  res = logsys_config_file_set_unlocked(i, error_string, file);
560  if (res < 0) {
561  break;
562  }
563  }
564  }
565 
566  pthread_mutex_unlock (&logsys_config_mutex);
567  return res;
568 }
569 
570 static void
571 logsys_file_format_get(char* file_format, int buf_len)
572 {
573  char *per_t;
574  file_format[0] = '\0';
575  per_t = strstr(format_buffer, "%t");
576  if (per_t) {
577  strcpy(file_format, "%t [%P] %H %N");
578  per_t += 2;
579  strncat(file_format, per_t, buf_len - strlen("%t [%P] %H %N"));
580  } else {
581  strcpy(file_format, "[%P] %H %N");
582  strncat(file_format, format_buffer, buf_len - strlen("[%P] %H %N"));
583  }
584 }
585 
586 int logsys_format_set (const char *format)
587 {
588  int i;
589  int c;
590  int w;
591  int reminder;
592  char syslog_format[128];
593  char file_format[128];
594 
595  if (format_buffer) {
596  free(format_buffer);
597  format_buffer = NULL;
598  }
599 
600  format_buffer = strdup(format ? format : "%7p [%6g] %b");
601  if (format_buffer == NULL) {
602  return -1;
603  }
604 
605  qb_log_format_set(QB_LOG_STDERR, format_buffer);
606 
607  logsys_file_format_get(file_format, 128);
608  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
609  if (logsys_loggers[i].target_id > 0) {
610  qb_log_format_set(logsys_loggers[i].target_id, file_format);
611  }
612  }
613 
614  /*
615  * This just goes through and remove %t and %p from
616  * the format string for syslog.
617  */
618  w = 0;
619  memset(syslog_format, '\0', sizeof(syslog_format));
620  for (c = 0; c < strlen(format_buffer); c++) {
621  if (format_buffer[c] == '%') {
622  reminder = c;
623  for (c++; c < strlen(format_buffer); c++) {
624  if (isdigit(format_buffer[c])) {
625  continue;
626  }
627  if (format_buffer[c] == 't' ||
628  format_buffer[c] == 'p') {
629  c++;
630  } else {
631  c = reminder;
632  }
633  break;
634  }
635  }
636  syslog_format[w] = format_buffer[c];
637  w++;
638  }
639  qb_log_format_set(QB_LOG_SYSLOG, syslog_format);
640 
641  return 0;
642 }
643 
644 char *logsys_format_get (void)
645 {
646  return format_buffer;
647 }
648 
650  const char *subsys,
651  unsigned int facility)
652 {
653  return qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, facility);
654 }
655 
657  const char *subsys,
658  unsigned int priority)
659 {
660  int i;
661 
662  pthread_mutex_lock (&logsys_config_mutex);
663  if (subsys != NULL) {
664  i = _logsys_config_subsys_get_unlocked (subsys);
665  if (i >= 0) {
666  logsys_loggers[i].syslog_priority = priority;
667  logsys_loggers[i].dirty = QB_TRUE;
668 
669  i = 0;
670  }
671  } else {
672  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
673  logsys_loggers[i].syslog_priority = priority;
674  logsys_loggers[i].dirty = QB_TRUE;
675  }
676  i = 0;
677  }
678  pthread_mutex_unlock (&logsys_config_mutex);
679 
680  return i;
681 }
682 
684  const char *subsys,
685  unsigned int priority)
686 {
687  int i;
688 
689  pthread_mutex_lock (&logsys_config_mutex);
690  if (subsys != NULL) {
691  i = _logsys_config_subsys_get_unlocked (subsys);
692  if (i >= 0) {
693  logsys_loggers[i].logfile_priority = priority;
694  logsys_loggers[i].dirty = QB_TRUE;
695  i = 0;
696  }
697  } else {
698  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
699  logsys_loggers[i].logfile_priority = priority;
700  logsys_loggers[i].dirty = QB_TRUE;
701  }
702  i = 0;
703  }
704  pthread_mutex_unlock (&logsys_config_mutex);
705 
706  return i;
707 }
708 
709 
710 static void _logsys_config_apply_per_file(int32_t s, const char *filename)
711 {
712  uint32_t syslog_priority = logsys_loggers[s].syslog_priority;
713  uint32_t logfile_priority = logsys_loggers[s].logfile_priority;
714 
715  qb_log_filter_ctl(s, QB_LOG_TAG_SET, QB_LOG_FILTER_FILE,
716  filename, LOG_TRACE);
717 
718  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_REMOVE,
719  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
720  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
721  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
722  if (logsys_loggers[s].target_id > 0) {
723  qb_log_filter_ctl(logsys_loggers[s].target_id,
724  QB_LOG_FILTER_REMOVE,
725  QB_LOG_FILTER_FILE, filename, LOG_TRACE);
726  }
727 
728  if (logsys_loggers[s].debug != LOGSYS_DEBUG_OFF) {
729  switch (logsys_loggers[s].debug) {
730  case LOGSYS_DEBUG_ON:
731  syslog_priority = LOG_DEBUG;
732  logfile_priority = LOG_DEBUG;
733  break;
734  case LOGSYS_DEBUG_TRACE:
735  syslog_priority = LOG_TRACE;
736  logfile_priority = LOG_TRACE;
737  break;
738  default:
739  assert(0);
740  }
741  }
742  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
743  QB_LOG_FILTER_FILE, filename,
744  syslog_priority);
745  qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
746  QB_LOG_FILTER_FILE, filename,
747  logfile_priority);
748  if (logsys_loggers[s].target_id > 0) {
749  qb_log_filter_ctl(logsys_loggers[s].target_id,
750  QB_LOG_FILTER_ADD,
751  QB_LOG_FILTER_FILE, filename,
752  logfile_priority);
753  }
754 }
755 
756 static void _logsys_config_apply_per_subsys(int32_t s)
757 {
758  int32_t f;
759  for (f = 0; f < logsys_loggers[s].file_idx; f++) {
760  _logsys_config_apply_per_file(s, logsys_loggers[s].files[f]);
761  }
762  if (logsys_loggers[s].target_id > 0) {
763  qb_log_ctl(logsys_loggers[s].target_id,
764  QB_LOG_CONF_ENABLED,
765  (logsys_loggers[s].mode & LOGSYS_MODE_OUTPUT_FILE));
766  }
767  logsys_loggers[s].dirty = QB_FALSE;
768 }
769 
770 static void _logsys_config_apply_blackbox(void) {
771  int blackbox_enable_res;
772 
773  blackbox_enable_res = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, logsys_blackbox_enabled);
774 
775  if (blackbox_enable_res < 0) {
776  LOGSYS_PERROR (-blackbox_enable_res, LOGSYS_LEVEL_WARNING,
777  "Unable to initialize log flight recorder. "\
778  "The most common cause of this error is " \
779  "not enough space on /dev/shm. Corosync will continue work, " \
780  "but blackbox will not be available");
781  }
782 }
783 
785 {
786  int32_t s;
787 
788  _logsys_config_apply_blackbox();
789 
790  for (s = 0; s <= LOGSYS_MAX_SUBSYS_COUNT; s++) {
791  if (strcmp(logsys_loggers[s].subsys, "") == 0) {
792  continue;
793  }
794  _logsys_config_apply_per_subsys(s);
795  }
796 }
797 
799  const char *subsys,
800  unsigned int debug)
801 {
802  int i;
803 
804  pthread_mutex_lock (&logsys_config_mutex);
805  if (subsys != NULL) {
806  i = _logsys_config_subsys_get_unlocked (subsys);
807  if (i >= 0) {
808  logsys_loggers[i].dirty = QB_TRUE;
809  logsys_loggers[i].debug = debug;
810  i = 0;
811  }
812  } else {
813  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
814  logsys_loggers[i].debug = debug;
815  logsys_loggers[i].dirty = QB_TRUE;
816  }
817  i = 0;
818  }
819  pthread_mutex_unlock (&logsys_config_mutex);
820 
821  return i;
822 }
823 
824 int logsys_priority_id_get (const char *name)
825 {
826  unsigned int i;
827 
828  for (i = 0; prioritynames[i].c_name != NULL; i++) {
829  if (strcasecmp(name, prioritynames[i].c_name) == 0) {
830  return (prioritynames[i].c_val);
831  }
832  }
833  return (-1);
834 }
835 
837 {
838  int i;
839  int err;
840 
841  err = qb_log_thread_start();
842  if (err != 0) {
843  return (err);
844  }
845 
846  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
847  for (i = 0; i <= LOGSYS_MAX_SUBSYS_COUNT; i++) {
848  if (logsys_loggers[i].target_id > 0) {
849  qb_log_ctl(logsys_loggers[i].target_id, QB_LOG_CONF_THREADED, QB_TRUE);
850  }
851  }
852 
853  logsys_thread_started = 1;
854 
855  return (0);
856 }
857 
858 void logsys_blackbox_set(int enable)
859 {
860 
861  pthread_mutex_lock (&logsys_config_mutex);
862 
863  logsys_blackbox_enabled = enable;
864 
865  pthread_mutex_unlock (&logsys_config_mutex);
866 }
867 
868 /*
869  * To set correct pid to qb blackbox filename after tty dettach (fork) we have to
870  * close (this function) and (if needed) reopen blackbox (logsys_blackbox_postfork function).
871  */
873 {
874 
875  (void)qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
876 }
877 
879 {
880 
881  _logsys_config_apply_blackbox();
882 }
#define LOGSYS_DEBUG_TRACE
Definition: logsys.h:92
#define LOGSYS_MAX_PERROR_MSG_LEN
Definition: logsys.h:85
char * logsys_format_get(void)
logsys_format_get
Definition: logsys.c:644
void logsys_blackbox_prefork(void)
Definition: logsys.c:872
int logsys_config_debug_set(const char *subsys, unsigned int debug)
enabling debug, disable message priority filtering.
Definition: logsys.c:798
#define IPC_LOGSYS_SIZE
Definition: logsys.c:81
int logsys_config_mode_set(const char *subsys, unsigned int mode)
logsys_config_mode_set
Definition: logsys.c:506
int logsys_thread_start(void)
logsys_thread_start
Definition: logsys.c:836
#define LOGSYS_MAX_SUBSYS_NAMELEN
Definition: logsys.h:84
int syslog_priority
Definition: logsys.c:92
#define LOGSYS_DEBUG_ON
Definition: logsys.h:91
#define LOGSYS_PERROR(err_num, level, fmt, args...)
The LOGSYS_PERROR macro.
Definition: logsys.h:314
#define LOGSYS_MODE_OUTPUT_FILE
Definition: logsys.h:58
int logsys_config_logfile_priority_set(const char *subsys, unsigned int priority)
logsys_config_logfile_priority_set
Definition: logsys.c:683
int logsys_config_syslog_priority_set(const char *subsys, unsigned int priority)
logsys_config_syslog_priority_set
Definition: logsys.c:656
int32_t target_id
Definition: logsys.c:96
int logfile_priority
Definition: logsys.c:93
void logsys_blackbox_set(int enable)
Definition: logsys.c:858
#define LOGSYS_LEVEL_WARNING
Definition: logsys.h:71
#define LOGSYS_MAX_SUBSYS_COUNT
Definition: logsys.h:83
void logsys_config_apply(void)
logsys_config_apply
Definition: logsys.c:784
int logsys_priority_id_get(const char *name)
logsys_priority_id_get
Definition: logsys.c:824
#define LOGSYS_LOGGER_NEEDS_INIT
Definition: logsys.c:104
char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]
Definition: logsys.c:88
int logsys_config_file_set(const char *subsys, const char **error_string, const char *file)
to close a logfile, just invoke this function with a NULL file or if you want to change logfile...
Definition: logsys.c:540
#define LOGSYS_MODE_OUTPUT_SYSLOG
Definition: logsys.h:60
int32_t dirty
Definition: logsys.c:99
Linked list API.
#define LOGSYS_DEBUG_OFF
Definition: logsys.h:90
int logsys_format_set(const char *format)
configuration bits that can only be done for the whole system
Definition: logsys.c:586
void logsys_system_fini(void)
logsys_system_fini
Definition: logsys.c:287
#define MAX_FILES_PER_SUBSYS
Definition: logsys.c:77
int c_val
Definition: logsys.c:60
unsigned int logsys_config_mode_get(const char *subsys)
logsys_config_mode_get
Definition: logsys.c:528
int init_status
Definition: logsys.c:94
unsigned int mode
Definition: logsys.c:90
int logsys_config_syslog_facility_set(const char *subsys, unsigned int facility)
per system/subsystem settings.
Definition: logsys.c:649
const char * c_name
Definition: logsys.c:59
#define LOGSYS_LOGGER_INIT_DONE
Definition: logsys.c:103
unsigned int debug
Definition: logsys.c:91
int32_t file_idx
Definition: logsys.c:98
int _logsys_system_setup(const char *mainsystem, unsigned int mode, int syslog_facility, int syslog_priority)
_logsys_system_setup
Definition: logsys.c:305
char * logfile
Definition: logsys.c:89
void logsys_blackbox_postfork(void)
Definition: logsys.c:878
int _logsys_subsys_create(const char *subsys, const char *filename)
_logsys_subsys_create
Definition: logsys.c:436
char * files[MAX_FILES_PER_SUBSYS]
Definition: logsys.c:97
#define LOGSYS_MODE_OUTPUT_STDERR
Definition: logsys.h:59
int _logsys_config_subsys_get(const char *subsys)
_logsys_config_subsys_get
Definition: logsys.c:470