[systemd-commits] 3 commits - man/journald.conf.xml src/journal src/systemd

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Mon Jun 24 18:06:40 PDT 2013


 man/journald.conf.xml         |   22 ++++++++---
 src/journal/journal-vacuum.c  |   50 ++++++++++++++++---------
 src/journal/journald-server.c |   84 +++++++++++++++++-------------------------
 src/systemd/sd-messages.h     |    1 
 4 files changed, 83 insertions(+), 74 deletions(-)

New commits:
commit 9d64774057400ee15e7ffb159294f73bb665eb84
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jun 24 21:00:28 2013 -0400

    journald: always vacuum empty offline files
    
    Corrupted empty files are relatively common. I think they are created
    when a coredump for a user who never logged anything before is
    attempted to be written, but the write does not succeed because the
    coredump is too big, but there are probably other ways to create
    those, especially if the machine crashes at the right time.
    Non-corrupted empty files can also happen, e.g. if a journal file is
    opened, but nothing is ever successfully written to it and it is
    rotated because of MaxFileSec=. Either way, each "empty" journal file
    costs around 3 MB, and there's little point in keeping them around.

diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index 1ddb043..79572f1 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -128,6 +128,24 @@ static void patch_realtime(
 #endif
 }
 
+static int journal_file_empty(int dir_fd, const char *name) {
+        int fd, r;
+        le64_t n_entries;
+
+        fd = openat(dir_fd, name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
+        if (fd < 0)
+                return -errno;
+
+        if (lseek(fd, offsetof(Header, n_entries), SEEK_SET) < 0)
+                return -errno;
+
+        r = read(fd, &n_entries, sizeof(n_entries));
+        if (r != sizeof(n_entries))
+                return r == 0 ? -EINVAL : -errno;
+
+        return le64toh(n_entries) == 0;
+}
+
 int journal_directory_vacuum(
                 const char *directory,
                 uint64_t max_use,
@@ -247,6 +265,17 @@ int journal_directory_vacuum(
                         /* We do not vacuum active files or unknown files! */
                         continue;
 
+                if (journal_file_empty(dirfd(d), de->d_name)) {
+
+                        /* Always vacuum empty non-online files. */
+
+                        if (unlinkat(dirfd(d), de->d_name, 0) >= 0)
+                                log_debug("Deleted empty journal %s/%s.", directory, de->d_name);
+                        else if (errno != ENOENT)
+                                log_warning("Failed to delete %s/%s: %m", directory, de->d_name);
+                        continue;
+                }
+
                 patch_realtime(directory, de->d_name, &st, &realtime);
 
                 GREEDY_REALLOC(list, n_allocated, n_list + 1);

commit 670b110c3b59dfa335ac43065b2038400d1d04a9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jun 24 21:02:16 2013 -0400

    journald: fix space limits reporting
    
    Reporting of the free space was bogus, since the remaining space
    was compared with the maximum allowed, instead of the current
    use being compared with the maximum allowed. Simplify and fix
    by reporting limits directly at the point where they are calculated.
    
    Also, assign a UUID to the message.

diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index 26f47f8..6e43914 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -237,7 +237,17 @@
                                 while the former apply if persistent
                                 logging is enabled and the system is
                                 fully booted
-                                up. <varname>SystemMaxUse=</varname>
+                                up. <command>journalctl</command> and
+                                <command>systemd-journald</command>
+                                ignore all files with names not ending
+                                with <literal>.journal</literal> or
+                                <literal>.journal~</literal>, so only
+                                such files, located in the appropriate
+                                directories, are taken into account
+                                when calculating current disk usage.
+                                </para>
+
+                                <para><varname>SystemMaxUse=</varname>
                                 and <varname>RuntimeMaxUse=</varname>
                                 control how much disk space the
                                 journal may use up at
@@ -271,11 +281,11 @@
                                 values in bytes or use K, M, G, T, P,
                                 E as units for the specified sizes
                                 (equal to 1024, 1024²,... bytes).
-                                Note that size limits are
-                                enforced synchronously to journal
-                                files as they are extended, and need
-                                no explicit rotation step triggered by
-                                time.</para></listitem>
+                                Note that size limits are enforced
+                                synchronously when journal files
+                                are extended, and no explicit
+                                rotation step triggered by
+                                time is needed.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index c7d047a..44ba916 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -89,21 +89,22 @@ static const char* const split_mode_table[] = {
 DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
 
-static uint64_t available_space(Server *s) {
+static uint64_t available_space(Server *s, bool verbose) {
         char ids[33];
         _cleanup_free_ char *p = NULL;
-        const char *f;
         sd_id128_t machine;
         struct statvfs ss;
-        uint64_t sum = 0, avail = 0, ss_avail = 0;
+        uint64_t sum = 0, ss_avail = 0, avail = 0;
         int r;
         _cleanup_closedir_ DIR *d = NULL;
         usec_t ts;
+        const char *f;
         JournalMetrics *m;
 
         ts = now(CLOCK_MONOTONIC);
 
-        if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
+        if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts
+            && !verbose)
                 return s->cached_available_space;
 
         r = sd_id128_get_machine(&machine);
@@ -156,19 +157,27 @@ static uint64_t available_space(Server *s) {
                 sum += (uint64_t) st.st_blocks * 512UL;
         }
 
-        avail = sum >= m->max_use ? 0 : m->max_use - sum;
-
         ss_avail = ss.f_bsize * ss.f_bavail;
+        avail = ss_avail > m->keep_free ? ss_avail - m->keep_free : 0;
 
-        ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
-
-        if (ss_avail < avail)
-                avail = ss_avail;
-
-        s->cached_available_space = avail;
+        s->cached_available_space = MIN(m->max_use, avail) > sum ? MIN(m->max_use, avail) - sum : 0;
         s->cached_available_space_timestamp = ts;
 
-        return avail;
+        if (verbose) {
+                char    fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
+                        fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX];
+
+                server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
+                                      "%s journal is using %s (max %s, leaving %s of free %s, current limit %s).",
+                                      s->system_journal ? "Permanent" : "Runtime",
+                                      format_bytes(fb1, sizeof(fb1), sum),
+                                      format_bytes(fb2, sizeof(fb2), m->max_use),
+                                      format_bytes(fb3, sizeof(fb3), m->keep_free),
+                                      format_bytes(fb4, sizeof(fb4), ss_avail),
+                                      format_bytes(fb5, sizeof(fb5), MIN(m->max_use, avail)));
+        }
+
+        return s->cached_available_space;
 }
 
 static void server_read_file_gid(Server *s) {
@@ -853,7 +862,7 @@ void server_dispatch_message(
         }
 
         rl = journal_rate_limit_test(s->rate_limit, path,
-                                     priority & LOG_PRIMASK, available_space(s));
+                                     priority & LOG_PRIMASK, available_space(s, false));
 
         if (rl == 0)
                 return;
@@ -899,28 +908,13 @@ static int system_journal_open(Server *s) {
                 fn = strappenda(fn, "/system.journal");
                 r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
 
-                if (r >= 0) {
-                        char fb[FORMAT_BYTES_MAX];
-                        uint64_t avail;
-
+                if (r >= 0)
                         server_fix_perms(s, s->system_journal, 0);
+        } else if (r < 0) {
+                if (r != -ENOENT && r != -EROFS)
+                        log_warning("Failed to open system journal: %s", strerror(-r));
 
-                        server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.",
-                                              format_bytes(fb, sizeof(fb), s->system_metrics.max_use));
-
-                        avail = available_space(s);
-
-                        if (s->system_metrics.max_use > avail)
-                               server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to SystemKeepFree.",
-                                                     format_bytes(fb, sizeof(fb), avail));
-
-                } else if (r < 0) {
-
-                        if (r != -ENOENT && r != -EROFS)
-                                log_warning("Failed to open system journal: %s", strerror(-r));
-
-                        r = 0;
-                }
+                r = 0;
         }
 
         if (!s->runtime_journal &&
@@ -961,22 +955,12 @@ static int system_journal_open(Server *s) {
                         }
                 }
 
-                if (s->runtime_journal) {
-                        char fb[FORMAT_BYTES_MAX];
-                        uint64_t avail;
-
+                if (s->runtime_journal)
                         server_fix_perms(s, s->runtime_journal, 0);
-                        server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.",
-                                              format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use));
-
-                        avail = available_space(s);
-
-                        if (s->system_metrics.max_use > avail)
-                               server_driver_message(s, SD_ID128_NULL, "Journal size currently limited to %s due to RuntimeKeepFree.",
-                                                     format_bytes(fb, sizeof(fb), avail));
-                }
         }
 
+        available_space(s, true);
+
         return r;
 }
 
@@ -1228,8 +1212,8 @@ int process_event(Server *s, struct epoll_event *ev) {
                                         label = (char*) CMSG_DATA(cmsg);
                                         label_len = cmsg->cmsg_len - CMSG_LEN(0);
                                 } else if (cmsg->cmsg_level == SOL_SOCKET &&
-                                         cmsg->cmsg_type == SO_TIMESTAMP &&
-                                         cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
+                                           cmsg->cmsg_type == SO_TIMESTAMP &&
+                                           cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
                                         tv = (struct timeval*) CMSG_DATA(cmsg);
                                 else if (cmsg->cmsg_level == SOL_SOCKET &&
                                          cmsg->cmsg_type == SCM_RIGHTS) {
@@ -1455,7 +1439,7 @@ int server_init(Server *s) {
 
         zero(*s);
         s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd =
-            s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
+                s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
         s->compress = true;
         s->seal = true;
 
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
index 2f80749..c811a06 100644
--- a/src/systemd/sd-messages.h
+++ b/src/systemd/sd-messages.h
@@ -39,6 +39,7 @@ extern "C" {
 #define SD_MESSAGE_JOURNAL_STOP     SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b)
 #define SD_MESSAGE_JOURNAL_DROPPED  SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e)
 #define SD_MESSAGE_JOURNAL_MISSED   SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06)
+#define SD_MESSAGE_JOURNAL_USAGE    SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6)
 
 #define SD_MESSAGE_COREDUMP         SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
 

commit 30cb029b8bf6578ed1595d87abdedc6923fd4608
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jun 24 07:59:41 2013 -0400

    journal/vacuum: cleanup

diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index 4a3a5a9..1ddb043 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -135,10 +135,11 @@ int journal_directory_vacuum(
                 usec_t max_retention_usec,
                 usec_t *oldest_usec) {
 
-        DIR *d;
+        _cleanup_closedir_ DIR *d = NULL;
         int r = 0;
         struct vacuum_info *list = NULL;
-        unsigned n_list = 0, n_allocated = 0, i;
+        unsigned n_list = 0, i;
+        size_t n_allocated = 0;
         uint64_t sum = 0;
         usec_t retention_limit = 0;
 
@@ -248,19 +249,7 @@ int journal_directory_vacuum(
 
                 patch_realtime(directory, de->d_name, &st, &realtime);
 
-                if (n_list >= n_allocated) {
-                        struct vacuum_info *j;
-
-                        n_allocated = MAX(n_allocated * 2U, 8U);
-                        j = realloc(list, n_allocated * sizeof(struct vacuum_info));
-                        if (!j) {
-                                free(p);
-                                r = -ENOMEM;
-                                goto finish;
-                        }
-
-                        list = j;
-                }
+                GREEDY_REALLOC(list, n_allocated, n_list + 1);
 
                 list[n_list].filename = p;
                 list[n_list].usage = 512UL * (uint64_t) st.st_blocks;
@@ -308,11 +297,7 @@ int journal_directory_vacuum(
 finish:
         for (i = 0; i < n_list; i++)
                 free(list[i].filename);
-
         free(list);
 
-        if (d)
-                closedir(d);
-
         return r;
 }



More information about the systemd-commits mailing list