summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoern Engel <joern@logfs.org>2015-09-08 18:13:02 -0700
committerJoern Engel <joern@logfs.org>2015-09-15 12:30:06 -0700
commit8ac093b09668a0b8e2d983d152caba39c3cfbcd3 (patch)
treef8d89e10cbbf7a9be27c1334cafb4668fc34b67a
parent9e8d1d2b56adbf60d7bb0a7fd7146c24b12bb423 (diff)
downloadcancd-8ac093b09668a0b8e2d983d152caba39c3cfbcd3.tar.gz
Close idle logfiles
We hit the maximum file limit. 75% of that seems to be from active machines, but we may also have stale ones that we needlessly keep open. It is fairly cheap to close them once an hour. Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r--cancd.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/cancd.c b/cancd.c
index dd7e0f2..96f7182 100644
--- a/cancd.c
+++ b/cancd.c
@@ -441,6 +441,25 @@ uint64_t gethrtime(void)
return tod.tv_sec * 1000000000ULL + tod.tv_nsec;
}
+static void close_logfile(struct source_ip *sip)
+{
+ int fd;
+
+ /*
+ * We cache the open fd for 60s. We also cache the filesize.
+ * This reduces cpu overhead a bit, but means logrotate has to
+ * keep the file around for 60s after rotation and we can
+ * overshoot the size limit a bit.
+ */
+ do {
+ if (sip->fd < 0 || gethrtime() < sip->reopen_time)
+ return;
+ fd = sip->fd;
+ } while (!__sync_bool_compare_and_swap(&sip->fd, fd, -1));
+
+ close(fd);
+}
+
static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t socklen)
{
int err;
@@ -452,16 +471,7 @@ static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t so
if (!name)
return;
- /*
- * We cache the open fd for 60s. We also cache the filesize.
- * This reduces cpu overhead a bit, but means logrotate has to
- * keep the file around for 60s after rotation and we can
- * overshoot the size limit a bit.
- */
- if (sip->fd >= 0 && gethrtime() > sip->reopen_time) {
- close(sip->fd);
- sip->fd = -1;
- }
+ close_logfile(sip);
if (sip->fd < 0) {
sip->fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644);
@@ -734,6 +744,14 @@ static void dns_visitor(void *_sip, long unused, u32 ip, size_t unused2)
const char *old;
char *new, *c;
+ /*
+ * Close idle logfiles. Maybe the machine no longer exists,
+ * maybe it was renamed, maybe it has gone quiet for an hour.
+ * Either way, it no longer saves resources to keep the file
+ * open.
+ */
+ close_logfile(sip);
+
he = gethostbyaddr(&ip, 4, AF_INET);
if (!he)
return;