1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-08 08:58:27 +03:00

journalctl: show coredumps again when --unit= is specified

This is a revised version of cbd5f5d7d6d652d52a18170123f5d08baf7e9862,
which is reverted by 560412148fa62d779ea522d43960dd3acd44b261.

The filter condition for _UID= field was added by
fdcd37df3b97abc381c7b7a29b81cc013c7a3230. However, after
888e378da2dbf4520e68a9d7e59712a3cd5a830f, coredumps for system services are
stored by systemd-coredump user. Hence, _UID=0 does not match anything anymore.

When we are reading the system journal, let's set _UID=<systemd-coredump>,
then we can show coredumps for system services again. When we are reading
an external journal, then the uid of systemd-coredump may be different
from the one on the current system, so let's drop the filter condition
for _UID= in that case.
This commit is contained in:
Yu Watanabe 2024-12-07 04:08:59 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent 9cbd4f9b61
commit fbee22c237
3 changed files with 65 additions and 17 deletions

View File

@ -135,6 +135,7 @@ static int get_possible_units(
static int add_units(sd_journal *j) {
_cleanup_strv_free_ char **patterns = NULL;
bool added = false;
MatchUnitFlag flags = MATCH_UNIT_ALL;
int r;
assert(j);
@ -142,6 +143,12 @@ static int add_units(sd_journal *j) {
if (strv_isempty(arg_system_units) && strv_isempty(arg_user_units))
return 0;
/* When --directory/-D, --root, --file/-i, or --machine/-M is specified, the opened journal file may
* be external, and the uid of the systemd-coredump user that generates the coredump entries may be
* different from the one in the current host. Let's relax the filter condition in such cases. */
if (arg_directory || arg_root || arg_file_stdin || arg_file || arg_machine)
flags &= ~MATCH_UNIT_COREDUMP_UID;
STRV_FOREACH(i, arg_system_units) {
_cleanup_free_ char *u = NULL;
@ -154,7 +161,7 @@ static int add_units(sd_journal *j) {
if (r < 0)
return r;
} else {
r = add_matches_for_unit(j, u);
r = add_matches_for_unit_full(j, flags, u);
if (r < 0)
return r;
r = sd_journal_add_disjunction(j);
@ -173,7 +180,7 @@ static int add_units(sd_journal *j) {
return r;
SET_FOREACH(u, units) {
r = add_matches_for_unit(j, u);
r = add_matches_for_unit_full(j, flags, u);
if (r < 0)
return r;
r = sd_journal_add_disjunction(j);
@ -197,7 +204,7 @@ static int add_units(sd_journal *j) {
if (r < 0)
return r;
} else {
r = add_matches_for_user_unit(j, u);
r = add_matches_for_user_unit_full(j, flags, u);
if (r < 0)
return r;
r = sd_journal_add_disjunction(j);
@ -216,7 +223,7 @@ static int add_units(sd_journal *j) {
return r;
SET_FOREACH(u, units) {
r = add_matches_for_user_unit(j, u);
r = add_matches_for_user_unit_full(j, flags, u);
if (r < 0)
return r;
r = sd_journal_add_disjunction(j);

View File

@ -37,6 +37,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "time-util.h"
#include "user-util.h"
#include "utf8.h"
#include "web-util.h"
@ -1627,7 +1628,39 @@ int add_matches_for_invocation_id(sd_journal *j, sd_id128_t id) {
return r;
}
int add_matches_for_unit_full(sd_journal *j, bool all, const char *unit) {
static int add_matches_for_coredump_uid(sd_journal *j, MatchUnitFlag flags, const char *unit) {
static uid_t cached_uid = 0;
int r;
assert(j);
assert(unit);
if (!FLAGS_SET(flags, MATCH_UNIT_COREDUMP_UID))
return 0;
if (cached_uid == 0) {
const char *user = "systemd-coredump";
r = get_user_creds(&user, &cached_uid, NULL, NULL, NULL, 0);
if (r < 0) {
log_debug_errno(r, "Failed to resolve systemd-coredump user, ignoring: %m");
cached_uid = UID_INVALID;
} else if (cached_uid == 0) /* Huh? Let's handle that gracefully. */
cached_uid = UID_INVALID;
}
if (!uid_is_valid(cached_uid))
return 0;
r = journal_add_matchf(j, "_UID="UID_FMT, cached_uid);
if (r < 0)
return r;
/* for systemd-coredump older than 888e378da2dbf4520e68a9d7e59712a3cd5a830f */
return sd_journal_add_match(j, "_UID=0", SIZE_MAX);
}
int add_matches_for_unit_full(sd_journal *j, MatchUnitFlag flags, const char *unit) {
int r;
assert(j);
@ -1648,16 +1681,16 @@ int add_matches_for_unit_full(sd_journal *j, bool all, const char *unit) {
(r = journal_add_match_pair(j, "OBJECT_SYSTEMD_UNIT", unit))
);
if (r == 0 && all)
if (r == 0 && FLAGS_SET(flags, MATCH_UNIT_COREDUMP))
(void) (
/* Look for coredumps of the service */
(r = sd_journal_add_disjunction(j)) ||
(r = sd_journal_add_match(j, "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR, SIZE_MAX)) ||
(r = sd_journal_add_match(j, "_UID=0", SIZE_MAX)) ||
(r = add_matches_for_coredump_uid(j, flags, unit)) ||
(r = journal_add_match_pair(j, "COREDUMP_UNIT", unit))
);
if (r == 0 && all && endswith(unit, ".slice"))
if (r == 0 && FLAGS_SET(flags, MATCH_UNIT_SLICE) && endswith(unit, ".slice"))
/* Show all messages belonging to a slice */
(void) (
(r = sd_journal_add_disjunction(j)) ||
@ -1667,7 +1700,7 @@ int add_matches_for_unit_full(sd_journal *j, bool all, const char *unit) {
return r;
}
int add_matches_for_user_unit_full(sd_journal *j, bool all, const char *unit) {
int add_matches_for_user_unit_full(sd_journal *j, MatchUnitFlag flags, const char *unit) {
uid_t uid = getuid();
int r;
@ -1691,7 +1724,7 @@ int add_matches_for_user_unit_full(sd_journal *j, bool all, const char *unit) {
(r = sd_journal_add_match(j, "_UID=0", SIZE_MAX))
);
if (r == 0 && all)
if (r == 0 && FLAGS_SET(flags, MATCH_UNIT_COREDUMP))
(void) (
/* Look for coredumps of the service */
(r = sd_journal_add_disjunction(j)) ||
@ -1700,7 +1733,7 @@ int add_matches_for_user_unit_full(sd_journal *j, bool all, const char *unit) {
(r = sd_journal_add_match(j, "_UID=0", SIZE_MAX))
);
if (r == 0 && all && endswith(unit, ".slice"))
if (r == 0 && FLAGS_SET(flags, MATCH_UNIT_SLICE) && endswith(unit, ".slice"))
/* Show all messages belonging to a slice */
(void) (
(r = sd_journal_add_disjunction(j)) ||
@ -1907,10 +1940,10 @@ static int set_matches_for_discover_id(
return add_matches_for_invocation_id(j, id);
if (type == LOG_SYSTEM_UNIT_INVOCATION_ID)
return add_matches_for_unit_full(j, /* all = */ false, unit);
return add_matches_for_unit_full(j, /* flags = */ 0, unit);
if (type == LOG_USER_UNIT_INVOCATION_ID)
return add_matches_for_user_unit_full(j, /* all = */ false, unit);
return add_matches_for_user_unit_full(j, /* flags = */ 0, unit);
return -EINVAL;
}

View File

@ -56,13 +56,21 @@ int add_match_this_boot(sd_journal *j, const char *machine);
int add_matches_for_invocation_id(sd_journal *j, sd_id128_t id);
int add_matches_for_unit_full(sd_journal *j, bool all, const char *unit);
typedef enum MatchUnitFlag {
MATCH_UNIT_SLICE = 1 << 0,
MATCH_UNIT_COREDUMP = 1 << 1,
MATCH_UNIT_COREDUMP_UID = 1 << 2,
MATCH_UNIT_ALL = MATCH_UNIT_SLICE | MATCH_UNIT_COREDUMP | MATCH_UNIT_COREDUMP_UID,
} MatchUnitFlag;
int add_matches_for_unit_full(sd_journal *j, MatchUnitFlag flags, const char *unit);
static inline int add_matches_for_unit(sd_journal *j, const char *unit) {
return add_matches_for_unit_full(j, true, unit);
return add_matches_for_unit_full(j, MATCH_UNIT_ALL, unit);
}
int add_matches_for_user_unit_full(sd_journal *j, bool all, const char *unit);
int add_matches_for_user_unit_full(sd_journal *j, MatchUnitFlag flags, const char *unit);
static inline int add_matches_for_user_unit(sd_journal *j, const char *unit) {
return add_matches_for_user_unit_full(j, true, unit);
return add_matches_for_user_unit_full(j, MATCH_UNIT_ALL, unit);
}
int show_journal_by_unit(