[systemd-commits] 4 commits - TODO src/journal src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Sun Jan 4 18:06:52 PST 2015


 TODO                             |    4 --
 src/journal/journal-file.c       |   65 ++++++++++++++++++++++++++++++---------
 src/journal/journal-file.h       |    1 
 src/journal/journald-server.c    |   24 +++++---------
 src/journal/test-journal-flush.c |    3 -
 src/shared/util.c                |    6 +--
 6 files changed, 64 insertions(+), 39 deletions(-)

New commits:
commit 9bc5cd6d74d6efc7769d6a25b21e451dae39fe76
Author: Colin Walters <walters at verbum.org>
Date:   Thu Jan 1 14:57:08 2015 -0500

    util: Fix signedness error in lines(), match implementations
    
    Regression introduced by ed757c0cb03eef50e8d9aeb4682401c3e9486f0b
    
    Mirror the implementation of columns(), since the fd_columns()
    functions returns a negative integer for errors.
    
    Also fix columns() to return the unsigned variable instead of the
    signed intermediary (they're the same, but better to be explicit).

diff --git a/src/shared/util.c b/src/shared/util.c
index dfaf7f7..390ad1d 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3456,7 +3456,7 @@ unsigned columns(void) {
                 c = 80;
 
         cached_columns = c;
-        return c;
+        return cached_columns;
 }
 
 int fd_lines(int fd) {
@@ -3473,7 +3473,7 @@ int fd_lines(int fd) {
 
 unsigned lines(void) {
         const char *e;
-        unsigned l;
+        int l;
 
         if (_likely_(cached_lines > 0))
                 return cached_lines;
@@ -3481,7 +3481,7 @@ unsigned lines(void) {
         l = 0;
         e = getenv("LINES");
         if (e)
-                (void) safe_atou(e, &l);
+                (void) safe_atoi(e, &l);
 
         if (l <= 0)
                 l = fd_lines(STDOUT_FILENO);

commit 6fc25464bf64b5df2f0efda70bc5c497914108c8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Jan 5 02:58:04 2015 +0100

    update TODO

diff --git a/TODO b/TODO
index b031f4a..ec3746b 100644
--- a/TODO
+++ b/TODO
@@ -60,10 +60,6 @@ Features:
 
 * port libmount hookup to use API's own inotify interface, as soon as that is table in libmount
 
-* journald: broken file systems are real (btrfs), we need to handle
-  SIGBUS in some way if we cannot write or read from the disk.
-  https://bugzilla.redhat.com/show_bug.cgi?id=1151848
-
 * "systemctl preset-all" should probably order the unit files it
   operates on lexicographically before starting to work, in order to
   ensure deterministic behaviour if two unit files conflict (like DMs

commit 8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Jan 5 02:48:50 2015 +0100

    journald: reuse IOVEC_TOTAL_SIZE() macros where possible

diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index c28aba8..4613550 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -521,12 +521,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
         }
 
         if (vacuumed || !shall_try_append_again(f, r)) {
-                size_t size = 0;
-                unsigned i;
-                for (i = 0; i < n; i++)
-                        size += iovec[i].iov_len;
-
-                log_error_errno(r, "Failed to write entry (%d items, %zu bytes), ignoring: %m", n, size);
+                log_error_errno(r, "Failed to write entry (%d items, %zu bytes), ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
                 return;
         }
 
@@ -539,14 +534,9 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
 
         log_debug("Retrying write.");
         r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
-        if (r < 0) {
-                size_t size = 0;
-                unsigned i;
-                for (i = 0; i < n; i++)
-                        size += iovec[i].iov_len;
-
-                log_error_errno(r, "Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %m", n, size);
-        } else
+        if (r < 0)
+                log_error_errno(r, "Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
+        else
                 server_schedule_sync(s, priority);
 }
 

commit 2678031a179a9b91fc799f8ef951a548c66c4b49
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Jan 5 02:09:01 2015 +0100

    journald: when we detect the journal file we are about to write to has been deleted, rotate
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1171719

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 1736ff5..304ce03 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -67,6 +67,9 @@
 /* How much to increase the journal file size at once each time we allocate something new. */
 #define FILE_SIZE_INCREASE (8ULL*1024ULL*1024ULL)              /* 8MB */
 
+/* Reread fstat() of the file for detecting deletions at least this often */
+#define LAST_STAT_REFRESH_USEC (5*USEC_PER_SEC)
+
 /* The mmap context to use for the header we pick as one above the last defined typed */
 #define CONTEXT_HEADER _OBJECT_TYPE_MAX
 
@@ -319,6 +322,22 @@ static int journal_file_verify_header(JournalFile *f) {
         return 0;
 }
 
+static int journal_file_fstat(JournalFile *f) {
+        assert(f);
+        assert(f->fd >= 0);
+
+        if (fstat(f->fd, &f->last_stat) < 0)
+                return -errno;
+
+        f->last_stat_usec = now(CLOCK_MONOTONIC);
+
+        /* Refuse appending to files that are already deleted */
+        if (f->last_stat.st_nlink <= 0)
+                return -EIDRM;
+
+        return 0;
+}
+
 static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
         uint64_t old_size, new_size;
         int r;
@@ -340,8 +359,21 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         if (new_size < le64toh(f->header->header_size))
                 new_size = le64toh(f->header->header_size);
 
-        if (new_size <= old_size)
-                return 0;
+        if (new_size <= old_size) {
+
+                /* We already pre-allocated enough space, but before
+                 * we write to it, let's check with fstat() if the
+                 * file got deleted, in order make sure we don't throw
+                 * away the data immediately. Don't check fstat() for
+                 * all writes though, but only once ever 10s. */
+
+                if (f->last_stat_usec + LAST_STAT_REFRESH_USEC > now(CLOCK_MONOTONIC))
+                        return 0;
+
+                return journal_file_fstat(f);
+        }
+
+        /* Allocate more space. */
 
         if (f->metrics.max_size > 0 && new_size > f->metrics.max_size)
                 return -E2BIG;
@@ -376,12 +408,9 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
         if (r != 0)
                 return -r;
 
-        if (fstat(f->fd, &f->last_stat) < 0)
-                return -errno;
-
         f->header->arena_size = htole64(new_size - le64toh(f->header->header_size));
 
-        return 0;
+        return journal_file_fstat(f);
 }
 
 static unsigned type_to_context(ObjectType type) {
@@ -392,6 +421,8 @@ static unsigned type_to_context(ObjectType type) {
 }
 
 static int journal_file_move_to(JournalFile *f, ObjectType type, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
+        int r;
+
         assert(f);
         assert(ret);
 
@@ -403,8 +434,11 @@ static int journal_file_move_to(JournalFile *f, ObjectType type, bool keep_alway
                 /* Hmm, out of range? Let's refresh the fstat() data
                  * first, before we trust that check. */
 
-                if (fstat(f->fd, &f->last_stat) < 0 ||
-                    offset + size > (uint64_t) f->last_stat.st_size)
+                r = journal_file_fstat(f);
+                if (r < 0)
+                        return r;
+
+                if (offset + size > (uint64_t) f->last_stat.st_size)
                         return -EADDRNOTAVAIL;
         }
 
@@ -2548,10 +2582,9 @@ int journal_file_open(
                 goto fail;
         }
 
-        if (fstat(f->fd, &f->last_stat) < 0) {
-                r = -errno;
+        r = journal_file_fstat(f);
+        if (r < 0)
                 goto fail;
-        }
 
         if (f->last_stat.st_size == 0 && f->writable) {
                 /* Let's attach the creation time to the journal file,
@@ -2580,10 +2613,9 @@ int journal_file_open(
                 if (r < 0)
                         goto fail;
 
-                if (fstat(f->fd, &f->last_stat) < 0) {
-                        r = -errno;
+                r = journal_file_fstat(f);
+                if (r < 0)
                         goto fail;
-                }
 
                 newly_created = true;
         }
@@ -2700,8 +2732,11 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
         if (r < 0)
                 return -ENOMEM;
 
+        /* Try to rename the file to the archived version. If the file
+         * already was deleted, we'll get ENOENT, let's ignore that
+         * case. */
         r = rename(old_file->path, p);
-        if (r < 0)
+        if (r < 0 && errno != ENOENT)
                 return -errno;
 
         old_file->header->state = STATE_ARCHIVED;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 19fd725..b3a0679 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -82,6 +82,7 @@ typedef struct JournalFile {
 
         char *path;
         struct stat last_stat;
+        usec_t last_stat_usec;
 
         Header *header;
         HashItem *data_hash_table;
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 019c3a6..c28aba8 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -318,6 +318,7 @@ static int do_rotate(
                         log_error_errno(r, "Failed to create new %s journal: %m", name);
         else
                 server_fix_perms(s, *f, uid);
+
         return r;
 }
 
@@ -466,7 +467,8 @@ static bool shall_try_append_again(JournalFile *f, int r) {
            -EPROTONOSUPPORT  Unsupported feature
            -EBADMSG          Corrupted
            -ENODATA          Truncated
-           -ESHUTDOWN        Already archived */
+           -ESHUTDOWN        Already archived
+           -EIDRM            Journal file has been deleted */
 
         if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
                 log_debug("%s: Allocation limit reached, rotating.", f->path);
@@ -480,6 +482,8 @@ static bool shall_try_append_again(JournalFile *f, int r) {
                 log_warning("%s: Journal file corrupted, rotating.", f->path);
         else if (r == -EIO)
                 log_warning("%s: IO error, rotating.", f->path);
+        else if (r == -EIDRM)
+                log_warning("%s: Journal file has been deleted, rotating.", f->path);
         else
                 return false;
 
diff --git a/src/journal/test-journal-flush.c b/src/journal/test-journal-flush.c
index 0ca24e0..40ede4a 100644
--- a/src/journal/test-journal-flush.c
+++ b/src/journal/test-journal-flush.c
@@ -39,8 +39,6 @@ int main(int argc, char *argv[]) {
         r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
         assert_se(r >= 0);
 
-        unlink(fn);
-
         r = sd_journal_open(&j, 0);
         assert_se(r >= 0);
 
@@ -68,6 +66,7 @@ int main(int argc, char *argv[]) {
 
         journal_file_close(new_journal);
 
+        unlink(fn);
         assert_se(rmdir(dn) == 0);
 
         return 0;



More information about the systemd-commits mailing list