Changeset 988 for vendor/current/lib/util/debug.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/util/debug.c
r860 r988 20 20 */ 21 21 22 #include "includes.h" 22 #include "replace.h" 23 #include <talloc.h> 23 24 #include "system/filesys.h" 24 25 #include "system/syslog.h" 25 #include "lib/util/time.h" 26 #include "system/locale.h" 27 #include "time_basic.h" 28 #include "close_low_fd.h" 29 #include "memory.h" 30 #include "samba_util.h" /* LIST_SEP */ 31 #include "debug.h" 26 32 27 33 /* define what facility to use for syslog */ … … 32 38 /* -------------------------------------------------------------------------- ** 33 39 * Defines... 34 *35 * FORMAT_BUFR_MAX - Index of the last byte of the format buffer;36 * format_bufr[FORMAT_BUFR_MAX] should always be reserved37 * for a terminating null byte.38 40 */ 39 41 42 /* 43 * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved 44 * for a terminating null byte. 45 */ 40 46 #define FORMAT_BUFR_SIZE 1024 41 #define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)42 47 43 48 /* -------------------------------------------------------------------------- ** … … 89 94 struct debug_settings settings; 90 95 char *debugf; 96 debug_callback_fn callback; 97 void *callback_private; 91 98 } state = { 92 99 .settings = { 93 100 .timestamp_logs = true 94 } 101 }, 102 .fd = 2 /* stderr by default */ 95 103 }; 104 105 #if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL) 106 static int debug_level_to_priority(int level) 107 { 108 /* 109 * map debug levels to syslog() priorities 110 */ 111 static const int priority_map[] = { 112 LOG_ERR, /* 0 */ 113 LOG_WARNING, /* 1 */ 114 LOG_NOTICE, /* 2 */ 115 LOG_NOTICE, /* 3 */ 116 LOG_NOTICE, /* 4 */ 117 LOG_NOTICE, /* 5 */ 118 LOG_INFO, /* 6 */ 119 LOG_INFO, /* 7 */ 120 LOG_INFO, /* 8 */ 121 LOG_INFO, /* 9 */ 122 }; 123 int priority; 124 125 if( level >= ARRAY_SIZE(priority_map) || level < 0) 126 priority = LOG_DEBUG; 127 else 128 priority = priority_map[level]; 129 130 return priority; 131 } 132 #endif 133 134 /* -------------------------------------------------------------------------- ** 135 * Debug backends. When logging to DEBUG_FILE, send the log entries to 136 * all active backends. 137 */ 138 139 static void debug_file_log(int msg_level, 140 const char *msg, const char *msg_no_nl) 141 { 142 check_log_size(); 143 write(state.fd, msg, strlen(msg)); 144 } 145 146 #ifdef WITH_SYSLOG 147 static void debug_syslog_reload(bool enabled, bool previously_enabled, 148 const char *prog_name) 149 { 150 if (enabled && !previously_enabled) { 151 #ifdef LOG_DAEMON 152 openlog(prog_name, LOG_PID, SYSLOG_FACILITY); 153 #else 154 /* for old systems that have no facility codes. */ 155 openlog(prog_name, LOG_PID ); 156 #endif 157 return; 158 } 159 160 if (!enabled && previously_enabled) { 161 closelog(); 162 } 163 } 164 165 static void debug_syslog_log(int msg_level, 166 const char *msg, const char *msg_no_nl) 167 { 168 int priority; 169 170 priority = debug_level_to_priority(msg_level); 171 172 /* 173 * Specify the facility to interoperate with other syslog 174 * callers (vfs_full_audit for example). 175 */ 176 priority |= SYSLOG_FACILITY; 177 178 syslog(priority, "%s", msg); 179 } 180 #endif /* WITH_SYSLOG */ 181 182 #ifdef HAVE_LIBSYSTEMD_JOURNAL 183 #include <systemd/sd-journal.h> 184 static void debug_systemd_log(int msg_level, 185 const char *msg, const char *msg_no_nl) 186 { 187 sd_journal_send("MESSAGE=%s", msg_no_nl, 188 "PRIORITY=%d", debug_level_to_priority(msg_level), 189 "LEVEL=%d", msg_level, 190 NULL); 191 } 192 #endif 193 194 #ifdef HAVE_LTTNG_TRACEF 195 #include <lttng/tracef.h> 196 static void debug_lttng_log(int msg_level, 197 const char *msg, const char *msg_no_nl) 198 { 199 tracef(msg_no_nl); 200 } 201 #endif /* WITH_LTTNG_TRACEF */ 202 203 #ifdef HAVE_GPFS 204 #include "gpfswrap.h" 205 static void debug_gpfs_reload(bool enabled, bool previously_enabled, 206 const char *prog_name) 207 { 208 gpfswrap_init(); 209 210 if (enabled && !previously_enabled) { 211 gpfswrap_init_trace(); 212 return; 213 } 214 215 if (!enabled && previously_enabled) { 216 gpfswrap_fini_trace(); 217 return; 218 } 219 220 if (enabled) { 221 /* 222 * Trigger GPFS library to adjust state if necessary. 223 */ 224 gpfswrap_query_trace(); 225 } 226 } 227 228 static void debug_gpfs_log(int msg_level, 229 const char *msg, const char *msg_no_nl) 230 { 231 gpfswrap_add_trace(msg_level, msg_no_nl); 232 } 233 #endif /* HAVE_GPFS */ 234 235 static struct debug_backend { 236 const char *name; 237 int log_level; 238 int new_log_level; 239 void (*reload)(bool enabled, bool prev_enabled, const char *prog_name); 240 void (*log)(int msg_level, const char *msg, const char *msg_no_nl); 241 } debug_backends[] = { 242 { 243 .name = "file", 244 .log = debug_file_log, 245 }, 246 #ifdef WITH_SYSLOG 247 { 248 .name = "syslog", 249 .reload = debug_syslog_reload, 250 .log = debug_syslog_log, 251 }, 252 #endif 253 254 #ifdef HAVE_LIBSYSTEMD_JOURNAL 255 { 256 .name = "systemd", 257 .log = debug_systemd_log, 258 }, 259 #endif 260 261 #ifdef HAVE_LTTNG_TRACEF 262 { 263 .name = "lttng", 264 .log = debug_lttng_log, 265 }, 266 #endif 267 268 #ifdef HAVE_GPFS 269 { 270 .name = "gpfs", 271 .reload = debug_gpfs_reload, 272 .log = debug_gpfs_log, 273 }, 274 #endif 275 }; 276 277 static struct debug_backend *debug_find_backend(const char *name) 278 { 279 int i; 280 281 for (i = 0; i < ARRAY_SIZE(debug_backends); i++) { 282 if (strcmp(name, debug_backends[i].name) == 0) { 283 return &debug_backends[i]; 284 } 285 } 286 287 return NULL; 288 } 289 290 /* 291 * parse "backend[:option][@loglevel] 292 */ 293 static void debug_backend_parse_token(char *tok) 294 { 295 char *backend_name_option, *backend_name,*backend_level, *saveptr; 296 struct debug_backend *b; 297 298 /* 299 * First parse into backend[:option] and loglevel 300 */ 301 backend_name_option = strtok_r(tok, "@\0", &saveptr); 302 if (backend_name_option == NULL) { 303 return; 304 } 305 306 backend_level = strtok_r(NULL, "\0", &saveptr); 307 308 /* 309 * Now parse backend[:option] 310 */ 311 backend_name = strtok_r(backend_name_option, ":\0", &saveptr); 312 if (backend_name == NULL) { 313 return; 314 } 315 316 /* 317 * No backend is using the option yet. 318 */ 319 #if 0 320 backend_option = strtok_r(NULL, "\0", &saveptr); 321 #endif 322 323 /* 324 * Find and update backend 325 */ 326 b = debug_find_backend(backend_name); 327 if (b == NULL) { 328 return; 329 } 330 331 if (backend_level == NULL) { 332 b->new_log_level = MAX_DEBUG_LEVEL; 333 } else { 334 b->new_log_level = atoi(backend_level); 335 } 336 } 337 338 /* 339 * parse "backend1[:option1][@loglevel1] backend2[option2][@loglevel2] ... " 340 * and enable/disable backends accordingly 341 */ 342 static void debug_set_backends(const char *param) 343 { 344 size_t str_len = strlen(param); 345 char str[str_len+1]; 346 char *tok, *saveptr; 347 int i; 348 349 /* 350 * initialize new_log_level to detect backends that have been 351 * disabled 352 */ 353 for (i = 0; i < ARRAY_SIZE(debug_backends); i++) { 354 debug_backends[i].new_log_level = -1; 355 } 356 357 memcpy(str, param, str_len + 1); 358 359 tok = strtok_r(str, LIST_SEP, &saveptr); 360 if (tok == NULL) { 361 return; 362 } 363 364 while (tok != NULL) { 365 debug_backend_parse_token(tok); 366 tok = strtok_r(NULL, LIST_SEP, &saveptr); 367 } 368 369 /* 370 * Let backends react to config changes 371 */ 372 for (i = 0; i < ARRAY_SIZE(debug_backends); i++) { 373 struct debug_backend *b = &debug_backends[i]; 374 375 if (b->reload) { 376 bool enabled = b->new_log_level > -1; 377 bool previously_enabled = b->log_level > -1; 378 379 b->reload(enabled, previously_enabled, state.prog_name); 380 } 381 b->log_level = b->new_log_level; 382 } 383 } 384 385 static void debug_backends_log(const char *msg, int msg_level) 386 { 387 char msg_no_nl[FORMAT_BUFR_SIZE]; 388 int i, len; 389 390 /* 391 * Some backends already add an extra newline, so also provide 392 * a buffer without the newline character. 393 */ 394 len = MIN(strlen(msg), FORMAT_BUFR_SIZE - 1); 395 if (msg[len - 1] == '\n') { 396 len--; 397 } 398 399 memcpy(msg_no_nl, msg, len); 400 msg_no_nl[len] = '\0'; 401 402 for (i = 0; i < ARRAY_SIZE(debug_backends); i++) { 403 if (msg_level <= debug_backends[i].log_level) { 404 debug_backends[i].log(msg_level, msg, msg_no_nl); 405 } 406 } 407 } 96 408 97 409 /* -------------------------------------------------------------------------- ** 98 410 * External variables. 99 *100 * debugf - Debug file name.101 * DEBUGLEVEL - System-wide debug message limit. Messages with message-102 * levels higher than DEBUGLEVEL will not be processed.103 411 */ 104 412 … … 109 417 bool override_logfile; 110 418 419 static const char *default_classname_table[] = { 420 [DBGC_ALL] = "all", 421 [DBGC_TDB] = "tdb", 422 [DBGC_PRINTDRIVERS] = "printdrivers", 423 [DBGC_LANMAN] = "lanman", 424 [DBGC_SMB] = "smb", 425 [DBGC_RPC_PARSE] = "rpc_parse", 426 [DBGC_RPC_SRV] = "rpc_srv", 427 [DBGC_RPC_CLI] = "rpc_cli", 428 [DBGC_PASSDB] = "passdb", 429 [DBGC_SAM] = "sam", 430 [DBGC_AUTH] = "auth", 431 [DBGC_WINBIND] = "winbind", 432 [DBGC_VFS] = "vfs", 433 [DBGC_IDMAP] = "idmap", 434 [DBGC_QUOTA] = "quota", 435 [DBGC_ACLS] = "acls", 436 [DBGC_LOCKING] = "locking", 437 [DBGC_MSDFS] = "msdfs", 438 [DBGC_DMAPI] = "dmapi", 439 [DBGC_REGISTRY] = "registry", 440 [DBGC_SCAVENGER] = "scavenger", 441 [DBGC_DNS] = "dns", 442 [DBGC_LDB] = "ldb", 443 [DBGC_TEVENT] = "tevent", 444 }; 445 111 446 /* 112 447 * This is to allow reading of DEBUGLEVEL_CLASS before the debug 113 448 * system has been initialized. 114 449 */ 115 static const int debug_class_list_initial[ DBGC_MAX_FIXED + 1];450 static const int debug_class_list_initial[ARRAY_SIZE(default_classname_table)]; 116 451 117 452 static int debug_num_classes = 0; … … 125 460 * Used to check log size. 126 461 * 127 * syslog_level - Internal copy of the message debug level. Written by462 * current_msg_level - Internal copy of the message debug level. Written by 128 463 * dbghdr() and read by Debug1(). 129 464 * … … 143 478 144 479 static int debug_count = 0; 145 #ifdef WITH_SYSLOG 146 static int syslog_level = 0; 147 #endif 148 static char *format_bufr = NULL; 480 static int current_msg_level = 0; 481 static char format_bufr[FORMAT_BUFR_SIZE]; 149 482 static size_t format_pos = 0; 150 483 static bool log_overflow = false; … … 155 488 * must be in the table in the order of DBGC_<class name>.. 156 489 */ 157 static const char *default_classname_table[] = {158 "all", /* DBGC_ALL; index refs traditional DEBUGLEVEL */159 "tdb", /* DBGC_TDB */160 "printdrivers", /* DBGC_PRINTDRIVERS */161 "lanman", /* DBGC_LANMAN */162 "smb", /* DBGC_SMB */163 "rpc_parse", /* DBGC_RPC_PARSE */164 "rpc_srv", /* DBGC_RPC_SRV */165 "rpc_cli", /* DBGC_RPC_CLI */166 "passdb", /* DBGC_PASSDB */167 "sam", /* DBGC_SAM */168 "auth", /* DBGC_AUTH */169 "winbind", /* DBGC_WINBIND */170 "vfs", /* DBGC_VFS */171 "idmap", /* DBGC_IDMAP */172 "quota", /* DBGC_QUOTA */173 "acls", /* DBGC_ACLS */174 "locking", /* DBGC_LOCKING */175 "msdfs", /* DBGC_MSDFS */176 "dmapi", /* DBGC_DMAPI */177 "registry", /* DBGC_REGISTRY */178 NULL179 };180 490 181 491 static char **classname_table = NULL; … … 200 510 DEBUGLEVEL_CLASS = discard_const_p(int, debug_class_list_initial); 201 511 } 202 203 TALLOC_FREE(format_bufr);204 512 205 513 debug_num_classes = 0; … … 218 526 /* prepare strings */ 219 527 for (i = 0; i < debug_num_classes; i++) { 220 buf = talloc_asprintf_append(buf, 528 buf = talloc_asprintf_append(buf, 221 529 "%s:%d%s", 222 530 classname_table[i], … … 303 611 ****************************************************************************/ 304 612 305 int debug_lookup_classname(const char *classname)613 static int debug_lookup_classname(const char *classname) 306 614 { 307 615 int ndx; … … 337 645 } 338 646 339 /**************************************************************************** 340 parse the debug levels from smbcontrol. Example debug level parameter: 341 printdrivers:7 342 ****************************************************************************/ 343 344 static bool debug_parse_params(char **params) 345 { 346 int i, ndx; 647 static bool debug_parse_param(char *param) 648 { 347 649 char *class_name; 348 650 char *class_level; 349 350 if (!params) 651 char *saveptr; 652 int ndx; 653 654 class_name = strtok_r(param, ":", &saveptr); 655 if (class_name == NULL) { 351 656 return false; 352 353 /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10" 354 * v.s. "all:10", this is the traditional way to set DEBUGLEVEL 355 */ 356 if (isdigit((int)params[0][0])) { 357 DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]); 358 i = 1; /* start processing at the next params */ 359 } else { 360 DEBUGLEVEL_CLASS[DBGC_ALL] = 0; 361 i = 0; /* DBGC_ALL not specified OR class name was included */ 362 } 363 364 /* Array is debug_num_classes long */ 365 for (ndx = DBGC_ALL; ndx < debug_num_classes; ndx++) { 366 DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL_CLASS[DBGC_ALL]; 367 } 368 369 /* Fill in new debug class levels */ 370 for (; i < debug_num_classes && params[i]; i++) { 371 char *saveptr; 372 if ((class_name = strtok_r(params[i],":", &saveptr)) && 373 (class_level = strtok_r(NULL, "\0", &saveptr)) && 374 ((ndx = debug_lookup_classname(class_name)) != -1)) { 375 DEBUGLEVEL_CLASS[ndx] = atoi(class_level); 376 } else { 377 DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i])); 378 return false; 379 } 380 } 657 } 658 659 class_level = strtok_r(NULL, "\0", &saveptr); 660 if (class_level == NULL) { 661 return false; 662 } 663 664 ndx = debug_lookup_classname(class_name); 665 if (ndx == -1) { 666 return false; 667 } 668 669 DEBUGLEVEL_CLASS[ndx] = atoi(class_level); 381 670 382 671 return true; … … 391 680 bool debug_parse_levels(const char *params_str) 392 681 { 393 char **params; 682 size_t str_len = strlen(params_str); 683 char str[str_len+1]; 684 char *tok, *saveptr; 685 int i; 394 686 395 687 /* Just in case */ 396 688 debug_init(); 397 689 398 params = str_list_make(NULL, params_str, NULL); 399 400 if (debug_parse_params(params)) { 401 debug_dump_status(5); 402 TALLOC_FREE(params); 690 memcpy(str, params_str, str_len+1); 691 692 tok = strtok_r(str, LIST_SEP, &saveptr); 693 if (tok == NULL) { 403 694 return true; 695 } 696 697 /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10" 698 * v.s. "all:10", this is the traditional way to set DEBUGLEVEL 699 */ 700 if (isdigit(tok[0])) { 701 DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(tok); 702 tok = strtok_r(NULL, LIST_SEP, &saveptr); 404 703 } else { 405 TALLOC_FREE(params); 406 return false; 407 } 704 DEBUGLEVEL_CLASS[DBGC_ALL] = 0; 705 } 706 707 /* Array is debug_num_classes long */ 708 for (i = DBGC_ALL+1; i < debug_num_classes; i++) { 709 DEBUGLEVEL_CLASS[i] = DEBUGLEVEL_CLASS[DBGC_ALL]; 710 } 711 712 while (tok != NULL) { 713 bool ok; 714 715 ok = debug_parse_param(tok); 716 if (!ok) { 717 DEBUG(0,("debug_parse_params: unrecognized debug " 718 "class name or format [%s]\n", tok)); 719 return false; 720 } 721 722 tok = strtok_r(NULL, LIST_SEP, &saveptr); 723 } 724 725 debug_dump_status(5); 726 727 return true; 408 728 } 409 729 … … 426 746 static void debug_init(void) 427 747 { 428 const char **p;748 size_t i; 429 749 430 750 if (state.initialized) … … 435 755 debug_setup_talloc_log(); 436 756 437 for(p = default_classname_table; *p; p++) { 438 debug_add_class(*p); 439 } 440 format_bufr = talloc_array(NULL, char, FORMAT_BUFR_SIZE); 441 if (!format_bufr) { 442 smb_panic("debug_init: unable to create buffer"); 443 } 444 } 445 446 /* This forces in some smb.conf derived values into the debug system. 447 * There are no pointers in this structure, so we can just 448 * structure-assign it in */ 449 void debug_set_settings(struct debug_settings *settings) 450 { 757 for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) { 758 debug_add_class(default_classname_table[i]); 759 } 760 761 for (i = 0; i < ARRAY_SIZE(debug_backends); i++) { 762 debug_backends[i].log_level = -1; 763 debug_backends[i].new_log_level = -1; 764 } 765 } 766 767 void debug_set_settings(struct debug_settings *settings, 768 const char *logging_param, 769 int syslog_level, bool syslog_only) 770 { 771 char fake_param[256]; 772 size_t len = 0; 773 774 /* 775 * This forces in some smb.conf derived values into the debug 776 * system. There are no pointers in this structure, so we can 777 * just structure-assign it in 778 */ 451 779 state.settings = *settings; 780 781 /* 782 * If 'logging' is not set, create backend settings from 783 * deprecated 'syslog' and 'syslog only' parameters 784 */ 785 if (logging_param != NULL) { 786 len = strlen(logging_param); 787 } 788 if (len == 0) { 789 if (syslog_only) { 790 snprintf(fake_param, sizeof(fake_param), 791 "syslog@%d", syslog_level - 1); 792 } else { 793 snprintf(fake_param, sizeof(fake_param), 794 "syslog@%d file@%d", syslog_level -1, 795 MAX_DEBUG_LEVEL); 796 } 797 798 logging_param = fake_param; 799 } 800 801 debug_set_backends(logging_param); 452 802 } 453 803 … … 469 819 } 470 820 if (prog_name) { 821 const char *p = strrchr(prog_name, '/'); 822 823 if (p) { 824 prog_name = p + 1; 825 } 826 471 827 state.prog_name = prog_name; 472 828 } 473 829 reopen_logs_internal(); 474 475 if (state.logtype == DEBUG_FILE) {476 #ifdef WITH_SYSLOG477 const char *p = strrchr_m( prog_name,'/' );478 if (p)479 prog_name = p + 1;480 #ifdef LOG_DAEMON481 openlog( prog_name, LOG_PID, SYSLOG_FACILITY );482 #else483 /* for old systems that have no facility codes. */484 openlog( prog_name, LOG_PID );485 #endif486 #endif487 }488 830 } 489 831 … … 512 854 { 513 855 return (state.logtype == DEBUG_DEFAULT_STDERR) || (state.logtype == DEBUG_STDERR); 856 } 857 858 bool debug_get_output_is_stdout(void) 859 { 860 return (state.logtype == DEBUG_DEFAULT_STDOUT) || (state.logtype == DEBUG_STDOUT); 861 } 862 863 void debug_set_callback(void *private_ptr, debug_callback_fn fn) 864 { 865 debug_init(); 866 if (fn) { 867 state.logtype = DEBUG_CALLBACK; 868 state.callback_private = private_ptr; 869 state.callback = fn; 870 } else { 871 state.logtype = DEBUG_DEFAULT_STDERR; 872 state.callback_private = NULL; 873 state.callback = NULL; 874 } 875 } 876 877 static void debug_callback_log(const char *msg, int msg_level) 878 { 879 size_t msg_len = strlen(msg); 880 char msg_copy[msg_len]; 881 882 if ((msg_len > 0) && (msg[msg_len-1] == '\n')) { 883 memcpy(msg_copy, msg, msg_len-1); 884 msg_copy[msg_len-1] = '\0'; 885 msg = msg_copy; 886 } 887 888 state.callback(state.callback_private, msg_level, msg); 514 889 } 515 890 … … 532 907 bool ret = true; 533 908 534 char *fname = NULL;535 909 if (state.reopening_logs) { 536 910 return true; … … 541 915 542 916 switch (state.logtype) { 917 case DEBUG_CALLBACK: 918 return true; 543 919 case DEBUG_STDOUT: 920 case DEBUG_DEFAULT_STDOUT: 544 921 debug_close_fd(state.fd); 545 922 state.fd = 1; … … 558 935 oldumask = umask( 022 ); 559 936 560 fname = state.debugf; 561 if (!fname) { 937 if (!state.debugf) { 562 938 return false; 563 939 } … … 573 949 ret = false; 574 950 } else { 951 smb_set_close_on_exec(new_fd); 575 952 old_fd = state.fd; 576 953 state.fd = new_fd; … … 586 963 587 964 /* Take over stderr to catch output into logs */ 588 if (state.fd > 0 && dup2(state.fd, 2) == -1) { 589 close_low_fds(true); /* Close stderr too, if dup2 can't point it 590 at the logfile */ 965 if (state.fd > 0) { 966 if (dup2(state.fd, 2) == -1) { 967 /* Close stderr too, if dup2 can't point it - 968 at the logfile. There really isn't much 969 that can be done on such a fundamental 970 failure... */ 971 close_low_fd(2); 972 } 591 973 } 592 974 … … 644 1026 */ 645 1027 646 if( geteuid() != 0) { 1028 #if _SAMBA_BUILD_ == 3 1029 if (geteuid() != sec_initial_uid()) 1030 #else 1031 if( geteuid() != 0) 1032 #endif 1033 { 647 1034 /* We don't check sec_initial_uid() here as it isn't 648 1035 * available in common code and we don't generally … … 658 1045 maxlog = state.settings.max_log_size * 1024; 659 1046 660 if (state.schedule_reopen_logs || 661 (fstat(state.fd, &st) == 0 1047 if (state.schedule_reopen_logs) { 1048 (void)reopen_logs_internal(); 1049 } 1050 1051 if (maxlog && (fstat(state.fd, &st) == 0 662 1052 && st.st_size > maxlog )) { 663 1053 (void)reopen_logs_internal(); 664 if (state.fd > 0 && fstat(state.fd, &st) == 0) { 665 if (st.st_size > maxlog) { 666 char *name = NULL; 667 668 if (asprintf(&name, "%s.old", state.debugf ) < 0) { 669 return; 670 } 671 (void)rename(state.debugf, name); 672 673 if (!reopen_logs_internal()) { 674 /* We failed to reopen a log - continue using the old name. */ 675 (void)rename(name, state.debugf); 676 } 677 SAFE_FREE(name); 1054 if (state.fd > 2 && (fstat(state.fd, &st) == 0 1055 && st.st_size > maxlog)) { 1056 char name[strlen(state.debugf) + 5]; 1057 1058 snprintf(name, sizeof(name), "%s.old", state.debugf); 1059 1060 (void)rename(state.debugf, name); 1061 1062 if (!reopen_logs_internal()) { 1063 /* We failed to reopen a log - continue using the old name. */ 1064 (void)rename(name, state.debugf); 678 1065 } 679 1066 } … … 694 1081 int fd = open( "/dev/console", O_WRONLY, 0); 695 1082 if (fd != -1) { 1083 smb_set_close_on_exec(fd); 696 1084 state.fd = fd; 697 1085 DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n", … … 712 1100 ************************************************************************/ 713 1101 714 int Debug1( const char *format_str, ... ) 715 { 716 va_list ap; 1102 static void Debug1(const char *msg) 1103 { 717 1104 int old_errno = errno; 718 1105 719 1106 debug_count++; 720 1107 721 if ( state.logtype != DEBUG_FILE ) { 722 va_start( ap, format_str ); 723 if (state.fd > 0) 724 (void)vdprintf( state.fd, format_str, ap ); 725 va_end( ap ); 726 errno = old_errno; 727 goto done; 728 } 729 730 #ifdef WITH_SYSLOG 731 if( !state.settings.syslog_only) 732 #endif 733 { 734 if( state.fd <= 0 ) { 735 mode_t oldumask = umask( 022 ); 736 int fd = open( state.debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 ); 737 (void)umask( oldumask ); 738 if(fd == -1) { 739 errno = old_errno; 740 goto done; 741 } 742 state.fd = fd; 743 } 744 } 745 746 #ifdef WITH_SYSLOG 747 if( syslog_level < state.settings.syslog ) { 748 /* map debug levels to syslog() priorities 749 * note that not all DEBUG(0, ...) calls are 750 * necessarily errors */ 751 static const int priority_map[4] = { 752 LOG_ERR, /* 0 */ 753 LOG_WARNING, /* 1 */ 754 LOG_NOTICE, /* 2 */ 755 LOG_INFO, /* 3 */ 756 }; 757 int priority; 758 char *msgbuf = NULL; 759 int ret; 760 761 if( syslog_level >= ARRAY_SIZE(priority_map) || syslog_level < 0) 762 priority = LOG_DEBUG; 763 else 764 priority = priority_map[syslog_level]; 765 766 /* 767 * Specify the facility to interoperate with other syslog 768 * callers (vfs_full_audit for example). 769 */ 770 priority |= SYSLOG_FACILITY; 771 772 va_start(ap, format_str); 773 ret = vasprintf(&msgbuf, format_str, ap); 774 va_end(ap); 775 776 if (ret != -1) { 777 syslog(priority, "%s", msgbuf); 778 } 779 SAFE_FREE(msgbuf); 780 } 781 #endif 782 783 check_log_size(); 784 785 #ifdef WITH_SYSLOG 786 if( !state.settings.syslog_only) 787 #endif 788 { 789 va_start( ap, format_str ); 790 if (state.fd > 0) 791 (void)vdprintf( state.fd, format_str, ap ); 792 va_end( ap ); 793 } 794 795 done: 1108 switch(state.logtype) { 1109 case DEBUG_CALLBACK: 1110 debug_callback_log(msg, current_msg_level); 1111 break; 1112 case DEBUG_STDOUT: 1113 case DEBUG_STDERR: 1114 case DEBUG_DEFAULT_STDOUT: 1115 case DEBUG_DEFAULT_STDERR: 1116 if (state.fd > 0) { 1117 write(state.fd, msg, strlen(msg)); 1118 } 1119 break; 1120 case DEBUG_FILE: 1121 debug_backends_log(msg, current_msg_level); 1122 break; 1123 }; 1124 796 1125 errno = old_errno; 797 798 return( 0 ); 799 } 800 1126 } 801 1127 802 1128 /************************************************************************** … … 809 1135 { 810 1136 format_bufr[format_pos] = '\0'; 811 (void)Debug1( "%s", format_bufr);1137 (void)Debug1(format_bufr); 812 1138 format_pos = 0; 813 1139 } … … 834 1160 bool timestamp = (state.logtype == DEBUG_FILE && (state.settings.timestamp_logs)); 835 1161 836 if (!format_bufr) { 837 debug_init(); 838 } 1162 debug_init(); 839 1163 840 1164 for( i = 0; msg[i]; i++ ) { … … 846 1170 847 1171 /* If there's room, copy the character to the format buffer. */ 848 if ( format_pos < FORMAT_BUFR_MAX)1172 if (format_pos < FORMAT_BUFR_SIZE - 1) 849 1173 format_bufr[format_pos++] = msg[i]; 850 1174 … … 856 1180 * continuation indicator. 857 1181 */ 858 if ( format_pos >= FORMAT_BUFR_MAX) {1182 if (format_pos >= FORMAT_BUFR_SIZE - 1) { 859 1183 bufr_print(); 860 1184 (void)Debug1( " +>\n" ); … … 897 1221 Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) ) 898 1222 899 Notes: This function takes care of setting syslog_level.1223 Notes: This function takes care of setting current_msg_level. 900 1224 901 1225 ****************************************************************************/ … … 905 1229 /* Ensure we don't lose any real errno value. */ 906 1230 int old_errno = errno; 1231 bool verbose = false; 1232 char header_str[300]; 1233 size_t hs_len; 1234 struct timeval tv; 1235 struct timeval_buf tvbuf; 907 1236 908 1237 if( format_pos ) { … … 919 1248 } 920 1249 921 #ifdef WITH_SYSLOG 922 /* Set syslog_level. */ 923 syslog_level = level; 924 #endif 1250 /* Set current_msg_level. */ 1251 current_msg_level = level; 925 1252 926 1253 /* Don't print a header if we're logging to stdout. */ … … 932 1259 * not yet loaded, then default to timestamps on. 933 1260 */ 934 if( state.settings.timestamp_logs || state.settings.debug_prefix_timestamp) { 935 char header_str[200]; 936 937 header_str[0] = '\0'; 938 939 if( state.settings.debug_pid) 940 slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)getpid()); 941 942 if( state.settings.debug_uid) { 943 size_t hs_len = strlen(header_str); 944 slprintf(header_str + hs_len, 945 sizeof(header_str) - 1 - hs_len, 946 ", effective(%u, %u), real(%u, %u)", 947 (unsigned int)geteuid(), (unsigned int)getegid(), 948 (unsigned int)getuid(), (unsigned int)getgid()); 949 } 950 951 if (state.settings.debug_class && (cls != DBGC_ALL)) { 952 size_t hs_len = strlen(header_str); 953 slprintf(header_str + hs_len, 954 sizeof(header_str) -1 - hs_len, 955 ", class=%s", 956 classname_table[cls]); 957 } 958 959 /* Print it all out at once to prevent split syslog output. */ 960 if( state.settings.debug_prefix_timestamp ) { 961 char *time_str = current_timestring(NULL, 962 state.settings.debug_hires_timestamp); 963 (void)Debug1( "[%s, %2d%s] ", 964 time_str, 965 level, header_str); 966 talloc_free(time_str); 967 } else { 968 char *time_str = current_timestring(NULL, 969 state.settings.debug_hires_timestamp); 970 (void)Debug1( "[%s, %2d%s] %s(%s)\n", 971 time_str, 972 level, header_str, location, func ); 973 talloc_free(time_str); 974 } 975 } 1261 if (!(state.settings.timestamp_logs || 1262 state.settings.debug_prefix_timestamp)) { 1263 return true; 1264 } 1265 1266 GetTimeOfDay(&tv); 1267 timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp, 1268 &tvbuf); 1269 1270 hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d", 1271 tvbuf.buf, level); 1272 if (hs_len >= sizeof(header_str)) { 1273 goto full; 1274 } 1275 1276 if (unlikely(DEBUGLEVEL_CLASS[ cls ] >= 10)) { 1277 verbose = true; 1278 } 1279 1280 if (verbose || state.settings.debug_pid) { 1281 hs_len += snprintf( 1282 header_str + hs_len, sizeof(header_str) - hs_len, 1283 ", pid=%u", (unsigned int)getpid()); 1284 if (hs_len >= sizeof(header_str)) { 1285 goto full; 1286 } 1287 } 1288 1289 if (verbose || state.settings.debug_uid) { 1290 hs_len += snprintf( 1291 header_str + hs_len, sizeof(header_str) - hs_len, 1292 ", effective(%u, %u), real(%u, %u)", 1293 (unsigned int)geteuid(), (unsigned int)getegid(), 1294 (unsigned int)getuid(), (unsigned int)getgid()); 1295 if (hs_len >= sizeof(header_str)) { 1296 goto full; 1297 } 1298 } 1299 1300 if ((verbose || state.settings.debug_class) 1301 && (cls != DBGC_ALL)) { 1302 hs_len += snprintf( 1303 header_str + hs_len, sizeof(header_str) - hs_len, 1304 ", class=%s", classname_table[cls]); 1305 if (hs_len >= sizeof(header_str)) { 1306 goto full; 1307 } 1308 } 1309 1310 /* 1311 * No +=, see man man strlcat 1312 */ 1313 hs_len = strlcat(header_str, "] ", sizeof(header_str)); 1314 if (hs_len >= sizeof(header_str)) { 1315 goto full; 1316 } 1317 1318 if (!state.settings.debug_prefix_timestamp) { 1319 hs_len += snprintf( 1320 header_str + hs_len, sizeof(header_str) - hs_len, 1321 "%s(%s)\n", location, func); 1322 if (hs_len >= sizeof(header_str)) { 1323 goto full; 1324 } 1325 } 1326 1327 full: 1328 (void)Debug1(header_str); 976 1329 977 1330 errno = old_errno; … … 992 1345 ***************************************************************************/ 993 1346 994 bool dbgtext( const char *format_str, ... ) 995 { 996 va_list ap; 1347 static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0); 1348 static inline bool __dbgtext_va(const char *format_str, va_list ap) 1349 { 997 1350 char *msgbuf = NULL; 998 1351 bool ret = true; 999 1352 int res; 1000 1353 1001 va_start(ap, format_str);1002 1354 res = vasprintf(&msgbuf, format_str, ap); 1003 va_end(ap);1004 1005 1355 if (res != -1) { 1006 1356 format_debug_text(msgbuf); … … 1012 1362 } 1013 1363 1014 1015 /* the registered mutex handlers */ 1016 static struct { 1017 const char *name; 1018 struct debug_ops ops; 1019 } debug_handlers; 1020 1021 /** 1022 log suspicious usage - print comments and backtrace 1023 */ 1024 _PUBLIC_ void log_suspicious_usage(const char *from, const char *info) 1025 { 1026 if (!debug_handlers.ops.log_suspicious_usage) return; 1027 1028 debug_handlers.ops.log_suspicious_usage(from, info); 1029 } 1030 1031 1032 /** 1033 print suspicious usage - print comments and backtrace 1034 */ 1035 _PUBLIC_ void print_suspicious_usage(const char* from, const char* info) 1036 { 1037 if (!debug_handlers.ops.print_suspicious_usage) return; 1038 1039 debug_handlers.ops.print_suspicious_usage(from, info); 1040 } 1041 1042 _PUBLIC_ uint32_t get_task_id(void) 1043 { 1044 if (debug_handlers.ops.get_task_id) { 1045 return debug_handlers.ops.get_task_id(); 1046 } 1047 return getpid(); 1048 } 1049 1050 _PUBLIC_ void log_task_id(void) 1051 { 1052 if (!debug_handlers.ops.log_task_id) return; 1053 1054 if (!reopen_logs_internal()) return; 1055 1056 debug_handlers.ops.log_task_id(state.fd); 1057 } 1058 1059 /** 1060 register a set of debug handlers. 1061 */ 1062 _PUBLIC_ void register_debug_handlers(const char *name, struct debug_ops *ops) 1063 { 1064 debug_handlers.name = name; 1065 debug_handlers.ops = *ops; 1066 } 1364 bool dbgtext_va(const char *format_str, va_list ap) 1365 { 1366 return __dbgtext_va(format_str, ap); 1367 } 1368 1369 bool dbgtext(const char *format_str, ... ) 1370 { 1371 va_list ap; 1372 bool ret; 1373 1374 va_start(ap, format_str); 1375 ret = __dbgtext_va(format_str, ap); 1376 va_end(ap); 1377 1378 return ret; 1379 }
Note:
See TracChangeset
for help on using the changeset viewer.