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