text log_limit {
if (!parse_and_exit)
{
- this_log->rf = rf_open(new_config->pool, $1, RF_APPEND);
+ this_log->rf = rf_open(new_config->pool, $1, RF_APPEND, this_log->limit);
if (!this_log->rf) cf_error("Unable to open log file '%s': %m", $1);
}
this_log->filename = $1;
| MRTDUMP text ';' {
if (!parse_and_exit)
{
- struct rfile *f = rf_open(new_config->pool, $2, RF_APPEND);
+ struct rfile *f = rf_open(new_config->pool, $2, RF_APPEND, 0);
if (!f) cf_error("Unable to open MRTDump file '%s': %m", $2);
new_config->mrtdump_file = f;
}
resource r;
struct stat stat;
int fd;
+ off_t limit;
_Atomic off_t pos;
};
}
struct rfile *
-rf_open(pool *p, const char *name, enum rf_mode mode)
+rf_open(pool *p, const char *name, enum rf_mode mode, off_t limit)
{
int fd = rf_open_get_fd(name, mode);
struct rfile *r = ralloc(p, &rf_class);
r->fd = fd;
+ r->limit = limit;
switch (mode)
{
(a->stat.st_ino == b->stat.st_ino);
}
-void
+int
rf_write(struct rfile *r, const void *buf, size_t count)
{
- while ((write(r->fd, buf, count) < 0) && (errno == EINTR))
- ;
- atomic_fetch_add_explicit(&r->pos, count, memory_order_relaxed);
+ if (r->limit && (atomic_fetch_add_explicit(&r->pos, count, memory_order_relaxed) + (off_t) count > r->limit))
+ {
+ atomic_fetch_sub_explicit(&r->pos, count, memory_order_relaxed);
+ return 0;
+ }
+ else
+ {
+ while ((write(r->fd, buf, count) < 0) && (errno == EINTR))
+ ;
+ return 1;
+ }
}
if ((rename(lc->filename, lc->backup) < 0) && (unlink(lc->filename) < 0))
return lts_request(lc, NULL, "Log Rotate Failed");
- struct rfile *rf = rf_open(log_pool, lc->filename, RF_APPEND);
+ struct rfile *rf = rf_open(log_pool, lc->filename, RF_APPEND, lc->limit);
if (!rf)
return lts_request(lc, NULL, "Log Rotate Failed");
*buf->buf.pos = '\n';
byte *begin = l->terminal ? buf->buf.start : buf->tm_pos;
off_t msg_len = buf->buf.pos - begin + 1;
- if (l->limit && (rf_size(rf) + msg_len > l->limit))
+ do {
+ if (rf_write(rf, buf->tm_pos, msg_len))
+ break;
+
+ log_lock();
+ rf = atomic_load_explicit(&l->rf, memory_order_acquire);
+ if (rf_write(rf, buf->tm_pos, msg_len))
{
- log_lock();
- rf = atomic_load_explicit(&l->rf, memory_order_acquire);
- if (rf_size(rf) + msg_len > l->limit)
- {
- log_rotate(l);
- rf = atomic_load_explicit(&l->rf, memory_order_relaxed);
- }
log_unlock();
+ break;
}
- rf_write(l->rf, buf->tm_pos, msg_len);
+ log_rotate(l);
+ log_unlock();
+
+ rf = atomic_load_explicit(&l->rf, memory_order_relaxed);
+ } while (!rf_write(rf, buf->tm_pos, msg_len));
}
#ifdef HAVE_SYSLOG_H
else
rmove(l->rf, log_pool);
else if (l->filename)
{
- l->rf = rf_open(log_pool, l->filename, RF_APPEND);
+ l->rf = rf_open(log_pool, l->filename, RF_APPEND, l->limit);
erf = l->rf ? 0 : errno;
}
log_unlock();
dbg_rf = NULL;
else if (!*f)
dbg_rf = &rf_stderr;
- else if (!(dbg_rf = rf_open(&root_pool, f, RF_APPEND)))
+ else if (!(dbg_rf = rf_open(&root_pool, f, RF_APPEND, 0)))
{
/* Cannot use die() nor log() here, logging is not yet initialized */
fprintf(stderr, "bird: Unable to open debug file %s: %s\n", f, strerror(errno));
RF_APPEND,
};
-struct rfile *rf_open(struct pool *, const char *name, enum rf_mode mode);
+struct rfile *rf_open(struct pool *, const char *name, enum rf_mode mode, off_t limit);
off_t rf_size(struct rfile *);
int rf_same(struct rfile *, struct rfile *);
-void rf_write(struct rfile *, const void *, size_t);
+int rf_write(struct rfile *, const void *, size_t);
extern struct rfile rf_stderr;