2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

isc_log_create now has three parameters, the additional one used to

return an isc_logconfig_t.  isc_log_cretechannel and isc_log_usechannel
now take an isc_logconfig_t instead of an isc_log_t; this is to address
reconfiguration in a multithreaded environment.

isc_logconfig_create, isc_logconfig_get, isc_logconfig_use and
isc_logconfig_destroy were added to work with the new isc_logconfig_t type.

isc_logregister_categories and dns_log_init are now both void rather than
returning isc_result_t.
This commit is contained in:
David Lawrence 2000-02-26 19:57:02 +00:00
parent 3dbea10f98
commit edcd1247ad
9 changed files with 396 additions and 247 deletions

View File

@ -1028,6 +1028,7 @@ main(int argc, char *argv[]) {
signer_key_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_logconfig_t *logconfig;
dns_result_register();
@ -1107,11 +1108,11 @@ main(int argc, char *argv[]) {
}
if (verbose > 0) {
RUNTIME_CHECK(isc_log_create(mctx, &log) == ISC_R_SUCCESS);
RUNTIME_CHECK(dns_log_init(log) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_log_usechannel(log, "default_stderr",
RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig)
== ISC_R_SUCCESS);
dns_log_init(log);
RUNTIME_CHECK(isc_log_usechannel(logconfig, "default_stderr",
NULL, NULL) == ISC_R_SUCCESS);
dns_lctx = log;
}
argc -= isc_commandline_index;

View File

@ -218,6 +218,7 @@ main(int argc, char **argv)
client_t *client;
isc_logdestination_t destination;
isc_log_t *lctx;
isc_logconfig_t *lcfg;
UNUSED(argc);
UNUSED(argv);
@ -235,21 +236,20 @@ main(int argc, char **argv)
* Set up logging.
*/
lctx = NULL;
result = isc_log_create(mem, &lctx);
INSIST(result == ISC_R_SUCCESS);
result = dns_log_init(lctx);
result = isc_log_create(mem, &lctx, &lcfg);
INSIST(result == ISC_R_SUCCESS);
dns_log_init(lctx);
destination.file.stream = stderr;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
result = isc_log_createchannel(lctx, "_default",
result = isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination, ISC_LOG_PRINTTIME);
INSIST(result == ISC_R_SUCCESS);
result = isc_log_usechannel(lctx, "_default", NULL, NULL);
result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
INSIST(result == ISC_R_SUCCESS);
/*

View File

@ -63,6 +63,7 @@ ns_log_init(void) {
isc_result_t result;
isc_logdestination_t destination;
unsigned int flags;
isc_logconfig_t *lcfg;
ns_g_categories = categories;
ns_g_modules = modules;
@ -75,16 +76,13 @@ ns_log_init(void) {
/*
* Setup a logging context.
*/
result = isc_log_create(ns_g_mctx, &ns_g_lctx);
result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg);
if (result != ISC_R_SUCCESS)
return (result);
result = isc_log_registercategories(ns_g_lctx, ns_g_categories);
if (result != ISC_R_SUCCESS)
goto cleanup;
isc_log_registercategories(ns_g_lctx, ns_g_categories);
isc_log_registermodules(ns_g_lctx, ns_g_modules);
result = dns_log_init(ns_g_lctx);
if (result != ISC_R_SUCCESS)
goto cleanup;
dns_log_init(ns_g_lctx);
/*
* Create and install the default channel.
@ -95,14 +93,14 @@ ns_log_init(void) {
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
flags = ISC_LOG_PRINTTIME;
result = isc_log_createchannel(ns_g_lctx, "_default",
result = isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination, flags);
} else {
destination.facility = LOG_DAEMON;
flags = ISC_LOG_PRINTTIME;
result = isc_log_createchannel(ns_g_lctx, "_default",
result = isc_log_createchannel(lcfg, "_default",
ISC_LOG_TOSYSLOG,
ISC_LOG_DYNAMIC,
&destination, flags);
@ -110,7 +108,7 @@ ns_log_init(void) {
if (result != ISC_R_SUCCESS)
goto cleanup;
result = isc_log_usechannel(ns_g_lctx, "_default", NULL, NULL);
result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: log_test.c,v 1.7 2000/02/03 23:03:46 halley Exp $ */
/* $Id: log_test.c,v 1.8 2000/02/26 19:57:00 tale Exp $ */
/* Principal Authors: DCL */
@ -44,19 +44,13 @@ char usage[] = "Usage: %s [-m] [-s syslog_logfile] [-r file_versions]\n";
progname, isc_result_totext(result)); \
}
#define CHECK_DNS(expr) result = expr; \
if (result != DNS_R_SUCCESS) { \
fprintf(stderr, "%s: " #expr "%s: exiting\n", \
progname, dns_result_totext(result)); \
}
int
main (int argc, char **argv) {
char *progname, *syslog_file, *message;
int ch, i, file_versions;
isc_boolean_t show_final_mem = ISC_FALSE;
isc_log_t *lctx;
isc_logconfig_t *lcfg;
isc_mem_t *mctx;
isc_result_t result;
isc_logdestination_t destination;
@ -113,8 +107,9 @@ main (int argc, char **argv) {
lctx = NULL;
CHECK_ISC(isc_mem_create(0, 0, &mctx));
CHECK_ISC(isc_log_create(mctx, &lctx));
CHECK_DNS(dns_log_init(lctx));
CHECK_ISC(isc_log_create(mctx, &lctx, &lcfg));
dns_log_init(lctx);
/*
* Create a file channel to test file opening, size limiting and
@ -125,7 +120,7 @@ main (int argc, char **argv) {
destination.file.maximum_size = 1;
destination.file.versions = file_versions;
CHECK_ISC(isc_log_createchannel(lctx, "file_test", ISC_LOG_TOFILE,
CHECK_ISC(isc_log_createchannel(lcfg, "file_test", ISC_LOG_TOFILE,
ISC_LOG_INFO, &destination,
ISC_LOG_PRINTTIME|
ISC_LOG_PRINTLEVEL|
@ -137,7 +132,7 @@ main (int argc, char **argv) {
*/
destination.file.stream = stderr;
CHECK_ISC(isc_log_createchannel(lctx, "debug_test", ISC_LOG_TOFILEDESC,
CHECK_ISC(isc_log_createchannel(lcfg, "debug_test", ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC, &destination,
ISC_LOG_PRINTTIME|
ISC_LOG_PRINTLEVEL));
@ -145,27 +140,27 @@ main (int argc, char **argv) {
/*
* Test the usability of the four predefined logging channels.
*/
CHECK_ISC(isc_log_usechannel(lctx, "default_syslog",
CHECK_ISC(isc_log_usechannel(lcfg, "default_syslog",
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE));
CHECK_ISC(isc_log_usechannel(lctx, "default_stderr",
CHECK_ISC(isc_log_usechannel(lcfg, "default_stderr",
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE));
CHECK_ISC(isc_log_usechannel(lctx, "default_debug",
CHECK_ISC(isc_log_usechannel(lcfg, "default_debug",
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE));
CHECK_ISC(isc_log_usechannel(lctx, "null",
CHECK_ISC(isc_log_usechannel(lcfg, "null",
DNS_LOGCATEGORY_DATABASE,
NULL));
/*
* Use the custom channels.
*/
CHECK_ISC(isc_log_usechannel(lctx, "file_test",
CHECK_ISC(isc_log_usechannel(lcfg, "file_test",
DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_DB));
CHECK_ISC(isc_log_usechannel(lctx, "debug_test",
CHECK_ISC(isc_log_usechannel(lcfg, "debug_test",
DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_RBTDB));
@ -199,7 +194,7 @@ main (int argc, char **argv) {
* Reset the internal default to use syslog instead of stderr,
* and test it.
*/
CHECK_ISC(isc_log_usechannel(lctx, "default_syslog",
CHECK_ISC(isc_log_usechannel(lcfg, "default_syslog",
ISC_LOGCATEGORY_DEFAULT,
NULL));
isc_log_write(lctx, DNS_LOGCATEGORY_SECURITY, DNS_LOGMODULE_RBT,
@ -261,7 +256,7 @@ main (int argc, char **argv) {
/*
* Test out the duplicate filtering using the debug_test channel.
*/
isc_log_setduplicateinterval(lctx, 10);
isc_log_setduplicateinterval(lcfg, 10);
message = "This message should appear only once on stderr";
isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
@ -269,7 +264,7 @@ main (int argc, char **argv) {
isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,
ISC_LOG_CRITICAL, message);
isc_log_setduplicateinterval(lctx, 1);
isc_log_setduplicateinterval(lcfg, 1);
message = "This message should appear twice on stderr";
isc_log_write1(lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RBTDB,

View File

@ -1028,6 +1028,7 @@ main(int argc, char *argv[]) {
signer_key_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_logconfig_t *logconfig;
dns_result_register();
@ -1107,11 +1108,11 @@ main(int argc, char *argv[]) {
}
if (verbose > 0) {
RUNTIME_CHECK(isc_log_create(mctx, &log) == ISC_R_SUCCESS);
RUNTIME_CHECK(dns_log_init(log) == ISC_R_SUCCESS);
RUNTIME_CHECK(isc_log_usechannel(log, "default_stderr",
RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig)
== ISC_R_SUCCESS);
dns_log_init(log);
RUNTIME_CHECK(isc_log_usechannel(logconfig, "default_stderr",
NULL, NULL) == ISC_R_SUCCESS);
dns_lctx = log;
}
argc -= isc_commandline_index;

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: log.h,v 1.11 2000/02/03 23:40:57 halley Exp $ */
/* $Id: log.h,v 1.12 2000/02/26 19:57:01 tale Exp $ */
/* Principal Authors: DCL */
@ -58,7 +58,7 @@ extern isc_logmodule_t dns_modules[];
#define DNS_LOGMODULE_XFER_OUT (&dns_modules[14])
#define DNS_LOGMODULE_ACL (&dns_modules[15])
isc_result_t
void
dns_log_init(isc_log_t *lctx);
/*
* Make the libdns.a categories and modules available for use with the
@ -70,20 +70,8 @@ dns_log_init(isc_log_t *lctx);
* dns_log_init() is called only once.
*
* Ensures:
* ISC_R_SUCCESS
* The catgories and modules defined above are available for
* use by isc_log_usechannnel() and isc_log_write().
*
* ISC_R_NOMEMORY
* The catgories and modules defined above are not available for
* use by isc_log_usechannnel() and isc_log_write(), and no
* additional memory is being used because of the call to
* dns_log_init().
*
*
* Returns:
* ISC_R_SUCCESS Success
* ISC_R_NOMEMORY Resource limit: Out of memory
*/
ISC_LANG_ENDDECLS

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: log.c,v 1.13 2000/02/03 23:43:49 halley Exp $ */
/* $Id: log.c,v 1.14 2000/02/26 19:57:00 tale Exp $ */
/* Principal Authors: DCL */
@ -68,18 +68,12 @@ isc_logmodule_t dns_modules[] = {
isc_log_t *dns_lctx;
isc_result_t
void
dns_log_init(isc_log_t *lctx) {
isc_result_t result;
REQUIRE(dns_lctx == NULL);
result = isc_log_registercategories(lctx, dns_categories);
if (result == ISC_R_SUCCESS) {
isc_log_registercategories(lctx, dns_categories);
isc_log_registermodules(lctx, dns_modules);
dns_lctx = lctx;
}
return (result);
dns_lctx = lctx;
}

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: log.h,v 1.8 2000/02/03 23:07:50 halley Exp $ */
/* $Id: log.h,v 1.9 2000/02/26 19:57:02 tale Exp $ */
#ifndef ISC_LOG_H
#define ISC_LOG_H 1
@ -75,6 +75,11 @@ ISC_LANG_BEGINDECLS
*/
typedef struct isc_log isc_log_t;
/*
* Channel configuration. Details are internal to the implementation.
*/
typedef struct isc_logconfig isc_logconfig_t;
/*
* Used to name the categories used by a library. An array of isc_logcategory
* structures names each category, and the id value is initialized by calling
@ -138,7 +143,7 @@ extern isc_logcategory_t isc_categories[];
#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0])
isc_result_t
isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp);
isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp);
/*
* Establish a new logging context, with default channels.
*
@ -167,6 +172,15 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp);
* ISC_R_UNEXPECTED The mutex lock could not be initialized.
*/
isc_result_t
isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp);
isc_logconfig_t *
isc_logconfig_get(isc_log_t *lctx);
isc_result_t
isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg);
void
isc_log_destroy(isc_log_t **lctxp);
/*
@ -184,8 +198,10 @@ isc_log_destroy(isc_log_t **lctxp);
* The logging context is marked as invalid.
*/
void
isc_logconfig_destroy(isc_logconfig_t **lcfgp);
isc_result_t
void
isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]);
/*
* Identify logging categories a library will use.
@ -249,9 +265,9 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]);
*/
isc_result_t
isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
int level, isc_logdestination_t *destination,
unsigned int flags);
isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
unsigned int type, int level,
isc_logdestination_t *destination, unsigned int flags);
/*
* Specify the parameters of a logging channel.
*
@ -313,7 +329,7 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
*/
isc_result_t
isc_log_usechannel(isc_log_t *lctx, const char *name,
isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
isc_logcategory_t *category, isc_logmodule_t *module);
/*
* Associate a named logging channel with a category and module that
@ -502,7 +518,7 @@ isc_log_getdebuglevel(isc_log_t *lctx);
*/
void
isc_log_setduplicateinterval(isc_log_t *lctx, unsigned int interval);
isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval);
/*
* Set the interval over which duplicate log messages will be ignored
* by isc_log_[v]write1(), in seconds.
@ -525,7 +541,7 @@ isc_log_setduplicateinterval(isc_log_t *lctx, unsigned int interval);
*/
unsigned int
isc_log_getduplicateinterval(isc_log_t *lctx);
isc_log_getduplicateinterval(isc_logconfig_t *lcfg);
/*
* Get the current duplicate filtering interval.
*

View File

@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: log.c,v 1.15 2000/02/03 23:08:25 halley Exp $ */
/* $Id: log.c,v 1.16 2000/02/26 19:57:01 tale Exp $ */
/* Principal Authors: DCL */
@ -29,15 +29,19 @@
#include <isc/assertions.h>
#include <isc/boolean.h>
#include <isc/dir.h>
#include <isc/error.h>
#include <isc/list.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/mutex.h>
#include <isc/print.h>
#include <isc/time.h>
#include <isc/util.h>
#define LOG_MAGIC 0x494C4F47U /* ILOG. */
#define VALID_CONTEXT(lctx) ((lctx) != NULL && (lctx)->magic == LOG_MAGIC)
#define LCTX_MAGIC 0x4C637478U /* Lctx. */
#define VALID_CONTEXT(lctx) ((lctx) != NULL && (lctx)->magic == LCTX_MAGIC)
#define LCFG_MAGIC 0x4C636667U /* Lcfg. */
#define VALID_CONFIG(lcfg) ((lcfg) != NULL && (lcfg)->magic == LCFG_MAGIC)
#define LOG_BUFFER_SIZE (8 * 1024)
@ -58,6 +62,7 @@ struct isc_logchannel {
int level;
unsigned int flags;
isc_logdestination_t destination;
/* XXXDCL should be an ISC_LINK, so this can be an ISC_LIST */
isc_logchannel_t * next;
};
@ -74,6 +79,7 @@ typedef struct isc_logchannellist isc_logchannellist_t;
struct isc_logchannellist {
isc_logmodule_t * module;
isc_logchannel_t * channel;
/* XXXDCL should be an ISC_LINK, so this can be an ISC_LIST */
isc_logchannellist_t * next;
};
@ -86,12 +92,24 @@ typedef struct isc_logmessage isc_logmessage_t;
struct isc_logmessage {
char * text;
isc_time_t time;
isc_logmessage_t * next;
ISC_LINK(isc_logmessage_t) link;
};
/*
* XXX describe
*/
struct isc_logconfig {
unsigned int magic;
isc_log_t * lctx;
isc_logchannel_t * channels;
isc_logchannellist_t ** channellists;
unsigned int channellist_count;
unsigned int duplicate_interval;
};
/*
* This isc_log structure provides the context for the isc_log functions.
* The log context locks itself in isc_log_vwrite, the internal backend to
* The log context locks itself in isc_log_doit, the internal backend to
* isc_log_write. The locking is necessary both to provide exclusive access
* to the the buffer into which the message is formatted and to guard against
* competing threads trying to write to the same syslog resource. (On
@ -100,20 +118,24 @@ struct isc_logmessage {
* context in the same program competing for syslog's attention. Thus
* There Can Be Only One, but this is not enforced.
* XXX enforce it?
*
* Note that the category and module information is not locked.
* This is because in the usual case, only one isc_log_t is ever created
* in a program, and the category/module registration happens only once.
* XXX it might be wise to add more locking overall.
*/
struct isc_log {
/* Not locked. */
unsigned int magic;
isc_mem_t * mctx;
isc_mutex_t lock;
char buffer[LOG_BUFFER_SIZE];
int debug_level;
unsigned int duplicate_interval;
isc_logchannel_t * channels;
isc_logchannellist_t ** categories;
unsigned int category_count;
isc_logmodule_t ** modules;
unsigned int module_count;
int debug_level;
char buffer[LOG_BUFFER_SIZE];
ISC_LIST(isc_logmessage_t) messages;
isc_mutex_t lock;
/* Locked by isc_log lock. */
isc_logconfig_t * logconfig;
};
/*
@ -133,9 +155,7 @@ static const int syslog_map[] = {
/*
* When adding new categories, a corresponding ISC_LOGCATEGORY_foo
* definition needs to be added to <isc/log.h>. Each name string should
* end with a colon-space pair because they are used in the formatted
* log message when ISC_LOG_PRINTCATEGORY is enabled.
* definition needs to be added to <isc/log.h>.
*
* The default category is provided so that the internal default can
* be overridden. Since the default is always looked up as the first
@ -156,9 +176,12 @@ isc_logchannellist_t default_channel;
* Forward declarations.
*/
static isc_result_t
assignchannel(isc_log_t *lctx, unsigned int category_id,
assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
isc_logmodule_t *module, isc_logchannel_t *channel);
static isc_result_t
sync_channellist(isc_logconfig_t *lcfg);
static unsigned int
greatest_version(isc_logchannel_t *channel);
@ -188,37 +211,82 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
* Establish a new logging context, with default channels.
*/
isc_result_t
isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) {
isc_log_t *lctx;
isc_logdestination_t destination;
isc_result_t result;
isc_logconfig_t *lcfg = NULL;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(mctx != NULL);
REQUIRE(lctxp != NULL && *lctxp == NULL);
lctx = (isc_log_t *)isc_mem_get(mctx, sizeof(*lctx));
if (lctx == NULL)
return (ISC_R_NOMEMORY);
if (lctx != NULL) {
lctx->mctx = mctx;
lctx->channels = NULL;
lctx->categories = NULL;
lctx->category_count = 0;
lctx->debug_level = 0;
lctx->duplicate_interval = 0;
lctx->modules = NULL;
lctx->module_count = 0;
lctx->debug_level = 0;
ISC_LIST_INIT(lctx->messages);
result = isc_mutex_init(&lctx->lock);
RUNTIME_CHECK(isc_mutex_init(&lctx->lock) == ISC_R_SUCCESS);
/*
* Normally the magic number is the last thing set in the structure,
* but isc_log_createchannel() needs a valid context. If the channel
* creation fails, the lctx is not returned to the caller.
* Normally setting the magic number is the last step done
* in a creation function, but a valid log context is needed
* by isc_log_registercategories and isc_logconfig_create.
* If either fails, the lctx is destroyed and not returned
* to the caller.
*/
lctx->magic = LOG_MAGIC;
lctx->magic = LCTX_MAGIC;
isc_log_registercategories(lctx, isc_categories);
result = isc_logconfig_create(lctx, &lcfg);
} else
result = ISC_R_NOMEMORY;
if (result == ISC_R_SUCCESS) {
lctx->logconfig = lcfg;
*lctxp = lctx;
if (lcfgp != NULL)
*lcfgp = lcfg;
} else
if (lctx != NULL)
isc_log_destroy(&lctx);
return (result);
}
isc_result_t
isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) {
isc_logconfig_t *lcfg;
isc_logdestination_t destination;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(lcfgp != NULL && *lcfgp == NULL);
REQUIRE(VALID_CONTEXT(lctx));
lcfg = (isc_logconfig_t *)isc_mem_get(lctx->mctx, sizeof(*lcfg));
if (lcfg != NULL) {
lcfg->lctx = lctx;
lcfg->channels = NULL;
lcfg->channellists = NULL;
lcfg->channellist_count = 0;
lcfg->duplicate_interval = 0;
/*
* Normally the magic number is the last thing set in the
* structure, but isc_log_createchannel() needs a valid
* config. If the channel creation fails, the lcfg is not
* returned to the caller.
*/
lcfg->magic = LCFG_MAGIC;
} else
result = ISC_R_NOMEMORY;
/*
* Create the default channels:
@ -226,7 +294,7 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
*/
if (result == ISC_R_SUCCESS) {
destination.facility = LOG_INFO;
result = isc_log_createchannel(lctx, "default_syslog",
result = isc_log_createchannel(lcfg, "default_syslog",
ISC_LOG_TOSYSLOG, ISC_LOG_INFO,
&destination, 0);
}
@ -236,7 +304,7 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
result = isc_log_createchannel(lctx, "default_stderr",
result = isc_log_createchannel(lcfg, "default_stderr",
ISC_LOG_TOFILEDESC,
ISC_LOG_INFO,
&destination,
@ -247,14 +315,14 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
* Set the default category's channel to default_stderr.
* XXX I find this odd.
*/
default_channel.channel = lctx->channels;
default_channel.channel = lcfg->channels;
if (result == ISC_R_SUCCESS) {
destination.file.stream = stderr;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
result = isc_log_createchannel(lctx, "default_debug",
result = isc_log_createchannel(lcfg, "default_debug",
ISC_LOG_TOFILEDESC,
ISC_LOG_DYNAMIC,
&destination,
@ -262,20 +330,52 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
}
if (result == ISC_R_SUCCESS)
result = isc_log_createchannel(lctx, "null",
result = isc_log_createchannel(lcfg, "null",
ISC_LOG_TONULL,
ISC_LOG_DYNAMIC,
NULL, 0);
if (result == ISC_R_SUCCESS)
result = isc_log_registercategories(lctx, isc_categories);
*lcfgp = lcfg;
else
if (lcfg != NULL)
isc_logconfig_destroy(&lcfg);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, lctx, sizeof(*lctx));
return (result);
}
}
*lctxp = lctx;
isc_logconfig_t *
isc_logconfig_get(isc_log_t *lctx) {
return (lctx->logconfig);
}
isc_result_t
isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) {
isc_logconfig_t *old_cfg;
isc_result_t result;
REQUIRE(VALID_CONTEXT(lctx));
REQUIRE(VALID_CONFIG(lcfg));
REQUIRE(lcfg->lctx == lctx);
/*
* Ensure that lcfg->channellist_count == lctx->category_count.
* They won't be equal if isc_log_usechannel has not been called
* since any call to isc_log_registercategories.
*/
result = sync_channellist(lcfg);
if (result != ISC_R_SUCCESS)
return (result);
LOCK(&lctx->lock);
old_cfg = lctx->logconfig;
lctx->logconfig = lcfg;
UNLOCK(&lctx->lock);
isc_logconfig_destroy(&old_cfg);
return (ISC_R_SUCCESS);
}
@ -283,18 +383,63 @@ isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp) {
void
isc_log_destroy(isc_log_t **lctxp) {
isc_log_t *lctx;
isc_logconfig_t *lcfg;
isc_mem_t *mctx;
isc_logchannel_t *channel, *next_channel;
isc_logchannellist_t *channellist, *next_channellist;
isc_logmessage_t *message, *next_message;
unsigned int i;
isc_logmessage_t *message;
REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp));
lctx = *lctxp;
mctx = lctx->mctx;
for (channel = lctx->channels; channel != NULL;
if (lctx->logconfig != NULL) {
lcfg = lctx->logconfig;
lctx->logconfig = NULL;
isc_logconfig_destroy(&lcfg);
}
RUNTIME_CHECK(isc_mutex_destroy(&lctx->lock) == ISC_R_SUCCESS);
while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) {
ISC_LIST_UNLINK(lctx->messages, message, link);
isc_mem_put(mctx, message,
sizeof(*message) + strlen(message->text) + 1);
}
lctx->buffer[0] = '\0';
lctx->debug_level = 0;
lctx->category_count = 0;
lctx->module_count = 0;
lctx->mctx = NULL;
lctx->magic = 0;
isc_mem_put(mctx, lctx, sizeof(*lctx));
*lctxp = NULL;
}
void
isc_logconfig_destroy(isc_logconfig_t **lcfgp) {
isc_logconfig_t *lcfg;
isc_mem_t *mctx;
isc_logchannel_t *channel, *next_channel;
isc_logchannellist_t *item, *next_item;
unsigned int i;
REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp));
lcfg = *lcfgp;
/*
* This function cannot be called with a logconfig that is in
* use by a log context.
*/
REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg);
mctx = lcfg->lctx->mctx;
for (channel = lcfg->channels; channel != NULL;
channel = next_channel) {
next_channel = channel->next;
@ -309,39 +454,28 @@ isc_log_destroy(isc_log_t **lctxp) {
isc_mem_put(mctx, channel, sizeof(*channel));
}
for (i = 0; i < lctx->category_count; i++)
for (channellist = lctx->categories[i]; channellist != NULL;
channellist = next_channellist) {
next_channellist = channellist->next;
isc_mem_put(mctx, channellist, sizeof(*channellist));
for (i = 0; i < lcfg->channellist_count; i++)
for (item = lcfg->channellists[i]; item != NULL;
item = next_item) {
next_item = item->next;
isc_mem_put(mctx, item, sizeof(*item));
}
isc_mem_put(mctx, &lctx->categories[0],
lctx->category_count * sizeof(isc_logchannellist_t **));
isc_mem_put(mctx, lcfg->channellists,
lcfg->channellist_count * sizeof(isc_logchannellist_t **));
for (message = ISC_LIST_HEAD(lctx->messages); message != NULL;
message = next_message) {
lcfg->duplicate_interval = 0;
lcfg->magic = 0;
next_message = message->next;
isc_mem_put(mctx, message,
sizeof(*message) + strlen(message->text) + 1);
}
ISC_LIST_INIT(lctx->messages);
isc_mem_put(mctx, lcfg, sizeof(*lcfg));
isc_mutex_destroy(&lctx->lock);
lctx->magic = 0;
isc_mem_put(mctx, lctx, sizeof(*lctx));
*lctxp = NULL;
*lcfgp = NULL;
}
isc_result_t
void
isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) {
isc_logchannellist_t **lists;
isc_logcategory_t *catp;
unsigned int old_count, new_count, bytes;
unsigned int old_count, new_count;
REQUIRE(VALID_CONTEXT(lctx));
REQUIRE(categories != NULL);
@ -355,23 +489,7 @@ isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) {
for (new_count = old_count, catp = categories; catp->name != NULL; )
catp++->id = new_count++;
lists = (isc_logchannellist_t **)isc_mem_get(lctx->mctx,
new_count * sizeof(isc_logchannellist_t *));
if (lists == NULL)
return (ISC_R_NOMEMORY);
memset(lists, 0, new_count * sizeof(isc_logchannellist_t *));
if (old_count != 0) {
bytes = old_count * sizeof(isc_logchannellist_t *);
memcpy(lists, lctx->categories, bytes);
isc_mem_put(lctx->mctx, lctx->categories, bytes);
}
lctx->categories = lists;
lctx->category_count = new_count;
return (ISC_R_SUCCESS);
}
void
@ -395,13 +513,14 @@ isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) {
}
isc_result_t
isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
int level, isc_logdestination_t *destination,
unsigned int flags)
isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
unsigned int type, int level,
isc_logdestination_t *destination, unsigned int flags)
{
isc_logchannel_t *channel;
isc_mem_t *mctx;
REQUIRE(VALID_CONTEXT(lctx));
REQUIRE(VALID_CONFIG(lcfg));
REQUIRE(name != NULL);
REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE ||
type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL);
@ -409,16 +528,17 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
REQUIRE(level >= ISC_LOG_CRITICAL);
REQUIRE((flags & ~ISC_LOG_PRINTALL) == 0);
/* XXX DCL find duplicate names? */
/* XXXDCL find duplicate names? */
channel = (isc_logchannel_t *)isc_mem_get(lctx->mctx,
sizeof(*channel));
mctx = lcfg->lctx->mctx;
channel = (isc_logchannel_t *)isc_mem_get(mctx, sizeof(*channel));
if (channel == NULL)
return (ISC_R_NOMEMORY);
channel->name = isc_mem_strdup(lctx->mctx, name);
channel->name = isc_mem_strdup(mctx, name);
if (channel->name == NULL) {
isc_mem_put(lctx->mctx, channel, sizeof(*channel));
isc_mem_put(mctx, channel, sizeof(*channel));
return (ISC_R_NOMEMORY);
}
@ -438,7 +558,7 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
* writable memory.
*/
FILE_NAME(channel) =
isc_mem_strdup(lctx->mctx, destination->file.name);
isc_mem_strdup(mctx, destination->file.name);
FILE_STREAM(channel) = NULL;
FILE_MAXSIZE(channel) = destination->file.maximum_size;
FILE_VERSIONS(channel) = destination->file.versions;
@ -456,19 +576,17 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
break;
default:
isc_mem_put(lctx->mctx, channel->name,
strlen(channel->name) + 1);
isc_mem_put(lctx->mctx, channel, sizeof(*channel));
isc_mem_put(mctx, channel->name, strlen(channel->name) + 1);
isc_mem_put(mctx, channel, sizeof(*channel));
return (ISC_R_UNEXPECTED);
}
channel->next = lctx->channels;
lctx->channels = channel;
channel->next = lcfg->channels;
lcfg->channels = channel;
/*
* If default_stderr was redefined, make the default category
* point to the new default_stderr.
* XXX I find this odd.
*/
if (strcmp(name, "default_stderr") == 0)
default_channel.channel = channel;
@ -477,19 +595,23 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
}
isc_result_t
isc_log_usechannel(isc_log_t *lctx, const char *name,
isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
isc_logcategory_t *category, isc_logmodule_t *module)
{
isc_log_t *lctx;
isc_logchannel_t *channel;
isc_result_t result;
isc_result_t result = ISC_R_SUCCESS;
unsigned int i;
REQUIRE(VALID_CONTEXT(lctx));
REQUIRE(VALID_CONFIG(lcfg));
REQUIRE(name != NULL);
lctx = lcfg->lctx;
REQUIRE(category == NULL || category->id < lctx->category_count);
REQUIRE(module == NULL || module->id < lctx->module_count);
for (channel = lctx->channels; channel != NULL;
for (channel = lcfg->channels; channel != NULL;
channel = channel->next)
if (strcmp(name, channel->name) == 0)
break;
@ -497,13 +619,8 @@ isc_log_usechannel(isc_log_t *lctx, const char *name,
if (channel == NULL)
return (ISC_R_NOTFOUND);
/*
* Silence bogus GCC warning, "`result' might be used uninitialized".
*/
result = ISC_R_SUCCESS;
if (category != NULL)
result = assignchannel(lctx, category->id, module, channel);
result = assignchannel(lcfg, category->id, module, channel);
else
/*
@ -511,7 +628,7 @@ isc_log_usechannel(isc_log_t *lctx, const char *name,
* the default channel.
*/
for (i = 0; i < lctx->category_count; i++) {
result = assignchannel(lctx, i, module, channel);
result = assignchannel(lcfg, i, module, channel);
if (result != ISC_R_SUCCESS)
break;
}
@ -590,17 +707,17 @@ isc_log_getdebuglevel(isc_log_t *lctx) {
}
void
isc_log_setduplicateinterval(isc_log_t *lctx, unsigned int interval) {
REQUIRE(VALID_CONTEXT(lctx));
isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval) {
REQUIRE(VALID_CONFIG(lcfg));
lctx->duplicate_interval = interval;
lcfg->duplicate_interval = interval;
}
unsigned int
isc_log_getduplicateinterval(isc_log_t *lctx) {
REQUIRE(VALID_CONTEXT(lctx));
isc_log_getduplicateinterval(isc_logconfig_t *lcfg) {
REQUIRE(VALID_CONTEXT(lcfg));
return (lctx->duplicate_interval);
return (lcfg->duplicate_interval);
}
/* XXXDCL NT -- This interface will assuredly be changing. */
@ -615,7 +732,9 @@ isc_log_closefilelogs(isc_log_t *lctx) {
REQUIRE(VALID_CONTEXT(lctx));
for (channel = lctx->channels; channel != NULL; channel= channel->next)
for (channel = lctx->logconfig->channels; channel != NULL;
channel = channel->next)
if (channel->type == ISC_LOG_TOFILE &&
FILE_STREAM(channel) != NULL) {
(void)fclose(FILE_STREAM(channel));
@ -628,16 +747,28 @@ isc_log_closefilelogs(isc_log_t *lctx) {
****/
static isc_result_t
assignchannel(isc_log_t *lctx, unsigned int category_id,
assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
isc_logmodule_t *module, isc_logchannel_t *channel)
{
isc_logchannellist_t *new_item;
isc_log_t *lctx;
isc_result_t result;
REQUIRE(VALID_CONFIG(lcfg));
lctx = lcfg->lctx;
REQUIRE(VALID_CONTEXT(lctx));
REQUIRE(category_id < lctx->category_count);
REQUIRE(module == NULL || module->id < lctx->module_count);
REQUIRE(channel != NULL);
/*
* Ensure lcfg->channellist_count == lctx->category_count.
*/
result = sync_channellist(lcfg);
if (result != ISC_R_SUCCESS)
return (result);
new_item = (isc_logchannellist_t *)isc_mem_get(lctx->mctx,
sizeof(*new_item));
if (new_item == NULL)
@ -645,16 +776,52 @@ assignchannel(isc_log_t *lctx, unsigned int category_id,
new_item->channel = channel;
new_item->module = module;
new_item->next = lctx->categories[category_id];
new_item->next = lcfg->channellists[category_id];
lctx->categories[category_id] = new_item;
lcfg->channellists[category_id] = new_item;
return (ISC_R_SUCCESS);
}
static isc_result_t
sync_channellist(isc_logconfig_t *lcfg) {
int bytes;
isc_log_t *lctx;
isc_logchannellist_t **lists;
REQUIRE(VALID_CONFIG(lcfg));
lctx = lcfg->lctx;
REQUIRE(lctx->category_count != 0);
if (lctx->category_count == lcfg->channellist_count)
return (ISC_R_SUCCESS);
bytes = lctx->category_count * sizeof(isc_logchannellist_t *);
lists = (isc_logchannellist_t **)isc_mem_get(lctx->mctx, bytes);
if (lists == NULL)
return (ISC_R_NOMEMORY);
memset(lists, 0, bytes);
if (lcfg->channellist_count != 0) {
bytes = lcfg->channellist_count *
sizeof(isc_logchannellist_t *);
memcpy(lists, lcfg->channellists, bytes);
isc_mem_put(lctx->mctx, lcfg->channellists, bytes);
}
lcfg->channellists = lists;
lcfg->channellist_count = lctx->category_count;
return (ISC_R_SUCCESS);
}
static unsigned int
greatest_version(isc_logchannel_t *channel)
{
greatest_version(isc_logchannel_t *channel) {
/* XXXDCL HIGHLY NT */
char *dirname, *basename, *digit_end;
int version, greatest = -1;
@ -836,6 +1003,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
struct tm *timeptr;
time_t now;
isc_boolean_t matched = ISC_FALSE;
isc_logconfig_t *lcfg;
isc_logchannel_t *channel;
isc_logchannellist_t *category_channels;
isc_result_t result;
@ -859,10 +1027,11 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
level_string[0] = '\0';
lctx->buffer[0] = '\0';
category_channels = lctx->categories[category->id];
LOCK(&lctx->lock);
if (isc_mutex_lock(&lctx->lock) != ISC_R_SUCCESS)
return;
lcfg = lctx->logconfig;
category_channels = lcfg->channellists[category->id];
/*
* XXX duplicate filtering (do not write multiple times to same source
@ -877,12 +1046,12 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
break;
if (category_channels == NULL && ! matched &&
category_channels != lctx->categories[0])
category_channels != lcfg->channellists[0])
/*
* No category/module pair was explicitly configured.
* Try the category named "default".
*/
category_channels = lctx->categories[0];
category_channels = lcfg->channellists[0];
if (category_channels == NULL && ! matched)
/*
@ -951,7 +1120,7 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
isc_interval_t interval;
isc_interval_set(&interval,
lctx->duplicate_interval, 0);
lcfg->duplicate_interval, 0);
/*
* 'oldest' is the age of the oldest messages
@ -974,29 +1143,23 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
* so it should be dropped from
* the history.
*
* XXX Setting the interval
* Setting the interval to be
* to be longer will obviously
* not cause the expired
* message to spring back into
* existence.
*/
new = message->next;
new = ISC_LIST_NEXT(message,
link);
ISC_LIST_UNLINK(lctx->messages,
message, link);
isc_mem_put(lctx->mctx,
message,
sizeof(*message) + 1 +
strlen(message->text));
lctx->messages.head = new;
if (new == NULL)
/*
* Last element of the
* list was removed, so
* the tail pointer
* is no longer valid.
*/
lctx->messages.tail =
NULL;
message = new;
continue;
}
@ -1012,11 +1175,11 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
* Unlock the mutex and
* get the hell out of Dodge.
*/
isc_mutex_unlock(&lctx->lock);
UNLOCK(&lctx->lock);
return;
}
message = message->next;
message = ISC_LIST_NEXT(message, link);
}
/*
@ -1040,20 +1203,13 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
* This will cause the message
* to immediately expire on
* the next call to [v]write1.
* XXX ok?
* What's a fella to do if
* getting the time fails?
*/
isc_time_settoepoch(&new->time);
new->next = NULL;
if (ISC_LIST_EMPTY(lctx->messages)) {
lctx->messages.head = new;
lctx->messages.tail = new;
} else {
lctx->messages.tail->next =
new;
lctx->messages.tail = new;
}
ISC_LIST_APPEND(lctx->messages,
new, link);
}
}
}
@ -1145,5 +1301,5 @@ isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
} while (1);
isc_mutex_unlock(&lctx->lock);
UNLOCK(&lctx->lock);
}