]>
Commit | Line | Data |
---|---|---|
7b2ddfa4 SD |
1 | /* |
2 | * Copyright (c) 2002-2005 MontaVista Software, Inc. | |
8a45e2b1 | 3 | * Copyright (c) 2006-2011 Red Hat, Inc. |
7b2ddfa4 SD |
4 | * |
5 | * All rights reserved. | |
6 | * | |
46b01638 | 7 | * Author: Steven Dake (sdake@redhat.com) |
8a45e2b1 | 8 | * Jan Friesse (jfriesse@redhat.com) |
7b2ddfa4 SD |
9 | * |
10 | * This software licensed under BSD license, the text of which follows: | |
3568f266 | 11 | * |
7b2ddfa4 SD |
12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions are met: | |
14 | * | |
15 | * - Redistributions of source code must retain the above copyright notice, | |
16 | * this list of conditions and the following disclaimer. | |
17 | * - Redistributions in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the documentation | |
19 | * and/or other materials provided with the distribution. | |
20 | * - Neither the name of the MontaVista Software, Inc. nor the names of its | |
21 | * contributors may be used to endorse or promote products derived from this | |
22 | * software without specific prior written permission. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
34 | * THE POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | |
031c02f5 | 36 | |
b283ef8f FDN |
37 | #include "config.h" |
38 | ||
e1f53138 | 39 | #include <corosync/totem/totem.h> |
8ad583a5 | 40 | #include <corosync/logsys.h> |
f008cf44 | 41 | #ifdef LOGCONFIG_USE_ICMAP |
7e1c9771 | 42 | #include <corosync/icmap.h> |
b283ef8f FDN |
43 | #define MAP_KEYNAME_MAXLEN ICMAP_KEYNAME_MAXLEN |
44 | #define map_get_string(key_name, value) icmap_get_string(key_name, value) | |
45 | #else | |
46 | #include <corosync/cmap.h> | |
47 | static cmap_handle_t cmap_handle; | |
48 | static const char *main_logfile; | |
49 | #define MAP_KEYNAME_MAXLEN CMAP_KEYNAME_MAXLEN | |
50 | #define map_get_string(key_name, value) cmap_get_string(cmap_handle, key_name, value) | |
51 | #endif | |
e1f53138 | 52 | |
7b2ddfa4 | 53 | #include "util.h" |
f008cf44 | 54 | #include "logconfig.h" |
7b2ddfa4 | 55 | |
7b2ddfa4 | 56 | static char error_string_response[512]; |
bc87f196 | 57 | |
84f5c3b6 FDN |
58 | /** |
59 | * insert_into_buffer | |
60 | * @target_buffer: a buffer where to write results | |
61 | * @bufferlen: tell us the size of the buffer to avoid overflows | |
62 | * @entry: entry that needs to be added to the buffer | |
63 | * @after: can either be NULL or set to a string. | |
64 | * if NULL, @entry is prependend to logsys_format_get buffer. | |
65 | * if set, @entry is added immediately after @after. | |
66 | * | |
67 | * Since the function is specific to logsys_format_get handling, it is implicit | |
68 | * that source is logsys_format_get(); | |
69 | * | |
70 | * In case of failure, target_buffer could be left dirty. So don't trust | |
71 | * any data leftover in it. | |
72 | * | |
73 | * Searching for "after" assumes that there is only entry of "after" | |
74 | * in the source. Afterall we control the string here and for logging format | |
75 | * it makes little to no sense to have duplicate format entries. | |
76 | * | |
77 | * Returns: 0 on success, -1 on failure | |
78 | **/ | |
79 | static int insert_into_buffer( | |
80 | char *target_buffer, | |
81 | size_t bufferlen, | |
82 | const char *entry, | |
83 | const char *after) | |
84 | { | |
85 | const char *current_format = NULL; | |
86 | ||
87 | current_format = logsys_format_get(); | |
88 | ||
89 | /* if the entry is already in the format we don't add it again */ | |
90 | if (strstr(current_format, entry) != NULL) { | |
91 | return -1; | |
92 | } | |
93 | ||
94 | /* if there is no "after", simply prepend the requested entry | |
95 | * otherwise go for beautiful string manipulation.... </sarcasm> */ | |
96 | if (!after) { | |
97 | if (snprintf(target_buffer, bufferlen - 1, "%s%s", | |
98 | entry, | |
99 | current_format) >= bufferlen - 1) { | |
100 | return -1; | |
101 | } | |
102 | } else { | |
103 | const char *afterpos; | |
104 | size_t afterlen; | |
105 | size_t templen; | |
106 | ||
107 | /* check if after is contained in the format | |
108 | * and afterlen has a meaning or return an error */ | |
109 | afterpos = strstr(current_format, after); | |
110 | afterlen = strlen(after); | |
111 | if ((!afterpos) || (!afterlen)) { | |
112 | return -1; | |
113 | } | |
114 | ||
115 | templen = afterpos - current_format + afterlen; | |
116 | if (snprintf(target_buffer, templen + 1, "%s", current_format) | |
117 | >= bufferlen - 1) { | |
118 | return -1; | |
119 | } | |
120 | if (snprintf(target_buffer + templen, bufferlen - ( templen + 1 ), | |
121 | "%s%s", entry, current_format + templen) | |
122 | >= bufferlen - ( templen + 1 )) { | |
123 | return -1; | |
124 | } | |
125 | } | |
126 | return 0; | |
127 | } | |
128 | ||
c3c75acf | 129 | /* |
79dba9c5 | 130 | * format set is global specific option that |
c3c75acf FDN |
131 | * doesn't apply at system/subsystem level. |
132 | */ | |
133 | static int corosync_main_config_format_set ( | |
c3c75acf | 134 | const char **error_string) |
7b2ddfa4 | 135 | { |
c3c75acf | 136 | const char *error_reason; |
84f5c3b6 | 137 | char new_format_buffer[PATH_MAX]; |
8a45e2b1 | 138 | char *value = NULL; |
55d97fd8 | 139 | int err = 0; |
48cb28b0 | 140 | char timestamp_str_to_add[8]; |
5c257afb | 141 | |
b283ef8f | 142 | if (map_get_string("logging.fileline", &value) == CS_OK) { |
c3c75acf FDN |
143 | if (strcmp (value, "on") == 0) { |
144 | if (!insert_into_buffer(new_format_buffer, | |
145 | sizeof(new_format_buffer), | |
37e17e7a | 146 | " %f:%l", "g]")) { |
c3c75acf | 147 | err = logsys_format_set(new_format_buffer); |
7b2ddfa4 | 148 | } else |
c3c75acf FDN |
149 | if (!insert_into_buffer(new_format_buffer, |
150 | sizeof(new_format_buffer), | |
151 | "%f:%l", NULL)) { | |
152 | err = logsys_format_set(new_format_buffer); | |
64a83a76 | 153 | } |
c3c75acf FDN |
154 | } else |
155 | if (strcmp (value, "off") == 0) { | |
156 | /* nothing to do here */ | |
157 | } else { | |
158 | error_reason = "unknown value for fileline"; | |
df6b87f2 | 159 | free(value); |
c3c75acf | 160 | goto parse_error; |
64a83a76 | 161 | } |
8a45e2b1 JF |
162 | |
163 | free(value); | |
c3c75acf | 164 | } |
8a45e2b1 | 165 | |
55d97fd8 FDN |
166 | if (err) { |
167 | error_reason = "not enough memory to set logging format buffer"; | |
168 | goto parse_error; | |
169 | } | |
170 | ||
b283ef8f | 171 | if (map_get_string("logging.function_name", &value) == CS_OK) { |
c3c75acf FDN |
172 | if (strcmp (value, "on") == 0) { |
173 | if (!insert_into_buffer(new_format_buffer, | |
174 | sizeof(new_format_buffer), | |
175 | "%n:", "f:")) { | |
176 | err = logsys_format_set(new_format_buffer); | |
e2d327e5 | 177 | } else |
c3c75acf FDN |
178 | if (!insert_into_buffer(new_format_buffer, |
179 | sizeof(new_format_buffer), | |
37e17e7a | 180 | " %n", "g]")) { |
c3c75acf | 181 | err = logsys_format_set(new_format_buffer); |
64a83a76 | 182 | } |
c3c75acf FDN |
183 | } else |
184 | if (strcmp (value, "off") == 0) { | |
185 | /* nothing to do here */ | |
186 | } else { | |
187 | error_reason = "unknown value for function_name"; | |
df6b87f2 | 188 | free(value); |
c3c75acf | 189 | goto parse_error; |
64a83a76 | 190 | } |
8a45e2b1 JF |
191 | |
192 | free(value); | |
c3c75acf | 193 | } |
8a45e2b1 | 194 | |
55d97fd8 FDN |
195 | if (err) { |
196 | error_reason = "not enough memory to set logging format buffer"; | |
197 | goto parse_error; | |
198 | } | |
199 | ||
48cb28b0 JF |
200 | memset(timestamp_str_to_add, 0, sizeof(timestamp_str_to_add)); |
201 | ||
b283ef8f | 202 | if (map_get_string("logging.timestamp", &value) == CS_OK) { |
c3c75acf | 203 | if (strcmp (value, "on") == 0) { |
48cb28b0 | 204 | strcpy(timestamp_str_to_add, "%t"); |
bd2fff5b JF |
205 | #ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS |
206 | } else if (strcmp (value, "hires") == 0) { | |
48cb28b0 | 207 | strcpy(timestamp_str_to_add, "%T"); |
bd2fff5b JF |
208 | #endif |
209 | } else if (strcmp (value, "off") == 0) { | |
c3c75acf FDN |
210 | /* nothing to do here */ |
211 | } else { | |
212 | error_reason = "unknown value for timestamp"; | |
df6b87f2 | 213 | free(value); |
c3c75acf | 214 | goto parse_error; |
3568f266 | 215 | } |
8a45e2b1 JF |
216 | |
217 | free(value); | |
48cb28b0 JF |
218 | } else { |
219 | /* | |
220 | * Display hires timestamp by default, otherwise standard timestamp | |
221 | */ | |
222 | #ifdef QB_FEATURE_LOG_HIRES_TIMESTAMPS | |
223 | strcpy(timestamp_str_to_add, "%T"); | |
224 | #else | |
225 | strcpy(timestamp_str_to_add, "%t"); | |
226 | #endif | |
227 | } | |
228 | ||
229 | if(strcmp(timestamp_str_to_add, "") != 0) { | |
230 | strcat(timestamp_str_to_add, " "); | |
231 | if (insert_into_buffer(new_format_buffer, sizeof(new_format_buffer), | |
232 | timestamp_str_to_add, NULL) == 0) { | |
233 | err = logsys_format_set(new_format_buffer); | |
234 | } | |
c3c75acf FDN |
235 | } |
236 | ||
55d97fd8 FDN |
237 | if (err) { |
238 | error_reason = "not enough memory to set logging format buffer"; | |
239 | goto parse_error; | |
240 | } | |
241 | ||
c3c75acf FDN |
242 | return (0); |
243 | ||
244 | parse_error: | |
245 | *error_string = error_reason; | |
246 | ||
247 | return (-1); | |
248 | } | |
249 | ||
79dba9c5 JF |
250 | /* |
251 | * blackbox is another global specific option that | |
252 | * doesn't apply at system/subsystem level. | |
253 | */ | |
254 | static int corosync_main_config_blackbox_set ( | |
255 | const char **error_string) | |
256 | { | |
257 | const char *error_reason; | |
258 | char *value = NULL; | |
259 | ||
260 | if (map_get_string("logging.blackbox", &value) == CS_OK) { | |
261 | if (strcmp (value, "on") == 0) { | |
262 | (void)logsys_blackbox_set(QB_TRUE); | |
263 | } else if (strcmp (value, "off") == 0) { | |
264 | (void)logsys_blackbox_set(QB_FALSE); | |
265 | } else { | |
266 | error_reason = "unknown value for blackbox"; | |
267 | free(value); | |
268 | goto parse_error; | |
269 | } | |
270 | ||
271 | free(value); | |
272 | } else { | |
273 | (void)logsys_blackbox_set(QB_TRUE); | |
274 | } | |
275 | ||
276 | return (0); | |
277 | ||
278 | parse_error: | |
279 | *error_string = error_reason; | |
280 | ||
281 | return (-1); | |
282 | } | |
283 | ||
99db3567 | 284 | static int corosync_main_config_log_destination_set ( |
8a45e2b1 JF |
285 | const char *path, |
286 | const char *key, | |
99db3567 JF |
287 | const char *subsys, |
288 | const char **error_string, | |
99db3567 JF |
289 | unsigned int mode_mask, |
290 | char deprecated, | |
125848d8 | 291 | char default_value, |
99db3567 JF |
292 | const char *replacement) |
293 | { | |
294 | static char formatted_error_reason[128]; | |
8a45e2b1 | 295 | char *value = NULL; |
99db3567 | 296 | unsigned int mode; |
b283ef8f | 297 | char key_name[MAP_KEYNAME_MAXLEN]; |
99db3567 | 298 | |
b283ef8f FDN |
299 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, key); |
300 | if (map_get_string(key_name, &value) == CS_OK) { | |
99db3567 JF |
301 | if (deprecated) { |
302 | log_printf(LOGSYS_LEVEL_WARNING, | |
028c4738 | 303 | "Warning: the %s config parameter has been obsoleted." |
99db3567 | 304 | " See corosync.conf man page %s directive.", |
8a45e2b1 | 305 | key, replacement); |
99db3567 JF |
306 | } |
307 | ||
c9baa674 JF |
308 | mode = logsys_config_mode_get (subsys); |
309 | ||
a1bf354e | 310 | if (strcmp (value, "yes") == 0 || strcmp (value, "on") == 0) { |
99db3567 JF |
311 | mode |= mode_mask; |
312 | if (logsys_config_mode_set(subsys, mode) < 0) { | |
8a45e2b1 JF |
313 | sprintf (formatted_error_reason, "unable to set mode %s", key); |
314 | goto parse_error; | |
99db3567 JF |
315 | } |
316 | } else | |
a1bf354e | 317 | if (strcmp (value, "no") == 0 || strcmp (value, "off") == 0) { |
99db3567 JF |
318 | mode &= ~mode_mask; |
319 | if (logsys_config_mode_set(subsys, mode) < 0) { | |
8a45e2b1 JF |
320 | sprintf (formatted_error_reason, "unable to unset mode %s", key); |
321 | goto parse_error; | |
99db3567 JF |
322 | } |
323 | } else { | |
8a45e2b1 JF |
324 | sprintf (formatted_error_reason, "unknown value for %s", key); |
325 | goto parse_error; | |
99db3567 JF |
326 | } |
327 | } | |
f2a1fcc5 CC |
328 | /* Set to default if we are the top-level logger */ |
329 | else if (!subsys && !deprecated) { | |
330 | ||
125848d8 CC |
331 | mode = logsys_config_mode_get (subsys); |
332 | if (default_value) { | |
333 | mode |= mode_mask; | |
334 | } | |
335 | else { | |
336 | mode &= ~mode_mask; | |
337 | } | |
338 | if (logsys_config_mode_set(subsys, mode) < 0) { | |
f2a1fcc5 | 339 | sprintf (formatted_error_reason, "unable to change mode %s", key); |
125848d8 CC |
340 | goto parse_error; |
341 | } | |
342 | } | |
99db3567 | 343 | |
8a45e2b1 JF |
344 | free(value); |
345 | return (0); | |
346 | ||
347 | parse_error: | |
348 | *error_string = formatted_error_reason; | |
349 | free(value); | |
350 | return (-1); | |
99db3567 JF |
351 | } |
352 | ||
c3c75acf | 353 | static int corosync_main_config_set ( |
8a45e2b1 | 354 | const char *path, |
c3c75acf FDN |
355 | const char *subsys, |
356 | const char **error_string) | |
357 | { | |
358 | const char *error_reason = error_string_response; | |
5ff37d49 | 359 | char *value = NULL; |
6d79a218 | 360 | int mode; |
b283ef8f | 361 | char key_name[MAP_KEYNAME_MAXLEN]; |
c3c75acf FDN |
362 | |
363 | /* | |
364 | * this bit abuses the internal logsys exported API | |
365 | * to guarantee that all configured subsystems are | |
366 | * initialized too. | |
367 | * | |
368 | * using this approach avoids some headaches caused | |
369 | * by IPC and TOTEM that have a special logging | |
370 | * handling requirements | |
371 | */ | |
372 | if (subsys != NULL) { | |
37e17e7a | 373 | if (_logsys_subsys_create(subsys, NULL) < 0) { |
c3c75acf FDN |
374 | error_reason = "unable to create new logging subsystem"; |
375 | goto parse_error; | |
376 | } | |
377 | } | |
378 | ||
379 | mode = logsys_config_mode_get(subsys); | |
380 | if (mode < 0) { | |
381 | error_reason = "unable to get mode"; | |
382 | goto parse_error; | |
383 | } | |
384 | ||
8a45e2b1 | 385 | if (corosync_main_config_log_destination_set (path, "to_stderr", subsys, &error_reason, |
125848d8 | 386 | LOGSYS_MODE_OUTPUT_STDERR, 0, 1, NULL) != 0) |
99db3567 | 387 | goto parse_error; |
c3c75acf | 388 | |
8a45e2b1 | 389 | if (corosync_main_config_log_destination_set (path, "to_syslog", subsys, &error_reason, |
125848d8 | 390 | LOGSYS_MODE_OUTPUT_SYSLOG, 0, 1, NULL) != 0) |
99db3567 | 391 | goto parse_error; |
c3c75acf | 392 | |
b283ef8f FDN |
393 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_facility"); |
394 | if (map_get_string(key_name, &value) == CS_OK) { | |
c3c75acf FDN |
395 | int syslog_facility; |
396 | ||
78a5260c | 397 | syslog_facility = qb_log_facility2int(value); |
c3c75acf FDN |
398 | if (syslog_facility < 0) { |
399 | error_reason = "unknown syslog facility specified"; | |
400 | goto parse_error; | |
401 | } | |
402 | if (logsys_config_syslog_facility_set(subsys, | |
403 | syslog_facility) < 0) { | |
404 | error_reason = "unable to set syslog facility"; | |
405 | goto parse_error; | |
406 | } | |
8a45e2b1 JF |
407 | |
408 | free(value); | |
c3c75acf | 409 | } |
125848d8 CC |
410 | else { |
411 | /* Set default here in case of a reload */ | |
412 | if (logsys_config_syslog_facility_set(subsys, | |
413 | qb_log_facility2int("daemon")) < 0) { | |
414 | error_reason = "unable to set syslog facility"; | |
415 | goto parse_error; | |
416 | } | |
417 | } | |
c3c75acf | 418 | |
b283ef8f FDN |
419 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_level"); |
420 | if (map_get_string(key_name, &value) == CS_OK) { | |
c07b3bdc FDN |
421 | int syslog_priority; |
422 | ||
423 | log_printf(LOGSYS_LEVEL_WARNING, | |
028c4738 | 424 | "Warning: the syslog_level config parameter has been obsoleted." |
c07b3bdc FDN |
425 | " See corosync.conf man page syslog_priority directive."); |
426 | ||
427 | syslog_priority = logsys_priority_id_get(value); | |
df6b87f2 JF |
428 | free(value); |
429 | ||
c07b3bdc FDN |
430 | if (syslog_priority < 0) { |
431 | error_reason = "unknown syslog level specified"; | |
432 | goto parse_error; | |
433 | } | |
434 | if (logsys_config_syslog_priority_set(subsys, | |
435 | syslog_priority) < 0) { | |
436 | error_reason = "unable to set syslog level"; | |
437 | goto parse_error; | |
438 | } | |
439 | } | |
440 | ||
b283ef8f FDN |
441 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "syslog_priority"); |
442 | if (map_get_string(key_name, &value) == CS_OK) { | |
c3c75acf FDN |
443 | int syslog_priority; |
444 | ||
445 | syslog_priority = logsys_priority_id_get(value); | |
df6b87f2 | 446 | free(value); |
c3c75acf FDN |
447 | if (syslog_priority < 0) { |
448 | error_reason = "unknown syslog priority specified"; | |
449 | goto parse_error; | |
450 | } | |
451 | if (logsys_config_syslog_priority_set(subsys, | |
452 | syslog_priority) < 0) { | |
453 | error_reason = "unable to set syslog priority"; | |
454 | goto parse_error; | |
455 | } | |
456 | } | |
d2a5e144 | 457 | else if(strcmp(key_name, "logging.syslog_priority") == 0){ |
125848d8 CC |
458 | if (logsys_config_syslog_priority_set(subsys, |
459 | logsys_priority_id_get("info")) < 0) { | |
460 | error_reason = "unable to set syslog level"; | |
461 | goto parse_error; | |
462 | } | |
463 | } | |
c3c75acf | 464 | |
f008cf44 | 465 | #ifdef LOGCONFIG_USE_ICMAP |
b283ef8f FDN |
466 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "logfile"); |
467 | if (map_get_string(key_name, &value) == CS_OK) { | |
a80febda | 468 | if (logsys_config_file_set (subsys, &error_reason, value) < 0) { |
c3c75acf FDN |
469 | goto parse_error; |
470 | } | |
8a45e2b1 | 471 | free(value); |
c3c75acf | 472 | } |
b283ef8f FDN |
473 | #else |
474 | if (!subsys) { | |
475 | if (logsys_config_file_set (subsys, &error_reason, main_logfile) < 0) { | |
476 | goto parse_error; | |
477 | } | |
478 | } | |
479 | #endif | |
c3c75acf | 480 | |
8a45e2b1 | 481 | if (corosync_main_config_log_destination_set (path, "to_file", subsys, &error_reason, |
125848d8 | 482 | LOGSYS_MODE_OUTPUT_FILE, 1, 0, "to_logfile") != 0) |
8a45e2b1 JF |
483 | goto parse_error; |
484 | ||
485 | if (corosync_main_config_log_destination_set (path, "to_logfile", subsys, &error_reason, | |
125848d8 | 486 | LOGSYS_MODE_OUTPUT_FILE, 0, 0, NULL) != 0) |
0e58141a AS |
487 | goto parse_error; |
488 | ||
b283ef8f FDN |
489 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "logfile_priority"); |
490 | if (map_get_string(key_name, &value) == CS_OK) { | |
c3c75acf FDN |
491 | int logfile_priority; |
492 | ||
493 | logfile_priority = logsys_priority_id_get(value); | |
df6b87f2 | 494 | free(value); |
c3c75acf FDN |
495 | if (logfile_priority < 0) { |
496 | error_reason = "unknown logfile priority specified"; | |
497 | goto parse_error; | |
498 | } | |
499 | if (logsys_config_logfile_priority_set(subsys, | |
500 | logfile_priority) < 0) { | |
501 | error_reason = "unable to set logfile priority"; | |
a549daed JM |
502 | goto parse_error; |
503 | } | |
c3c75acf | 504 | } |
d2a5e144 | 505 | else if(strcmp(key_name,"logging.logfile_priority") == 0){ |
125848d8 CC |
506 | if (logsys_config_logfile_priority_set(subsys, |
507 | logsys_priority_id_get("info")) < 0) { | |
508 | error_reason = "unable to set syslog level"; | |
509 | goto parse_error; | |
510 | } | |
511 | } | |
dbca1c61 | 512 | |
b283ef8f FDN |
513 | snprintf(key_name, MAP_KEYNAME_MAXLEN, "%s.%s", path, "debug"); |
514 | if (map_get_string(key_name, &value) == CS_OK) { | |
57176550 JF |
515 | if (strcmp (value, "trace") == 0) { |
516 | if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_TRACE) < 0) { | |
517 | error_reason = "unable to set debug trace"; | |
df6b87f2 | 518 | free(value); |
57176550 JF |
519 | goto parse_error; |
520 | } | |
521 | } else | |
c3c75acf | 522 | if (strcmp (value, "on") == 0) { |
57176550 | 523 | if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_ON) < 0) { |
c3c75acf | 524 | error_reason = "unable to set debug on"; |
df6b87f2 | 525 | free(value); |
c3c75acf FDN |
526 | goto parse_error; |
527 | } | |
528 | } else | |
529 | if (strcmp (value, "off") == 0) { | |
57176550 | 530 | if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_OFF) < 0) { |
c3c75acf | 531 | error_reason = "unable to set debug off"; |
df6b87f2 | 532 | free(value); |
c3c75acf FDN |
533 | goto parse_error; |
534 | } | |
535 | } else { | |
536 | error_reason = "unknown value for debug"; | |
df6b87f2 | 537 | free(value); |
c3c75acf | 538 | goto parse_error; |
dbca1c61 | 539 | } |
8a45e2b1 | 540 | free(value); |
c3c75acf | 541 | } |
125848d8 CC |
542 | else { |
543 | if (logsys_config_debug_set (subsys, LOGSYS_DEBUG_OFF) < 0) { | |
544 | error_reason = "unable to set debug off"; | |
125848d8 CC |
545 | goto parse_error; |
546 | } | |
547 | } | |
c3c75acf | 548 | |
c3c75acf FDN |
549 | return (0); |
550 | ||
551 | parse_error: | |
552 | *error_string = error_reason; | |
553 | ||
554 | return (-1); | |
555 | } | |
556 | ||
557 | static int corosync_main_config_read_logging ( | |
c3c75acf FDN |
558 | const char **error_string) |
559 | { | |
c3c75acf | 560 | const char *error_reason; |
f008cf44 | 561 | #ifdef LOGCONFIG_USE_ICMAP |
8a45e2b1 JF |
562 | icmap_iter_t iter; |
563 | const char *key_name; | |
b283ef8f FDN |
564 | #else |
565 | cmap_iter_handle_t iter; | |
566 | char key_name[CMAP_KEYNAME_MAXLEN]; | |
567 | #endif | |
568 | char key_subsys[MAP_KEYNAME_MAXLEN]; | |
569 | char key_item[MAP_KEYNAME_MAXLEN]; | |
8a45e2b1 | 570 | int res; |
c3c75acf | 571 | |
8a45e2b1 JF |
572 | /* format set is supported only for toplevel */ |
573 | if (corosync_main_config_format_set(&error_reason) < 0) { | |
574 | goto parse_error; | |
575 | } | |
c3c75acf | 576 | |
79dba9c5 JF |
577 | if (corosync_main_config_blackbox_set(&error_reason) < 0) { |
578 | goto parse_error; | |
579 | } | |
580 | ||
8a45e2b1 JF |
581 | if (corosync_main_config_set ("logging", NULL, &error_reason) < 0) { |
582 | goto parse_error; | |
583 | } | |
c3c75acf | 584 | |
8a45e2b1 JF |
585 | /* |
586 | * we will need 2 of these to compensate for new logging | |
587 | * config format | |
588 | */ | |
f008cf44 | 589 | #ifdef LOGCONFIG_USE_ICMAP |
8a45e2b1 JF |
590 | iter = icmap_iter_init("logging.logger_subsys."); |
591 | while ((key_name = icmap_iter_next(iter, NULL, NULL)) != NULL) { | |
b283ef8f FDN |
592 | #else |
593 | cmap_iter_init(cmap_handle, "logging.logger_subsys.", &iter); | |
594 | while ((cmap_iter_next(cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) { | |
595 | #endif | |
8a45e2b1 | 596 | res = sscanf(key_name, "logging.logger_subsys.%[^.].%s", key_subsys, key_item); |
c3c75acf | 597 | |
8a45e2b1 JF |
598 | if (res != 2) { |
599 | continue ; | |
c3c75acf FDN |
600 | } |
601 | ||
8a45e2b1 JF |
602 | if (strcmp(key_item, "subsys") != 0) { |
603 | continue ; | |
c3c75acf | 604 | } |
8a45e2b1 | 605 | |
cc81696f JF |
606 | if (snprintf(key_item, MAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s", |
607 | key_subsys) >= MAP_KEYNAME_MAXLEN) { | |
608 | /* | |
609 | * This should never happen | |
610 | */ | |
611 | error_reason = "Can't snprintf logger_subsys key_item"; | |
612 | goto parse_error; | |
613 | } | |
8a45e2b1 JF |
614 | |
615 | if (corosync_main_config_set(key_item, key_subsys, &error_reason) < 0) { | |
616 | goto parse_error; | |
f50a6a11 | 617 | } |
3568f266 | 618 | } |
f008cf44 | 619 | #ifdef LOGCONFIG_USE_ICMAP |
8a45e2b1 | 620 | icmap_iter_finalize(iter); |
b283ef8f FDN |
621 | #else |
622 | cmap_iter_finalize(cmap_handle, iter); | |
623 | #endif | |
5c257afb | 624 | |
37e17e7a | 625 | logsys_config_apply(); |
f5467e33 CC |
626 | return 0; |
627 | ||
628 | parse_error: | |
c3c75acf | 629 | *error_string = error_reason; |
f5467e33 | 630 | |
f5467e33 CC |
631 | return (-1); |
632 | } | |
633 | ||
f008cf44 | 634 | #ifdef LOGCONFIG_USE_ICMAP |
8a45e2b1 JF |
635 | static void main_logging_notify( |
636 | int32_t event, | |
637 | const char *key_name, | |
638 | struct icmap_notify_value new_val, | |
639 | struct icmap_notify_value old_val, | |
640 | void *user_data) | |
b283ef8f FDN |
641 | #else |
642 | static void main_logging_notify( | |
643 | cmap_handle_t cmap_handle_unused, | |
644 | cmap_handle_t cmap_track_handle_unused, | |
645 | int32_t event, | |
646 | const char *key_name, | |
647 | struct cmap_notify_value new_val, | |
648 | struct cmap_notify_value old_val, | |
649 | void *user_data) | |
650 | #endif | |
c3c75acf FDN |
651 | { |
652 | const char *error_string; | |
1a046793 CC |
653 | static int reload_in_progress = 0; |
654 | ||
655 | /* If a full reload happens then suspend updates for individual keys until | |
656 | * it's all completed | |
657 | */ | |
658 | if (strcmp(key_name, "config.reload_in_progress") == 0) { | |
659 | if (*(uint8_t *)new_val.data == 1) { | |
660 | reload_in_progress = 1; | |
661 | } else { | |
662 | reload_in_progress = 0; | |
663 | } | |
664 | } | |
665 | if (reload_in_progress) { | |
666 | log_printf(LOGSYS_LEVEL_DEBUG, "Ignoring key change, reload in progress. %s\n", key_name); | |
667 | return; | |
668 | } | |
c3c75acf | 669 | |
8a45e2b1 JF |
670 | /* |
671 | * Reload the logsys configuration | |
672 | */ | |
673 | if (logsys_format_set(NULL) == -1) { | |
674 | fprintf (stderr, "Unable to setup logging format.\n"); | |
c3c75acf | 675 | } |
8a45e2b1 | 676 | corosync_main_config_read_logging(&error_string); |
c3c75acf FDN |
677 | } |
678 | ||
f008cf44 | 679 | #ifdef LOGCONFIG_USE_ICMAP |
8a45e2b1 | 680 | static void add_logsys_config_notification(void) |
c3c75acf | 681 | { |
2967ad3b | 682 | icmap_track_t icmap_track = NULL; |
c3c75acf | 683 | |
8a45e2b1 JF |
684 | icmap_track_add("logging.", |
685 | ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX, | |
686 | main_logging_notify, | |
687 | NULL, | |
688 | &icmap_track); | |
1a046793 CC |
689 | |
690 | icmap_track_add("config.reload_in_progress", | |
691 | ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY, | |
692 | main_logging_notify, | |
693 | NULL, | |
694 | &icmap_track); | |
ae229831 | 695 | } |
b283ef8f FDN |
696 | #else |
697 | static void add_logsys_config_notification(void) | |
698 | { | |
699 | cmap_track_handle_t cmap_track; | |
700 | ||
701 | cmap_track_add(cmap_handle, "logging.", | |
702 | CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX, | |
703 | main_logging_notify, | |
704 | NULL, | |
705 | &cmap_track); | |
1a046793 CC |
706 | |
707 | cmap_track_add(cmap_handle, "config.reload_in_progress", | |
708 | CMAP_TRACK_ADD | CMAP_TRACK_MODIFY, | |
709 | main_logging_notify, | |
710 | NULL, | |
711 | &cmap_track); | |
b283ef8f FDN |
712 | } |
713 | #endif | |
ae229831 | 714 | |
f008cf44 FDN |
715 | int corosync_log_config_read ( |
716 | #ifndef LOGCONFIG_USE_ICMAP | |
b283ef8f FDN |
717 | cmap_handle_t cmap_h, |
718 | const char *default_logfile, | |
719 | #endif | |
bc87f196 | 720 | const char **error_string) |
f5467e33 | 721 | { |
9e2fa013 | 722 | const char *error_reason = error_string_response; |
f5467e33 | 723 | |
f008cf44 | 724 | #ifndef LOGCONFIG_USE_ICMAP |
b283ef8f FDN |
725 | if (!cmap_h) { |
726 | error_reason = "No cmap handle"; | |
727 | return (-1); | |
728 | } | |
729 | if (!default_logfile) { | |
730 | error_reason = "No default logfile"; | |
731 | return (-1); | |
732 | } | |
733 | cmap_handle = cmap_h; | |
734 | main_logfile = default_logfile; | |
735 | #endif | |
736 | ||
8a45e2b1 | 737 | if (corosync_main_config_read_logging(error_string) < 0) { |
c3c75acf FDN |
738 | error_reason = *error_string; |
739 | goto parse_error; | |
740 | } | |
f5467e33 | 741 | |
8a45e2b1 | 742 | add_logsys_config_notification(); |
f5467e33 | 743 | |
3568f266 | 744 | return 0; |
7b2ddfa4 SD |
745 | |
746 | parse_error: | |
870046d0 | 747 | snprintf (error_string_response, sizeof(error_string_response), |
3568f266 PC |
748 | "parse error in config: %s.\n", |
749 | error_reason); | |
750 | ||
7b2ddfa4 | 751 | *error_string = error_string_response; |
7b2ddfa4 SD |
752 | return (-1); |
753 | } |