+ journal_fh = NULL;
+ journal_size = 0;
+} /* }}} journal_close */
+
+/* MUST hold journal_lock before calling */
+static void journal_new_file(void) /* {{{ */
+{
+ struct timeval now;
+ int new_fd;
+ char new_file[PATH_MAX + 1];
+
+ assert(journal_dir != NULL);
+ assert(journal_cur != NULL);
+
+ journal_close();
+
+ gettimeofday(&now, NULL);
+ /* this format assures that the files sort in strcmp() order */
+ snprintf(new_file, PATH_MAX, "%s/%s.%010d.%06d",
+ journal_dir, JOURNAL_BASE, (int)now.tv_sec, (int)now.tv_usec);
+
+ new_fd = open(new_file, O_WRONLY|O_CREAT|O_APPEND,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (new_fd < 0)
+ goto error;
+
+ journal_fh = fdopen(new_fd, "a");
+ if (journal_fh == NULL)
+ goto error;
+
+ journal_size = ftell(journal_fh);
+ RRDD_LOG(LOG_DEBUG, "started new journal %s", new_file);
+
+ /* record the file in the journal set */
+ rrd_add_strdup(&journal_cur->files, &journal_cur->files_num, new_file);
+
+ return;
+
+error:
+ RRDD_LOG(LOG_CRIT,
+ "JOURNALING DISABLED: Error while trying to create %s : %s",
+ new_file, rrd_strerror(errno));
+ RRDD_LOG(LOG_CRIT,
+ "JOURNALING DISABLED: All values will be flushed at shutdown");
+
+ close(new_fd);
+ config_flush_at_shutdown = 1;
+
+} /* }}} journal_new_file */
+
+/* MUST NOT hold journal_lock before calling this */
+static void journal_rotate(void) /* {{{ */
+{
+ journal_set *old_js = NULL;
+
+ if (journal_dir == NULL)
+ return;
+
+ RRDD_LOG(LOG_DEBUG, "rotating journals");
+
+ pthread_mutex_lock(&stats_lock);
+ ++stats_journal_rotate;
+ pthread_mutex_unlock(&stats_lock);
+
+ pthread_mutex_lock(&journal_lock);
+
+ journal_close();
+
+ /* rotate the journal sets */
+ old_js = journal_old;
+ journal_old = journal_cur;
+ journal_cur = calloc(1, sizeof(journal_set));
+
+ if (journal_cur != NULL)
+ journal_new_file();
+ else
+ RRDD_LOG(LOG_CRIT, "journal_rotate: malloc(journal_set) failed\n");
+
+ pthread_mutex_unlock(&journal_lock);
+
+ journal_set_remove(old_js);
+ journal_set_free (old_js);
+