+void read_cur_epoch() {
+ int fd;
+ /* Reset to -1 in case the read fails */
+ cur_epoch=-1;
+ fd = open(LAST_EPOCH_FILE, O_RDONLY);
+ if (fd != -1) {
+ char snum[MAX_EPOCH_SIZE];
+ ssize_t len;
+ len = read(fd, snum, MAX_EPOCH_SIZE-1);
+ if (len != -1) {
+ snum[len]='\0';
+ sscanf(snum,"%d",&cur_epoch);
+ cur_epoch++; /* Let's not stone the last epoch */
+ close(fd);
+ }
+ }
+ return;
+}
+
+
+/* Dumps the current epoch in a file to cope with
+ * reboots and killings of fprobe */
+
+void update_cur_epoch_file(int n) {
+ int fd, len;
+ char snum[MAX_EPOCH_SIZE];
+ len=snprintf(snum, MAX_EPOCH_SIZE-1,"%d", n);
+ fd = open(LAST_EPOCH_FILE, O_RDWR|O_CREAT|O_TRUNC);
+ if (fd == -1) {
+ my_log(LOG_ERR, "open() failed: %s.The next restart will resume logging from epoch id 0.",LAST_EPOCH_FILE);
+ return;
+ }
+ write(fd, snum, len);
+ close(fd);
+}
+
+/* Get the file descriptor corresponding to the current file.
+ * The kludgy implementation is to abstract away the 'current
+ * file descriptor', which may also be a socket.
+ */
+
+unsigned get_data_file_fd(char *fname, int cur_fd) {
+ struct Time now;
+ unsigned cur_uptime;
+
+ struct statfs statfs;
+ int ret_fd;
+
+ /* We check if the amount of space left on the disk < some threshold and start reusing logs, or bail out if that
+ * doesn't solve the problem */
+ gettime(&now);
+ cur_uptime = getuptime_minutes(&now);
+
+ if (cur_fd != START_DATA_FD) {
+ if (fstatfs(cur_fd, &statfs) == -1) {
+ my_log(LOG_ERR, "PANIC! Can't stat disk to calculate free blocks");
+ }
+ else {
+ if (min_free && (statfs.f_bavail < min_free)
+ && (cur_epoch==last_peak))
+ {
+ my_log(LOG_INFO, "Disk almost full (%u free blocks). I'm going to drop data. Max epochs = %d\n",statfs.f_bavail,cur_epoch);
+ cur_epoch = -1;
+ }
+ /*
+ else
+ assume that we can reclaim space by overwriting our own files
+ and that the difference in size will not fill the disk - sapan
+ */
+ }
+ }
+
+ /* If epoch length has been exceeded,
+ * or we're starting up
+ * or we're going back to the first epoch */
+ if (((cur_uptime - prev_uptime) > epoch_length) || (cur_fd < 0) || (cur_epoch==-1)) {
+ int write_fd;
+ prev_uptime = cur_uptime;
+ cur_epoch = (cur_epoch + 1) % log_epochs;
+ if (cur_epoch>last_peak) last_peak = cur_epoch;
+ if (cur_fd>0) {
+ close(cur_fd);
+ /* Compress the finished file */
+ char gzip_cmd[MAX_PATH_LEN+sizeof("gzip -f ")];
+ snprintf(gzip_cmd, MAX_PATH_LEN+sizeof("gzip -f "),"gzip -f %s",cur_output_file);
+ system(gzip_cmd);
+ }
+ snprintf(cur_output_file,MAX_PATH_LEN,"%s.%d",fname,cur_epoch);
+ if ((write_fd = open(cur_output_file, O_RDWR|O_CREAT|O_TRUNC)) < 0) {
+ my_log(LOG_ERR, "open(): %s (%s)\n", cur_output_file, strerror(errno));
+ exit(1);
+ }
+ if (fchmod(write_fd,S_IRUSR|S_IWUSR|S_IROTH|S_IRGRP) == -1) {
+ my_log(LOG_ERR, "fchmod() failed: %s (%s). Continuing...\n", cur_output_file, strerror(errno));
+ }
+ update_cur_epoch_file(cur_epoch);
+ ret_fd = write_fd;
+ }
+ else {
+ ret_fd = cur_fd;
+ }
+ return(ret_fd);
+}
+