[systemd-commits] 5 commits - README TODO configure.ac man/journald.conf.xml src/journal
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Oct 16 14:00:39 PDT 2012
README | 1
TODO | 2
configure.ac | 41 +++++++++++++++++
man/journald.conf.xml | 51 +++++++++++++++++++++
src/journal/journal-file.c | 55 +++++++++++++++++++++--
src/journal/journal-file.h | 2
src/journal/journal-vacuum.c | 91 ++++++++++++++++++++++++++++++++++++---
src/journal/journal-vacuum.h | 2
src/journal/journald-gperf.gperf | 2
src/journal/journald.c | 48 +++++++++++++-------
src/journal/journald.conf | 2
src/journal/journald.h | 4 +
src/journal/sd-journal.c | 8 ++-
src/journal/test-journal.c | 2
14 files changed, 278 insertions(+), 33 deletions(-)
New commits:
commit 5e6870eab5aa00675e4cd2f914fd1c25642fc964
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 16 23:00:04 2012 +0200
journalctl: properly track rotated journals in follow mode
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 99ac1fd..16ed423 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -1333,7 +1333,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
m->wd = inotify_add_watch(j->inotify_fd, m->path,
IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE|
- IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|
+ IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT|IN_MOVED_FROM|
IN_ONLYDIR);
if (m->wd > 0 && hashmap_put(j->directories_by_wd, INT_TO_PTR(m->wd), m) < 0)
@@ -1951,7 +1951,7 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
if (r < 0)
log_debug("Failed to add file %s/%s: %s", d->path, e->name, strerror(-r));
- } else if (e->mask & (IN_DELETE|IN_UNMOUNT)) {
+ } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
r = remove_file(j, d->path, e->name);
if (r < 0)
commit 44a5fa34d9f9a5050cdf4a497e6ccf5af2d1678d
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 16 22:59:28 2012 +0200
sd-journal: fix bad memory access
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 88b382f..99ac1fd 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -1258,11 +1258,13 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename)
return 0;
hashmap_remove(j->files, f->path);
+
+ log_debug("File %s got removed.", f->path);
+
journal_file_close(f);
j->current_invalidate_counter ++;
- log_debug("File %s got removed.", f->path);
return 0;
}
commit 4b69bfdb5bb51db7583de6dc0ecc337b77921f6b
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 16 22:59:14 2012 +0200
update TODO
diff --git a/TODO b/TODO
index e0482f6..218aad2 100644
--- a/TODO
+++ b/TODO
@@ -19,6 +19,8 @@ F18:
Features:
+* journald: don't make SystemMinFileSize= configurable
+
* clean up date formatting and parsing so that all absolute/relative timestamps we format can also be parsed
* introduce hybrid-sleep.target
commit fb0951b02ebf51a93acf12721d8857d31ce57ba3
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 16 22:58:07 2012 +0200
journal: implement time-based rotation/vacuuming
This also enables time-based rotation (but not vacuuming) after 1month,
so that not more one month of journal is lost at a time per vacuuming.
diff --git a/README b/README
index 25dadde..d947f27 100644
--- a/README
+++ b/README
@@ -47,6 +47,7 @@ REQUIREMENTS:
libgcrypt (optional)
libaudit (optional)
libacl (optional)
+ libattr (optional)
libselinux (optional)
liblzma (optional)
tcpwrappers (optional)
diff --git a/configure.ac b/configure.ac
index 1bb657d..62e83be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-
+#
# This file is part of systemd.
#
# Copyright 2010-2012 Lennart Poettering
@@ -341,6 +341,44 @@ AC_SUBST(ACL_LIBS)
AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
# ------------------------------------------------------------------------------
+AC_ARG_ENABLE([xattr],
+ AS_HELP_STRING([--disable-xattr],[Disable optional XATTR support]),
+ [case "${enableval}" in
+ yes) have_xattr=yes ;;
+ no) have_xattr=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --disable-xattr) ;;
+ esac],
+ [have_xattr=auto])
+
+if test "x${have_xattr}" != xno ; then
+ AC_CHECK_HEADERS(
+ [attr/xattr.h],
+ [have_xattr=yes],
+ [if test "x$have_xattr" = xyes ; then
+ AC_MSG_ERROR([*** XATTR headers not found.])
+ fi])
+
+ AC_CHECK_LIB(
+ [attr],
+ [fsetxattr],
+ [have_xattr=yes],
+ [if test "x$have_xattr" = xyes ; then
+ AC_MSG_ERROR([*** libattr not found.])
+ fi])
+
+ if test "x$have_xattr" = xyes ; then
+ XATTR_LIBS="-lattr"
+ AC_DEFINE(HAVE_XATTR, 1, [XATTR available])
+ else
+ have_xattr=no
+ fi
+else
+ XATTR_LIBS=
+fi
+AC_SUBST(XATTR_LIBS)
+AM_CONDITIONAL([HAVE_XATTR], [test "x$have_xattr" != xno])
+
+# ------------------------------------------------------------------------------
AC_ARG_ENABLE([gcrypt],
AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
[case "${enableval}" in
@@ -823,6 +861,7 @@ AC_MSG_RESULT([
SELinux: ${have_selinux}
XZ: ${have_xz}
ACL: ${have_acl}
+ XATTR: ${have_xattr}
GCRYPT: ${have_gcrypt}
QRENCODE: ${have_qrencode}
MICROHTTPD: ${have_microhttpd}
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index b06a23d..66189bd 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -279,6 +279,57 @@
</varlistentry>
<varlistentry>
+ <term><varname>MaxFileSec=</varname></term>
+
+ <listitem><para>The maximum time to
+ store entries in a single journal
+ file, before rotating to the next
+ one. Normally time-based rotation
+ should not be required as size-based
+ rotation with options such as
+ <varname>SystemMaxFileSize=</varname>
+ should be sufficient to ensure that
+ journal files don't grow without
+ bounds. However, to ensure that not
+ too much data is lost at once when old
+ journal files are deleted it might
+ make sense to change this value from
+ the default of one month. Set to 0 to
+ turn off this feature. This setting
+ takes time values which may be
+ suffixed with the units year, month,
+ week, day, h, m to override the
+ default time unit of
+ seconds.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MaxRetentionSec=</varname></term>
+
+ <listitem><para>The maximum time to
+ store journal entries for. This
+ controls whether journal files
+ containing entries older then the
+ specified time span are
+ deleted. Normally time-based deletion
+ of old journal files should not be
+ required as size-based deletion with
+ options such as
+ <varname>SystemMaxUse=</varname>
+ should be sufficient to ensure that
+ journal files don't grow without
+ bounds. However, to enforce data
+ retention policies it might make sense
+ to set change this value from the
+ default of 0 (which turns off this
+ feature). This settings also takes
+ time values which may be suffixed with
+ the units year, month, week, day, h, m
+ to override the default time unit of
+ seconds. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>ForwardToSyslog=</varname></term>
<term><varname>ForwardToKMsg=</varname></term>
<term><varname>ForwardToConsole=</varname></term>
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index ba04d16..ae01e5d 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -27,6 +27,10 @@
#include <fcntl.h>
#include <stddef.h>
+#ifdef HAVE_XATTR
+#include <attr/xattr.h>
+#endif
+
#include "journal-def.h"
#include "journal-file.h"
#include "journal-authenticate.h"
@@ -1978,7 +1982,7 @@ void journal_file_print_header(JournalFile *f) {
(unsigned long long) le64toh(f->header->arena_size),
(unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
(unsigned long long) le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
- yes_no(journal_file_rotate_suggested(f)),
+ yes_no(journal_file_rotate_suggested(f, 0)),
(unsigned long long) le64toh(f->header->head_entry_seqnum),
(unsigned long long) le64toh(f->header->tail_entry_seqnum),
format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)),
@@ -2080,7 +2084,22 @@ int journal_file_open(
}
if (f->last_stat.st_size == 0 && f->writable) {
- newly_created = true;
+#ifdef HAVE_XATTR
+ uint64_t crtime;
+
+ /* Let's attach the creation time to the journal file,
+ * so that the vacuuming code knows the age of this
+ * file even if the file might end up corrupted one
+ * day... Ideally we'd just use the creation time many
+ * file systems maintain for each file, but there is
+ * currently no usable API to query this, hence let's
+ * emulate this via extended attributes. If extended
+ * attributes are not supported we'll just skip this,
+ * and rely solely on mtime/atime/ctime of the file.*/
+
+ crtime = htole64((uint64_t) now(CLOCK_REALTIME));
+ fsetxattr(f->fd, "user.crtime_usec", &crtime, sizeof(crtime), XATTR_CREATE);
+#endif
#ifdef HAVE_GCRYPT
/* Try to load the FSPRG state, and if we can't, then
@@ -2100,6 +2119,8 @@ int journal_file_open(
r = -errno;
goto fail;
}
+
+ newly_created = true;
}
if (f->last_stat.st_size < (off_t) HEADER_SIZE_MIN) {
@@ -2207,8 +2228,8 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1);
snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1,
"-%016llx-%016llx.journal",
- (unsigned long long) le64toh((*f)->header->tail_entry_seqnum),
- (unsigned long long) le64toh((*f)->header->tail_entry_realtime));
+ (unsigned long long) le64toh((*f)->header->head_entry_seqnum),
+ (unsigned long long) le64toh((*f)->header->head_entry_realtime));
r = rename(old_file->path, p);
free(p);
@@ -2501,7 +2522,7 @@ int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, u
return 1;
}
-bool journal_file_rotate_suggested(JournalFile *f) {
+bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) {
assert(f);
/* If we gained new header fields we gained new features,
@@ -2539,5 +2560,15 @@ bool journal_file_rotate_suggested(JournalFile *f) {
return true;
}
+ if (max_file_usec > 0) {
+ usec_t t, h;
+
+ h = le64toh(f->header->head_entry_realtime);
+ t = now(CLOCK_REALTIME);
+
+ if (h > 0 && t > h + max_file_usec)
+ return true;
+ }
+
return false;
}
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 5b1530e..f52ee8c 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -184,4 +184,4 @@ void journal_default_metrics(JournalMetrics *m, int fd);
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to);
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
-bool journal_file_rotate_suggested(JournalFile *f);
+bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec);
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index ac16bdf..22c9cfc 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -25,6 +25,10 @@
#include <sys/statvfs.h>
#include <unistd.h>
+#ifdef HAVE_XATTR
+#include <attr/xattr.h>
+#endif
+
#include "journal-def.h"
#include "journal-file.h"
#include "journal-vacuum.h"
@@ -68,18 +72,89 @@ static int vacuum_compare(const void *_a, const void *_b) {
return strcmp(a->filename, b->filename);
}
-int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free) {
+static void patch_realtime(
+ const char *dir,
+ const char *fn,
+ const struct stat *st,
+ unsigned long long *realtime) {
+
+ usec_t x;
+
+#ifdef HAVE_XATTR
+ uint64_t crtime;
+ _cleanup_free_ const char *path = NULL;
+#endif
+
+ /* The timestamp was determined by the file name, but let's
+ * see if the file might actually be older than the file name
+ * suggested... */
+
+ assert(dir);
+ assert(fn);
+ assert(st);
+ assert(realtime);
+
+ x = timespec_load(&st->st_ctim);
+ if (x > 0 && x != (usec_t) -1 && x < *realtime)
+ *realtime = x;
+
+ x = timespec_load(&st->st_atim);
+ if (x > 0 && x != (usec_t) -1 && x < *realtime)
+ *realtime = x;
+
+ x = timespec_load(&st->st_mtim);
+ if (x > 0 && x != (usec_t) -1 && x < *realtime)
+ *realtime = x;
+
+#ifdef HAVE_XATTR
+ /* Let's read the original creation time, if possible. Ideally
+ * we'd just query the creation time the FS might provide, but
+ * unfortunately there's currently no sane API to query
+ * it. Hence let's implement this manually... */
+
+ /* Unfortunately there is is not fgetxattrat(), so we need to
+ * go via path here. :-( */
+
+ path = strjoin(dir, "/", fn, NULL);
+ if (!path)
+ return;
+
+ if (getxattr(path, "user.crtime_usec", &crtime, sizeof(crtime)) == sizeof(crtime)) {
+ crtime = le64toh(crtime);
+
+ if (crtime > 0 && crtime != (uint64_t) -1 && crtime < *realtime)
+ *realtime = crtime;
+ }
+#endif
+}
+
+int journal_directory_vacuum(
+ const char *directory,
+ uint64_t max_use,
+ uint64_t min_free,
+ usec_t max_retention_usec,
+ usec_t *oldest_usec) {
+
DIR *d;
int r = 0;
struct vacuum_info *list = NULL;
unsigned n_list = 0, n_allocated = 0, i;
uint64_t sum = 0;
+ usec_t retention_limit = 0;
assert(directory);
- if (max_use <= 0)
+ if (max_use <= 0 && min_free <= 0 && max_retention_usec <= 0)
return 0;
+ if (max_retention_usec > 0) {
+ retention_limit = now(CLOCK_REALTIME);
+ if (retention_limit > max_retention_usec)
+ retention_limit -= max_retention_usec;
+ else
+ max_retention_usec = retention_limit = 0;
+ }
+
d = opendir(directory);
if (!d)
return -errno;
@@ -170,6 +245,8 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
} else
continue;
+ patch_realtime(directory, de->d_name, &st, &realtime);
+
if (n_list >= n_allocated) {
struct vacuum_info *j;
@@ -199,7 +276,7 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
if (n_list > 0)
qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare);
- for(i = 0; i < n_list; i++) {
+ for (i = 0; i < n_list; i++) {
struct statvfs ss;
if (fstatvfs(dirfd(d), &ss) < 0) {
@@ -207,8 +284,9 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
goto finish;
}
- if (sum <= max_use &&
- (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free)
+ if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
+ (max_use <= 0 || sum <= max_use) &&
+ (min_free <= 0 || (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free))
break;
if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
@@ -218,6 +296,9 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
log_warning("Failed to delete %s/%s: %m", directory, list[i].filename);
}
+ if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec))
+ *oldest_usec = list[i].realtime;
+
finish:
for (i = 0; i < n_list; i++)
free(list[i].filename);
diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h
index 9841d72..f5e3e52 100644
--- a/src/journal/journal-vacuum.h
+++ b/src/journal/journal-vacuum.h
@@ -23,4 +23,4 @@
#include <inttypes.h>
-int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free);
+int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free, usec_t max_retention_usec, usec_t *oldest_usec);
diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf
index 4c021ed..1635e1c 100644
--- a/src/journal/journald-gperf.gperf
+++ b/src/journal/journald-gperf.gperf
@@ -28,6 +28,8 @@ Journal.RuntimeMaxUse, config_parse_bytes_off, 0, offsetof(Server, runtime_
Journal.RuntimeMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_size)
Journal.RuntimeMinFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.min_size)
Journal.RuntimeKeepFree, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.keep_free)
+Journal.MaxRetentionSec, config_parse_usec, 0, offsetof(Server, max_retention_usec)
+Journal.MaxFileSec, config_parse_usec, 0, offsetof(Server, max_file_usec)
Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog)
Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, forward_to_kmsg)
Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, forward_to_console)
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 4dcf7d3..f56e822 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -361,6 +361,8 @@ static void server_vacuum(Server *s) {
log_debug("Vacuuming...");
+ s->oldest_file_usec = 0;
+
r = sd_id128_get_machine(&machine);
if (r < 0) {
log_error("Failed to get machine ID: %s", strerror(-r));
@@ -376,7 +378,7 @@ static void server_vacuum(Server *s) {
return;
}
- r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free);
+ r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
log_error("Failed to vacuum %s: %s", p, strerror(-r));
free(p);
@@ -389,7 +391,7 @@ static void server_vacuum(Server *s) {
return;
}
- r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free);
+ r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
log_error("Failed to vacuum %s: %s", p, strerror(-r));
free(p);
@@ -482,7 +484,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
if (!f)
return;
- if (journal_file_rotate_suggested(f)) {
+ if (journal_file_rotate_suggested(f, s->max_file_usec)) {
log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
server_rotate(s);
server_vacuum(s);
@@ -1543,24 +1545,38 @@ int main(int argc, char *argv[]) {
for (;;) {
struct epoll_event event;
- int t;
+ int t = -1;
+ usec_t n;
-#ifdef HAVE_GCRYPT
- usec_t u;
+ n = now(CLOCK_REALTIME);
- if (server.system_journal &&
- journal_file_next_evolve_usec(server.system_journal, &u)) {
- usec_t n;
+ if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) {
- n = now(CLOCK_REALTIME);
+ /* The retention time is reached, so let's vacuum! */
+ if (server.oldest_file_usec + server.max_retention_usec < n) {
+ log_info("Retention time reached.");
+ server_rotate(&server);
+ server_vacuum(&server);
+ continue;
+ }
- if (n >= u)
- t = 0;
- else
- t = (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC);
- } else
+ /* Calculate when to rotate the next time */
+ t = (int) ((server.oldest_file_usec + server.max_retention_usec - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC);
+ log_info("Sleeping for %i ms", t);
+ }
+
+#ifdef HAVE_GCRYPT
+ if (server.system_journal) {
+ usec_t u;
+
+ if (journal_file_next_evolve_usec(server.system_journal, &u)) {
+ if (n >= u)
+ t = 0;
+ else
+ t = MIN(t, (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
+ }
+ }
#endif
- t = -1;
r = epoll_wait(server.epoll_fd, &event, 1, t);
if (r < 0) {
diff --git a/src/journal/journald.conf b/src/journal/journald.conf
index e5f3b76..4964833 100644
--- a/src/journal/journald.conf
+++ b/src/journal/journald.conf
@@ -22,6 +22,8 @@
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMinFileSize=
+#MaxRetentionSec=
+#MaxFileSec=1month
#ForwardToSyslog=yes
#ForwardToKMsg=no
#ForwardToConsole=no
diff --git a/src/journal/journald.h b/src/journal/journald.h
index 25e7ec3..e3ef3b5 100644
--- a/src/journal/journald.h
+++ b/src/journal/journald.h
@@ -91,6 +91,10 @@ typedef struct Server {
uint64_t var_available_timestamp;
+ usec_t max_retention_usec;
+ usec_t max_file_usec;
+ usec_t oldest_file_usec;
+
gid_t file_gid;
bool file_gid_valid;
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index 2273500..2fd49c1 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) {
journal_file_close(f);
- journal_directory_vacuum(".", 3000000, 0);
+ journal_directory_vacuum(".", 3000000, 0, 0, NULL);
log_error("Exiting...");
commit 1f2da9ec5152cbf48c214969e079d9281ef68660
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Oct 16 21:40:48 2012 +0200
journal: sort data items of entries by offset
This should slightly optimize disk access patterns on rotating disks for
simple readers.
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index f775fec..ba04d16 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1053,6 +1053,16 @@ void journal_file_post_change(JournalFile *f) {
log_error("Failed to truncate file to its own size: %m");
}
+static int entry_item_cmp(const void *_a, const void *_b) {
+ const EntryItem *a = _a, *b = _b;
+
+ if (le64toh(a->object_offset) < le64toh(b->object_offset))
+ return -1;
+ if (le64toh(a->object_offset) > le64toh(b->object_offset))
+ return 1;
+ return 0;
+}
+
int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) {
unsigned i;
EntryItem *items;
@@ -1097,6 +1107,10 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
items[i].hash = o->data.hash;
}
+ /* Order by the position on disk, in order to improve seek
+ * times for rotating media. */
+ qsort(items, n_iovec, sizeof(EntryItem), entry_item_cmp);
+
r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset);
journal_file_post_change(f);
More information about the systemd-commits
mailing list