When there is no matching entry stored in journal, then initial call of
`sd_journal_previous()` following `sd_journal_seek_tail()` returns
zero, and does not move the read pointer.
In the main loop, on every journal event, we call `sd_journal_next()`,
even though the current location is tail, and it takes no effect.
In such a case, we need to call `sd_journal_previous()` instead of
`sd_journal_next()`.
Previously, get_boots() used for three ways; finding boot entry by
boot ID, finding boot entry by offset, listing up all boot IDs.
Let's split it into three for each usecase.
No functional change, just refactoring.
When closing the FILE handle attached to a memstream, it may attempt to
do a realloc() that may fail during OOM situations, in which case we are
left with the buffer pointer pointing to NULL and buffer size > 0. For
example:
```
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
void *realloc(void *ptr, size_t size) {
return NULL;
}
int main(int argc, char *argv[])
{
FILE *f;
char *buf;
size_t sz = 0;
f = open_memstream(&buf, &sz);
if (!f)
return -ENOMEM;
fputs("Hello", f);
fflush(f);
printf("buf: 0x%lx, sz: %lu, errno: %d\n",
(unsigned long) buf, sz, errno);
fclose(f);
printf("buf: 0x%lx, sz: %lu, errno: %d\n",
(unsigned long) buf, sz, errno);
return 0;
}
```
```
$ gcc -o main main.c
$ ./main
buf: 0x74d4a0, sz: 5, errno: 0
buf: 0x0, sz: 5, errno: 0
```
This might do unexpected things if the underlying code expects a valid
pointer to the memstream buffer after closing the handle.
Found by Nallocfuzz.
Recent gcc versions have started to trigger false positive
maybe-uninitialized warnings. Let's make sure we initialize
variables annotated with _cleanup_ to avoid these.
This reverts commit 1db6dbb1dc.
The original patch was reverted because of issue #25369. The issue was created
because it wrongly assumed that sd_journal_seek_tail() seeks to 'current' tail.
But in fact, only when a subsequent sd_journal_previous() is called that it's
pointing to the tail at that time. The concept of 'tail' in sd_journal_seek_tail()
only has a logical meaning, and a sd_journal_previous is needed. In fact, if we
look at the codes in journalctl, we can see sd_journal_seek_tail() is followed by
sd_journal_previous(). By contrary, a sd_journal_next() after a 'logical' tail does
not make much sense. So the original patch is correct, and projects that are
using 'sd_journal_next()' right after 'sd_journal_seek_tail()' should do fixes
as in https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2823#note_1637715.
This illustrates bug in sd_journal_next() or friends;
calling sd_jounral_next() followed by sd_journal_seek_tail() makes the
location saved in sd-journal something corrupted, and subsequent
sd_journal_previous() or friends may fail or provides unexpected result.
Set --boot with --follow only if it's not already set and if --merge is
not used, since it's not compatible with --boot.
Follow-up to 2dd9285bac.
Resolves: #24565
Let's use the same common directory as the unit logic uses.
This means we have less to clean up, and opens the door to eventually
allow unprivileged operation of the
mount_image_privately_interactively() logic.
Otherwise, if getopt() and friends are used before parse_argv(), then
the GNU extensions may be ignored.
This should not change any behavior at least now, as we usually use
getopt_long() only once per invocation. But in the next commit,
getopt_long() will be used for other arrays, hence this change will
become necessary.
The bit flips during journal verification cause various types of journal
corruptions, so it's useful to go through it even without a sealing key
to see how we handle corrupted stuff.
Also, provide a sealing key if running in "CI mode" (i.e. arguments),
to check the FSS-related codepaths in CIs as well.
Follow-up for #25147 (db4691961c)
--follow sets arg_lines to 10, which breaks
--grep as the latter implies --reverse.
So let's not set --reverse if --follow is used.
Chasing symlinks is a core function that's used in a lot of places
so it deservers a less verbose names so let's rename it to chase()
and chaseat().
We also slightly change the pattern used for the chaseat() helpers
so we get chase_and_openat() and similar.
Let's color output when we're forwarding to the console. To make this
work, we inherit TERM from pid 1 and use it to decide whether we should
output colors or not.
All daemons use a similar scheme to read their main config files and theirs
drop-ins. The main config files are always stored in /etc/systemd directory and
it's easy enough to construct the name of the drop-in directories based on the
name of the main config file.
Hence the new helper does that internally, which allows to reduce and simplify
the args passed previously to config_parse_many_nulstr().
Besides the overall code simplification it results:
16 files changed, 87 insertions(+), 159 deletions(-)
it allows to identify clearly the locations in the code where configuration
files are parsed.
This is a follow-up for #26669 (81fb5375b3).
After the mentioned commit, we stopped checking if the
entry is within the range of --until if --lines is used.
However, when --since, --until and --lines=N are used
altogether, and the number of lines between --since
and --until is smaller than N, we would seek to --since
later (f582695107).
This breaks the assumption that if --lines is set,
the boundary is never exceeded because the counter of
outputs gets us covered.
Before this commit, if --since is used with --lines=N,
we seek to the place of --since and search afterwards
there, resulting in outputing the first N lines.
After this commit, we only do the above if --since is used without
--reverse and --lines. Otherwise we seek to the tail first and check
if the entry is within the range of --since later.
Before this commit, when --lines is specified, we jump to the tail and
search afterwards from there, thus breaking --until if used together.
After this commit:
If both --until and any of --reverse and --lines is specified, things get
a little tricky. We seek to the place of --until first. If only --reverse or
--reverse and --lines is specified, we search backwards and let the output
counter handle --lines for us. If only --lines is used, we just jump backwards
arg_lines and search afterwards from there.
Let's log exactly at one place about failed writing of log lines to
journal file: in shall_try_append_again().
Then, if we decide to suppress a retry-after-vacuum because we already
vacuumed anyway then say this explicitly as "supressed rotation",
because that's what we do here.
This removes triplicate logging about the same error, and logs exactly
once, plus optional one "suppressed rotation" message. (plus more debug
output). The triplicate logging was bad in particular because it had no
understanding of the actual error codes and just showed generic UNIX
error strings ("Not a XENIX named type file"). By relying on
shall_try_append_again() to do all logging we now get very clean error
strings for all conditions.
Fixes: #26496
We always want to pass the error code along with the log call, so that
it can add it to structured logging, even if the format string does not
contain %m.