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 */
58 const char *c_name;
59 int c_val;
60};
61
62static 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 */
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
105static int logsys_system_needs_init = LOGSYS_LOGGER_NEEDS_INIT;
106
107static struct logsys_logger logsys_loggers[LOGSYS_MAX_SUBSYS_COUNT + 1];
108
109static int32_t _logsys_config_mode_set_unlocked(int32_t subsysid, uint32_t new_mode);
110static void _logsys_config_apply_per_file(int32_t s, const char *filename);
111static void _logsys_config_apply_per_subsys(int32_t s);
112static void _logsys_subsys_filename_add (int32_t s, const char *filename);
113static void logsys_file_format_get(char* file_format, int buf_len);
114
115static char *format_buffer=NULL;
116
117static int logsys_thread_started = 0;
118
119static int logsys_blackbox_enabled = 1;
120
121static 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 */
143static 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
254static 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
275static 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
405static 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
427int _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
458{
459 int i;
460
461 i = _logsys_config_subsys_get_unlocked (subsys);
462
463 return i;
464}
465
466static 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
489int 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
508unsigned int logsys_config_mode_get (const char *subsys)
509{
510 int i;
511
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
547static void
548logsys_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
571int 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
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
692static 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;
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,
727 qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
728 QB_LOG_FILTER_FILE, filename,
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,
735 }
736}
737
738static 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
752static 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
819int 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
853void 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
911#endif
912
913 return (res);
914}
cs_error_t qb_to_cs_error(int result)
qb_to_cs_error
cs_error_t
The cs_error_t enum.
Definition corotypes.h:98
@ CS_OK
Definition corotypes.h:99
@ CS_ERR_NOT_SUPPORTED
Definition corotypes.h:117
unsigned int logsys_config_mode_get(const char *subsys)
logsys_config_mode_get
Definition logsys.c:508
int logsys_config_mode_set(const char *subsys, unsigned int mode)
logsys_config_mode_set
Definition logsys.c:489
void logsys_blackbox_set(int enable)
Definition logsys.c:853
void logsys_blackbox_prefork(void)
Definition logsys.c:863
void logsys_system_fini(void)
logsys_system_fini
Definition logsys.c:284
char * logsys_format_get(void)
logsys_format_get
Definition logsys.c:630
int logsys_config_debug_get(const char *subsys)
Return the debug flag for this subsys.
Definition logsys.c:780
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
int logsys_config_syslog_priority_set(const char *subsys, unsigned int priority)
logsys_config_syslog_priority_set
Definition logsys.c:642
void logsys_config_apply(void)
logsys_config_apply
Definition logsys.c:766
#define IPC_LOGSYS_SIZE
Definition logsys.c:80
int logsys_priority_id_get(const char *name)
logsys_priority_id_get
Definition logsys.c:819
#define LOGSYS_LOGGER_INIT_DONE
Definition logsys.c:102
int logsys_config_logfile_priority_set(const char *subsys, unsigned int priority)
logsys_config_logfile_priority_set
Definition logsys.c:667
int logsys_thread_start(void)
logsys_thread_start
Definition logsys.c:831
int logsys_config_debug_set(const char *subsys, unsigned int debug)
enabling debug, disable message priority filtering.
Definition logsys.c:795
int _logsys_config_subsys_get(const char *subsys)
_logsys_config_subsys_get
Definition logsys.c:457
int _logsys_subsys_create(const char *subsys, const char *filename)
_logsys_subsys_create
Definition logsys.c:427
int logsys_config_syslog_facility_set(const char *subsys, unsigned int facility)
per system/subsystem settings.
Definition logsys.c:635
cs_error_t logsys_reopen_log_files(void)
Definition logsys.c:875
#define MAX_FILES_PER_SUBSYS
Definition logsys.c:76
void logsys_blackbox_postfork(void)
Definition logsys.c:869
int _logsys_system_setup(const char *mainsystem, unsigned int mode, int syslog_facility, int syslog_priority)
_logsys_system_setup
Definition logsys.c:302
int logsys_format_set(const char *format)
configuration bits that can only be done for the whole system
Definition logsys.c:571
#define LOGSYS_LOGGER_NEEDS_INIT
Definition logsys.c:103
#define LOGSYS_MAX_SUBSYS_NAMELEN
Definition logsys.h:86
#define LOGSYS_DEBUG_OFF
Definition logsys.h:92
#define LOGSYS_MODE_OUTPUT_STDERR
Definition logsys.h:61
#define LOGSYS_DEBUG_TRACE
Definition logsys.h:94
#define LOGSYS_PERROR(err_num, level, fmt, args...)
The LOGSYS_PERROR macro.
Definition logsys.h:326
#define LOGSYS_DEBUG_ON
Definition logsys.h:93
#define LOGSYS_LEVEL_WARNING
Definition logsys.h:73
#define LOGSYS_MAX_PERROR_MSG_LEN
Definition logsys.h:87
#define LOGSYS_MODE_OUTPUT_FILE
Definition logsys.h:60
#define LOGSYS_MODE_OUTPUT_SYSLOG
Definition logsys.h:62
#define LOGSYS_MAX_SUBSYS_COUNT
Definition logsys.h:85
int logfile_priority
Definition logsys.c:92
int syslog_priority
Definition logsys.c:91
int32_t dirty
Definition logsys.c:98
char * files[MAX_FILES_PER_SUBSYS]
Definition logsys.c:96
unsigned int mode
Definition logsys.c:89
char subsys[LOGSYS_MAX_SUBSYS_NAMELEN]
Definition logsys.c:87
int init_status
Definition logsys.c:93
int32_t file_idx
Definition logsys.c:97
int32_t target_id
Definition logsys.c:95
char * logfile
Definition logsys.c:88
unsigned int debug
Definition logsys.c:90
const char * c_name
Definition logsys.c:58
int c_val
Definition logsys.c:59