mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 14:07:59 +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:
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
/*
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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.
|
||||
*
|
||||
|
472
lib/isc/log.c
472
lib/isc/log.c
@@ -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);
|
||||
@@ -411,14 +530,15 @@ isc_log_createchannel(isc_log_t *lctx, const char *name, unsigned int type,
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user