]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journalctl: track more closely whether we're within --until= range
authorMike Yuan <me@yhndnzj.com>
Sat, 12 Jul 2025 16:35:14 +0000 (18:35 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 4 Aug 2025 18:50:36 +0000 (19:50 +0100)
Follow-up for 81fb5375b3b3bfc22d023d7908ad9eee4b3c1ffb

The offending commit fails to account for the case where
we have fewer lines before --until= than what's specified
in --lines=. Aside from that, if --grep= + --lines=+N are used,
we might also seek forward in the middle of the loop,
breaking the --until= boundary.

Let's turn the logic around then. Context.until_safe will
be set iff we're certain that there's enough to output,
and it gets reset whenever we seek forward.

Fixes #38121
Replaces #38122

(cherry picked from commit f11e882721f81c3379eb0902dad2ffb9d9a72175)

src/journal/journalctl-show.c

index 9f07facad426c4e15f994b0b950acaa2c1ac3560..323ce20c6db2aaecfd6d450a7f4abff840223a8f 100644 (file)
@@ -20,6 +20,7 @@ typedef struct Context {
         bool has_cursor;
         bool need_seek;
         bool since_seeked;
+        bool until_safe;
         bool ellipsized;
         bool previous_boot_id_valid;
         sd_id128_t previous_boot_id;
@@ -104,10 +105,15 @@ static int seek_journal(Context *c) {
                                 return log_error_errno(r, "Failed to seek to tail: %m");
                 }
 
-                if (arg_reverse)
+                if (arg_reverse) {
                         r = sd_journal_previous(j);
-                else /* arg_lines_needs_seek_end */
+                        c->until_safe = true; /* can't possibly go beyond --until= if --reverse */
+
+                } else { /* arg_lines_needs_seek_end() */
                         r = sd_journal_previous_skip(j, arg_lines);
+                        c->until_safe = r >= arg_lines; /* We have enough lines to output before --until= is hit.
+                                                           No need to check timestamp of each journal entry */
+                }
 
         } else if (arg_since_set) {
                 /* This is placed after arg_reverse and arg_lines. If --since is used without
@@ -161,11 +167,10 @@ static int show(Context *c) {
                                 break;
                 }
 
-                if (arg_until_set && !arg_reverse && (arg_lines < 0 || arg_since_set || c->has_cursor)) {
+                if (arg_until_set && !c->until_safe) {
                         /* If --lines= is set, we usually rely on the n_shown to tell us when to stop.
-                         * However, if --since= or one of the cursor argument 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. */
+                         * However, in the case where we may have less than --lines= to output let's check
+                         * whether the individual entries are in range. */
 
                         usec_t usec;
 
@@ -194,6 +199,11 @@ static int show(Context *c) {
                                         return log_error_errno(r, "Failed to seek to date: %m");
                                 c->since_seeked = true;
 
+                                /* We just jumped forward, meaning there might suddenly be less than
+                                 * --lines= to show within the --until= range, hence keep a close eye on
+                                 * timestamps from now on. */
+                                c->until_safe = false;
+
                                 c->need_seek = true;
                                 continue;
                         }
@@ -222,6 +232,12 @@ static int show(Context *c) {
                         r = sd_journal_get_data(j, "MESSAGE", &message, &len);
                         if (r < 0) {
                                 if (r == -ENOENT) {
+                                        /* We will skip some entries forward, meaning there might suddenly
+                                         * be less than --lines= to show within the --until= range, hence
+                                         * keep a close eye on timestamps from now on. */
+                                        if (!arg_reverse)
+                                                c->until_safe = false;
+
                                         c->need_seek = true;
                                         continue;
                                 }
@@ -236,6 +252,12 @@ static int show(Context *c) {
                         if (r < 0)
                                 return r;
                         if (r == 0) {
+                                /* We will skip some entries forward, meaning there might suddenly
+                                 * be less than --lines= to show within the --until= range, hence
+                                 * keep a close eye on timestamps from now on. */
+                                if (!arg_reverse)
+                                        c->until_safe = false;
+
                                 c->need_seek = true;
                                 continue;
                         }