Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169832091
D20764.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D20764.diff
View Options
Index: usr.sbin/syslogd/syslog.conf.5
===================================================================
--- usr.sbin/syslogd/syslog.conf.5
+++ usr.sbin/syslogd/syslog.conf.5
@@ -28,7 +28,7 @@
.\" @(#)syslog.conf.5 8.1 (Berkeley) 6/9/93
.\" $FreeBSD$
.\"
-.Dd November 1, 2016
+.Dd June 25, 2019
.Dt SYSLOG.CONF 5
.Os
.Sh NAME
@@ -342,6 +342,21 @@
.Dq -
option may improve performance,
especially if the kernel is logging many messages.
+.Pp
+Options may be specified after the pathname.
+The options, delimited by whitespace, take the form of a letter,
+potentially followed by an associated value.
+The available options are:
+.Bl -tag -indent
+.It Ar R size
+Limit the growth of the file to the given size.
+If the file exceeds that size, enter
+.Dq recycle
+mode, in which the last 32 KBytes of the file become a circular buffer
+which is continually overwritten, preserving the bulk of the original file.
+The size is specified in bytes, with the usual power-of-two suffixes
+recognized.
+.El
.It
A hostname (preceded by an at
.Pq Dq @
Index: usr.sbin/syslogd/syslogd.c
===================================================================
--- usr.sbin/syslogd/syslogd.c
+++ usr.sbin/syslogd/syslogd.c
@@ -199,6 +199,24 @@
static STAILQ_HEAD(, socklist) shead = STAILQ_HEAD_INITIALIZER(shead);
/*
+ * If a file has a size limit specified, and that limit is exceeded, we treat
+ * the last few kbytes of the file as a circular buffer and repeatedly overwrite
+ * it. When that happens we write a msg to the file saying that we're doing so.
+ * This effectively turns the end of the file into a small circular buffer but
+ * preserves the bulk of the file (and thus hopefully preserves some clue as to
+ * what began spewing to the log to create this condition).
+ *
+ */
+#define LIMIT_CIRCBUF_SIZE (32 * 1024)
+#define LIMIT_CIRCBUF_MESSAGE \
+"\n" \
+"\n*******************************************************************************" \
+"\nsyslogd: Configured file size limit has been exceeded; data has been lost." \
+"\nsyslogd: From here down the file is being recycled in circular-buffer mode." \
+"\n*******************************************************************************" \
+"\n"
+
+/*
* Flags to logmsg().
*/
@@ -242,8 +260,11 @@
struct addrinfo *f_addr;
} f_forw; /* forwarding address */
- char f_fname[MAXPATHLEN];
struct {
+ char f_fname[MAXPATHLEN];
+ off_t f_fsizelimit;
+ } f_logfile;
+ struct {
char f_pname[MAXPATHLEN];
pid_t f_pid;
} f_pipe;
@@ -251,7 +272,8 @@
#define fu_uname f_un.f_uname
#define fu_forw_hname f_un.f_forw.f_hname
#define fu_forw_addr f_un.f_forw.f_addr
-#define fu_fname f_un.f_fname
+#define fu_fname f_un.f_logfile.f_fname
+#define fu_fsizelimit f_un.f_logfile.f_fsizelimit
#define fu_pipe_pname f_un.f_pipe.f_pname
#define fu_pipe_pid f_un.f_pipe.f_pid
char f_prevline[MAXSVLINE]; /* last message logged */
@@ -1727,6 +1749,18 @@
case F_FILE:
dprintf(" %s\n", f->fu_fname);
iovlist_append(il, "\n");
+ /*
+ * If this file has a size limit, and we're about to write to a
+ * location beyond that limit, seek to limit-CIRCBUF_SIZE before
+ * writing and drop a message into the file to say we lost data.
+ */
+ if (f->fu_fsizelimit != 0 && f->fu_fsizelimit <
+ lseek(f->f_file, 0, SEEK_CUR)) {
+ lseek(f->f_file, f->fu_fsizelimit - LIMIT_CIRCBUF_SIZE,
+ SEEK_SET);
+ write(f->f_file, LIMIT_CIRCBUF_MESSAGE,
+ sizeof(LIMIT_CIRCBUF_MESSAGE) - 1);
+ }
if (writev(f->f_file, il->iov, il->iovcnt) < 0) {
/*
* If writev(2) fails for potentially transient errors
@@ -2529,6 +2563,42 @@
}
/*
+ * Parse a filename config line to extract the filename and any options that may
+ * follow it on the line, storing the values into f->f_un.logfile.
+ */
+static void
+parse_fline(const char *p, struct filed *f)
+{
+ char *q, *r, *s;
+ uint64_t sizelimit;
+
+ (void)strlcpy(f->fu_fname, p, sizeof(f->fu_fname));
+
+ /* If there are no spaces on the line, no options follow the name. */
+ if ((q = strpbrk(f->fu_fname, "\t ")) == NULL)
+ return;
+
+ /* The only option we support right now is 'R' for recycle. */
+ r = q + strspn(q, "\t ");
+ if (*r++ != 'R')
+ return;
+
+ /* The thing following the R must be numeric. */
+ s = r + strspn(r, "\t ");
+ if (expand_number(s, &sizelimit) == -1)
+ return;
+
+ /*
+ * Looks like a valid R <size> option is present. Terminate fu_name at
+ * the first space and store the limit associated with the file.
+ */
+ *q = 0;
+ f->fu_fsizelimit = sizelimit;
+ if (f->fu_fsizelimit < LIMIT_CIRCBUF_SIZE)
+ f->fu_fsizelimit = LIMIT_CIRCBUF_SIZE;
+}
+
+/*
* Crack a configuration file line
*/
static struct filed *
@@ -2746,9 +2816,14 @@
break;
case '/':
- if ((f->f_file = open(p, logflags, 0600)) < 0) {
+ /* Parse the filename and any options into f->f_un.f_logfile. */
+ parse_fline(p, f);
+ if (f->fu_fsizelimit != 0) {
+ logflags &= ~O_APPEND;
+ }
+ if ((f->f_file = open(f->fu_fname, logflags, 0600)) < 0) {
f->f_type = F_UNUSED;
- logerror(p);
+ logerror(f->fu_fname);
break;
}
if (syncfile)
@@ -2761,7 +2836,12 @@
(void)strlcpy(f->fu_fname, p + sizeof(_PATH_DEV) - 1,
sizeof(f->fu_fname));
} else {
- (void)strlcpy(f->fu_fname, p, sizeof(f->fu_fname));
+ /*
+ * O_APPEND isn't used when limiting file size; limiting
+ * requires seeking. Start by seeking to end of file.
+ */
+ if (f->fu_fsizelimit != 0)
+ lseek(f->f_file, 0, SEEK_END);
f->f_type = F_FILE;
}
break;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 3, 5:10 PM (20 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37710754
Default Alt Text
D20764.diff (5 KB)
Attached To
Mode
D20764: Allow limiting the size of syslogd output files using options in syslog.conf
Attached
Detach File
Event Timeline
Log In to Comment