pacemaker  1.1.18-7fdfbbe
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
logging.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <crm_internal.h>
20 
21 #include <sys/param.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <sys/stat.h>
25 #include <sys/utsname.h>
26 
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <limits.h>
32 #include <ctype.h>
33 #include <pwd.h>
34 #include <grp.h>
35 #include <time.h>
36 #include <libgen.h>
37 #include <signal.h>
38 #include <bzlib.h>
39 
40 #include <qb/qbdefs.h>
41 
42 #include <crm/crm.h>
43 #include <crm/common/mainloop.h>
44 
45 unsigned int crm_log_priority = LOG_NOTICE;
46 unsigned int crm_log_level = LOG_INFO;
47 static gboolean crm_tracing_enabled(void);
48 unsigned int crm_trace_nonlog = 0;
49 bool crm_is_daemon = 0;
50 
51 #ifdef HAVE_G_LOG_SET_DEFAULT_HANDLER
52 GLogFunc glib_log_default;
53 
54 static void
55 crm_glib_handler(const gchar * log_domain, GLogLevelFlags flags, const gchar * message,
56  gpointer user_data)
57 {
58  int log_level = LOG_WARNING;
59  GLogLevelFlags msg_level = (flags & G_LOG_LEVEL_MASK);
60  static struct qb_log_callsite *glib_cs = NULL;
61 
62  if (glib_cs == NULL) {
63  glib_cs = qb_log_callsite_get(__FUNCTION__, __FILE__, "glib-handler", LOG_DEBUG, __LINE__, crm_trace_nonlog);
64  }
65 
66 
67  switch (msg_level) {
68  case G_LOG_LEVEL_CRITICAL:
69  log_level = LOG_CRIT;
70 
71  if (crm_is_callsite_active(glib_cs, LOG_DEBUG, 0) == FALSE) {
72  /* log and record how we got here */
73  crm_abort(__FILE__, __FUNCTION__, __LINE__, message, TRUE, TRUE);
74  }
75  break;
76 
77  case G_LOG_LEVEL_ERROR:
78  log_level = LOG_ERR;
79  break;
80  case G_LOG_LEVEL_MESSAGE:
81  log_level = LOG_NOTICE;
82  break;
83  case G_LOG_LEVEL_INFO:
84  log_level = LOG_INFO;
85  break;
86  case G_LOG_LEVEL_DEBUG:
87  log_level = LOG_DEBUG;
88  break;
89 
90  case G_LOG_LEVEL_WARNING:
91  case G_LOG_FLAG_RECURSION:
92  case G_LOG_FLAG_FATAL:
93  case G_LOG_LEVEL_MASK:
94  log_level = LOG_WARNING;
95  break;
96  }
97 
98  do_crm_log(log_level, "%s: %s", log_domain, message);
99 }
100 #endif
101 
102 #ifndef NAME_MAX
103 # define NAME_MAX 256
104 #endif
105 
106 static void
107 crm_trigger_blackbox(int nsig)
108 {
109  if(nsig == SIGTRAP) {
110  /* Turn it on if it wasn't already */
111  crm_enable_blackbox(nsig);
112  }
113  crm_write_blackbox(nsig, NULL);
114 }
115 
116 const char *
117 daemon_option(const char *option)
118 {
119  char env_name[NAME_MAX];
120  const char *value = NULL;
121 
122  snprintf(env_name, NAME_MAX, "PCMK_%s", option);
123  value = getenv(env_name);
124  if (value != NULL) {
125  crm_trace("Found %s = %s", env_name, value);
126  return value;
127  }
128 
129  snprintf(env_name, NAME_MAX, "HA_%s", option);
130  value = getenv(env_name);
131  if (value != NULL) {
132  crm_trace("Found %s = %s", env_name, value);
133  return value;
134  }
135 
136  crm_trace("Nothing found for %s", option);
137  return NULL;
138 }
139 
140 void
141 set_daemon_option(const char *option, const char *value)
142 {
143  char env_name[NAME_MAX];
144 
145  snprintf(env_name, NAME_MAX, "PCMK_%s", option);
146  if (value) {
147  crm_trace("Setting %s to %s", env_name, value);
148  setenv(env_name, value, 1);
149  } else {
150  crm_trace("Unsetting %s", env_name);
151  unsetenv(env_name);
152  }
153 
154  snprintf(env_name, NAME_MAX, "HA_%s", option);
155  if (value) {
156  crm_trace("Setting %s to %s", env_name, value);
157  setenv(env_name, value, 1);
158  } else {
159  crm_trace("Unsetting %s", env_name);
160  unsetenv(env_name);
161  }
162 }
163 
164 gboolean
165 daemon_option_enabled(const char *daemon, const char *option)
166 {
167  const char *value = daemon_option(option);
168 
169  if (value != NULL && crm_is_true(value)) {
170  return TRUE;
171 
172  } else if (value != NULL && strstr(value, daemon)) {
173  return TRUE;
174  }
175 
176  return FALSE;
177 }
178 
179 void
181 {
182 #ifdef HAVE_G_LOG_SET_DEFAULT_HANDLER
183  g_log_set_default_handler(glib_log_default, NULL);
184 #endif
185 }
186 
187 #define FMT_MAX 256
188 static void
189 set_format_string(int method, const char *daemon)
190 {
191  int offset = 0;
192  char fmt[FMT_MAX];
193 
194  if (method > QB_LOG_STDERR) {
195  /* When logging to a file */
196  struct utsname res;
197 
198  if (uname(&res) == 0) {
199  offset +=
200  snprintf(fmt + offset, FMT_MAX - offset, "%%t [%lu] %s %10s: ",
201  (unsigned long) getpid(), res.nodename, daemon);
202  } else {
203  offset += snprintf(fmt + offset, FMT_MAX - offset, "%%t [%lu] %10s: ",
204  (unsigned long) getpid(), daemon);
205  }
206  }
207 
208  if (method == QB_LOG_SYSLOG) {
209  offset += snprintf(fmt + offset, FMT_MAX - offset, "%%g %%-7p: %%b");
210  crm_extended_logging(method, QB_FALSE);
211  } else if (crm_tracing_enabled()) {
212  offset += snprintf(fmt + offset, FMT_MAX - offset, "(%%-12f:%%5l %%g) %%-7p: %%n:\t%%b");
213  } else {
214  offset += snprintf(fmt + offset, FMT_MAX - offset, "%%g %%-7p: %%n:\t%%b");
215  }
216 
217  CRM_LOG_ASSERT(offset > 0);
218  qb_log_format_set(method, fmt);
219 }
220 
221 gboolean
222 crm_add_logfile(const char *filename)
223 {
224  bool is_default = false;
225  static int default_fd = -1;
226  static gboolean have_logfile = FALSE;
227 
228  /* @COMPAT This should be CRM_LOG_DIR "/pacemaker.log". We aren't changing
229  * it yet because it will be a significant user-visible change to publicize.
230  */
231  const char *default_logfile = "/var/log/pacemaker.log";
232 
233  struct stat parent;
234  int fd = 0, rc = 0;
235  FILE *logfile = NULL;
236  char *parent_dir = NULL;
237  char *filename_cp;
238 
239  if (filename == NULL && have_logfile == FALSE) {
240  filename = default_logfile;
241  }
242 
243  if (filename == NULL) {
244  return FALSE; /* Nothing to do */
245  } else if(safe_str_eq(filename, "none")) {
246  return FALSE; /* Nothing to do */
247  } else if(safe_str_eq(filename, "/dev/null")) {
248  return FALSE; /* Nothing to do */
249  } else if(safe_str_eq(filename, default_logfile)) {
250  is_default = TRUE;
251  }
252 
253  if(is_default && default_fd >= 0) {
254  return TRUE; /* Nothing to do */
255  }
256 
257  /* Check the parent directory */
258  filename_cp = strdup(filename);
259  parent_dir = dirname(filename_cp);
260  rc = stat(parent_dir, &parent);
261 
262  if (rc != 0) {
263  crm_err("Directory '%s' does not exist: logging to '%s' is disabled", parent_dir, filename);
264  free(filename_cp);
265  return FALSE;
266  }
267  free(filename_cp);
268 
269  errno = 0;
270  logfile = fopen(filename, "a");
271  if(logfile == NULL) {
272  crm_err("%s (%d): Logging to '%s' as uid=%u, gid=%u is disabled",
273  pcmk_strerror(errno), errno, filename, geteuid(), getegid());
274  return FALSE;
275  }
276 
277  /* Check/Set permissions if we're root */
278  if (geteuid() == 0) {
279  struct stat st;
280  uid_t pcmk_uid = 0;
281  gid_t pcmk_gid = 0;
282  gboolean fix = FALSE;
283  int logfd = fileno(logfile);
284 
285  rc = fstat(logfd, &st);
286  if (rc < 0) {
287  crm_perror(LOG_WARNING, "Cannot stat %s", filename);
288  fclose(logfile);
289  return FALSE;
290  }
291 
292  if(crm_user_lookup(CRM_DAEMON_USER, &pcmk_uid, &pcmk_gid) == 0) {
293  if (st.st_gid != pcmk_gid) {
294  /* Wrong group */
295  fix = TRUE;
296  } else if ((st.st_mode & S_IRWXG) != (S_IRGRP | S_IWGRP)) {
297  /* Not read/writable by the correct group */
298  fix = TRUE;
299  }
300  }
301 
302  if (fix) {
303  rc = fchown(logfd, pcmk_uid, pcmk_gid);
304  if (rc < 0) {
305  crm_warn("Cannot change the ownership of %s to user %s and gid %d",
306  filename, CRM_DAEMON_USER, pcmk_gid);
307  }
308 
309  rc = fchmod(logfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
310  if (rc < 0) {
311  crm_warn("Cannot change the mode of %s to rw-rw----", filename);
312  }
313 
314  fprintf(logfile, "Set r/w permissions for uid=%d, gid=%d on %s\n",
315  pcmk_uid, pcmk_gid, filename);
316  if (fflush(logfile) < 0 || fsync(logfd) < 0) {
317  crm_err("Couldn't write out logfile: %s", filename);
318  }
319  }
320  }
321 
322  /* Close and reopen with libqb */
323  fclose(logfile);
324  fd = qb_log_file_open(filename);
325 
326  if (fd < 0) {
327  crm_perror(LOG_WARNING, "Couldn't send additional logging to %s", filename);
328  return FALSE;
329  }
330 
331  if(is_default) {
332  default_fd = fd;
333 
334  } else if(default_fd >= 0) {
335  crm_notice("Switching to %s", filename);
336  qb_log_ctl(default_fd, QB_LOG_CONF_ENABLED, QB_FALSE);
337  }
338 
339  crm_notice("Additional logging available in %s", filename);
340  qb_log_ctl(fd, QB_LOG_CONF_ENABLED, QB_TRUE);
341  /* qb_log_ctl(fd, QB_LOG_CONF_FILE_SYNC, 1); Turn on synchronous writes */
342 
343  /* Enable callsites */
345  have_logfile = TRUE;
346 
347  return TRUE;
348 }
349 
350 static int blackbox_trigger = 0;
351 static char *blackbox_file_prefix = NULL;
352 
353 static void
354 blackbox_logger(int32_t t, struct qb_log_callsite *cs, time_t timestamp, const char *msg)
355 {
356  if(cs && cs->priority < LOG_ERR) {
357  crm_write_blackbox(SIGTRAP, cs); /* Bypass the over-dumping logic */
358  } else {
359  crm_write_blackbox(0, cs);
360  }
361 }
362 
363 static void
364 crm_control_blackbox(int nsig, bool enable)
365 {
366  int lpc = 0;
367 
368  if (blackbox_file_prefix == NULL) {
369  pid_t pid = getpid();
370 
371  blackbox_file_prefix = malloc(NAME_MAX);
372  snprintf(blackbox_file_prefix, NAME_MAX, "%s/%s-%lu",
373  CRM_BLACKBOX_DIR, crm_system_name, (unsigned long) pid);
374  }
375 
376  if (enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
377  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 5 * 1024 * 1024); /* Any size change drops existing entries */
378  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); /* Setting the size seems to disable it */
379 
380  /* Enable synchronous logging */
381  for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
382  qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_TRUE);
383  }
384 
385  crm_notice("Initiated blackbox recorder: %s", blackbox_file_prefix);
386 
387  /* Save to disk on abnormal termination */
388  crm_signal(SIGSEGV, crm_trigger_blackbox);
389  crm_signal(SIGABRT, crm_trigger_blackbox);
390  crm_signal(SIGILL, crm_trigger_blackbox);
391  crm_signal(SIGBUS, crm_trigger_blackbox);
392  crm_signal(SIGFPE, crm_trigger_blackbox);
393 
395 
396  blackbox_trigger = qb_log_custom_open(blackbox_logger, NULL, NULL, NULL);
397  qb_log_ctl(blackbox_trigger, QB_LOG_CONF_ENABLED, QB_TRUE);
398  crm_trace("Trigger: %d is %d %d", blackbox_trigger,
399  qb_log_ctl(blackbox_trigger, QB_LOG_CONF_STATE_GET, 0), QB_LOG_STATE_ENABLED);
400 
402 
403  } else if (!enable && qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
404  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
405 
406  /* Disable synchronous logging again when the blackbox is disabled */
407  for (lpc = QB_LOG_BLACKBOX; lpc < QB_LOG_TARGET_MAX; lpc++) {
408  qb_log_ctl(lpc, QB_LOG_CONF_FILE_SYNC, QB_FALSE);
409  }
410  }
411 }
412 
413 void
415 {
416  crm_control_blackbox(nsig, TRUE);
417 }
418 
419 void
421 {
422  crm_control_blackbox(nsig, FALSE);
423 }
424 
425 void
426 crm_write_blackbox(int nsig, struct qb_log_callsite *cs)
427 {
428  static int counter = 1;
429  static time_t last = 0;
430 
431  char buffer[NAME_MAX];
432  time_t now = time(NULL);
433 
434  if (blackbox_file_prefix == NULL) {
435  return;
436  }
437 
438  switch (nsig) {
439  case 0:
440  case SIGTRAP:
441  /* The graceful case - such as assertion failure or user request */
442 
443  if (nsig == 0 && now == last) {
444  /* Prevent over-dumping */
445  return;
446  }
447 
448  snprintf(buffer, NAME_MAX, "%s.%d", blackbox_file_prefix, counter++);
449  if (nsig == SIGTRAP) {
450  crm_notice("Blackbox dump requested, please see %s for contents", buffer);
451 
452  } else if (cs) {
453  syslog(LOG_NOTICE,
454  "Problem detected at %s:%d (%s), please see %s for additional details",
455  cs->function, cs->lineno, cs->filename, buffer);
456  } else {
457  crm_notice("Problem detected, please see %s for additional details", buffer);
458  }
459 
460  last = now;
461  qb_log_blackbox_write_to_file(buffer);
462 
463  /* Flush the existing contents
464  * A size change would also work
465  */
466  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
467  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
468  break;
469 
470  default:
471  /* Do as little as possible, just try to get what we have out
472  * We logged the filename when the blackbox was enabled
473  */
474  crm_signal(nsig, SIG_DFL);
475  qb_log_blackbox_write_to_file(blackbox_file_prefix);
476  qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
477  raise(nsig);
478  break;
479  }
480 }
481 
482 gboolean
483 crm_log_cli_init(const char *entity)
484 {
485  return crm_log_init(entity, LOG_ERR, FALSE, FALSE, 0, NULL, TRUE);
486 }
487 
488 static const char *
489 crm_quark_to_string(uint32_t tag)
490 {
491  const char *text = g_quark_to_string(tag);
492 
493  if (text) {
494  return text;
495  }
496  return "";
497 }
498 
499 static void
500 crm_log_filter_source(int source, const char *trace_files, const char *trace_fns,
501  const char *trace_fmts, const char *trace_tags, const char *trace_blackbox,
502  struct qb_log_callsite *cs)
503 {
504  if (qb_log_ctl(source, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
505  return;
506  } else if (cs->tags != crm_trace_nonlog && source == QB_LOG_BLACKBOX) {
507  /* Blackbox gets everything if enabled */
508  qb_bit_set(cs->targets, source);
509 
510  } else if (source == blackbox_trigger && blackbox_trigger > 0) {
511  /* Should this log message result in the blackbox being dumped */
512  if (cs->priority <= LOG_ERR) {
513  qb_bit_set(cs->targets, source);
514 
515  } else if (trace_blackbox) {
516  char *key = crm_strdup_printf("%s:%d", cs->function, cs->lineno);
517 
518  if (strstr(trace_blackbox, key) != NULL) {
519  qb_bit_set(cs->targets, source);
520  }
521  free(key);
522  }
523 
524  } else if (source == QB_LOG_SYSLOG) { /* No tracing to syslog */
525  if (cs->priority <= crm_log_priority && cs->priority <= crm_log_level) {
526  qb_bit_set(cs->targets, source);
527  }
528  /* Log file tracing options... */
529  } else if (cs->priority <= crm_log_level) {
530  qb_bit_set(cs->targets, source);
531  } else if (trace_files && strstr(trace_files, cs->filename) != NULL) {
532  qb_bit_set(cs->targets, source);
533  } else if (trace_fns && strstr(trace_fns, cs->function) != NULL) {
534  qb_bit_set(cs->targets, source);
535  } else if (trace_fmts && strstr(trace_fmts, cs->format) != NULL) {
536  qb_bit_set(cs->targets, source);
537  } else if (trace_tags
538  && cs->tags != 0
539  && cs->tags != crm_trace_nonlog && g_quark_to_string(cs->tags) != NULL) {
540  qb_bit_set(cs->targets, source);
541  }
542 }
543 
544 static void
545 crm_log_filter(struct qb_log_callsite *cs)
546 {
547  int lpc = 0;
548  static int need_init = 1;
549  static const char *trace_fns = NULL;
550  static const char *trace_tags = NULL;
551  static const char *trace_fmts = NULL;
552  static const char *trace_files = NULL;
553  static const char *trace_blackbox = NULL;
554 
555  if (need_init) {
556  need_init = 0;
557  trace_fns = getenv("PCMK_trace_functions");
558  trace_fmts = getenv("PCMK_trace_formats");
559  trace_tags = getenv("PCMK_trace_tags");
560  trace_files = getenv("PCMK_trace_files");
561  trace_blackbox = getenv("PCMK_trace_blackbox");
562 
563  if (trace_tags != NULL) {
564  uint32_t tag;
565  char token[500];
566  const char *offset = NULL;
567  const char *next = trace_tags;
568 
569  do {
570  offset = next;
571  next = strchrnul(offset, ',');
572  snprintf(token, sizeof(token), "%.*s", (int)(next - offset), offset);
573 
574  tag = g_quark_from_string(token);
575  crm_info("Created GQuark %u from token '%s' in '%s'", tag, token, trace_tags);
576 
577  if (next[0] != 0) {
578  next++;
579  }
580 
581  } while (next != NULL && next[0] != 0);
582  }
583  }
584 
585  cs->targets = 0; /* Reset then find targets to enable */
586  for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
587  crm_log_filter_source(lpc, trace_files, trace_fns, trace_fmts, trace_tags, trace_blackbox,
588  cs);
589  }
590 }
591 
592 gboolean
593 crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags)
594 {
595  gboolean refilter = FALSE;
596 
597  if (cs == NULL) {
598  return FALSE;
599  }
600 
601  if (cs->priority != level) {
602  cs->priority = level;
603  refilter = TRUE;
604  }
605 
606  if (cs->tags != tags) {
607  cs->tags = tags;
608  refilter = TRUE;
609  }
610 
611  if (refilter) {
612  crm_log_filter(cs);
613  }
614 
615  if (cs->targets == 0) {
616  return FALSE;
617  }
618  return TRUE;
619 }
620 
621 void
623 {
624  static gboolean log = TRUE;
625 
626  if (log) {
627  log = FALSE;
628  crm_debug
629  ("Enabling callsites based on priority=%d, files=%s, functions=%s, formats=%s, tags=%s",
630  crm_log_level, getenv("PCMK_trace_files"), getenv("PCMK_trace_functions"),
631  getenv("PCMK_trace_formats"), getenv("PCMK_trace_tags"));
632  }
633  qb_log_filter_fn_set(crm_log_filter);
634 }
635 
636 static gboolean
637 crm_tracing_enabled(void)
638 {
639  if (crm_log_level >= LOG_TRACE) {
640  return TRUE;
641  } else if (getenv("PCMK_trace_files") || getenv("PCMK_trace_functions")
642  || getenv("PCMK_trace_formats") || getenv("PCMK_trace_tags")) {
643  return TRUE;
644  }
645  return FALSE;
646 }
647 
648 static int
649 crm_priority2int(const char *name)
650 {
651  struct syslog_names {
652  const char *name;
653  int priority;
654  };
655  static struct syslog_names p_names[] = {
656  {"emerg", LOG_EMERG},
657  {"alert", LOG_ALERT},
658  {"crit", LOG_CRIT},
659  {"error", LOG_ERR},
660  {"warning", LOG_WARNING},
661  {"notice", LOG_NOTICE},
662  {"info", LOG_INFO},
663  {"debug", LOG_DEBUG},
664  {NULL, -1}
665  };
666  int lpc;
667 
668  for (lpc = 0; name != NULL && p_names[lpc].name != NULL; lpc++) {
669  if (crm_str_eq(p_names[lpc].name, name, TRUE)) {
670  return p_names[lpc].priority;
671  }
672  }
673  return crm_log_priority;
674 }
675 
676 
677 static void
678 crm_identity(const char *entity, int argc, char **argv)
679 {
680  if(crm_system_name != NULL) {
681  /* Nothing to do */
682 
683  } else if (entity) {
684  free(crm_system_name);
685  crm_system_name = strdup(entity);
686 
687  } else if (argc > 0 && argv != NULL) {
688  char *mutable = strdup(argv[0]);
689  char *modified = basename(mutable);
690 
691  if (strstr(modified, "lt-") == modified) {
692  modified += 3;
693  }
694 
695  free(crm_system_name);
696  crm_system_name = strdup(modified);
697  free(mutable);
698 
699  } else if (crm_system_name == NULL) {
700  crm_system_name = strdup("Unknown");
701  }
702 
703  setenv("PCMK_service", crm_system_name, 1);
704 }
705 
706 
707 void
708 crm_log_preinit(const char *entity, int argc, char **argv)
709 {
710  /* Configure libqb logging with nothing turned on */
711 
712  int lpc = 0;
713  int32_t qb_facility = 0;
714 
715  static bool have_logging = FALSE;
716 
717  if(have_logging == FALSE) {
718  have_logging = TRUE;
719 
720  crm_xml_init(); /* Sets buffer allocation strategy */
721 
722  if (crm_trace_nonlog == 0) {
723  crm_trace_nonlog = g_quark_from_static_string("Pacemaker non-logging tracepoint");
724  }
725 
726  umask(S_IWGRP | S_IWOTH | S_IROTH);
727 
728  /* Redirect messages from glib functions to our handler */
729 #ifdef HAVE_G_LOG_SET_DEFAULT_HANDLER
730  glib_log_default = g_log_set_default_handler(crm_glib_handler, NULL);
731 #endif
732 
733  /* and for good measure... - this enum is a bit field (!) */
734  g_log_set_always_fatal((GLogLevelFlags) 0); /*value out of range */
735 
736  /* Who do we log as */
737  crm_identity(entity, argc, argv);
738 
739  qb_facility = qb_log_facility2int("local0");
740  qb_log_init(crm_system_name, qb_facility, LOG_ERR);
741  crm_log_level = LOG_CRIT;
742 
743  /* Nuke any syslog activity until it's asked for */
744  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
745 
746  /* Set format strings and disable threading
747  * Pacemaker and threads do not mix well (due to the amount of forking)
748  */
749  qb_log_tags_stringify_fn_set(crm_quark_to_string);
750  for (lpc = QB_LOG_SYSLOG; lpc < QB_LOG_TARGET_MAX; lpc++) {
751  qb_log_ctl(lpc, QB_LOG_CONF_THREADED, QB_FALSE);
752  set_format_string(lpc, crm_system_name);
753  }
754  }
755 }
756 
757 gboolean
758 crm_log_init(const char *entity, uint8_t level, gboolean daemon, gboolean to_stderr,
759  int argc, char **argv, gboolean quiet)
760 {
761  const char *syslog_priority = NULL;
762  const char *logfile = daemon_option("logfile");
763  const char *facility = daemon_option("logfacility");
764  const char *f_copy = facility;
765 
767  crm_log_preinit(entity, argc, argv);
768 
769  if(level > crm_log_level) {
770  crm_log_level = level;
771  }
772 
773  /* Should we log to syslog */
774  if (facility == NULL) {
775  if(crm_is_daemon) {
776  facility = "daemon";
777  } else {
778  facility = "none";
779  }
780  set_daemon_option("logfacility", facility);
781  }
782 
783  if (safe_str_eq(facility, "none")) {
784  quiet = TRUE;
785 
786 
787  } else {
788  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, qb_log_facility2int(facility));
789  }
790 
791  if (daemon_option_enabled(crm_system_name, "debug")) {
792  /* Override the default setting */
793  crm_log_level = LOG_DEBUG;
794  }
795 
796  /* What lower threshold do we have for sending to syslog */
797  syslog_priority = daemon_option("logpriority");
798  if(syslog_priority) {
799  int priority = crm_priority2int(syslog_priority);
800  crm_log_priority = priority;
801  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", priority);
802  } else {
803  qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", LOG_NOTICE);
804  }
805 
806  if (!quiet) {
807  /* Nuke any syslog activity */
808  qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
809  }
810 
811  /* Should we log to stderr */
812  if (daemon_option_enabled(crm_system_name, "stderr")) {
813  /* Override the default setting */
814  to_stderr = TRUE;
815  }
816  crm_enable_stderr(to_stderr);
817 
818  /* Should we log to a file */
819  if (safe_str_eq("none", logfile)) {
820  /* No soup^Hlogs for you! */
821  } else if(crm_is_daemon) {
822  /* The daemons always get a log file, unless explicitly set to configured 'none' */
823  crm_add_logfile(logfile);
824  } else if(logfile) {
825  crm_add_logfile(logfile);
826  }
827 
830  }
831 
832  /* Summary */
833  crm_trace("Quiet: %d, facility %s", quiet, f_copy);
834  daemon_option("logfile");
835  daemon_option("logfacility");
836 
838 
839  /* Ok, now we can start logging... */
840  if (quiet == FALSE && crm_is_daemon == FALSE) {
841  crm_log_args(argc, argv);
842  }
843 
844  if (crm_is_daemon) {
845  const char *user = getenv("USER");
846 
847  if (user != NULL && safe_str_neq(user, "root") && safe_str_neq(user, CRM_DAEMON_USER)) {
848  crm_trace("Not switching to corefile directory for %s", user);
849  crm_is_daemon = FALSE;
850  }
851  }
852 
853  if (crm_is_daemon) {
854  int user = getuid();
855  const char *base = CRM_CORE_DIR;
856  struct passwd *pwent = getpwuid(user);
857 
858  if (pwent == NULL) {
859  crm_perror(LOG_ERR, "Cannot get name for uid: %d", user);
860 
861  } else if (safe_str_neq(pwent->pw_name, "root")
862  && safe_str_neq(pwent->pw_name, CRM_DAEMON_USER)) {
863  crm_trace("Don't change active directory for regular user: %s", pwent->pw_name);
864 
865  } else if (chdir(base) < 0) {
866  crm_perror(LOG_INFO, "Cannot change active directory to %s", base);
867 
868  } else {
869  crm_info("Changed active directory to %s", base);
870 #if 0
871  {
872  char path[512];
873 
874  snprintf(path, 512, "%s-%lu", crm_system_name, (unsigned long) getpid());
875  mkdir(path, 0750);
876  chdir(path);
877  crm_info("Changed active directory to %s/%s/%s", base, pwent->pw_name, path);
878  }
879 #endif
880  }
881 
882  /* Original meanings from signal(7)
883  *
884  * Signal Value Action Comment
885  * SIGTRAP 5 Core Trace/breakpoint trap
886  * SIGUSR1 30,10,16 Term User-defined signal 1
887  * SIGUSR2 31,12,17 Term User-defined signal 2
888  *
889  * Our usage is as similar as possible
890  */
893  mainloop_add_signal(SIGTRAP, crm_trigger_blackbox);
894  }
895 
896  return TRUE;
897 }
898 
899 /* returns the old value */
900 unsigned int
901 set_crm_log_level(unsigned int level)
902 {
903  unsigned int old = crm_log_level;
904 
905  crm_log_level = level;
907  crm_trace("New log level: %d", level);
908  return old;
909 }
910 
911 void
912 crm_enable_stderr(int enable)
913 {
914  if (enable && qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
915  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
917 
918  } else if (enable == FALSE) {
919  qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_FALSE);
920  }
921 }
922 
923 void
924 crm_bump_log_level(int argc, char **argv)
925 {
926  static int args = TRUE;
927  int level = crm_log_level;
928 
929  if (args && argc > 1) {
930  crm_log_args(argc, argv);
931  }
932 
933  if (qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_STATE_GET, 0) == QB_LOG_STATE_ENABLED) {
934  set_crm_log_level(level + 1);
935  }
936 
937  /* Enable after potentially logging the argstring, not before */
938  crm_enable_stderr(TRUE);
939 }
940 
941 unsigned int
943 {
944  return crm_log_level;
945 }
946 
947 #define ARGS_FMT "Invoked: %s"
948 void
949 crm_log_args(int argc, char **argv)
950 {
951  int lpc = 0;
952  int len = 0;
953  int existing_len = 0;
954  int line = __LINE__;
955  static int logged = 0;
956 
957  char *arg_string = NULL;
958 
959  if (argc == 0 || argv == NULL || logged) {
960  return;
961  }
962 
963  logged = 1;
964 
965  for (; lpc < argc; lpc++) {
966  if (argv[lpc] == NULL) {
967  break;
968  }
969 
970  len = 2 + strlen(argv[lpc]); /* +1 space, +1 EOS */
971  arg_string = realloc_safe(arg_string, len + existing_len);
972  existing_len += sprintf(arg_string + existing_len, "%s ", argv[lpc]);
973  }
974 
975  qb_log_from_external_source(__func__, __FILE__, ARGS_FMT, LOG_NOTICE, line, 0, arg_string);
976 
977  free(arg_string);
978 }
979 
980 const char *
982 {
983  int error = ABS(rc);
984 
985  switch (error) {
986  case E2BIG: return "E2BIG";
987  case EACCES: return "EACCES";
988  case EADDRINUSE: return "EADDRINUSE";
989  case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
990  case EAFNOSUPPORT: return "EAFNOSUPPORT";
991  case EAGAIN: return "EAGAIN";
992  case EALREADY: return "EALREADY";
993  case EBADF: return "EBADF";
994  case EBADMSG: return "EBADMSG";
995  case EBUSY: return "EBUSY";
996  case ECANCELED: return "ECANCELED";
997  case ECHILD: return "ECHILD";
998  case ECOMM: return "ECOMM";
999  case ECONNABORTED: return "ECONNABORTED";
1000  case ECONNREFUSED: return "ECONNREFUSED";
1001  case ECONNRESET: return "ECONNRESET";
1002  /* case EDEADLK: return "EDEADLK"; */
1003  case EDESTADDRREQ: return "EDESTADDRREQ";
1004  case EDOM: return "EDOM";
1005  case EDQUOT: return "EDQUOT";
1006  case EEXIST: return "EEXIST";
1007  case EFAULT: return "EFAULT";
1008  case EFBIG: return "EFBIG";
1009  case EHOSTDOWN: return "EHOSTDOWN";
1010  case EHOSTUNREACH: return "EHOSTUNREACH";
1011  case EIDRM: return "EIDRM";
1012  case EILSEQ: return "EILSEQ";
1013  case EINPROGRESS: return "EINPROGRESS";
1014  case EINTR: return "EINTR";
1015  case EINVAL: return "EINVAL";
1016  case EIO: return "EIO";
1017  case EISCONN: return "EISCONN";
1018  case EISDIR: return "EISDIR";
1019  case ELIBACC: return "ELIBACC";
1020  case ELOOP: return "ELOOP";
1021  case EMFILE: return "EMFILE";
1022  case EMLINK: return "EMLINK";
1023  case EMSGSIZE: return "EMSGSIZE";
1024  case EMULTIHOP: return "EMULTIHOP";
1025  case ENAMETOOLONG: return "ENAMETOOLONG";
1026  case ENETDOWN: return "ENETDOWN";
1027  case ENETRESET: return "ENETRESET";
1028  case ENETUNREACH: return "ENETUNREACH";
1029  case ENFILE: return "ENFILE";
1030  case ENOBUFS: return "ENOBUFS";
1031  case ENODATA: return "ENODATA";
1032  case ENODEV: return "ENODEV";
1033  case ENOENT: return "ENOENT";
1034  case ENOEXEC: return "ENOEXEC";
1035  case ENOKEY: return "ENOKEY";
1036  case ENOLCK: return "ENOLCK";
1037  case ENOLINK: return "ENOLINK";
1038  case ENOMEM: return "ENOMEM";
1039  case ENOMSG: return "ENOMSG";
1040  case ENOPROTOOPT: return "ENOPROTOOPT";
1041  case ENOSPC: return "ENOSPC";
1042  case ENOSR: return "ENOSR";
1043  case ENOSTR: return "ENOSTR";
1044  case ENOSYS: return "ENOSYS";
1045  case ENOTBLK: return "ENOTBLK";
1046  case ENOTCONN: return "ENOTCONN";
1047  case ENOTDIR: return "ENOTDIR";
1048  case ENOTEMPTY: return "ENOTEMPTY";
1049  case ENOTSOCK: return "ENOTSOCK";
1050  /* case ENOTSUP: return "ENOTSUP"; */
1051  case ENOTTY: return "ENOTTY";
1052  case ENOTUNIQ: return "ENOTUNIQ";
1053  case ENXIO: return "ENXIO";
1054  case EOPNOTSUPP: return "EOPNOTSUPP";
1055  case EOVERFLOW: return "EOVERFLOW";
1056  case EPERM: return "EPERM";
1057  case EPFNOSUPPORT: return "EPFNOSUPPORT";
1058  case EPIPE: return "EPIPE";
1059  case EPROTO: return "EPROTO";
1060  case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
1061  case EPROTOTYPE: return "EPROTOTYPE";
1062  case ERANGE: return "ERANGE";
1063  case EREMOTE: return "EREMOTE";
1064  case EREMOTEIO: return "EREMOTEIO";
1065 
1066  case EROFS: return "EROFS";
1067  case ESHUTDOWN: return "ESHUTDOWN";
1068  case ESPIPE: return "ESPIPE";
1069  case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
1070  case ESRCH: return "ESRCH";
1071  case ESTALE: return "ESTALE";
1072  case ETIME: return "ETIME";
1073  case ETIMEDOUT: return "ETIMEDOUT";
1074  case ETXTBSY: return "ETXTBSY";
1075  case EUNATCH: return "EUNATCH";
1076  case EUSERS: return "EUSERS";
1077  /* case EWOULDBLOCK: return "EWOULDBLOCK"; */
1078  case EXDEV: return "EXDEV";
1079 
1080 #ifdef EBADE
1081  /* Not available on OSX */
1082  case EBADE: return "EBADE";
1083  case EBADFD: return "EBADFD";
1084  case EBADSLT: return "EBADSLT";
1085  case EDEADLOCK: return "EDEADLOCK";
1086  case EBADR: return "EBADR";
1087  case EBADRQC: return "EBADRQC";
1088  case ECHRNG: return "ECHRNG";
1089 #ifdef EISNAM /* Not available on Illumos/Solaris */
1090  case EISNAM: return "EISNAM";
1091  case EKEYEXPIRED: return "EKEYEXPIRED";
1092  case EKEYREJECTED: return "EKEYREJECTED";
1093  case EKEYREVOKED: return "EKEYREVOKED";
1094 #endif
1095  case EL2HLT: return "EL2HLT";
1096  case EL2NSYNC: return "EL2NSYNC";
1097  case EL3HLT: return "EL3HLT";
1098  case EL3RST: return "EL3RST";
1099  case ELIBBAD: return "ELIBBAD";
1100  case ELIBMAX: return "ELIBMAX";
1101  case ELIBSCN: return "ELIBSCN";
1102  case ELIBEXEC: return "ELIBEXEC";
1103 #ifdef ENOMEDIUM /* Not available on Illumos/Solaris */
1104  case ENOMEDIUM: return "ENOMEDIUM";
1105  case EMEDIUMTYPE: return "EMEDIUMTYPE";
1106 #endif
1107  case ENONET: return "ENONET";
1108  case ENOPKG: return "ENOPKG";
1109  case EREMCHG: return "EREMCHG";
1110  case ERESTART: return "ERESTART";
1111  case ESTRPIPE: return "ESTRPIPE";
1112 #ifdef EUCLEAN /* Not available on Illumos/Solaris */
1113  case EUCLEAN: return "EUCLEAN";
1114 #endif
1115  case EXFULL: return "EXFULL";
1116 #endif
1117 
1118  case pcmk_err_generic: return "pcmk_err_generic";
1119  case pcmk_err_no_quorum: return "pcmk_err_no_quorum";
1120  case pcmk_err_schema_validation: return "pcmk_err_schema_validation";
1121  case pcmk_err_transform_failed: return "pcmk_err_transform_failed";
1122  case pcmk_err_old_data: return "pcmk_err_old_data";
1123  case pcmk_err_diff_failed: return "pcmk_err_diff_failed";
1124  case pcmk_err_diff_resync: return "pcmk_err_diff_resync";
1125  case pcmk_err_cib_modified: return "pcmk_err_cib_modified";
1126  case pcmk_err_cib_backup: return "pcmk_err_cib_backup";
1127  case pcmk_err_cib_save: return "pcmk_err_cib_save";
1128  case pcmk_err_cib_corrupt: return "pcmk_err_cib_corrupt";
1129  }
1130  return "Unknown";
1131 }
1132 
1133 
1134 const char *
1136 {
1137  int error = abs(rc);
1138 
1139  if (error == 0) {
1140  return "OK";
1141  } else if (error < PCMK_ERROR_OFFSET) {
1142  return strerror(error);
1143  }
1144 
1145  switch (error) {
1146  case pcmk_err_generic:
1147  return "Generic Pacemaker error";
1148  case pcmk_err_no_quorum:
1149  return "Operation requires quorum";
1151  return "Update does not conform to the configured schema";
1153  return "Schema transform failed";
1154  case pcmk_err_old_data:
1155  return "Update was older than existing configuration";
1156  case pcmk_err_diff_failed:
1157  return "Application of an update diff failed";
1158  case pcmk_err_diff_resync:
1159  return "Application of an update diff failed, requesting a full refresh";
1160  case pcmk_err_cib_modified:
1161  return "The on-disk configuration was manually modified";
1162  case pcmk_err_cib_backup:
1163  return "Could not archive the previous configuration";
1164  case pcmk_err_cib_save:
1165  return "Could not save the new configuration to disk";
1166  case pcmk_err_cib_corrupt:
1167  return "Could not parse on-disk configuration";
1168 
1170  return "Schema is already the latest available";
1171 
1172  /* The following cases will only be hit on systems for which they are non-standard */
1173  /* coverity[dead_error_condition] False positive on non-Linux */
1174  case ENOTUNIQ:
1175  return "Name not unique on network";
1176  /* coverity[dead_error_condition] False positive on non-Linux */
1177  case ECOMM:
1178  return "Communication error on send";
1179  /* coverity[dead_error_condition] False positive on non-Linux */
1180  case ELIBACC:
1181  return "Can not access a needed shared library";
1182  /* coverity[dead_error_condition] False positive on non-Linux */
1183  case EREMOTEIO:
1184  return "Remote I/O error";
1185  /* coverity[dead_error_condition] False positive on non-Linux */
1186  case EUNATCH:
1187  return "Protocol driver not attached";
1188  /* coverity[dead_error_condition] False positive on non-Linux */
1189  case ENOKEY:
1190  return "Required key not available";
1191  }
1192 
1193  crm_err("Unknown error code: %d", rc);
1194  return "Unknown error";
1195 }
1196 
1197 const char *
1199 {
1200  /* http://www.bzip.org/1.0.3/html/err-handling.html */
1201  switch (rc) {
1202  case BZ_OK:
1203  case BZ_RUN_OK:
1204  case BZ_FLUSH_OK:
1205  case BZ_FINISH_OK:
1206  case BZ_STREAM_END:
1207  return "Ok";
1208  case BZ_CONFIG_ERROR:
1209  return "libbz2 has been improperly compiled on your platform";
1210  case BZ_SEQUENCE_ERROR:
1211  return "library functions called in the wrong order";
1212  case BZ_PARAM_ERROR:
1213  return "parameter is out of range or otherwise incorrect";
1214  case BZ_MEM_ERROR:
1215  return "memory allocation failed";
1216  case BZ_DATA_ERROR:
1217  return "data integrity error is detected during decompression";
1218  case BZ_DATA_ERROR_MAGIC:
1219  return "the compressed stream does not start with the correct magic bytes";
1220  case BZ_IO_ERROR:
1221  return "error reading or writing in the compressed file";
1222  case BZ_UNEXPECTED_EOF:
1223  return "compressed file finishes before the logical end of stream is detected";
1224  case BZ_OUTBUFF_FULL:
1225  return "output data will not fit into the buffer provided";
1226  }
1227  return "Unknown error";
1228 }
1229 
1230 void
1231 crm_log_output_fn(const char *file, const char *function, int line, int level, const char *prefix,
1232  const char *output)
1233 {
1234  const char *next = NULL;
1235  const char *offset = NULL;
1236 
1237  if (output == NULL) {
1238  level = LOG_DEBUG;
1239  output = "-- empty --";
1240  }
1241 
1242  next = output;
1243  do {
1244  offset = next;
1245  next = strchrnul(offset, '\n');
1246  do_crm_log_alias(level, file, function, line, "%s [ %.*s ]", prefix,
1247  (int)(next - offset), offset);
1248  if (next[0] != 0) {
1249  next++;
1250  }
1251 
1252  } while (next != NULL && next[0] != 0);
1253 }
1254 
1255 char *
1256 crm_strdup_printf (char const *format, ...)
1257 {
1258  va_list ap;
1259  int len = 0;
1260  char *string = NULL;
1261 
1262  va_start(ap, format);
1263 
1264  len = vasprintf (&string, format, ap);
1265  CRM_ASSERT(len > 0);
1266 
1267  va_end(ap);
1268  return string;
1269 }
#define CRM_CORE_DIR
Definition: config.h:38
#define LOG_TRACE
Definition: logging.h:29
gboolean daemon_option_enabled(const char *daemon, const char *option)
Definition: logging.c:165
void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite)
Definition: logging.c:426
A dumping ground.
#define crm_notice(fmt, args...)
Definition: logging.h:250
#define ETIME
Definition: portability.h:257
void crm_enable_stderr(int enable)
Definition: logging.c:912
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:150
gboolean mainloop_add_signal(int sig, void(*dispatch)(int sig))
Definition: mainloop.c:327
const char * pcmk_strerror(int rc)
Definition: logging.c:1135
#define ENOSTR
Definition: portability.h:265
char unsigned int set_crm_log_level(unsigned int level)
Definition: logging.c:901
#define ARGS_FMT
Definition: logging.c:947
gboolean crm_log_init(const char *entity, uint8_t level, gboolean daemon, gboolean to_stderr, int argc, char **argv, gboolean quiet)
Definition: logging.c:758
#define EKEYREJECTED
Definition: portability.h:269
#define pcmk_err_old_data
Definition: error.h:49
#define pcmk_err_schema_unchanged
Definition: error.h:55
#define EREMOTEIO
Definition: portability.h:241
void crm_xml_init(void)
Definition: xml.c:5093
char * crm_system_name
Definition: utils.c:70
int crm_user_lookup(const char *name, uid_t *uid, gid_t *gid)
Definition: utils.c:433
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:150
#define do_crm_log_alias(level, file, function, line, fmt, args...)
Log a message as if it came from a different code location.
Definition: logging.h:196
uint32_t pid
Definition: internal.h:49
unsigned int crm_trace_nonlog
Definition: logging.c:48
char * strerror(int errnum)
Wrappers for and extensions to glib mainloop.
gboolean crm_log_cli_init(const char *entity)
Definition: logging.c:483
#define FMT_MAX
Definition: logging.c:187
void crm_bump_log_level(int argc, char **argv)
Definition: logging.c:924
#define pcmk_err_diff_failed
Definition: error.h:50
char uname[MAX_NAME]
Definition: internal.h:53
void crm_log_deinit(void)
Definition: logging.c:180
#define pcmk_err_diff_resync
Definition: error.h:51
#define crm_warn(fmt, args...)
Definition: logging.h:249
int daemon(int nochdir, int noclose)
#define crm_debug(fmt, args...)
Definition: logging.h:253
void crm_log_output_fn(const char *file, const char *function, int line, int level, const char *prefix, const char *output)
Definition: logging.c:1231
gboolean crm_signal(int sig, void(*dispatch)(int sig))
Definition: mainloop.c:302
#define pcmk_err_no_quorum
Definition: error.h:46
#define pcmk_err_schema_validation
Definition: error.h:47
#define crm_trace(fmt, args...)
Definition: logging.h:254
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:129
int setenv(const char *name, const char *value, int why)
#define CRM_BLACKBOX_DIR
Definition: config.h:29
void crm_enable_blackbox(int nsig)
Definition: logging.c:414
#define pcmk_err_cib_save
Definition: error.h:54
const char * pcmk_errorname(int rc)
Definition: logging.c:981
#define pcmk_err_cib_backup
Definition: error.h:53
#define pcmk_err_generic
Definition: error.h:45
#define CRM_DAEMON_USER
Definition: config.h:47
#define ECOMM
Definition: portability.h:233
#define PCMK_ERROR_OFFSET
Definition: error.h:43
void crm_log_args(int argc, char **argv)
Definition: logging.c:949
#define ENOSR
Definition: portability.h:261
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:213
#define pcmk_err_transform_failed
Definition: error.h:48
uint32_t counter
Definition: internal.h:50
void crm_log_preinit(const char *entity, int argc, char **argv)
Definition: logging.c:708
#define ENOKEY
Definition: portability.h:249
gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags)
Definition: logging.c:593
#define ELIBACC
Definition: portability.h:237
const char * daemon_option(const char *option)
Definition: logging.c:117
#define EUNATCH
Definition: portability.h:245
unsigned int get_crm_log_level(void)
Definition: logging.c:942
unsigned int crm_log_level
Definition: logging.c:46
#define ENODATA
Definition: portability.h:253
void crm_disable_blackbox(int nsig)
Definition: logging.c:420
#define crm_perror(level, fmt, args...)
Log a system error message.
Definition: logging.h:226
#define crm_err(fmt, args...)
Definition: logging.h:248
#define ENOTUNIQ
Definition: portability.h:229
#define NAME_MAX
Definition: logging.c:103
const char * bz2_strerror(int rc)
Definition: logging.c:1198
void set_daemon_option(const char *option, const char *value)
Definition: logging.c:141
#define pcmk_err_cib_modified
Definition: error.h:52
#define uint32_t
Definition: stdint.in.h:158
#define CRM_ASSERT(expr)
Definition: error.h:35
#define uint8_t
Definition: stdint.in.h:144
char * strchrnul(const char *s, int c_in)
gboolean crm_is_true(const char *s)
Definition: strings.c:165
bool crm_is_daemon
Definition: logging.c:49
unsigned int crm_log_priority
Definition: logging.c:45
#define safe_str_eq(a, b)
Definition: util.h:72
gboolean crm_add_logfile(const char *filename)
Definition: logging.c:222
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
void crm_abort(const char *file, const char *function, int line, const char *condition, gboolean do_core, gboolean do_fork)
Definition: utils.c:656
#define pcmk_err_cib_corrupt
Definition: error.h:56
void crm_update_callsites(void)
Definition: logging.c:622
#define crm_info(fmt, args...)
Definition: logging.h:251
uint64_t flags
Definition: remote.c:156
#define int32_t
Definition: stdint.in.h:157