923a60
From 6930375c3f0d9681f27b42f1d0406721c3f9a013 Mon Sep 17 00:00:00 2001
923a60
From: Lennart Poettering <lennart@poettering.net>
923a60
Date: Mon, 2 Nov 2015 23:14:30 +0100
923a60
Subject: [PATCH] sd-journal: various clean-ups and modernizations
923a60
923a60
- Always print a debug log message about files and directories we cannot
923a60
  open right when it happens instead of the caller, thus reducing the
923a60
  number of places where we need to generate the debug message.
923a60
923a60
- Always push the errors we encounter immediately into the error set,
923a60
  when we run into them, instead of in the caller. Thus, we never forget
923a60
  to push them in.
923a60
923a60
- Use stack instead of heap memory where we can.
923a60
923a60
- Make remove_file() void, since it cannot fail anyway and always
923a60
  returned 0.
923a60
923a60
- Make local machine check of journal directories explicit in a
923a60
  function, to make things more readable.
923a60
923a60
- Port to all directory listing loops FOREACH_DIRENT_ALL()
923a60
923a60
- sd-daemon is library code, hence never log at higher log levels than
923a60
  LOG_DEBUG.
923a60
923a60
(cherry picked from commit d617408ecbe69db69aefddfcb10a6c054ea46ba0)
923a60
923a60
Related: #1465759
923a60
---
923a60
 src/journal/sd-journal.c | 242 ++++++++++++++++++---------------------
923a60
 1 file changed, 111 insertions(+), 131 deletions(-)
923a60
923a60
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
923a60
index 3749f9e895..9895d9608f 100644
923a60
--- a/src/journal/sd-journal.c
923a60
+++ b/src/journal/sd-journal.c
923a60
@@ -1171,6 +1171,8 @@ static bool file_has_type_prefix(const char *prefix, const char *filename) {
923a60
 }
923a60
 
923a60
 static bool file_type_wanted(int flags, const char *filename) {
923a60
+        assert(filename);
923a60
+
923a60
         if (!endswith(filename, ".journal") && !endswith(filename, ".journal~"))
923a60
                 return false;
923a60
 
923a60
@@ -1195,7 +1197,7 @@ static bool file_type_wanted(int flags, const char *filename) {
923a60
 
923a60
 static int add_any_file(sd_journal *j, const char *path) {
923a60
         JournalFile *f = NULL;
923a60
-        int r;
923a60
+        int r, k;
923a60
 
923a60
         assert(j);
923a60
         assert(path);
923a60
@@ -1204,20 +1206,23 @@ static int add_any_file(sd_journal *j, const char *path) {
923a60
                 return 0;
923a60
 
923a60
         if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
923a60
-                log_warning("Too many open journal files, not adding %s.", path);
923a60
-                return set_put_error(j, -ETOOMANYREFS);
923a60
+                log_debug("Too many open journal files, not adding %s.", path);
923a60
+                r = -ETOOMANYREFS;
923a60
+                goto fail;
923a60
         }
923a60
 
923a60
         r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
923a60
-        if (r < 0)
923a60
-                return r;
923a60
+        if (r < 0) {
923a60
+                log_debug_errno(r, "Failed to open journal file %s: %m", path);
923a60
+                goto fail;
923a60
+        }
923a60
 
923a60
         /* journal_file_dump(f); */
923a60
 
923a60
         r = ordered_hashmap_put(j->files, f->path, f);
923a60
         if (r < 0) {
923a60
                 journal_file_close(f);
923a60
-                return r;
923a60
+                goto fail;
923a60
         }
923a60
 
923a60
         log_debug("File %s added.", f->path);
923a60
@@ -1227,10 +1232,17 @@ static int add_any_file(sd_journal *j, const char *path) {
923a60
         j->current_invalidate_counter ++;
923a60
 
923a60
         return 0;
923a60
+
923a60
+fail:
923a60
+        k = set_put_error(j, r);
923a60
+        if (k < 0)
923a60
+                return k;
923a60
+
923a60
+        return r;
923a60
 }
923a60
 
923a60
 static int add_file(sd_journal *j, const char *prefix, const char *filename) {
923a60
-        char *path = NULL;
923a60
+        const char *path;
923a60
 
923a60
         assert(j);
923a60
         assert(prefix);
923a60
@@ -1250,24 +1262,20 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) {
923a60
         return add_any_file(j, path);
923a60
 }
923a60
 
923a60
-static int remove_file(sd_journal *j, const char *prefix, const char *filename) {
923a60
-        _cleanup_free_ char *path;
923a60
+static void remove_file(sd_journal *j, const char *prefix, const char *filename) {
923a60
+        const char *path;
923a60
         JournalFile *f;
923a60
 
923a60
         assert(j);
923a60
         assert(prefix);
923a60
         assert(filename);
923a60
 
923a60
-        path = strjoin(prefix, "/", filename, NULL);
923a60
-        if (!path)
923a60
-                return -ENOMEM;
923a60
-
923a60
+        path = strjoina(prefix, "/", filename);
923a60
         f = ordered_hashmap_get(j->files, path);
923a60
         if (!f)
923a60
-                return 0;
923a60
+                return;
923a60
 
923a60
         remove_file_real(j, f);
923a60
-        return 0;
923a60
 }
923a60
 
923a60
 static void remove_file_real(sd_journal *j, JournalFile *f) {
923a60
@@ -1296,12 +1304,27 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
923a60
         j->current_invalidate_counter ++;
923a60
 }
923a60
 
923a60
+static int dirname_is_machine_id(const char *fn) {
923a60
+        sd_id128_t id, machine;
923a60
+        int r;
923a60
+
923a60
+        r = sd_id128_get_machine(&machine);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_id128_from_string(fn, &id;;
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        return sd_id128_equal(id, machine);
923a60
+}
923a60
+
923a60
 static int add_directory(sd_journal *j, const char *prefix, const char *dirname) {
923a60
         _cleanup_free_ char *path = NULL;
923a60
-        int r;
923a60
         _cleanup_closedir_ DIR *d = NULL;
923a60
-        sd_id128_t id, mid;
923a60
+        struct dirent *de = NULL;
923a60
         Directory *m;
923a60
+        int r, k;
923a60
 
923a60
         assert(j);
923a60
         assert(prefix);
923a60
@@ -1310,35 +1333,36 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
923a60
         log_debug("Considering %s/%s.", prefix, dirname);
923a60
 
923a60
         if ((j->flags & SD_JOURNAL_LOCAL_ONLY) &&
923a60
-            (sd_id128_from_string(dirname, &id) < 0 ||
923a60
-             sd_id128_get_machine(&mid) < 0 ||
923a60
-             !(sd_id128_equal(id, mid) || path_startswith(prefix, "/run"))))
923a60
+            !(dirname_is_machine_id(dirname) > 0 || path_startswith(prefix, "/run")))
923a60
             return 0;
923a60
 
923a60
         path = strjoin(prefix, "/", dirname, NULL);
923a60
-        if (!path)
923a60
-                return -ENOMEM;
923a60
+        if (!path) {
923a60
+                r = -ENOMEM;
923a60
+                goto fail;
923a60
+        }
923a60
 
923a60
         d = opendir(path);
923a60
         if (!d) {
923a60
-                log_debug_errno(errno, "Failed to open %s: %m", path);
923a60
-                if (errno == ENOENT)
923a60
-                        return 0;
923a60
-                return -errno;
923a60
+                r = log_debug_errno(errno, "Failed to open directory %s: %m", path);
923a60
+                goto fail;
923a60
         }
923a60
 
923a60
         m = hashmap_get(j->directories_by_path, path);
923a60
         if (!m) {
923a60
                 m = new0(Directory, 1);
923a60
-                if (!m)
923a60
-                        return -ENOMEM;
923a60
+                if (!m) {
923a60
+                        r = -ENOMEM;
923a60
+                        goto fail;
923a60
+                }
923a60
 
923a60
                 m->is_root = false;
923a60
                 m->path = path;
923a60
 
923a60
                 if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
923a60
                         free(m);
923a60
-                        return -ENOMEM;
923a60
+                        r = -ENOMEM;
923a60
+                        goto fail;
923a60
                 }
923a60
 
923a60
                 path = NULL; /* avoid freeing in cleanup */
923a60
@@ -1360,41 +1384,30 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname)
923a60
                         inotify_rm_watch(j->inotify_fd, m->wd);
923a60
         }
923a60
 
923a60
-        for (;;) {
923a60
-                struct dirent *de;
923a60
-
923a60
-                errno = 0;
923a60
-                de = readdir(d);
923a60
-                if (!de && errno != 0) {
923a60
-                        r = -errno;
923a60
-                        log_debug_errno(errno, "Failed to read directory %s: %m", m->path);
923a60
-                        return r;
923a60
-                }
923a60
-                if (!de)
923a60
-                        break;
923a60
+        FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
923a60
 
923a60
                 if (dirent_is_file_with_suffix(de, ".journal") ||
923a60
-                    dirent_is_file_with_suffix(de, ".journal~")) {
923a60
-                        r = add_file(j, m->path, de->d_name);
923a60
-                        if (r < 0) {
923a60
-                                log_debug_errno(r, "Failed to add file %s/%s: %m",
923a60
-                                                m->path, de->d_name);
923a60
-                                r = set_put_error(j, r);
923a60
-                                if (r < 0)
923a60
-                                        return r;
923a60
-                        }
923a60
-                }
923a60
+                    dirent_is_file_with_suffix(de, ".journal~"))
923a60
+                        (void) add_file(j, m->path, de->d_name);
923a60
         }
923a60
 
923a60
         check_network(j, dirfd(d));
923a60
 
923a60
         return 0;
923a60
+
923a60
+fail:
923a60
+        k = set_put_error(j, r);
923a60
+        if (k < 0)
923a60
+                return k;
923a60
+
923a60
+        return r;
923a60
 }
923a60
 
923a60
-static int add_root_directory(sd_journal *j, const char *p) {
923a60
+static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
923a60
         _cleanup_closedir_ DIR *d = NULL;
923a60
+        struct dirent *de;
923a60
         Directory *m;
923a60
-        int r;
923a60
+        int r, k;
923a60
 
923a60
         assert(j);
923a60
         assert(p);
923a60
@@ -1407,26 +1420,35 @@ static int add_root_directory(sd_journal *j, const char *p) {
923a60
                 p = strjoina(j->prefix, p);
923a60
 
923a60
         d = opendir(p);
923a60
-        if (!d)
923a60
-                return -errno;
923a60
+        if (!d) {
923a60
+                if (errno == ENOENT && missing_ok)
923a60
+                        return 0;
923a60
+
923a60
+                r = log_debug_errno(errno, "Failed to open root directory %s: %m", p);
923a60
+                goto fail;
923a60
+        }
923a60
 
923a60
         m = hashmap_get(j->directories_by_path, p);
923a60
         if (!m) {
923a60
                 m = new0(Directory, 1);
923a60
-                if (!m)
923a60
-                        return -ENOMEM;
923a60
+                if (!m) {
923a60
+                        r = -ENOMEM;
923a60
+                        goto fail;
923a60
+                }
923a60
 
923a60
                 m->is_root = true;
923a60
                 m->path = strdup(p);
923a60
                 if (!m->path) {
923a60
                         free(m);
923a60
-                        return -ENOMEM;
923a60
+                        r = -ENOMEM;
923a60
+                        goto fail;
923a60
                 }
923a60
 
923a60
                 if (hashmap_put(j->directories_by_path, m->path, m) < 0) {
923a60
                         free(m->path);
923a60
                         free(m);
923a60
-                        return -ENOMEM;
923a60
+                        r = -ENOMEM;
923a60
+                        goto fail;
923a60
                 }
923a60
 
923a60
                 j->current_invalidate_counter ++;
923a60
@@ -1449,42 +1471,27 @@ static int add_root_directory(sd_journal *j, const char *p) {
923a60
         if (j->no_new_files)
923a60
                 return 0;
923a60
 
923a60
-        for (;;) {
923a60
-                struct dirent *de;
923a60
+        FOREACH_DIRENT_ALL(de, d, return log_debug_errno(errno, "Failed to read directory %s: %m", m->path)) {
923a60
                 sd_id128_t id;
923a60
 
923a60
-                errno = 0;
923a60
-                de = readdir(d);
923a60
-                if (!de && errno != 0) {
923a60
-                        r = -errno;
923a60
-                        log_debug_errno(errno, "Failed to read directory %s: %m", m->path);
923a60
-                        return r;
923a60
-                }
923a60
-                if (!de)
923a60
-                        break;
923a60
-
923a60
                 if (dirent_is_file_with_suffix(de, ".journal") ||
923a60
-                    dirent_is_file_with_suffix(de, ".journal~")) {
923a60
-                        r = add_file(j, m->path, de->d_name);
923a60
-                        if (r < 0) {
923a60
-                                log_debug_errno(r, "Failed to add file %s/%s: %m",
923a60
-                                                m->path, de->d_name);
923a60
-                                r = set_put_error(j, r);
923a60
-                                if (r < 0)
923a60
-                                        return r;
923a60
-                        }
923a60
-                } else if ((de->d_type == DT_DIR || de->d_type == DT_LNK || de->d_type == DT_UNKNOWN) &&
923a60
-                           sd_id128_from_string(de->d_name, &id) >= 0) {
923a60
-
923a60
-                        r = add_directory(j, m->path, de->d_name);
923a60
-                        if (r < 0)
923a60
-                                log_debug_errno(r, "Failed to add directory %s/%s: %m", m->path, de->d_name);
923a60
-                }
923a60
+                    dirent_is_file_with_suffix(de, ".journal~"))
923a60
+                        (void) add_file(j, m->path, de->d_name);
923a60
+                else if (IN_SET(de->d_type, DT_DIR, DT_LNK, DT_UNKNOWN) &&
923a60
+                         sd_id128_from_string(de->d_name, &id) >= 0)
923a60
+                        (void) add_directory(j, m->path, de->d_name);
923a60
         }
923a60
 
923a60
         check_network(j, dirfd(d));
923a60
 
923a60
         return 0;
923a60
+
923a60
+fail:
923a60
+        k = set_put_error(j, r);
923a60
+        if (k < 0)
923a60
+                return k;
923a60
+
923a60
+        return r;
923a60
 }
923a60
 
923a60
 static void remove_directory(sd_journal *j, Directory *d) {
923a60
@@ -1509,8 +1516,8 @@ static void remove_directory(sd_journal *j, Directory *d) {
923a60
 }
923a60
 
923a60
 static int add_search_paths(sd_journal *j) {
923a60
-        int r;
923a60
-        const char search_paths[] =
923a60
+
923a60
+        static const char search_paths[] =
923a60
                 "/run/log/journal\0"
923a60
                 "/var/log/journal\0";
923a60
         const char *p;
923a60
@@ -1520,14 +1527,8 @@ static int add_search_paths(sd_journal *j) {
923a60
         /* We ignore most errors here, since the idea is to only open
923a60
          * what's actually accessible, and ignore the rest. */
923a60
 
923a60
-        NULSTR_FOREACH(p, search_paths) {
923a60
-                r = add_root_directory(j, p);
923a60
-                if (r < 0 && r != -ENOENT) {
923a60
-                        r = set_put_error(j, r);
923a60
-                        if (r < 0)
923a60
-                                return r;
923a60
-                }
923a60
-        }
923a60
+        NULSTR_FOREACH(p, search_paths)
923a60
+                (void) add_root_directory(j, p, true);
923a60
 
923a60
         return 0;
923a60
 }
923a60
@@ -1551,17 +1552,14 @@ static int add_current_paths(sd_journal *j) {
923a60
                 if (!dir)
923a60
                         return -ENOMEM;
923a60
 
923a60
-                r = add_root_directory(j, dir);
923a60
-                if (r < 0) {
923a60
-                        set_put_error(j, r);
923a60
+                r = add_root_directory(j, dir, true);
923a60
+                if (r < 0)
923a60
                         return r;
923a60
-                }
923a60
         }
923a60
 
923a60
         return 0;
923a60
 }
923a60
 
923a60
-
923a60
 static int allocate_inotify(sd_journal *j) {
923a60
         assert(j);
923a60
 
923a60
@@ -1689,11 +1687,9 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
923a60
         if (!j)
923a60
                 return -ENOMEM;
923a60
 
923a60
-        r = add_root_directory(j, path);
923a60
-        if (r < 0) {
923a60
-                set_put_error(j, r);
923a60
+        r = add_root_directory(j, path, false);
923a60
+        if (r < 0)
923a60
                 goto fail;
923a60
-        }
923a60
 
923a60
         *ret = j;
923a60
         return 0;
923a60
@@ -1718,10 +1714,8 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
923a60
 
923a60
         STRV_FOREACH(path, paths) {
923a60
                 r = add_any_file(j, *path);
923a60
-                if (r < 0) {
923a60
-                        log_error_errno(r, "Failed to open %s: %m", *path);
923a60
+                if (r < 0)
923a60
                         goto fail;
923a60
-                }
923a60
         }
923a60
 
923a60
         j->no_new_files = true;
923a60
@@ -2061,7 +2055,7 @@ _public_ int sd_journal_get_fd(sd_journal *j) {
923a60
         if (j->no_new_files)
923a60
                 r = add_current_paths(j);
923a60
         else if (j->path)
923a60
-                r = add_root_directory(j, j->path);
923a60
+                r = add_root_directory(j, j->path, true);
923a60
         else
923a60
                 r = add_search_paths(j);
923a60
         if (r < 0)
923a60
@@ -2108,7 +2102,6 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {
923a60
 
923a60
 static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
923a60
         Directory *d;
923a60
-        int r;
923a60
 
923a60
         assert(j);
923a60
         assert(e);
923a60
@@ -2124,20 +2117,10 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
923a60
 
923a60
                         /* Event for a journal file */
923a60
 
923a60
-                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
923a60
-                                r = add_file(j, d->path, e->name);
923a60
-                                if (r < 0) {
923a60
-                                        log_debug_errno(r, "Failed to add file %s/%s: %m",
923a60
-                                                        d->path, e->name);
923a60
-                                        set_put_error(j, r);
923a60
-                                }
923a60
-
923a60
-                        } else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT)) {
923a60
-
923a60
-                                r = remove_file(j, d->path, e->name);
923a60
-                                if (r < 0)
923a60
-                                        log_debug_errno(r, "Failed to remove file %s/%s: %m", d->path, e->name);
923a60
-                        }
923a60
+                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB))
923a60
+                                (void) add_file(j, d->path, e->name);
923a60
+                        else if (e->mask & (IN_DELETE|IN_MOVED_FROM|IN_UNMOUNT))
923a60
+                                remove_file(j, d->path, e->name);
923a60
 
923a60
                 } else if (!d->is_root && e->len == 0) {
923a60
 
923a60
@@ -2150,11 +2133,8 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
923a60
 
923a60
                         /* Event for root directory */
923a60
 
923a60
-                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) {
923a60
-                                r = add_directory(j, d->path, e->name);
923a60
-                                if (r < 0)
923a60
-                                        log_debug_errno(r, "Failed to add directory %s/%s: %m", d->path, e->name);
923a60
-                        }
923a60
+                        if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB))
923a60
+                                (void) add_directory(j, d->path, e->name);
923a60
                 }
923a60
 
923a60
                 return;
923a60
@@ -2163,7 +2143,7 @@ static void process_inotify_event(sd_journal *j, struct inotify_event *e) {
923a60
         if (e->mask & IN_IGNORED)
923a60
                 return;
923a60
 
923a60
-        log_warning("Unknown inotify event.");
923a60
+        log_debug("Unknown inotify event.");
923a60
 }
923a60
 
923a60
 static int determine_change(sd_journal *j) {