diff options
author | Joern Engel <joern@logfs.org> | 2015-02-17 09:47:23 -0800 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2015-02-17 11:49:50 -0800 |
commit | bbb023f21912ab5c23201834a74a091222d308e2 (patch) | |
tree | 379d5ce14e513417feecb5192feb74ab3cfe2369 | |
parent | 9ea381132300997c2f255ff083a9f4246febc238 (diff) | |
download | cancd-bbb023f21912ab5c23201834a74a091222d308e2.tar.gz |
Add a maximum file size parameter
Sometimes there are a few noisy machines generating 100GB+ per day,
filling up the disk and preventing logrotate from cleaning things up.
Manual intervention is required and several hours or days of logs are
lost - depending on how timely the humans respond.
Having a fixed limit of 1GB or some other reasonable value ensures we
lose logs from the noisy machines, but not from the well-behaving ones
due to full disk.
Signed-off-by: Joern Engel <joern@logfs.org>
-rw-r--r-- | cancd.c | 29 |
1 files changed, 24 insertions, 5 deletions
@@ -81,6 +81,12 @@ static char *log_format = "%Q.log"; */ static uint16_t log_port = 7075; +/* + * Maximum file size to generate - to prevent noisy machine from + * filling the disk + */ +static uint64_t size_limit = UINT64_MAX; + /* Socket we are using */ static int sock_fd; @@ -423,7 +429,8 @@ out: static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t socklen) { - int fd; + int fd, err; + struct stat stat; const char *name; struct source_ip *sip = get_source_ip(addr); @@ -432,12 +439,16 @@ static void do_output(char *buf, int len, struct sockaddr_in *addr, socklen_t so return; fd = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644); - if (fd < 0) + if (fd < 0) { syslog(LOG_ERR, "Unable to open \"%s\": %s", name, strerror(errno)); - else { - write_formatted(fd, sip, buf, len); - close(fd); + return; } + err = fstat(fd, &stat); + if (err || stat.st_size > size_limit) + goto out; + write_formatted(fd, sip, buf, len); +out: + close(fd); } static int set_blocking(int blocking) @@ -613,6 +624,7 @@ extern int optopt; extern int opterr; static int parse_options(int argc, char *argv[]) { + char **garbage = NULL; int c; opterr = 0; @@ -655,6 +667,13 @@ static int parse_options(int argc, char *argv[]) print_usage(-EINVAL); } break; + case 's': + size_limit = strtoull(optarg, garbage, 0); + if (garbage) { + fprintf(stderr, PROGNAME ": Invalid size limit: \"%s\"\n", optarg); + print_usage(-EINVAL); + } + break; case 'D': daemonize = 0; break; |