[systemd-commits] 7 commits - src/journal src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Tue Aug 21 06:54:37 PDT 2012


 src/journal/journal-authenticate.c |   33 ++++++++++++++++
 src/journal/journal-authenticate.h |    2 +
 src/journal/journal-file.c         |   14 +++----
 src/journal/journal-verify.c       |   47 +++++++++++++++--------
 src/journal/journalctl.c           |    5 ++
 src/journal/journald.c             |   43 +++++++++++++++++----
 src/journal/mmap-cache.c           |   73 ++++++++++++-------------------------
 src/journal/mmap-cache.h           |    3 -
 src/shared/util.c                  |   19 ++++++++-
 9 files changed, 153 insertions(+), 86 deletions(-)

New commits:
commit cedb42bb694ef866b18608b14ac269d1ef7513f8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 15:53:48 2012 +0200

    journalctl: add a bit of color to the output

diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 0bbf4a0..36c3d2b 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -659,13 +659,15 @@ static int verify(sd_journal *j) {
 
         assert(j);
 
+        log_show_color(true);
+
         HASHMAP_FOREACH(f, j->files, i) {
                 int k;
                 usec_t from, to, total;
 
 #ifdef HAVE_GCRYPT
                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
-                        log_warning("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
+                        log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
 #endif
 
                 k = journal_file_verify(f, arg_verify_key, &from, &to, &total, true);

commit 24a598f889229e14c62f80c58d5d32cd9663c812
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 15:34:41 2012 +0200

    journal: properly handle EPIPE from /dev/kmsg

diff --git a/src/journal/journald.c b/src/journal/journald.c
index f2dd405..a5025f5 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -2161,7 +2161,7 @@ static int server_read_dev_kmsg(Server *s) {
                         return 0;
                 }
 
-                if (errno == EAGAIN || errno == EINTR)
+                if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
                         return 0;
 
                 log_error("Failed to read from kernel: %m");

commit fcde238921b857679363a95488a5a5af1dc1f243
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 15:33:21 2012 +0200

    journal: be more careful when keeping around mmaps we still need

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index f01f124..79f7598 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -311,8 +311,6 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         if (r != 0)
                 return -r;
 
-        mmap_cache_close_fd_range(f->mmap, f->fd, old_size);
-
         if (fstat(f->fd, &f->last_stat) < 0)
                 return -errno;
 
@@ -321,7 +319,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         return 0;
 }
 
-static int journal_file_move_to(JournalFile *f, int context, uint64_t offset, uint64_t size, void **ret) {
+static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
         assert(f);
         assert(ret);
 
@@ -335,7 +333,7 @@ static int journal_file_move_to(JournalFile *f, int context, uint64_t offset, ui
                         return -EADDRNOTAVAIL;
         }
 
-        return mmap_cache_get(f->mmap, f->fd, f->prot, context, offset, size, ret);
+        return mmap_cache_get(f->mmap, f->fd, f->prot, context, keep_always, offset, size, &f->last_stat, ret);
 }
 
 static uint64_t minimum_header_size(Object *o) {
@@ -373,7 +371,7 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
         /* One context for each type, plus one catch-all for the rest */
         context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
 
-        r = journal_file_move_to(f, context, offset, sizeof(ObjectHeader), &t);
+        r = journal_file_move_to(f, context, false, offset, sizeof(ObjectHeader), &t);
         if (r < 0)
                 return r;
 
@@ -393,7 +391,7 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
                 return -EBADMSG;
 
         if (s > sizeof(ObjectHeader)) {
-                r = journal_file_move_to(f, o->object.type, offset, s, &t);
+                r = journal_file_move_to(f, o->object.type, false, offset, s, &t);
                 if (r < 0)
                         return r;
 
@@ -457,7 +455,7 @@ int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object *
         if (r < 0)
                 return r;
 
-        r = journal_file_move_to(f, type, p, size, &t);
+        r = journal_file_move_to(f, type, false, p, size, &t);
         if (r < 0)
                 return r;
 
@@ -544,6 +542,7 @@ static int journal_file_map_data_hash_table(JournalFile *f) {
 
         r = journal_file_move_to(f,
                                  OBJECT_DATA_HASH_TABLE,
+                                 true,
                                  p, s,
                                  &t);
         if (r < 0)
@@ -565,6 +564,7 @@ static int journal_file_map_field_hash_table(JournalFile *f) {
 
         r = journal_file_move_to(f,
                                  OBJECT_FIELD_HASH_TABLE,
+                                 true,
                                  p, s,
                                  &t);
         if (r < 0)
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 90739a6..9156fd5 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -249,7 +249,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
 
                 c = (a + b) / 2;
 
-                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, c * sizeof(uint64_t), sizeof(uint64_t), (void **) &z);
+                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
                 if (r < 0)
                         return r;
 
@@ -261,9 +261,8 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
 
                 if (p < *z)
                         b = c;
-                else {
+                else
                         a = c;
-                }
         }
 
         return 0;
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index 69efb20..2b45e37 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -336,6 +336,7 @@ static int mmap_cache_make_room(MMapCache *m) {
                 Window *v;
 
                 v = m->windows + w;
+                assert(v->n_ref == 0);
 
                 if (v->ptr) {
                         mmap_cache_window_unmap(m, w);
@@ -354,8 +355,10 @@ static int mmap_cache_put(
                 unsigned fd_index,
                 int prot,
                 unsigned context,
+                bool keep_always,
                 uint64_t offset,
                 uint64_t size,
+                struct stat *st,
                 void **ret) {
 
         unsigned w;
@@ -387,6 +390,18 @@ static int mmap_cache_put(
                 wsize = WINDOW_SIZE;
         }
 
+        if (st) {
+                /* Memory maps that are larger then the files
+                   underneath have undefined behaviour. Hence, clamp
+                   things to the file size if we know it */
+
+                if (woffset >= (uint64_t) st->st_size)
+                        return -EADDRNOTAVAIL;
+
+                if (woffset + wsize > (uint64_t) st->st_size)
+                        wsize = PAGE_ALIGN(st->st_size - woffset);
+        }
+
         for (;;) {
                 d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset);
                 if (d != MAP_FAILED)
@@ -413,8 +428,13 @@ static int mmap_cache_put(
         v->offset = woffset;
         v->size = wsize;
 
-        v->n_ref = 0;
-        mmap_cache_window_add_lru(m, w);
+        if (keep_always)
+                v->n_ref = 1;
+        else {
+                v->n_ref = 0;
+                mmap_cache_window_add_lru(m, w);
+        }
+
         mmap_cache_fd_add(m, fd_index, w);
         mmap_cache_context_set(m, context, w);
 
@@ -581,8 +601,10 @@ int mmap_cache_get(
                 int fd,
                 int prot,
                 unsigned context,
+                bool keep_always,
                 uint64_t offset,
                 uint64_t size,
+                struct stat *st,
                 void **ret) {
 
         unsigned fd_index;
@@ -638,7 +660,7 @@ int mmap_cache_get(
                 return r;
 
         /* Not found? Then, let's add it */
-        return mmap_cache_put(m, fd, fd_index, prot, context, offset, size, ret);
+        return mmap_cache_put(m, fd, fd_index, prot, context, keep_always, offset, size, st, ret);
 }
 
 void mmap_cache_close_fd(MMapCache *m, int fd) {
@@ -679,51 +701,6 @@ void mmap_cache_close_fd(MMapCache *m, int fd) {
         m->n_fds --;
 }
 
-void mmap_cache_close_fd_range(MMapCache *m, int fd, uint64_t p) {
-        unsigned fd_index, c, w;
-        int r;
-
-        assert(m);
-        assert(fd > 0);
-
-        /* This drops all windows that include space right of the
-         * specified offset. This is useful to ensure that after the
-         * file size is extended we drop our mappings of the end and
-         * create it anew, since otherwise it is undefined whether
-         * mapping will continue to work as intended. */
-
-        r = mmap_cache_peek_fd_index(m, fd, &fd_index);
-        if (r <= 0)
-                return;
-
-        for (c = 0; c < m->contexts_max; c++) {
-                w = m->by_context[c];
-
-                if (w != (unsigned) -1 && m->windows[w].fd == fd)
-                        mmap_cache_context_unset(m, c);
-        }
-
-        w = m->by_fd[fd_index].windows;
-        while (w != (unsigned) -1) {
-                Window *v;
-
-                v = m->windows + w;
-                assert(v->fd == fd);
-                assert(v->by_fd_next == (unsigned) -1 ||
-                       m->windows[v->by_fd_next].fd == fd);
-
-                if (v->offset + v->size > p) {
-
-                        mmap_cache_window_unmap(m, w);
-                        mmap_cache_fd_remove(m, fd_index, w);
-                        v->fd = -1;
-
-                        w = m->by_fd[fd_index].windows;
-                } else
-                        w = v->by_fd_next;
-        }
-}
-
 void mmap_cache_close_context(MMapCache *m, unsigned context) {
         mmap_cache_context_unset(m, context);
 }
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
index aae4544..98a1a73 100644
--- a/src/journal/mmap-cache.h
+++ b/src/journal/mmap-cache.h
@@ -29,7 +29,6 @@ MMapCache* mmap_cache_new(void);
 MMapCache* mmap_cache_ref(MMapCache *m);
 MMapCache* mmap_cache_unref(MMapCache *m);
 
-int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, uint64_t offset, uint64_t size, void **ret);
+int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, uint64_t size, struct stat *st, void **ret);
 void mmap_cache_close_fd(MMapCache *m, int fd);
-void mmap_cache_close_fd_range(MMapCache *m, int fd, uint64_t range);
 void mmap_cache_close_context(MMapCache *m, unsigned context);

commit 369f0589218a874a88bc69c5481d8f90f987b7dd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 15:32:51 2012 +0200

    verify: optimize entry search a bit by using bisection

diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 8604b6e..90739a6 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -309,22 +309,46 @@ static int entry_points_to_data(
          * main entry array has already been verified we can rely on
          * its consistency.*/
 
+        i = 0;
         n = le64toh(f->header->n_entries);
         a = le64toh(f->header->entry_array_offset);
-        i = 0;
 
         while (i < n) {
-                uint64_t m, j;
+                uint64_t m, u;
 
                 r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
                 if (r < 0)
                         return r;
 
                 m = journal_file_entry_array_n_items(o);
-                for (j = 0; i < n && j < m; i++, j++)
-                        if (le64toh(o->entry_array.items[j]) == entry_p)
-                                return 0;
+                u = MIN(n - i, m);
+
+                if (entry_p <= le64toh(o->entry_array.items[u-1])) {
+                        uint64_t x, y, z;
+
+                        x = 0;
+                        y = u;
+
+                        while (x < y) {
+                                z = (x + y) / 2;
+
+                                if (le64toh(o->entry_array.items[z]) == entry_p)
+                                        return 0;
+
+                                if (x + 1 >= y)
+                                        break;
+
+                                if (entry_p < le64toh(o->entry_array.items[z]))
+                                        y = z;
+                                else
+                                        x = z;
+                        }
+
+                        log_error("Entry object doesn't exist in main entry array at %llu", (unsigned long long) entry_p);
+                        return -EBADMSG;
+                }
 
+                i += u;
                 a = le64toh(o->entry_array.next_entry_array_offset);
         }
 

commit a228a22fda4faa9ecb7c5a5e499980c8ae5d2a08
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 02:13:21 2012 +0200

    journalctl: really include .journal~ files in listing

diff --git a/src/shared/util.c b/src/shared/util.c
index 041b759..736cb15 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -1800,7 +1800,7 @@ char *ascii_strlower(char *t) {
         return t;
 }
 
-bool ignore_file(const char *filename) {
+static bool ignore_file_allow_backup(const char *filename) {
         assert(filename);
 
         return
@@ -1808,7 +1808,6 @@ bool ignore_file(const char *filename) {
                 streq(filename, "lost+found") ||
                 streq(filename, "aquota.user") ||
                 streq(filename, "aquota.group") ||
-                endswith(filename, "~") ||
                 endswith(filename, ".rpmnew") ||
                 endswith(filename, ".rpmsave") ||
                 endswith(filename, ".rpmorig") ||
@@ -1817,6 +1816,15 @@ bool ignore_file(const char *filename) {
                 endswith(filename, ".swp");
 }
 
+bool ignore_file(const char *filename) {
+        assert(filename);
+
+        if (endswith(filename, "~"))
+                return false;
+
+        return ignore_file_allow_backup(filename);
+}
+
 int fd_nonblock(int fd, bool nonblock) {
         int flags;
 
@@ -4262,7 +4270,12 @@ bool dirent_is_file(const struct dirent *de) {
 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
         assert(de);
 
-        if (!dirent_is_file(de))
+        if (de->d_type != DT_REG &&
+            de->d_type != DT_LNK &&
+            de->d_type != DT_UNKNOWN)
+                return false;
+
+        if (ignore_file_allow_backup(de->d_name))
                 return false;
 
         return endswith(de->d_name, suffix);

commit 72fbdd3349ad30d8a5074ea9a650f0909f96c299
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 01:43:37 2012 +0200

    journal: initialize libgcrypt explicitly, before using HMAC

diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index fd81797..fe5b6bd 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -413,12 +413,26 @@ finish:
         return r;
 }
 
+static void initialize_libgcrypt(void) {
+        const char *p;
+
+        if (gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P))
+                return;
+
+        p = gcry_check_version("1.4.5");
+        assert(p);
+
+        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+}
+
 int journal_file_hmac_setup(JournalFile *f) {
         gcry_error_t e;
 
         if (!f->seal)
                 return 0;
 
+        initialize_libgcrypt();
+
         e = gcry_md_open(&f->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
         if (e != 0)
                 return -ENOTSUP;

commit 89fef99014662a5a63e7deaedd6292b7fb4ab2f8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Aug 21 01:29:17 2012 +0200

    journal: automatically evolve FSS key even when nothing is logged

diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
index 4354810..fd81797 100644
--- a/src/journal/journal-authenticate.c
+++ b/src/journal/journal-authenticate.c
@@ -211,6 +211,9 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
         if (!f->seal)
                 return 0;
 
+        if (realtime <= 0)
+                realtime = now(CLOCK_MONOTONIC);
+
         r = journal_file_fsprg_need_evolve(f, realtime);
         if (r <= 0)
                 return 0;
@@ -517,3 +520,19 @@ int journal_file_parse_verification_key(JournalFile *f, const char *key) {
 
         return 0;
 }
+
+bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u) {
+        uint64_t epoch;
+
+        assert(f);
+        assert(u);
+
+        if (!f->seal)
+                return false;
+
+        epoch = FSPRG_GetEpoch(f->fsprg_state);
+
+        *u = (usec_t) (f->fss_start_usec + f->fss_interval_usec * epoch + f->fss_interval_usec);
+
+        return true;
+}
diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h
index 447c7b4..3586464 100644
--- a/src/journal/journal-authenticate.h
+++ b/src/journal/journal-authenticate.h
@@ -40,3 +40,5 @@ int journal_file_parse_verification_key(JournalFile *f, const char *key);
 
 int journal_file_fsprg_evolve(JournalFile *f, uint64_t realtime);
 int journal_file_fsprg_seek(JournalFile *f, uint64_t epoch);
+
+bool journal_file_next_evolve_usec(JournalFile *f, usec_t *u);
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
index 29a9229..8604b6e 100644
--- a/src/journal/journal-verify.c
+++ b/src/journal/journal-verify.c
@@ -34,14 +34,6 @@
 #include "compress.h"
 #include "fsprg.h"
 
-/* FIXME:
- *
- * - evolve key even if nothing happened in regular intervals
- *
- * - check with sparse
- *
- * */
-
 static int journal_file_object_verify(JournalFile *f, Object *o) {
         uint64_t i;
 
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 1dee74a..0bbf4a0 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -233,6 +233,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERIFY_KEY:
                         arg_action = ACTION_VERIFY;
                         arg_verify_key = optarg;
+                        arg_local = true;
                         break;
 
                 case ARG_INTERVAL:
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 7b3b647..f2dd405 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -48,6 +48,7 @@
 #include "journal-rate-limit.h"
 #include "journal-internal.h"
 #include "journal-vacuum.h"
+#include "journal-authenticate.h"
 #include "conf-parser.h"
 #include "journald.h"
 #include "virt.h"
@@ -2969,8 +2970,26 @@ int main(int argc, char *argv[]) {
 
         for (;;) {
                 struct epoll_event event;
+                int t;
 
-                r = epoll_wait(server.epoll_fd, &event, 1, -1);
+#ifdef HAVE_GCRYPT
+                usec_t u;
+
+                if (server.system_journal &&
+                    journal_file_next_evolve_usec(server.system_journal, &u)) {
+                        usec_t n;
+
+                        n = now(CLOCK_MONOTONIC);
+
+                        if (n >= u)
+                                t = 0;
+                        else
+                                t = (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC);
+                } else
+#endif
+                        t = -1;
+
+                r = epoll_wait(server.epoll_fd, &event, 1, t);
                 if (r < 0) {
 
                         if (errno == EINTR)
@@ -2979,14 +2998,20 @@ int main(int argc, char *argv[]) {
                         log_error("epoll_wait() failed: %m");
                         r = -errno;
                         goto finish;
-                } else if (r == 0)
-                        break;
+                }
 
-                r = process_event(&server, &event);
-                if (r < 0)
-                        goto finish;
-                else if (r == 0)
-                        break;
+                if (r > 0) {
+                        r = process_event(&server, &event);
+                        if (r < 0)
+                                goto finish;
+                        else if (r == 0)
+                                break;
+                }
+
+#ifdef HAVE_GCRYPT
+                if (server.system_journal)
+                        journal_file_maybe_append_tag(server.system_journal, 0);
+#endif
         }
 
         log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());



More information about the systemd-commits mailing list