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