]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journalctl: split out show()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 3 May 2023 23:13:59 +0000 (08:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 28 May 2023 05:52:32 +0000 (14:52 +0900)
No functional changes, just refactoring.

src/journal/journalctl.c

index 75af23ecc876a8e807906340d3ff1ff496e7a708..0f1a738fa549028b862f23efbaab62d05967b0f6 100644 (file)
@@ -2156,16 +2156,162 @@ static int wait_for_change(sd_journal *j, int poll_fd) {
         return 0;
 }
 
+typedef struct Context {
+        sd_journal *journal;
+        bool need_seek;
+        bool since_seeked;
+        bool ellipsized;
+        bool previous_boot_id_valid;
+        sd_id128_t previous_boot_id;
+        sd_id128_t previous_boot_id_output;
+        dual_timestamp previous_ts_output;
+} Context;
+
+static int show(Context *c) {
+        sd_journal *j;
+        int r, n_shown = 0;
+
+        assert(c);
+
+        j = ASSERT_PTR(c->journal);
+
+        while (arg_lines < 0 || n_shown < arg_lines || arg_follow) {
+                int flags;
+                size_t highlight[2] = {};
+
+                if (c->need_seek) {
+                        if (!arg_reverse)
+                                r = sd_journal_next(j);
+                        else
+                                r = sd_journal_previous(j);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to iterate through journal: %m");
+                        if (r == 0)
+                                break;
+                }
+
+                if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) {
+                        /* If --lines= is set, we usually rely on the n_shown to tell us
+                         * when to stop. However, if --since= is set too, we may end up
+                         * having less than --lines= to output. In this case let's also
+                         * check if the entry is in range. */
+
+                        usec_t usec;
+
+                        r = sd_journal_get_realtime_usec(j, &usec);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to determine timestamp: %m");
+                        if (usec > arg_until)
+                                break;
+                }
+
+                if (arg_since_set && (arg_reverse || !c->since_seeked)) {
+                        usec_t usec;
+
+                        r = sd_journal_get_realtime_usec(j, &usec);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to determine timestamp: %m");
+
+                        if (usec < arg_since) {
+                                if (arg_reverse)
+                                        break; /* Reached the earliest entry */
+
+                                /* arg_lines >= 0 (!since_seeked):
+                                 * We jumped arg_lines back and it seems to be too much */
+                                r = sd_journal_seek_realtime_usec(j, arg_since);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to seek to date: %m");
+                                c->since_seeked = true;
+
+                                c->need_seek = true;
+                                continue;
+                        }
+                        c->since_seeked = true; /* We're surely within the range of --since now */
+                }
+
+                if (!arg_merge && !arg_quiet) {
+                        sd_id128_t boot_id;
+
+                        r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
+                        if (r >= 0) {
+                                if (c->previous_boot_id_valid &&
+                                    !sd_id128_equal(boot_id, c->previous_boot_id))
+                                        printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n",
+                                               ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal());
+
+                                c->previous_boot_id = boot_id;
+                                c->previous_boot_id_valid = true;
+                        }
+                }
+
+                if (arg_compiled_pattern) {
+                        const void *message;
+                        size_t len;
+
+                        r = sd_journal_get_data(j, "MESSAGE", &message, &len);
+                        if (r < 0) {
+                                if (r == -ENOENT) {
+                                        c->need_seek = true;
+                                        continue;
+                                }
+
+                                return log_error_errno(r, "Failed to get MESSAGE field: %m");
+                        }
+
+                        assert_se(message = startswith(message, "MESSAGE="));
+
+                        r = pattern_matches_and_log(arg_compiled_pattern, message,
+                                                    len - strlen("MESSAGE="), highlight);
+                        if (r < 0)
+                                return r;
+                        if (r == 0) {
+                                c->need_seek = true;
+                                continue;
+                        }
+                }
+
+                flags =
+                        arg_all * OUTPUT_SHOW_ALL |
+                        arg_full * OUTPUT_FULL_WIDTH |
+                        colors_enabled() * OUTPUT_COLOR |
+                        arg_catalog * OUTPUT_CATALOG |
+                        arg_utc * OUTPUT_UTC |
+                        arg_no_hostname * OUTPUT_NO_HOSTNAME;
+
+                r = show_journal_entry(stdout, j, arg_output, 0, flags,
+                                       arg_output_fields, highlight, &c->ellipsized,
+                                       &c->previous_ts_output, &c->previous_boot_id_output);
+                c->need_seek = true;
+                if (r == -EADDRNOTAVAIL)
+                        break;
+                if (r < 0)
+                        return r;
+
+                n_shown++;
+
+                /* If journalctl take a long time to process messages, and during that time journal file
+                 * rotation occurs, a journalctl client will keep those rotated files open until it calls
+                 * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
+                 * in the "following" case.  By periodically calling sd_journal_process() during the processing
+                 * loop we shrink the window of time a client instance has open file descriptors for rotated
+                 * (deleted) journal files. */
+                if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
+                        r = sd_journal_process(j);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to process inotify events: %m");
+                }
+        }
+
+        return n_shown;
+}
+
 static int run(int argc, char *argv[]) {
+        bool need_seek = false, since_seeked = false, use_cursor = false, after_cursor = false;
         _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
         _cleanup_(umount_and_freep) char *mounted_dir = NULL;
-        bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false, since_seeked = false;
-        bool use_cursor = false, after_cursor = false;
         _cleanup_(sd_journal_closep) sd_journal *j = NULL;
-        sd_id128_t previous_boot_id = SD_ID128_NULL, previous_boot_id_output = SD_ID128_NULL;
-        dual_timestamp previous_ts_output = DUAL_TIMESTAMP_NULL;
         _cleanup_close_ int machine_fd = -EBADF;
-        int n_shown = 0, r, poll_fd = -EBADF;
+        int n_shown, r, poll_fd = -EBADF;
 
         setlocale(LC_ALL, "");
         log_setup();
@@ -2574,148 +2720,41 @@ static int run(int argc, char *argv[]) {
                 }
         }
 
-        for (;;) {
-                while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
-                        int flags;
-                        size_t highlight[2] = {};
-
-                        if (need_seek) {
-                                if (!arg_reverse)
-                                        r = sd_journal_next(j);
-                                else
-                                        r = sd_journal_previous(j);
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to iterate through journal: %m");
-                                if (r == 0)
-                                        break;
-                        }
-
-                        if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set)) {
-                                /* If --lines= is set, we usually rely on the n_shown to tell us
-                                 * when to stop. However, if --since= is set too, we may end up
-                                 * having less than --lines= to output. In this case let's also
-                                 * check if the entry is in range. */
-
-                                usec_t usec;
-
-                                r = sd_journal_get_realtime_usec(j, &usec);
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to determine timestamp: %m");
-                                if (usec > arg_until)
-                                        break;
-                        }
-
-                        if (arg_since_set && (arg_reverse || !since_seeked)) {
-                                usec_t usec;
-
-                                r = sd_journal_get_realtime_usec(j, &usec);
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to determine timestamp: %m");
-
-                                if (usec < arg_since) {
-                                        if (arg_reverse)
-                                                break; /* Reached the earliest entry */
-
-                                        /* arg_lines >= 0 (!since_seeked):
-                                         * We jumped arg_lines back and it seems to be too much */
-                                        r = sd_journal_seek_realtime_usec(j, arg_since);
-                                        if (r < 0)
-                                                return log_error_errno(r, "Failed to seek to date: %m");
-                                        since_seeked = true;
-
-                                        need_seek = true;
-                                        continue;
-                                }
-                                since_seeked = true; /* We're surely within the range of --since now */
-                        }
-
-                        if (!arg_merge && !arg_quiet) {
-                                sd_id128_t boot_id;
-
-                                r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
-                                if (r >= 0) {
-                                        if (previous_boot_id_valid &&
-                                            !sd_id128_equal(boot_id, previous_boot_id))
-                                                printf("%s-- Boot "SD_ID128_FORMAT_STR" --%s\n",
-                                                       ansi_highlight(), SD_ID128_FORMAT_VAL(boot_id), ansi_normal());
-
-                                        previous_boot_id = boot_id;
-                                        previous_boot_id_valid = true;
-                                }
-                        }
-
-                        if (arg_compiled_pattern) {
-                                const void *message;
-                                size_t len;
-
-                                r = sd_journal_get_data(j, "MESSAGE", &message, &len);
-                                if (r < 0) {
-                                        if (r == -ENOENT) {
-                                                need_seek = true;
-                                                continue;
-                                        }
-
-                                        return log_error_errno(r, "Failed to get MESSAGE field: %m");
-                                }
+        Context c = {
+                .journal = j,
+                .need_seek = need_seek,
+                .since_seeked = since_seeked,
+        };
 
-                                assert_se(message = startswith(message, "MESSAGE="));
+        if (arg_follow) {
+                if (arg_lines != 0 || arg_since_set) {
+                        r = show(&c);
+                        if (r < 0)
+                                return r;
 
-                                r = pattern_matches_and_log(arg_compiled_pattern, message,
-                                                            len - strlen("MESSAGE="), highlight);
-                                if (r < 0)
-                                        return r;
-                                if (r == 0) {
-                                        need_seek = true;
-                                        continue;
-                                }
-                        }
+                        fflush(stdout);
+                }
 
-                        flags =
-                                arg_all * OUTPUT_SHOW_ALL |
-                                arg_full * OUTPUT_FULL_WIDTH |
-                                colors_enabled() * OUTPUT_COLOR |
-                                arg_catalog * OUTPUT_CATALOG |
-                                arg_utc * OUTPUT_UTC |
-                                arg_no_hostname * OUTPUT_NO_HOSTNAME;
-
-                        r = show_journal_entry(stdout, j, arg_output, 0, flags,
-                                               arg_output_fields, highlight, &ellipsized,
-                                               &previous_ts_output, &previous_boot_id_output);
-                        need_seek = true;
-                        if (r == -EADDRNOTAVAIL)
-                                break;
+                for (;;) {
+                        r = wait_for_change(j, poll_fd);
                         if (r < 0)
                                 return r;
 
-                        n_shown++;
-
-                        /* If journalctl take a long time to process messages, and during that time journal file
-                         * rotation occurs, a journalctl client will keep those rotated files open until it calls
-                         * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
-                         * in the "following" case.  By periodically calling sd_journal_process() during the processing
-                         * loop we shrink the window of time a client instance has open file descriptors for rotated
-                         * (deleted) journal files. */
-                        if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
-                                r = sd_journal_process(j);
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to process inotify events: %m");
-                        }
-                }
+                        r = show(&c);
+                        if (r < 0)
+                                return r;
 
-                if (!arg_follow) {
-                        if (n_shown == 0 && !arg_quiet)
-                                printf("-- No entries --\n");
-                        break;
+                        fflush(stdout);
                 }
+        }
 
-                fflush(stdout);
-
-                r = wait_for_change(j, poll_fd);
-                if (r < 0)
-                        return r;
+        r = show(&c);
+        if (r < 0)
+                return r;
+        n_shown = r;
 
-                first_line = false;
-        }
+        if (n_shown == 0 && !arg_quiet)
+                printf("-- No entries --\n");
 
         r = update_cursor(j);
         if (r < 0)