bash implements process substitution using /dev/fd/N (this is documented
in man bash). We'd like kernel-install to work in chrooted RPM
scriptlets without /dev.
We can use here-strings instead. bash uses temporary files to implement
those.
In Fedora dnf-makecache.timer specifies OnBootSec=10min, but it fired
during boot in systemd-nspawn, because the clock ticks since the host's
boot.
Fix it by treating OnBootSec the same as OnStartupSec when running in
a container.
Use the "return log_error_errno(...)" idiom to have fewer curly braces.
The last hunk also fixes the return value of setup_journal(), but the
fix has no practical effect.
The intent of the assignments around the check for libcap was obviously
to avoid polluting LIBS. To work properly, LIBS must be restored from
the save_LIBS variable.
The practical effect is small though, because pretty much everything
links with libbasic, which links with CAP_LIBS.
We have two AC_CHECK_LIB checks for libdw. The first one has an empty
action-if-found, so it defaults to adding "-ldw" to LIBS. LIBS are
applied to everything we build. But only systemd-coredump needs libdw.
It already links to ELFUTILS_LIBS correctly in Makefile.am.
Drop the first AC_CHECK_LIB check. The second check is sufficient.
Q: Don't we already use "-Wl,--as-needed" to eliminate overlinking?
A: We do, but it is effective only for executables, not for shared
libraries. This is due to a libtool bug:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=347650
Instead of freezing in PID1 and letting the forked child freeze or
reboot when exec("/bin/sh") fails, just wait for the child's
exit and then do the freeze_or_reboot in PID1 as usual.
This means that when both crash_shell and crash_reboot are enabled, the
system will reboot after the shell exits.
The purpose of testing with the crippled hash function is to cover
the otherwise very unlikely codepath in bucket_calculate_dib() where
it has to fall back to recomputing the hash value.
This unlikely path was not covered by test-hashmap anymore after
57217c8f "test: hashmap - cripple the hash function by truncating the
input rather than the output".
Restore the test coverage by increasing the number of entries in the test.
The number was determined empirically by checking with lcov.
Use %m where previously %s was used together with strerrno().
Fixes: e53fc357a9 "tree-wide: remove a number of invocations of
strerror() and replace by %m"
Use %m where previously %s was used together with strerrno().
Fixes: e53fc357a9 "tree-wide: remove a number of invocations of
strerror() and replace by %m"
A few of the recent conversions to log_*_errno() were missing the errno
value arguments.
Fixes: e53fc357a9 "tree-wide: remove a number of invocations of
strerror() and replace by %m"
The size of the allocated array for received file descriptors was
incorrectly calculated. This did not matter when a single file
descriptor was received, but for more descriptors the allocation was
insufficient.
It's nicer if the assertion failure message from a bad use of xsprintf
actually mentions xsprintf instead of the expression the macro is
implemented as.
The assert_message_se macro was added in the previous commit as an
internal helper, but it can also be used for customizing assertion
failure messages like in this case.
Example:
char buf[10];
xsprintf(buf, "This is a %s message.\n", "long");
Before:
Assertion '(size_t) snprintf(buf, ELEMENTSOF(buf), "This is a %s
message.\n", "long") < ELEMENTSOF(buf)' failed at foo.c:6, function
main(). Aborting.
After:
Assertion 'xsprintf: buf[] must be big enough' failed at foo.c:6,
function main(). Aborting.
Making the array static allows gcc -O2 to generate smaller code:
"size systemd" before:
text data bss dec hex filename
1377286 128608 2632 1508526 1704ae systemd
After:
text data bss dec hex filename
1374326 128572 2664 1505562 16f91a systemd
(IN_SET still results in worse generated code than using
"x == FOO || x == BAR || ...". I don't think we'll be able to match
that with the C preprocessor.)
This change limits the use of IN_SET to sets with constant elements. All
present callers use constants. The compiler would report an "initializer
element is not constant" error otherwise.
Putting the set elements in an array variable and using ELEMENTSOF makes
it clearer what's going on.
Incidentally, it also makes gcc -O2 generate slightly smaller code:
"size systemd", before:
text data bss dec hex filename
1378318 128608 2632 1509558 1708b6 systemd
After:
text data bss dec hex filename
1377286 128608 2632 1508526 1704ae systemd
We do not print all non-OK job completion status messages to the console
in red, because not all of them are plain errors. We do however log the
same messages as LOG_ERR.
Differentiate the log levels by deducing them from the job result in a
way that more or less matches the color of the console message.
This is similar to "core: always try harder to get unit status
message format string", but for job completion status messages.
It makes generic status messages applicable for printing to the console.
And it rewrites the functions in a more table-based style.
unit_get_status_message_format() is used only with one of JOB_START,
JOB_STOP, JOB_RELOAD, all of which have fallback message strings
defined, so the function may never return NULL.
The starting/stopping messages are printed to the console only if the
corresponding format string is defined in the unit's vtable. To avoid
excessive messages on the console, the unit types whose start/stop
jobs are instantaneous had the format strings intentionally undefined.
When logging the same event to the journal, a fallback to generic
Starting/Stopping/Reloading messages is used.
The problem of excessive console messages with instantaneous jobs
is already resolved in a nicer way ("core: fix confusing logging of
instantaneous jobs"), so there's no longer a need to have two ways of
getting the format strings. Let's fold them into one function with
the fallback to generic message strings.
Return 1 from *_reload() methods to signify "we did something", just
like in *_start(). This causes "Reloading foo..." messages to be logged.
"Reloaded foo." messages are already logged.
For instantaneous jobs (e.g. starting of targets, sockets, slices, or
Type=simple services) the log shows the job completion
before starting:
systemd[1]: Created slice -.slice.
systemd[1]: Starting -.slice.
systemd[1]: Created slice System Slice.
systemd[1]: Starting System Slice.
systemd[1]: Listening on Journal Audit Socket.
systemd[1]: Starting Journal Audit Socket.
systemd[1]: Reached target Timers.
systemd[1]: Starting Timers.
...
The reason is that the job completes before the ->start() method returns
and only then does unit_start() print the "Starting ..." message.
The same thing happens when stopping units.
Rather than fixing the order of the messages, let's just not emit the
Starting/Stopping message at all when the job completes instantaneously.
The job completion message is sufficient in this case.
It is unused and rightly so. Users of the hashmap API should
not care about the idx values or any other Iterator internals.
_IDX_ITERATOR_FIRST in hashmap.h is an exception. It is needed
for ITERATOR_FIRST.
The comparison function we use for qsorting paths is overly indifferent.
Consider these 3 paths for sorting:
/foo
/bar
/foo/foo
qsort() may compare:
"/foo" with "/bar" => 0, indifference
"/bar" with "/foo/foo" => 0, indifference
and assume transitively that "/foo" and "/foo/foo" are also indifferent.
But this is wrong, we want "/foo" sorted before "/foo/foo".
The comparison function must be transitive.
Use path_compare(), which behaves properly.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1184016
Commit 668c965af "journal: skipping of exhausted journal files is bad if
direction changed" fixed a correctness issue, but it also significantly
limited the cases where the optimization that skips exhausted journal
files could apply.
As a result, some journalctl queries are much slower in v219 than in v218.
(e.g. queries where a "--since" cutoff should have quickly eliminated
older journal files from consideration, but didn't.)
If already in the initial iteration find_location_with_matches() finds
no entry, the journal file's location is not updated. This is fine,
except that:
- We must update at least f->last_direction. The optimization relies on
it. Let's separate that from journal_file_save_location() and update
it immediately after the direction checks.
- The optimization was conditional on "f->current_offset > 0", but it
would always be 0 in this scenario. This check is unnecessary for the
optimization.
Make sure we don't inspect sun_path of unnamed sockets.
Since we cannot know if two unnamed sockets' adresses refer to the same
socket, just return false.
When dbus.socket is updated like this:
-ListenStream=/var/run/dbus/system_bus_socket
+ListenStream=/run/dbus/system_bus_socket
... and daemon-reload is performed, bad things happen.
During deserialization systemd does not recognize that the two paths
refer to the same named socket and replaces the socket file with a new
one. As a result, applications hang when they try talking to dbus.
Fix this by finding a match not only when the path names are equal, but
also when they point to the same inode.
In socket_address_equal() it is necessary to move the address size
comparison into the abstract sockets branch. For path name sockets the
comparison must not be done and for other families it is redundant
(their sizes are constant and checked by socket_address_verify()).
FIFOs and special files can also have multiple pathnames, so compare the
inodes for them as well. Note that previously the pathname checks used
streq_ptr(), but the paths cannot be NULL.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1186018
The output of gnutls_certificate_verification_status_print() needs to be
freed.
Noticed this while staring at verify_cert_authorized() to see what could
possibly confuse gcc5 on armv7hl to segfault during compilation.
EOF is meaningless if the direction of iteration changes.
Move the EOF optimization under the direction check.
This fixes test-journal-interleaving for me.
Thanks to Filipe Brandenburger for telling me about the failure.
next_with_matches() is odd in that its "unit64_t *offset" parameter is
both input and output. In other it's purely for output.
The function is called from two places in next_beyond_location(). In
both of them "&cp" is used as the argument and in both cases cp is
guaranteed to equal f->current_offset.
Let's just have next_with_matches() ignore "*offset" on input and
operate with f->current_offset.
I did not investigate why it is, but it makes my usual benchmark run
reproducibly faster:
$ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null
real 0m4.032s
user 0m3.896s
sys 0m0.135s
(Compare to preceding commit, where real was 4.4s.)
I accidentally broke the detection of duplicate entries in 7943f42275
"journal: optimize iteration by returning previously found candidate
entry".
When we have a known location of a candidate entry, we must not return
from next_beyond_location() immediately. We must go through the
duplicates detection to make sure the candidate differs from the
already iterated entry.
This fix slows down iteration a bit, but it's still faster than it
was before the rework.
$ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null
real 0m4.448s
user 0m4.298s
sys 0m0.149s
(Compare with results from commit 7943f42275, where real was 5.3s before
the rework.)
In next_beyond_location() when the JournalFile's location type is
LOCATION_SEEK, it means there's nothing to do, because we already have
the location of the candidate entry. Do an early return. Note that now
next_beyond_location() does not anymore guarantee on return that the
entry is mapped, but previous patches made sure the caller does not
care.
This optimization is at least as good as "journal: optimize iteration:
skip files that cannot improve current candidate entry" was.
Timing results on my workstation, using:
$ time ./journalctl -q --since=2014-06-01 --until=2014-07-01 > /dev/null
Before "Revert "journal: optimize iteration: skip files that cannot
improve current candidate entry":
real 0m5.349s
user 0m5.166s
sys 0m0.181s
Now:
real 0m3.901s
user 0m3.724s
sys 0m0.176s
If from a previous iteration we know we are at the end of a journal
file, don't bother looking into the file again. This is complicated by
the fact that the EOF does not have to be permanent (think of
"journalctl -f"). So we also check if the number of entries in the
journal file changed.
This optimization has a similar effect as "journal: optimize iteration:
skip whole files behind current location" had.
set_location() is called from real_journal_next() when a winning entry
has been picked from among the candidates in journal files.
The location type is always set to LOCATION_DISCRETE. No need to pass
it as a parameter.
The per-JournalFile location information is already updated at this
point. No need for having the direction and offset here.
In next_beyond_location() when we find a candidate entry in a journal
file, save its location information in struct JournalFile.
The purpose of remembering the locations of candidate entries is to be
able to save work in the next iteration. This patch does only the
remembering part.
LOCATION_SEEK means the location identifies a candidate entry.
When a winner is picked from among candidates, it becomes
LOCATION_DISCRETE.
LOCATION_TAIL here signifies we've iterated the file to the end (or the
beginning in the case of reversed direction).
try_context() is such a hot path that the hashmap lookup is expensive.
The number of contexts is small - it is the number of object types.
Using a hashmap is overkill. A plain array will do.
Before:
$ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null
real 0m9.445s
user 0m9.228s
sys 0m0.213s
After:
$ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null
real 0m5.438s
user 0m5.266s
sys 0m0.170s
Note that numbers 0 and -1 are both replaced with OBJECT_UNUSED,
because they are treated the same everywhere (e.g. type_to_context()
translates them both to 0).
If type==0 and a non-NULL object were given as arguments to
journal_file_hmac_put_object(), its object type check would fail and it
would return -EBADMSG.
All existing callers use either a positive type or -1. Still, for
behavior consistency with journal_file_move_to_object() let's allow
type 0 to pass.
The only user is sd_journal_enumerate_unique() and, as explained in
the previous commit (fed67c38e3 "journal: map objects to context set by
caller, not by actual object type"), the use of them there is now
superfluous. Let's remove them.
This reverts major parts of commits:
ae97089d49 journal: fix access to munmapped memory in
sd_journal_enumerate_unique
06cc69d44c sd-journal: fix sd_journal_enumerate_unique skipping values
Tested with an "--enable-debug" build and "journalctl --list-boots".
It gives the expected number of results. Additionally, if I then revert
the previous commit ("journal: map objects to context set by caller, not
to actual object type"), it crashes with SIGSEGV, as expected.
When the caller of journal_file_move_to_object() specifies type==0,
the object header is at first mapped in context 0. Then after the header
is checked, the whole object is mapped in a context determined by
the actual object type (which is not even range-checked using
type_to_context()). This looks wrong. It should map in the
caller-specified context.
An old comment in sd_journal_enumerate_unique() supports this view:
/* We do not use the type context here, but 0 instead,
* so that we can look at this data object at the same
* time as one on another file */
Clearly the expectation was that the data object will remain mapped
in context 0 without being pushed away by mapping other objects in
context OBJECT_DATA.
I suspect that this was the real bug that got fixed by ae97089d49
"journal: fix access to munmapped memory in sd_journal_enumerate_unique".
In other words, journal_file_object_keep/release are superfluous after
applying this patch.
This is useful for exposing unsafe access to mmapped objects after
the context that they were mapped in was already moved.
For example:
journal_file_move_to_object(f1, OBJECT_DATA, p1, &o1);
journal_file_move_to_object(f2, OBJECT_DATA, p2, &o2);
t = o1->object.type; /* this usually works, but is unsafe */
There will be more debugging options later.
--enable-debug will enable them all.
--enable-debug=hashmap will enable only hashmap debugging.
Also rename the C #define to ENABLE_DEBUG_* pattern.