[systemd-devel] [PATCH] Add sync timer to journal server
Oleksii Shevchuk
alxchk at gmail.com
Sat Mar 16 02:56:39 PDT 2013
Sync journal with fdatasync every 1m (by default). Interval configured
via SyncInterval option at journal.conf. Manual sync can be performed
via sending SIGALRM.
---
src/journal/journal-file.c | 13 +++++--
src/journal/journal-file.h | 1 +
src/journal/journald-gperf.gperf | 1 +
src/journal/journald-server.c | 77 +++++++++++++++++++++++++++++++++++++++-
src/journal/journald-server.h | 4 +++
5 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 13fc8ed..42a410a 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -68,6 +68,16 @@
/* How many entries to keep in the entry array chain cache at max */
#define CHAIN_CACHE_MAX 20
+int journal_file_sync(JournalFile *f) {
+ if (! (f->writable && f->fd >= 0))
+ return -1;
+
+ if (fdatasync(f->fd))
+ return -errno;
+
+ return 0;
+}
+
void journal_file_close(JournalFile *f) {
assert(f);
@@ -81,8 +91,7 @@ void journal_file_close(JournalFile *f) {
if (f->mmap && f->fd >= 0)
mmap_cache_close_fd(f->mmap, f->fd);
- if (f->writable && f->fd >= 0)
- fdatasync(f->fd);
+ journal_file_sync(f);
if (f->header) {
/* Mark the file offline. Don't override the archived state if it already is set */
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index cdbc8e4..717d64c 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -106,6 +106,7 @@ int journal_file_open(
JournalFile *template,
JournalFile **ret);
+int journal_file_sync(JournalFile *f);
void journal_file_close(JournalFile *j);
int journal_file_open_reliably(
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 1baef14..e3594d6 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -18,6 +18,7 @@ struct ConfigPerfItem;
Journal.Storage, config_parse_storage, 0, offsetof(Server, storage)
Journal.Compress, config_parse_bool, 0, offsetof(Server, compress)
Journal.Seal, config_parse_bool, 0, offsetof(Server, seal)
+Journal.SyncInterval, config_parse_usec, 0, offsetof(Server, sync_interval)
Journal.RateLimitInterval, config_parse_usec, 0, offsetof(Server, rate_limit_interval)
Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst)
Journal.SystemMaxUse, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use)
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index ac565c7..ce6045c 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -67,6 +67,7 @@
#define USER_JOURNALS_MAX 1024
+#define DEFAULT_SYNC_INTERVAL (60*USEC_PER_SEC)
#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
#define DEFAULT_RATE_LIMIT_BURST 200
@@ -344,6 +345,25 @@ void server_rotate(Server *s) {
}
}
+void server_sync(Server *s) {
+ JournalFile *f;
+ void *k;
+ Iterator i;
+ int r;
+
+ log_info("Syncing journal...");
+
+ r = journal_file_sync(s->runtime_journal);
+ if (r < 0)
+ log_error("Failed to sync journal: %s", strerror(-r));
+
+ HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
+ r = journal_file_sync(f);
+ if (r < 0)
+ log_error("Failed to sync user journal: %s", strerror(-r));
+ }
+}
+
void server_vacuum(Server *s) {
char *p;
char ids[33];
@@ -1005,6 +1025,11 @@ int process_event(Server *s, struct epoll_event *ev) {
return 1;
}
+ if (sfsi.ssi_signo == SIGALRM) {
+ server_sync(s);
+ return 1;
+ }
+
return 0;
} else if (ev->data.fd == s->dev_kmsg_fd) {
@@ -1194,7 +1219,7 @@ static int open_signalfd(Server *s) {
assert(s);
assert_se(sigemptyset(&mask) == 0);
- sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
+ sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGALRM, -1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
@@ -1286,6 +1311,48 @@ static int server_parse_config_file(Server *s) {
return r;
}
+static int server_setup_sync_timer(Server *s) {
+ int r;
+
+ struct sigevent sync_timer = {
+ .sigev_notify = SIGEV_SIGNAL,
+ .sigev_signo = SIGALRM,
+ };
+
+ struct itimerspec sync_timer_interval = {
+ .it_value.tv_sec = s->sync_interval / USEC_PER_SEC,
+ .it_value.tv_nsec = s->sync_interval % USEC_PER_SEC,
+ .it_interval.tv_sec = s->sync_interval / USEC_PER_SEC,
+ .it_interval.tv_nsec = s->sync_interval % USEC_PER_SEC,
+ };
+
+ assert(s);
+
+ r = timer_create(CLOCK_MONOTONIC, &sync_timer, &s->sync_timer_id);
+ if (r < 0)
+ return -errno;
+
+ r = timer_settime(s->sync_timer_id, 0, &sync_timer_interval, NULL);
+ if (r < 0) {
+ timer_delete(s->sync_timer_id);
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int server_destroy_sync_timer(Server *s) {
+ int r;
+
+ assert(s);
+
+ r = timer_delete(s->sync_timer_id);
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
+
int server_init(Server *s) {
int n, r, fd;
@@ -1296,6 +1363,8 @@ int server_init(Server *s) {
s->compress = true;
s->seal = true;
+ s->sync_interval = DEFAULT_SYNC_INTERVAL;
+
s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
@@ -1412,6 +1481,10 @@ int server_init(Server *s) {
if (r < 0)
return r;
+ r = server_setup_sync_timer(s);
+ if (r < 0)
+ return r;
+
return 0;
}
@@ -1481,4 +1554,6 @@ void server_done(Server *s) {
if (s->udev)
udev_unref(s->udev);
+
+ server_destroy_sync_timer(s);
}
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 9f50a29..ffbf4c3 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -71,6 +71,7 @@ typedef struct Server {
size_t buffer_size;
JournalRateLimit *rate_limit;
+ usec_t sync_interval;
usec_t rate_limit_interval;
unsigned rate_limit_burst;
@@ -119,6 +120,8 @@ typedef struct Server {
uint64_t *kernel_seqnum;
struct udev *udev;
+
+ timer_t sync_timer_id;
} Server;
#define N_IOVEC_META_FIELDS 17
@@ -145,6 +148,7 @@ void server_fix_perms(Server *s, JournalFile *f, uid_t uid);
bool shall_try_append_again(JournalFile *f, int r);
int server_init(Server *s);
void server_done(Server *s);
+void server_sync(Server *s);
void server_vacuum(Server *s);
void server_rotate(Server *s);
int server_flush_to_var(Server *s);
--
1.8.1.2
More information about the systemd-devel
mailing list