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