diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-10-16 22:58:07 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-10-16 22:58:07 +0200 |
commit | fb0951b02ebf51a93acf12721d8857d31ce57ba3 (patch) | |
tree | b9dd7a414d8a5a600d4b41e8e830faef7b6cf22a /src/journal/journal-file.c | |
parent | 1f2da9ec5152cbf48c214969e079d9281ef68660 (diff) |
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.
Diffstat (limited to 'src/journal/journal-file.c')
-rw-r--r-- | src/journal/journal-file.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index ba04d1667b..ae01e5df50 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; } |