mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-21 14:17:27 -04:00
[master] rndc dnstap -roll
4411. [func] "rndc dnstap -roll" automatically rolls the dnstap output file; the previous version is saved with ".0" suffix, and earlier versions with ".1" and so on. An optional numeric argument indicates how many prior files to save. [RT #42830]
This commit is contained in:
parent
a2101037d9
commit
ffa622d7a3
14 changed files with 179 additions and 86 deletions
6
CHANGES
6
CHANGES
|
|
@ -1,3 +1,9 @@
|
|||
4411. [func] "rndc dnstap -roll" automatically rolls the
|
||||
dnstap output file; the previous version is
|
||||
saved with ".0" suffix, and earlier versions
|
||||
with ".1" and so on. An optional numeric argument
|
||||
indicates how many prior files to save. [RT #42830]
|
||||
|
||||
4410. [bug] Address use after free and memory leak with dnstap.
|
||||
[RT #42746]
|
||||
|
||||
|
|
|
|||
|
|
@ -272,8 +272,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_boolean_t readonly,
|
|||
result = ns_server_testgen(lex, text);
|
||||
} else if (command_compare(command, NS_COMMAND_MKEYS)) {
|
||||
result = ns_server_mkeys(ns_g_server, lex, text);
|
||||
} else if (command_compare(command, NS_COMMAND_DNSTAPREOPEN)) {
|
||||
result = ns_server_dnstap_reopen(ns_g_server);
|
||||
} else if (command_compare(command, NS_COMMAND_DNSTAP) ||
|
||||
command_compare(command, NS_COMMAND_DNSTAPREOPEN)) {
|
||||
result = ns_server_dnstap(ns_g_server, lex, text);
|
||||
} else {
|
||||
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#define NS_COMMAND_TESTGEN "testgen"
|
||||
#define NS_COMMAND_MKEYS "managed-keys"
|
||||
#define NS_COMMAND_DNSTAPREOPEN "dnstap-reopen"
|
||||
#define NS_COMMAND_DNSTAP "dnstap"
|
||||
|
||||
isc_result_t
|
||||
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
|
||||
|
|
|
|||
|
|
@ -740,6 +740,6 @@ ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text);
|
|||
* Close and reopen DNSTAP output file.
|
||||
*/
|
||||
isc_result_t
|
||||
ns_server_dnstap_reopen(ns_server_t *server);
|
||||
ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text);
|
||||
|
||||
#endif /* NAMED_SERVER_H */
|
||||
|
|
|
|||
|
|
@ -12211,14 +12211,45 @@ ns_server_mkeys(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
ns_server_dnstap_reopen(ns_server_t *server) {
|
||||
|
||||
ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
|
||||
#if HAVE_DNSTAP
|
||||
if (server->dtenv != NULL)
|
||||
return(dns_dt_reopen(server->dtenv));
|
||||
return (ISC_R_NOTFOUND);
|
||||
char *ptr;
|
||||
|
||||
if (server->dtenv == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
/* Check the command name. */
|
||||
ptr = next_token(lex, text);
|
||||
if (ptr == NULL)
|
||||
return (ISC_R_UNEXPECTEDEND);
|
||||
|
||||
/* "dnstap-reopen" was used in 9.11.0b1 */
|
||||
if (strcasecmp(ptr, "dnstap-reopen") == 0)
|
||||
return (dns_dt_reopen(server->dtenv, ISC_FALSE));
|
||||
|
||||
/* Find out what we are to do. */
|
||||
ptr = next_token(lex, text);
|
||||
if (ptr == NULL)
|
||||
return (ISC_R_UNEXPECTEDEND);
|
||||
|
||||
if (strcasecmp(ptr, "-reopen") == 0)
|
||||
return (dns_dt_reopen(server->dtenv, -1));
|
||||
else if ((strcasecmp(ptr, "-roll") == 0)) {
|
||||
int backups = 0;
|
||||
unsigned int n;
|
||||
ptr = next_token(lex, text);
|
||||
if (ptr != NULL) {
|
||||
n = sscanf(ptr, "%u", &backups);
|
||||
if (n != 1U)
|
||||
return (ISC_R_BADNUMBER);
|
||||
}
|
||||
return (dns_dt_reopen(server->dtenv, backups));
|
||||
} else
|
||||
return (DNS_R_SYNTAX);
|
||||
#else
|
||||
UNUSED(server);
|
||||
UNUSED(lex);
|
||||
UNUSED(text);
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,11 +306,18 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><userinput>dnstap-reopen</userinput></term>
|
||||
<term><userinput>dnstap ( -reopen | -roll <optional><replaceable>number</replaceable></optional> )</userinput></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Close and re-open DNSTAP output files. This allows the files
|
||||
to be renamed externally then to be re-opened.
|
||||
Close and re-open DNSTAP output files.
|
||||
<command>rndc dnstap -reopen</command> allows the output
|
||||
file to be renamed externally, then re-opened.
|
||||
<command>rndc dnstap -roll</command> causes the output file
|
||||
to be rolled automatically, similar to log files; the most
|
||||
recent output file has ".0" appended to its name; the
|
||||
previous most recent output file is moved to ".1", and so on.
|
||||
If <replaceable>number</replaceable> is specified, then the
|
||||
number of backup log files is limited to that number.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
@ -605,17 +612,17 @@
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><userinput>recursing</userinput></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Dump the list of queries <command>named</command> is currently
|
||||
recursing on, and the list of domains to which iterative
|
||||
queries are currently being sent. (The second list includes
|
||||
the number of fetches currently active for the given domain,
|
||||
and how many have been passed or dropped because of the
|
||||
<option>fetches-per-zone</option> option.)
|
||||
</para>
|
||||
</listitem>
|
||||
<term><userinput>recursing</userinput></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Dump the list of queries <command>named</command> is currently
|
||||
recursing on, and the list of domains to which iterative
|
||||
queries are currently being sent. (The second list includes
|
||||
the number of fetches currently active for the given domain,
|
||||
and how many have been passed or dropped because of the
|
||||
<option>fetches-per-zone</option> option.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
|
|
|||
|
|
@ -15,15 +15,16 @@ status=0
|
|||
|
||||
$DIG +short @10.53.0.3 -p 5300 a.example > dig.out
|
||||
|
||||
# check three different dnstap reopen/roll methods:
|
||||
# ns1: dnstap-reopen; ns2: dnstap -reopen; ns3: dnstap -roll
|
||||
mv ns1/dnstap.out ns1/dnstap.out.save
|
||||
mv ns2/dnstap.out ns2/dnstap.out.save
|
||||
mv ns3/dnstap.out ns3/dnstap.out.save
|
||||
|
||||
sleep 2
|
||||
|
||||
$RNDCCMD -s 10.53.0.1 dnstap-reopen | sed 's/^/I:ns1 /'
|
||||
$RNDCCMD -s 10.53.0.2 dnstap-reopen | sed 's/^/I:ns2 /'
|
||||
$RNDCCMD -s 10.53.0.3 dnstap-reopen | sed 's/^/I:ns3 /'
|
||||
$RNDCCMD -s 10.53.0.2 dnstap -reopen | sed 's/^/I:ns2 /'
|
||||
$RNDCCMD -s 10.53.0.3 dnstap -roll | sed 's/^/I:ns3 /'
|
||||
|
||||
$DIG +short @10.53.0.3 -p 5300 a.example > dig.out
|
||||
sleep 1
|
||||
|
|
@ -56,6 +57,7 @@ cr2=`$DNSTAPREAD ns2/dnstap.out.save | grep "CR " | wc -l`
|
|||
rq2=`$DNSTAPREAD ns2/dnstap.out.save | grep "RQ " | wc -l`
|
||||
rr2=`$DNSTAPREAD ns2/dnstap.out.save | grep "RR " | wc -l`
|
||||
|
||||
mv ns3/dnstap.out.0 ns3/dnstap.out.save
|
||||
udp3=`$DNSTAPREAD ns3/dnstap.out.save | grep "UDP " | wc -l`
|
||||
tcp3=`$DNSTAPREAD ns3/dnstap.out.save | grep "TCP " | wc -l`
|
||||
aq3=`$DNSTAPREAD ns3/dnstap.out.save | grep "AQ " | wc -l`
|
||||
|
|
|
|||
|
|
@ -196,8 +196,19 @@
|
|||
a human-readable format.
|
||||
</para>
|
||||
<para>
|
||||
<command>rndc dnstap-reopen</command> can be used reopen
|
||||
dnstap output files after renaming them.
|
||||
<command>rndc dnstap -roll</command> causes <command>dnstap</command>
|
||||
output files to be rolled like log files -- the most recent output
|
||||
file is renamed with a <filename>.0</filename> suffix, the next
|
||||
most recent with <filename>.1</filename>, etc. (Note that this
|
||||
only works when <command>dnstap</command> output is being written
|
||||
to a file, not to a UNIX domain socket.) An optional numerical
|
||||
argument specifies how many backup log files to retain; if not
|
||||
specified or set to 0, there is no limit.
|
||||
</para>
|
||||
<para>
|
||||
<command>rndc dnstap -reopen</command> simply closes and reopens
|
||||
the <command>dnstap</command> output channel without renaming
|
||||
the output file.
|
||||
</para>
|
||||
<para>
|
||||
For more information on <command>dnstap</command>, see
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ struct dns_dtenv {
|
|||
isc_region_t identity;
|
||||
isc_region_t version;
|
||||
char *path;
|
||||
dns_dtmode_t mode;
|
||||
};
|
||||
|
||||
#define CHECK(x) do { \
|
||||
|
|
@ -232,6 +233,7 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
|
|||
fstrm_writer_destroy(&fw);
|
||||
CHECK(ISC_R_FAILURE);
|
||||
}
|
||||
env->mode = mode;
|
||||
|
||||
isc_mem_attach(mctx, &env->mctx);
|
||||
|
||||
|
|
@ -265,25 +267,46 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dt_reopen(dns_dtenv_t *env) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_dt_reopen(dns_dtenv_t *env, int roll) {
|
||||
isc_result_t result;
|
||||
isc_logfile_t file;
|
||||
fstrm_res res;
|
||||
|
||||
REQUIRE(VALID_DTENV(env));
|
||||
|
||||
if (env->fw == NULL)
|
||||
return (ISC_R_FAILURE);
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSTAP,
|
||||
DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO,
|
||||
"reopening dnstap destination '%s'",
|
||||
"%s dnstap destination '%s'",
|
||||
(roll < 0) ? "reopening" : "rolling",
|
||||
env->path);
|
||||
|
||||
if (env->fw != NULL) {
|
||||
res = fstrm_writer_close(env->fw);
|
||||
if (res == fstrm_res_success)
|
||||
fstrm_writer_open(env->fw);
|
||||
return (ISC_R_SUCCESS);
|
||||
res = fstrm_writer_close(env->fw);
|
||||
if (res != fstrm_res_success)
|
||||
return (ISC_R_FAILURE);
|
||||
|
||||
if (roll >= 0) {
|
||||
/*
|
||||
* Create a temporary isc_logfile_t structure so we can
|
||||
* take advantage of the logfile rolling facility.
|
||||
*/
|
||||
char *filename = isc_mem_strdup(env->mctx, env->path);
|
||||
file.name = filename;
|
||||
file.stream = NULL;
|
||||
file.versions = roll != 0 ? roll : ISC_LOG_ROLLINFINITE;
|
||||
file.maximum_size = 0;
|
||||
file.maximum_reached = ISC_FALSE;
|
||||
result = isc_logfile_roll(&file);
|
||||
isc_mem_free(env->mctx, filename);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
|
||||
return (result);
|
||||
fstrm_writer_open(env->fw);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
|
|||
|
|
@ -150,10 +150,16 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
|
|||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dt_reopen(dns_dtenv_t *env);
|
||||
dns_dt_reopen(dns_dtenv_t *env, int roll);
|
||||
/*%<
|
||||
* Reopens files established by dns_dt_create().
|
||||
*
|
||||
* If 'roll' is non-negative and 'env->mode' is dns_dtmode_file,
|
||||
* then the file is automatically rolled over before reopening.
|
||||
* The value of 'roll' indicates the number of backup log files to
|
||||
* keep. If 'roll' is negative, or if 'env->mode' is dns_dtmode_unix,
|
||||
* then the channel is simply reopened.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'env' is a valid dnstap environment.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -139,11 +139,11 @@ ATF_TC_BODY(dispatchset_get, tc) {
|
|||
|
||||
static void
|
||||
senddone(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socket_t *socket = event->ev_arg;
|
||||
isc_socket_t *sock = event->ev_arg;
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
isc_socket_detach(&socket);
|
||||
isc_socket_detach(&sock);
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +152,7 @@ nameserver(isc_task_t *task, isc_event_t *event) {
|
|||
isc_result_t result;
|
||||
isc_region_t region;
|
||||
isc_socket_t *dummy;
|
||||
isc_socket_t *socket = event->ev_arg;
|
||||
isc_socket_t *sock = event->ev_arg;
|
||||
isc_socketevent_t *ev = (isc_socketevent_t *)event;
|
||||
static unsigned char buf1[16];
|
||||
static unsigned char buf2[16];
|
||||
|
|
@ -171,8 +171,8 @@ nameserver(isc_task_t *task, isc_event_t *event) {
|
|||
region.base = buf1;
|
||||
region.length = sizeof(buf1);
|
||||
dummy = NULL;
|
||||
isc_socket_attach(socket, &dummy);
|
||||
result = isc_socket_sendto(socket, ®ion, task, senddone, socket,
|
||||
isc_socket_attach(sock, &dummy);
|
||||
result = isc_socket_sendto(sock, ®ion, task, senddone, sock,
|
||||
&ev->address, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
isc_socket_detach(&dummy);
|
||||
|
|
@ -183,8 +183,8 @@ nameserver(isc_task_t *task, isc_event_t *event) {
|
|||
region.base = buf2;
|
||||
region.length = sizeof(buf2);
|
||||
dummy = NULL;
|
||||
isc_socket_attach(socket, &dummy);
|
||||
result = isc_socket_sendto(socket, ®ion, task, senddone, socket,
|
||||
isc_socket_attach(sock, &dummy);
|
||||
result = isc_socket_sendto(sock, ®ion, task, senddone, sock,
|
||||
&ev->address, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
isc_socket_detach(&dummy);
|
||||
|
|
@ -222,8 +222,8 @@ ATF_TC_BODY(dispatch_getnext, tc) {
|
|||
isc_region_t region;
|
||||
isc_result_t result;
|
||||
isc_sockaddr_t local;
|
||||
isc_socket_t *dsocket = NULL;
|
||||
isc_socket_t *socket = NULL;
|
||||
isc_socket_t *dsock = NULL;
|
||||
isc_socket_t *sock = NULL;
|
||||
isc_task_t *task = NULL;
|
||||
isc_uint16_t id;
|
||||
struct in_addr ina;
|
||||
|
|
@ -254,21 +254,21 @@ ATF_TC_BODY(dispatch_getnext, tc) {
|
|||
* Create a local udp nameserver on the loopback.
|
||||
*/
|
||||
result = isc_socket_create(socketmgr, AF_INET, isc_sockettype_udp,
|
||||
&socket);
|
||||
&sock);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
ina.s_addr = htonl(INADDR_LOOPBACK);
|
||||
isc_sockaddr_fromin(&local, &ina, 0);
|
||||
result = isc_socket_bind(socket, &local, 0);
|
||||
result = isc_socket_bind(sock, &local, 0);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
result = isc_socket_getsockname(socket, &local);
|
||||
result = isc_socket_getsockname(sock, &local);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
first = ISC_TRUE;
|
||||
region.base = rbuf;
|
||||
region.length = sizeof(rbuf);
|
||||
result = isc_socket_recv(socket, ®ion, 1, task, nameserver, socket);
|
||||
result = isc_socket_recv(sock, ®ion, 1, task, nameserver, sock);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
result = dns_dispatch_addresponse(dispatch, &local, task, response,
|
||||
|
|
@ -279,10 +279,10 @@ ATF_TC_BODY(dispatch_getnext, tc) {
|
|||
message[0] = (id >> 8) & 0xff;
|
||||
message[1] = id & 0xff;
|
||||
|
||||
isc_socket_attach(dns_dispatch_getsocket(dispatch), &dsocket);
|
||||
isc_socket_attach(dns_dispatch_getsocket(dispatch), &dsock);
|
||||
region.base = message;
|
||||
region.length = sizeof(message);
|
||||
result = isc_socket_sendto(dsocket, ®ion, task, senddone, dsocket,
|
||||
result = isc_socket_sendto(dsock, ®ion, task, senddone, dsock,
|
||||
&local, NULL);
|
||||
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -294,8 +294,8 @@ ATF_TC_BODY(dispatch_getnext, tc) {
|
|||
/*
|
||||
* Shutdown nameserver.
|
||||
*/
|
||||
isc_socket_cancel(socket, task, ISC_SOCKCANCEL_RECV);
|
||||
isc_socket_detach(&socket);
|
||||
isc_socket_cancel(sock, task, ISC_SOCKCANCEL_RECV);
|
||||
isc_socket_detach(&sock);
|
||||
isc_task_detach(&task);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -903,6 +903,15 @@ isc_log_setcontext(isc_log_t *lctx);
|
|||
*\li lctx be a valid context.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_logfile_roll(isc_logfile_t *file);
|
||||
/*%<
|
||||
* Roll a logfile.
|
||||
*
|
||||
* Requires:
|
||||
*\li file is not NULL.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_LOG_H */
|
||||
|
|
|
|||
|
|
@ -223,10 +223,7 @@ static isc_result_t
|
|||
sync_channellist(isc_logconfig_t *lcfg);
|
||||
|
||||
static isc_result_t
|
||||
greatest_version(isc_logchannel_t *channel, int *greatest);
|
||||
|
||||
static isc_result_t
|
||||
roll_log(isc_logchannel_t *channel);
|
||||
greatest_version(isc_logfile_t *file, int *greatest);
|
||||
|
||||
static void
|
||||
isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
|
||||
|
|
@ -1134,8 +1131,7 @@ sync_channellist(isc_logconfig_t *lcfg) {
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
||||
/* XXXDCL HIGHLY NT */
|
||||
greatest_version(isc_logfile_t *file, int *greatestp) {
|
||||
char *bname, *digit_end;
|
||||
const char *dirname;
|
||||
int version, greatest = -1;
|
||||
|
|
@ -1147,15 +1143,13 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
|||
char *bname2;
|
||||
#endif
|
||||
|
||||
REQUIRE(channel->type == ISC_LOG_TOFILE);
|
||||
|
||||
/*
|
||||
* It is safe to DE_CONST the file.name because it was copied
|
||||
* with isc_mem_strdup in isc_log_createchannel.
|
||||
* with isc_mem_strdup().
|
||||
*/
|
||||
bname = strrchr(FILE_NAME(channel), sep);
|
||||
bname = strrchr(file->name, sep);
|
||||
#ifdef _WIN32
|
||||
bname2 = strrchr(FILE_NAME(channel), '\\');
|
||||
bname2 = strrchr(file->name, '\\');
|
||||
if ((bname != NULL && bname2 != NULL && bname2 > bname) ||
|
||||
(bname == NULL && bname2 != NULL)) {
|
||||
bname = bname2;
|
||||
|
|
@ -1164,9 +1158,9 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
|||
#endif
|
||||
if (bname != NULL) {
|
||||
*bname++ = '\0';
|
||||
dirname = FILE_NAME(channel);
|
||||
dirname = file->name;
|
||||
} else {
|
||||
DE_CONST(FILE_NAME(channel), bname);
|
||||
DE_CONST(file->name, bname);
|
||||
dirname = ".";
|
||||
}
|
||||
bnamelen = strlen(bname);
|
||||
|
|
@ -1177,7 +1171,7 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
|||
/*
|
||||
* Replace the file separator if it was taken out.
|
||||
*/
|
||||
if (bname != FILE_NAME(channel))
|
||||
if (bname != file->name)
|
||||
*(bname - 1) = sep;
|
||||
|
||||
/*
|
||||
|
|
@ -1189,8 +1183,8 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
|||
while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
|
||||
if (dir.entry.length > bnamelen &&
|
||||
strncmp(dir.entry.name, bname, bnamelen) == 0 &&
|
||||
dir.entry.name[bnamelen] == '.') {
|
||||
|
||||
dir.entry.name[bnamelen] == '.')
|
||||
{
|
||||
version = strtol(&dir.entry.name[bnamelen + 1],
|
||||
&digit_end, 10);
|
||||
if (*digit_end == '\0' && version > greatest)
|
||||
|
|
@ -1204,23 +1198,25 @@ greatest_version(isc_logchannel_t *channel, int *greatestp) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
roll_log(isc_logchannel_t *channel) {
|
||||
isc_result_t
|
||||
isc_logfile_roll(isc_logfile_t *file) {
|
||||
int i, n, greatest;
|
||||
char current[PATH_MAX + 1];
|
||||
char new[PATH_MAX + 1];
|
||||
const char *path;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(file != NULL);
|
||||
|
||||
/*
|
||||
* Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER
|
||||
* is specified. Apparently complete external control over the log
|
||||
* files is desired.
|
||||
*/
|
||||
if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
|
||||
if (file->versions == ISC_LOG_ROLLNEVER)
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
path = FILE_NAME(channel);
|
||||
path = file->name;
|
||||
|
||||
/*
|
||||
* Set greatest_version to the greatest existing version
|
||||
|
|
@ -1228,30 +1224,29 @@ roll_log(isc_logchannel_t *channel) {
|
|||
* though the file names are 0 based, so an oldest log of log.1
|
||||
* is a greatest_version of 2.
|
||||
*/
|
||||
result = greatest_version(channel, &greatest);
|
||||
result = greatest_version(file, &greatest);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* Now greatest should be set to the highest version number desired.
|
||||
* Since the highest number is one less than FILE_VERSIONS(channel)
|
||||
* Since the highest number is one less than file->versions.
|
||||
* when not doing infinite log rolling, greatest will need to be
|
||||
* decremented when it is equal to -- or greater than --
|
||||
* FILE_VERSIONS(channel). When greatest is less than
|
||||
* FILE_VERSIONS(channel), it is already suitable for use as
|
||||
* file->versions. When greatest is less than
|
||||
* file->versions, it is already suitable for use as
|
||||
* the maximum version number.
|
||||
*/
|
||||
|
||||
if (FILE_VERSIONS(channel) == ISC_LOG_ROLLINFINITE ||
|
||||
FILE_VERSIONS(channel) > greatest)
|
||||
if (file->versions == ISC_LOG_ROLLINFINITE || file->versions > greatest)
|
||||
; /* Do nothing. */
|
||||
else
|
||||
/*
|
||||
* When greatest is >= FILE_VERSIONS(channel), it needs to
|
||||
* be reduced until it is FILE_VERSIONS(channel) - 1.
|
||||
* When greatest is >= file->versions, it needs to
|
||||
* be reduced until it is file->versions - 1.
|
||||
* Remove any excess logs on the way to that value.
|
||||
*/
|
||||
while (--greatest >= FILE_VERSIONS(channel)) {
|
||||
while (--greatest >= file->versions) {
|
||||
n = snprintf(current, sizeof(current), "%s.%d",
|
||||
path, greatest);
|
||||
if (n >= (int)sizeof(current) || n < 0)
|
||||
|
|
@ -1286,7 +1281,7 @@ roll_log(isc_logchannel_t *channel) {
|
|||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
if (FILE_VERSIONS(channel) != 0) {
|
||||
if (file->versions != 0) {
|
||||
n = snprintf(new, sizeof(new), "%s.0", path);
|
||||
if (n >= (int)sizeof(new) || n < 0)
|
||||
result = ISC_R_NOSPACE;
|
||||
|
|
@ -1348,11 +1343,11 @@ isc_log_open(isc_logchannel_t *channel) {
|
|||
if (result == ISC_R_SUCCESS && roll) {
|
||||
if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
|
||||
return (ISC_R_MAXSIZE);
|
||||
result = roll_log(channel);
|
||||
result = isc_logfile_roll(&channel->destination.file);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if ((channel->flags & ISC_LOG_OPENERR) == 0) {
|
||||
syslog(LOG_ERR,
|
||||
"isc_log_open: roll_log '%s' "
|
||||
"isc_log_open: isc_logfile_roll '%s' "
|
||||
"failed: %s",
|
||||
FILE_NAME(channel),
|
||||
isc_result_totext(result));
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ isc_logconfig_create
|
|||
isc_logconfig_destroy
|
||||
isc_logconfig_get
|
||||
isc_logconfig_use
|
||||
isc_logfile_roll
|
||||
isc_md5_final
|
||||
isc_md5_init
|
||||
isc_md5_invalidate
|
||||
|
|
|
|||
Loading…
Reference in a new issue