[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Mon Feb 28 20:33:01 MST 2011


The branch, master has been updated
       via  5f5ca91 lib/util: new merged debug system
       via  4acef31 lib/util move debug.[ch] out of the way
      from  b1f68b6 s4-libnet_vampire: Ignore some attributes when building working schema cache

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5f5ca913b7abfcf95782339fac2dc8c1541b1126
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Feb 24 16:14:03 2011 +1100

    lib/util: new merged debug system
    
    This is the s3 debug system, with a number of changes to tidy it up
    for common use.  The debug class system is simplified by the removal of the
    ISSET table, the system no longer attempts to cope with assignment of
    DEBUGLEVEL, and the full class table is always available (rather than
    just DEBUGLEVEL_CLASS[DBCG_ALL]) from startup.  It is also no longer
    confusingly described as a hack, but as the initial table.
    
    Autobuild-User: Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date: Tue Mar  1 04:32:12 CET 2011 on sn-devel-104

commit 4acef317a0e1692afc526a3805adf87403651170
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 1 07:40:22 2011 +1100

    lib/util move debug.[ch] out of the way
    
    This will allow a modified version of the s3 debug system to be the
    new common debug system.
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 lib/util/debug.c                                | 1030 ++++++++++++++++++---
 lib/util/debug.h                                |  313 +++++--
 lib/util/debug_s3.c                             |  105 +++
 source3/include/module.h => lib/util/debug_s3.h |   17 +-
 lib/util/wscript_build                          |    8 +-
 source3/Makefile.in                             |    2 +-
 source3/include/debug.h                         |  280 ------
 source3/include/includes.h                      |    2 -
 source3/include/local.h                         |    5 -
 source3/include/smb.h                           |    3 +-
 source3/lib/debug.c                             | 1118 -----------------------
 source3/pam_smbpass/pam_smb_auth.c              |    2 +-
 source3/param/loadparm.c                        |    1 -
 source3/wscript_build                           |    2 +-
 source4/param/loadparm.c                        |   30 +-
 15 files changed, 1263 insertions(+), 1655 deletions(-)
 create mode 100644 lib/util/debug_s3.c
 copy source3/include/module.h => lib/util/debug_s3.h (69%)
 delete mode 100644 source3/include/debug.h
 delete mode 100644 source3/lib/debug.c


Changeset truncated at 500 lines:

diff --git a/lib/util/debug.c b/lib/util/debug.c
index 845240f..d2f3d92 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -1,8 +1,9 @@
 /*
    Unix SMB/CIFS implementation.
-   Samba debug functions
-   Copyright (C) Andrew Tridgell 2003
-   Copyright (C) James J Myers	 2003
+   Samba utility functions
+   Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Elrond               2002
+   Copyright (C) Simo Sorce           2002
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,162 +21,386 @@
 
 #include "includes.h"
 #include "system/filesys.h"
-#include "system/time.h"
-#include "dynconfig/dynconfig.h"
+#include "system/syslog.h"
+#include "lib/util/time.h"
 
-/**
- * @file
- * @brief Debug logging
- **/
+/* define what facility to use for syslog */
+#ifndef SYSLOG_FACILITY
+#define SYSLOG_FACILITY LOG_DAEMON
+#endif
 
-/** 
- * this global variable determines what messages are printed 
+/* -------------------------------------------------------------------------- **
+ * Defines...
+ *
+ *  FORMAT_BUFR_MAX - Index of the last byte of the format buffer;
+ *                    format_bufr[FORMAT_BUFR_MAX] should always be reserved
+ *                    for a terminating null byte.
  */
-int _debug_level = 0;
-_PUBLIC_ int *debug_level = &_debug_level;
-static int debug_all_class_hack = 1;
-int *DEBUGLEVEL_CLASS = &debug_all_class_hack; /* For samba 3 */
-static bool debug_all_class_isset_hack = true;
-bool    *DEBUGLEVEL_CLASS_ISSET = &debug_all_class_isset_hack; /* For samba 3 */
 
-/* the registered mutex handlers */
-static struct {
-	const char *name;
-	struct debug_ops ops;
-} debug_handlers;
+#define FORMAT_BUFR_SIZE 1024
+#define FORMAT_BUFR_MAX (FORMAT_BUFR_SIZE - 1)
+
+/* -------------------------------------------------------------------------- **
+ * This module implements Samba's debugging utility.
+ *
+ * The syntax of a debugging log file is represented as:
+ *
+ *  <debugfile> :== { <debugmsg> }
+ *
+ *  <debugmsg>  :== <debughdr> '\n' <debugtext>
+ *
+ *  <debughdr>  :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
+ *
+ *  <debugtext> :== { <debugline> }
+ *
+ *  <debugline> :== TEXT '\n'
+ *
+ * TEXT     is a string of characters excluding the newline character.
+ * LEVEL    is the DEBUG level of the message (an integer in the range 0..10).
+ * TIME     is a timestamp.
+ * FILENAME is the name of the file from which the debug message was generated.
+ * FUNCTION is the function from which the debug message was generated.
+ *
+ * Basically, what that all means is:
+ *
+ * - A debugging log file is made up of debug messages.
+ *
+ * - Each debug message is made up of a header and text.  The header is
+ *   separated from the text by a newline.
+ *
+ * - The header begins with the timestamp and debug level of the message
+ *   enclosed in brackets.  The filename and function from which the
+ *   message was generated may follow.  The filename is terminated by a
+ *   colon, and the function name is terminated by parenthesis.
+ *
+ * - The message text is made up of zero or more lines, each terminated by
+ *   a newline.
+ */
 
 /* state variables for the debug system */
 static struct {
+	bool initialized;
 	int fd;   /* The log file handle */
 	enum debug_logtype logtype; /* The type of logging we are doing: eg stdout, file, stderr */
 	const char *prog_name;
 	bool reopening_logs;
-} state;
+	bool schedule_reopen_logs;
 
-static bool reopen_logs_scheduled;
-static bool check_reopen_logs(void)
-{
-	if (state.fd == 0 || reopen_logs_scheduled) {
-		reopen_logs_scheduled = false;
-		reopen_logs();
+	struct debug_settings settings;
+	char *debugf;
+} state = {
+	.settings = {
+		.timestamp_logs = true
 	}
+};
 
-	if (state.fd <= 0) 
-		return false;
+/* -------------------------------------------------------------------------- **
+ * External variables.
+ *
+ *  debugf        - Debug file name.
+ *  DEBUGLEVEL    - System-wide debug message limit.  Messages with message-
+ *                  levels higher than DEBUGLEVEL will not be processed.
+ */
 
-	return true;
-}
+/*
+   used to check if the user specified a
+   logfile on the command line
+*/
+bool    override_logfile;
 
-_PUBLIC_ void debug_schedule_reopen_logs(void)
-{
-	reopen_logs_scheduled = true;
-}
+/*
+ * This is to allow reading of DEBUGLEVEL_CLASS before the debug
+ * system has been initialized.
+ */
+static const int debug_class_list_initial[DBGC_MAX_FIXED + 1];
+
+static int debug_num_classes = 0;
+int     *DEBUGLEVEL_CLASS = discard_const_p(int, debug_class_list_initial);
+
+
+/* -------------------------------------------------------------------------- **
+ * Internal variables.
+ *
+ *  debug_count     - Number of debug messages that have been output.
+ *                    Used to check log size.
+ *
+ *  syslog_level    - Internal copy of the message debug level.  Written by
+ *                    dbghdr() and read by Debug1().
+ *
+ *  format_bufr     - Used to format debug messages.  The dbgtext() function
+ *                    prints debug messages to a string, and then passes the
+ *                    string to format_debug_text(), which uses format_bufr
+ *                    to build the formatted output.
+ *
+ *  format_pos      - Marks the first free byte of the format_bufr.
+ *
+ *
+ *  log_overflow    - When this variable is true, never attempt to check the
+ *                    size of the log. This is a hack, so that we can write
+ *                    a message using DEBUG, from open_logs() when we
+ *                    are unable to open a new log file for some reason.
+ */
+
+static int     debug_count    = 0;
+#ifdef WITH_SYSLOG
+static int     syslog_level   = 0;
+#endif
+static char *format_bufr = NULL;
+static size_t     format_pos     = 0;
+static bool    log_overflow   = false;
+
+/*
+ * Define all the debug class selection names here. Names *MUST NOT* contain
+ * white space. There must be one name for each DBGC_<class name>, and they
+ * must be in the table in the order of DBGC_<class name>..
+ */
+static const char *default_classname_table[] = {
+	"all",               /* DBGC_ALL; index refs traditional DEBUGLEVEL */
+	"tdb",               /* DBGC_TDB	  */
+	"printdrivers",      /* DBGC_PRINTDRIVERS */
+	"lanman",            /* DBGC_LANMAN       */
+	"smb",               /* DBGC_SMB          */
+	"rpc_parse",         /* DBGC_RPC_PARSE    */
+	"rpc_srv",           /* DBGC_RPC_SRV      */
+	"rpc_cli",           /* DBGC_RPC_CLI      */
+	"passdb",            /* DBGC_PASSDB       */
+	"sam",               /* DBGC_SAM          */
+	"auth",              /* DBGC_AUTH         */
+	"winbind",           /* DBGC_WINBIND      */
+	"vfs",		     /* DBGC_VFS	  */
+	"idmap",	     /* DBGC_IDMAP	  */
+	"quota",	     /* DBGC_QUOTA	  */
+	"acls",		     /* DBGC_ACLS	  */
+	"locking",	     /* DBGC_LOCKING	  */
+	"msdfs",	     /* DBGC_MSDFS	  */
+	"dmapi",	     /* DBGC_DMAPI	  */
+	"registry",          /* DBGC_REGISTRY     */
+	NULL
+};
 
-static void log_timestring(int level, const char *location, const char *func)
+static char **classname_table = NULL;
+
+
+/* -------------------------------------------------------------------------- **
+ * Functions...
+ */
+
+static void debug_init(void);
+
+/***************************************************************************
+ Free memory pointed to by global pointers.
+****************************************************************************/
+
+void gfree_debugsyms(void)
 {
-	char *t = NULL;
-	char *s = NULL;
+	TALLOC_FREE(classname_table);
+
+	if ( DEBUGLEVEL_CLASS != debug_class_list_initial ) {
+		TALLOC_FREE( DEBUGLEVEL_CLASS );
+		DEBUGLEVEL_CLASS = discard_const_p(int, debug_class_list_initial);
+	}
 
-	if (!check_reopen_logs()) return;
+	TALLOC_FREE(format_bufr);
 
-	if (state.logtype != DEBUG_FILE) return;
+	debug_num_classes = DBGC_MAX_FIXED;
 
-	t = timestring(NULL, time(NULL));
-	if (!t) return;
+	state.initialized = false;
+}
 
-	asprintf(&s, "[%s, %d %s:%s()]\n", t, level, location, func);
-	talloc_free(t);
-	if (!s) return;
+/****************************************************************************
+utility lists registered debug class names's
+****************************************************************************/
 
-	write(state.fd, s, strlen(s));
-	free(s);
+char *debug_list_class_names_and_levels(void)
+{
+	char *buf = NULL;
+	unsigned int i;
+	/* prepare strings */
+	for (i = 0; i < debug_num_classes; i++) {
+		buf = talloc_asprintf_append(buf, 
+					     "%s:%d%s",
+					     classname_table[i],
+					     DEBUGLEVEL_CLASS[i],
+					     i == (debug_num_classes - 1) ? "\n" : " ");
+		if (buf == NULL) {
+			return NULL;
+		}
+	}
+	return buf;
 }
 
-/**
-  the backend for debug messages. Note that the DEBUG() macro has already
-  ensured that the log level has been met before this is called
-*/
-_PUBLIC_ void dbghdr(int level, const char *location, const char *func)
+/****************************************************************************
+ Utility to translate names to debug class index's (internal version).
+****************************************************************************/
+
+static int debug_lookup_classname_int(const char* classname)
 {
-	log_timestring(level, location, func);
-	log_task_id();
+	int i;
+
+	if (!classname) return -1;
+
+	for (i=0; i < debug_num_classes; i++) {
+		if (strcmp(classname, classname_table[i])==0)
+			return i;
+	}
+	return -1;
 }
 
+/****************************************************************************
+ Add a new debug class to the system.
+****************************************************************************/
 
-_PUBLIC_ void dbghdrclass(int level, int dclass, const char *location, const char *func)
+int debug_add_class(const char *classname)
 {
-	/* Simple wrapper, Samba 4 doesn't do debug classes */
-	dbghdr(level, location, func);
+	int ndx;
+	int *new_class_list;
+	char **new_name_list;
+
+	if (!classname)
+		return -1;
+
+	/* check the init has yet been called */
+	debug_init();
+
+	ndx = debug_lookup_classname_int(classname);
+	if (ndx >= 0)
+		return ndx;
+	ndx = debug_num_classes;
+
+	if (DEBUGLEVEL_CLASS == debug_class_list_initial) {
+		/* Initial loading... */
+		new_class_list = NULL;
+	} else {
+		new_class_list = DEBUGLEVEL_CLASS;
+	}
+
+	new_class_list = talloc_realloc(NULL, new_class_list, int, ndx + 1);
+	if (!new_class_list)
+		return -1;
+	DEBUGLEVEL_CLASS = new_class_list;
+
+	DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL_CLASS[DBGC_ALL];
+
+	new_name_list = talloc_realloc(NULL, classname_table, char *, ndx + 1);
+	if (!new_name_list)
+		return -1;
+	classname_table = new_name_list;
+
+	classname_table[ndx] = talloc_strdup(classname_table, classname);
+	if (! classname_table[ndx])
+		return -1;
+
+	debug_num_classes = ndx + 1;
+
+	return ndx;
 }
 
-/**
-  the backend for debug messages. Note that the DEBUG() macro has already
-  ensured that the log level has been met before this is called
+/****************************************************************************
+ Utility to translate names to debug class index's (public version).
+****************************************************************************/
 
-  @note You should never have to call this function directly. Call the DEBUG()
-  macro instead.
-*/
-_PUBLIC_ void dbgtext(const char *format, ...)
+int debug_lookup_classname(const char *classname)
 {
-	va_list ap;
+	int ndx;
 
-	if (!check_reopen_logs()) return;
+	if (!classname || !*classname)
+		return -1;
 
-	va_start(ap, format);
-	vdprintf(state.fd, format, ap);
-	va_end(ap);
+	ndx = debug_lookup_classname_int(classname);
+
+	if (ndx != -1)
+		return ndx;
+
+	DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
+		  classname));
+	return debug_add_class(classname);
 }
 
-_PUBLIC_ const char *logfile = NULL;
+/****************************************************************************
+ Dump the current registered debug levels.
+****************************************************************************/
 
-/**
-  reopen the log file (usually called because the log file name might have changed)
-*/
-_PUBLIC_ void reopen_logs(void)
+static void debug_dump_status(int level)
 {
-	char *fname = NULL;
-	int old_fd = state.fd;
-	if (state.reopening_logs) {
-		return;
+	int q;
+
+	DEBUG(level, ("INFO: Current debug levels:\n"));
+	for (q = 0; q < debug_num_classes; q++) {
+		const char *classname = classname_table[q];
+		DEBUGADD(level, ("  %s: %d\n",
+				 classname,
+				 DEBUGLEVEL_CLASS[q]));
 	}
+}
 
-	switch (state.logtype) {
-	case DEBUG_STDOUT:
-	case DEBUG_DEFAULT_STDOUT:
-		state.fd = 1;
-		break;
+/****************************************************************************
+ parse the debug levels from smbcontrol. Example debug level parameter:
+ printdrivers:7
+****************************************************************************/
 
-	case DEBUG_STDERR:
-	case DEBUG_DEFAULT_STDERR:
-		state.fd = 2;
-		break;
+static bool debug_parse_params(char **params)
+{
+	int   i, ndx;
+	char *class_name;
+	char *class_level;
 
-	case DEBUG_FILE:
-		state.reopening_logs = true;
-		if (logfile && (*logfile) == '/') {
-			fname = strdup(logfile);
-		} else {
-			asprintf(&fname, "%s/%s.log", dyn_LOGFILEBASE, state.prog_name);
-		}
-		if (fname) {
-			int newfd = open(fname, O_CREAT|O_APPEND|O_WRONLY, 0600);
-			if (newfd == -1) {
-				DEBUG(1, ("Failed to open new logfile: %s\n", fname));
-				old_fd = -1;
-			} else {
-				state.fd = newfd;
-			}
-			free(fname);
+	if (!params)
+		return false;
+
+	/* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
+	 * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
+	 */
+	if (isdigit((int)params[0][0])) {
+		DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
+		i = 1; /* start processing at the next params */
+	} else {
+		DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
+		i = 0; /* DBGC_ALL not specified OR class name was included */
+	}
+
+	/* Array is debug_num_classes long */
+	for (ndx = DBGC_ALL; ndx < debug_num_classes; ndx++) {
+		DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL_CLASS[DBGC_ALL];
+	}
+		
+	/* Fill in new debug class levels */
+	for (; i < debug_num_classes && params[i]; i++) {
+		char *saveptr;
+		if ((class_name = strtok_r(params[i],":", &saveptr)) &&
+			(class_level = strtok_r(NULL, "\0", &saveptr)) &&
+            ((ndx = debug_lookup_classname(class_name)) != -1)) {
+				DEBUGLEVEL_CLASS[ndx] = atoi(class_level);
 		} else {
-			DEBUG(1, ("Failed to find name for file-based logfile!\n"));
+			DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
+			return false;
 		}
-		state.reopening_logs = false;
-
-		break;
 	}
 
-	if (old_fd > 2) {
-		close(old_fd);
+	return true;
+}
+
+/****************************************************************************
+ Parse the debug levels from smb.conf. Example debug level string:
+  3 tdb:5 printdrivers:7
+ Note: the 1st param has no "name:" preceeding it.
+****************************************************************************/
+
+bool debug_parse_levels(const char *params_str)
+{
+	char **params;
+
+	/* Just in case */
+	debug_init();
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list