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