dcavalca / rpms / systemd

Forked from rpms/systemd 4 months ago
Clone
923a60
From 9f7b08ba18ac3d4fd51e70d78d44b60ffb65411f Mon Sep 17 00:00:00 2001
923a60
From: Lennart Poettering <lennart@poettering.net>
923a60
Date: Mon, 2 Nov 2015 23:37:05 +0100
923a60
Subject: [PATCH] journalctl: when we fail to open a journal file, print why
923a60
923a60
When we enumerate journal files and encounter an invalid one, remember
923a60
which this, and show it to the user.
923a60
923a60
Note the possibly slightly surprising logic here: we store only one path
923a60
per error code. This means we show all error kinds but not every actual
923a60
error we encounter. This has the benefit of not requiring us to keep a
923a60
potentially unbounded list of errors with their sources around, but can
923a60
still provide a pretty complete overview on the errors we encountered.
923a60
923a60
Fixes #1669.
923a60
923a60
(cherry picked from commit 5768d2594940668506bb4cafa078f654cc20dc5a)
923a60
923a60
Resolves: #1465759
923a60
---
923a60
 src/journal/journal-internal.h |  2 +-
923a60
 src/journal/journalctl.c       | 27 +++++++++++++++----
923a60
 src/journal/sd-journal.c       | 49 +++++++++++++++++++++++++++-------
923a60
 3 files changed, 63 insertions(+), 15 deletions(-)
923a60
923a60
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
923a60
index 115d7776da..eb23ac28ad 100644
923a60
--- a/src/journal/journal-internal.h
923a60
+++ b/src/journal/journal-internal.h
923a60
@@ -123,7 +123,7 @@ struct sd_journal {
923a60
         Hashmap *directories_by_path;
923a60
         Hashmap *directories_by_wd;
923a60
 
923a60
-        Set *errors;
923a60
+        Hashmap *errors;
923a60
 };
923a60
 
923a60
 char *journal_make_match_string(sd_journal *j);
923a60
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
923a60
index 8c83797328..0be70764ef 100644
923a60
--- a/src/journal/journalctl.c
923a60
+++ b/src/journal/journalctl.c
923a60
@@ -1783,33 +1783,50 @@ static int access_check_var_log_journal(sd_journal *j) {
923a60
 static int access_check(sd_journal *j) {
923a60
         Iterator it;
923a60
         void *code;
923a60
+        char *path;
923a60
         int r = 0;
923a60
 
923a60
         assert(j);
923a60
 
923a60
-        if (set_isempty(j->errors)) {
923a60
+        if (hashmap_isempty(j->errors)) {
923a60
                 if (ordered_hashmap_isempty(j->files))
923a60
                         log_notice("No journal files were found.");
923a60
 
923a60
                 return 0;
923a60
         }
923a60
 
923a60
-        if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
923a60
+        if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
923a60
                 (void) access_check_var_log_journal(j);
923a60
 
923a60
                 if (ordered_hashmap_isempty(j->files))
923a60
                         r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
923a60
         }
923a60
 
923a60
-        SET_FOREACH(code, j->errors, it) {
923a60
+        HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
923a60
                 int err;
923a60
 
923a60
                 err = abs(PTR_TO_INT(code));
923a60
 
923a60
-                if (err == EACCES)
923a60
+                switch (err) {
923a60
+                case EACCES:
923a60
                         continue;
923a60
 
923a60
-                log_warning_errno(err, "An error was encountered while opening journal files, ignoring: %m");
923a60
+                case ENODATA:
923a60
+                        log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
923a60
+                        break;
923a60
+
923a60
+                case EPROTONOSUPPORT:
923a60
+                        log_warning_errno(err, "Journal file %s uses an unsupported feature, ignoring file.", path);
923a60
+                        break;
923a60
+
923a60
+                case EBADMSG:
923a60
+                        log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
923a60
+                        break;
923a60
+
923a60
+                default:
923a60
+                        log_warning_errno(err, "An error was encountered while opening journal file %s, ignoring file.", path);
923a60
+                        break;
923a60
+                }
923a60
         }
923a60
 
923a60
         return r;
923a60
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
923a60
index 9895d9608f..14b65cfedd 100644
923a60
--- a/src/journal/sd-journal.c
923a60
+++ b/src/journal/sd-journal.c
923a60
@@ -62,19 +62,46 @@ static bool journal_pid_changed(sd_journal *j) {
923a60
         return j->original_pid != getpid();
923a60
 }
923a60
 
923a60
-/* We return an error here only if we didn't manage to
923a60
-   memorize the real error. */
923a60
-static int set_put_error(sd_journal *j, int r) {
923a60
+static int journal_put_error(sd_journal *j, int r, const char *path) {
923a60
+        char *copy;
923a60
         int k;
923a60
 
923a60
+        /* Memorize an error we encountered, and store which
923a60
+         * file/directory it was generated from. Note that we store
923a60
+         * only *one* path per error code, as the error code is the
923a60
+         * key into the hashmap, and the path is the value. This means
923a60
+         * we keep track only of all error kinds, but not of all error
923a60
+         * locations. This has the benefit that the hashmap cannot
923a60
+         * grow beyond bounds.
923a60
+         *
923a60
+         * We return an error here only if we didn't manage to
923a60
+         * memorize the real error. */
923a60
+
923a60
         if (r >= 0)
923a60
                 return r;
923a60
 
923a60
-        k = set_ensure_allocated(&j->errors, NULL);
923a60
+        k = hashmap_ensure_allocated(&j->errors, NULL);
923a60
         if (k < 0)
923a60
                 return k;
923a60
 
923a60
-        return set_put(j->errors, INT_TO_PTR(r));
923a60
+        if (path) {
923a60
+                copy = strdup(path);
923a60
+                if (!copy)
923a60
+                        return -ENOMEM;
923a60
+        } else
923a60
+                copy = NULL;
923a60
+
923a60
+        k = hashmap_put(j->errors, INT_TO_PTR(r), copy);
923a60
+        if (k < 0) {
923a60
+                free(copy);
923a60
+
923a60
+                if (k == -EEXIST)
923a60
+                        return 0;
923a60
+
923a60
+                return k;
923a60
+        }
923a60
+
923a60
+        return 0;
923a60
 }
923a60
 
923a60
 static void detach_location(sd_journal *j) {
923a60
@@ -1234,7 +1261,7 @@ static int add_any_file(sd_journal *j, const char *path) {
923a60
         return 0;
923a60
 
923a60
 fail:
923a60
-        k = set_put_error(j, r);
923a60
+        k = journal_put_error(j, r, path);
923a60
         if (k < 0)
923a60
                 return k;
923a60
 
923a60
@@ -1396,7 +1423,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
923a60
         return 0;
923a60
 
923a60
 fail:
923a60
-        k = set_put_error(j, r);
923a60
+        k = journal_put_error(j, r, path ?: dirname);
923a60
         if (k < 0)
923a60
                 return k;
923a60
 
923a60
@@ -1487,7 +1514,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
923a60
         return 0;
923a60
 
923a60
 fail:
923a60
-        k = set_put_error(j, r);
923a60
+        k = journal_put_error(j, r, p);
923a60
         if (k < 0)
923a60
                 return k;
923a60
 
923a60
@@ -1732,6 +1759,7 @@ fail:
923a60
 _public_ void sd_journal_close(sd_journal *j) {
923a60
         Directory *d;
923a60
         JournalFile *f;
923a60
+        char *p;
923a60
 
923a60
         if (!j)
923a60
                 return;
923a60
@@ -1759,10 +1787,13 @@ _public_ void sd_journal_close(sd_journal *j) {
923a60
                 mmap_cache_unref(j->mmap);
923a60
         }
923a60
 
923a60
+        while ((p = hashmap_steal_first(j->errors)))
923a60
+                free(p);
923a60
+        hashmap_free(j->errors);
923a60
+
923a60
         free(j->path);
923a60
         free(j->prefix);
923a60
         free(j->unique_field);
923a60
-        set_free(j->errors);
923a60
         free(j);
923a60
 }
923a60