|
|
9a102d |
From e256e03710abfd96e74d0b278c2b7186e3c8888b Mon Sep 17 00:00:00 2001
|
|
|
9a102d |
From: David Tardon <dtardon@redhat.com>
|
|
|
9a102d |
Date: Thu, 12 Jan 2023 15:47:09 +0100
|
|
|
9a102d |
Subject: [PATCH] coredump: put context array into a struct
|
|
|
9a102d |
|
|
|
9a102d |
[dtardon: This is based on commit f46c706bdd4316ae8ed6baf7a8c382b90b84f648 ,
|
|
|
9a102d |
but does just the minimal change to introduce the Context struct that is
|
|
|
9a102d |
needed by the following commit.]
|
|
|
9a102d |
|
|
|
9a102d |
Related: #2155519
|
|
|
9a102d |
---
|
|
|
9a102d |
src/coredump/coredump.c | 208 +++++++++++++++++++++-------------------
|
|
|
9a102d |
1 file changed, 108 insertions(+), 100 deletions(-)
|
|
|
9a102d |
|
|
|
9a102d |
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
|
|
|
9a102d |
index fb3a6ecfe9..ebc56d8342 100644
|
|
|
9a102d |
--- a/src/coredump/coredump.c
|
|
|
9a102d |
+++ b/src/coredump/coredump.c
|
|
|
9a102d |
@@ -91,6 +91,10 @@ enum {
|
|
|
9a102d |
_CONTEXT_MAX
|
|
|
9a102d |
};
|
|
|
9a102d |
|
|
|
9a102d |
+typedef struct Context {
|
|
|
9a102d |
+ const char *meta[_CONTEXT_MAX];
|
|
|
9a102d |
+} Context;
|
|
|
9a102d |
+
|
|
|
9a102d |
typedef enum CoredumpStorage {
|
|
|
9a102d |
COREDUMP_STORAGE_NONE,
|
|
|
9a102d |
COREDUMP_STORAGE_EXTERNAL,
|
|
|
9a102d |
@@ -184,7 +188,7 @@ static int fix_acl(int fd, uid_t uid) {
|
|
|
9a102d |
return 0;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) {
|
|
|
9a102d |
+static int fix_xattr(int fd, const Context *context) {
|
|
|
9a102d |
|
|
|
9a102d |
static const char * const xattrs[_CONTEXT_MAX] = {
|
|
|
9a102d |
[CONTEXT_PID] = "user.coredump.pid",
|
|
|
9a102d |
@@ -209,10 +213,10 @@ static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) {
|
|
|
9a102d |
for (i = 0; i < _CONTEXT_MAX; i++) {
|
|
|
9a102d |
int k;
|
|
|
9a102d |
|
|
|
9a102d |
- if (isempty(context[i]) || !xattrs[i])
|
|
|
9a102d |
+ if (isempty(context->meta[i]) || !xattrs[i])
|
|
|
9a102d |
continue;
|
|
|
9a102d |
|
|
|
9a102d |
- k = fsetxattr(fd, xattrs[i], context[i], strlen(context[i]), XATTR_CREATE);
|
|
|
9a102d |
+ k = fsetxattr(fd, xattrs[i], context->meta[i], strlen(context->meta[i]), XATTR_CREATE);
|
|
|
9a102d |
if (k < 0 && r == 0)
|
|
|
9a102d |
r = -errno;
|
|
|
9a102d |
}
|
|
|
9a102d |
@@ -230,7 +234,7 @@ static int fix_permissions(
|
|
|
9a102d |
int fd,
|
|
|
9a102d |
const char *filename,
|
|
|
9a102d |
const char *target,
|
|
|
9a102d |
- const char *context[_CONTEXT_MAX],
|
|
|
9a102d |
+ const Context *context,
|
|
|
9a102d |
uid_t uid) {
|
|
|
9a102d |
|
|
|
9a102d |
int r;
|
|
|
9a102d |
@@ -273,18 +277,18 @@ static int maybe_remove_external_coredump(const char *filename, uint64_t size) {
|
|
|
9a102d |
return 1;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static int make_filename(const char *context[_CONTEXT_MAX], char **ret) {
|
|
|
9a102d |
+static int make_filename(const Context *context, char **ret) {
|
|
|
9a102d |
_cleanup_free_ char *c = NULL, *u = NULL, *p = NULL, *t = NULL;
|
|
|
9a102d |
sd_id128_t boot = {};
|
|
|
9a102d |
int r;
|
|
|
9a102d |
|
|
|
9a102d |
assert(context);
|
|
|
9a102d |
|
|
|
9a102d |
- c = filename_escape(context[CONTEXT_COMM]);
|
|
|
9a102d |
+ c = filename_escape(context->meta[CONTEXT_COMM]);
|
|
|
9a102d |
if (!c)
|
|
|
9a102d |
return -ENOMEM;
|
|
|
9a102d |
|
|
|
9a102d |
- u = filename_escape(context[CONTEXT_UID]);
|
|
|
9a102d |
+ u = filename_escape(context->meta[CONTEXT_UID]);
|
|
|
9a102d |
if (!u)
|
|
|
9a102d |
return -ENOMEM;
|
|
|
9a102d |
|
|
|
9a102d |
@@ -292,11 +296,11 @@ static int make_filename(const char *context[_CONTEXT_MAX], char **ret) {
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
return r;
|
|
|
9a102d |
|
|
|
9a102d |
- p = filename_escape(context[CONTEXT_PID]);
|
|
|
9a102d |
+ p = filename_escape(context->meta[CONTEXT_PID]);
|
|
|
9a102d |
if (!p)
|
|
|
9a102d |
return -ENOMEM;
|
|
|
9a102d |
|
|
|
9a102d |
- t = filename_escape(context[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
+ t = filename_escape(context->meta[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
if (!t)
|
|
|
9a102d |
return -ENOMEM;
|
|
|
9a102d |
|
|
|
9a102d |
@@ -313,7 +317,7 @@ static int make_filename(const char *context[_CONTEXT_MAX], char **ret) {
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
static int save_external_coredump(
|
|
|
9a102d |
- const char *context[_CONTEXT_MAX],
|
|
|
9a102d |
+ const Context *context,
|
|
|
9a102d |
int input_fd,
|
|
|
9a102d |
char **ret_filename,
|
|
|
9a102d |
int *ret_node_fd,
|
|
|
9a102d |
@@ -334,19 +338,19 @@ static int save_external_coredump(
|
|
|
9a102d |
assert(ret_data_fd);
|
|
|
9a102d |
assert(ret_size);
|
|
|
9a102d |
|
|
|
9a102d |
- r = parse_uid(context[CONTEXT_UID], &uid);
|
|
|
9a102d |
+ r = parse_uid(context->meta[CONTEXT_UID], &uid);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
return log_error_errno(r, "Failed to parse UID: %m");
|
|
|
9a102d |
|
|
|
9a102d |
- r = safe_atou64(context[CONTEXT_RLIMIT], &rlimit);
|
|
|
9a102d |
+ r = safe_atou64(context->meta[CONTEXT_RLIMIT], &rlimit);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
- return log_error_errno(r, "Failed to parse resource limit: %s", context[CONTEXT_RLIMIT]);
|
|
|
9a102d |
+ return log_error_errno(r, "Failed to parse resource limit: %s", context->meta[CONTEXT_RLIMIT]);
|
|
|
9a102d |
if (rlimit < page_size()) {
|
|
|
9a102d |
/* Is coredumping disabled? Then don't bother saving/processing the coredump.
|
|
|
9a102d |
* Anything below PAGE_SIZE cannot give a readable coredump (the kernel uses
|
|
|
9a102d |
* ELF_EXEC_PAGESIZE which is not easily accessible, but is usually the same as PAGE_SIZE. */
|
|
|
9a102d |
log_info("Resource limits disable core dumping for process %s (%s).",
|
|
|
9a102d |
- context[CONTEXT_PID], context[CONTEXT_COMM]);
|
|
|
9a102d |
+ context->meta[CONTEXT_PID], context->meta[CONTEXT_COMM]);
|
|
|
9a102d |
return -EBADSLT;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
@@ -371,7 +375,7 @@ static int save_external_coredump(
|
|
|
9a102d |
|
|
|
9a102d |
r = copy_bytes(input_fd, fd, max_size, 0);
|
|
|
9a102d |
if (r < 0) {
|
|
|
9a102d |
- log_error_errno(r, "Cannot store coredump of %s (%s): %m", context[CONTEXT_PID], context[CONTEXT_COMM]);
|
|
|
9a102d |
+ log_error_errno(r, "Cannot store coredump of %s (%s): %m", context->meta[CONTEXT_PID], context->meta[CONTEXT_COMM]);
|
|
|
9a102d |
goto fail;
|
|
|
9a102d |
}
|
|
|
9a102d |
*ret_truncated = r == 1;
|
|
|
9a102d |
@@ -659,12 +663,12 @@ static int get_process_container_parent_cmdline(pid_t pid, char** cmdline) {
|
|
|
9a102d |
return 1;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static int change_uid_gid(const char *context[]) {
|
|
|
9a102d |
+static int change_uid_gid(const Context *context) {
|
|
|
9a102d |
uid_t uid;
|
|
|
9a102d |
gid_t gid;
|
|
|
9a102d |
int r;
|
|
|
9a102d |
|
|
|
9a102d |
- r = parse_uid(context[CONTEXT_UID], &uid);
|
|
|
9a102d |
+ r = parse_uid(context->meta[CONTEXT_UID], &uid);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
return r;
|
|
|
9a102d |
|
|
|
9a102d |
@@ -677,7 +681,7 @@ static int change_uid_gid(const char *context[]) {
|
|
|
9a102d |
uid = gid = 0;
|
|
|
9a102d |
}
|
|
|
9a102d |
} else {
|
|
|
9a102d |
- r = parse_gid(context[CONTEXT_GID], &gid;;
|
|
|
9a102d |
+ r = parse_gid(context->meta[CONTEXT_GID], &gid;;
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
return r;
|
|
|
9a102d |
}
|
|
|
9a102d |
@@ -685,23 +689,23 @@ static int change_uid_gid(const char *context[]) {
|
|
|
9a102d |
return drop_privileges(uid, gid, 0);
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static bool is_journald_crash(const char *context[_CONTEXT_MAX]) {
|
|
|
9a102d |
+static bool is_journald_crash(const Context *context) {
|
|
|
9a102d |
assert(context);
|
|
|
9a102d |
|
|
|
9a102d |
- return streq_ptr(context[CONTEXT_UNIT], SPECIAL_JOURNALD_SERVICE);
|
|
|
9a102d |
+ return streq_ptr(context->meta[CONTEXT_UNIT], SPECIAL_JOURNALD_SERVICE);
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static bool is_pid1_crash(const char *context[_CONTEXT_MAX]) {
|
|
|
9a102d |
+static bool is_pid1_crash(const Context *context) {
|
|
|
9a102d |
assert(context);
|
|
|
9a102d |
|
|
|
9a102d |
- return streq_ptr(context[CONTEXT_UNIT], SPECIAL_INIT_SCOPE) ||
|
|
|
9a102d |
- streq_ptr(context[CONTEXT_PID], "1");
|
|
|
9a102d |
+ return streq_ptr(context->meta[CONTEXT_UNIT], SPECIAL_INIT_SCOPE) ||
|
|
|
9a102d |
+ streq_ptr(context->meta[CONTEXT_PID], "1");
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
#define SUBMIT_COREDUMP_FIELDS 4
|
|
|
9a102d |
|
|
|
9a102d |
static int submit_coredump(
|
|
|
9a102d |
- const char *context[_CONTEXT_MAX],
|
|
|
9a102d |
+ Context *context,
|
|
|
9a102d |
struct iovec *iovec,
|
|
|
9a102d |
size_t n_iovec_allocated,
|
|
|
9a102d |
size_t n_iovec,
|
|
|
9a102d |
@@ -760,11 +764,11 @@ static int submit_coredump(
|
|
|
9a102d |
if (coredump_size <= arg_process_size_max) {
|
|
|
9a102d |
_cleanup_free_ char *stacktrace = NULL;
|
|
|
9a102d |
|
|
|
9a102d |
- r = coredump_make_stack_trace(coredump_fd, context[CONTEXT_EXE], &stacktrace);
|
|
|
9a102d |
+ r = coredump_make_stack_trace(coredump_fd, context->meta[CONTEXT_EXE], &stacktrace);
|
|
|
9a102d |
if (r >= 0)
|
|
|
9a102d |
- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
|
|
|
9a102d |
- " (", context[CONTEXT_COMM], ") of user ",
|
|
|
9a102d |
- context[CONTEXT_UID], " dumped core.",
|
|
|
9a102d |
+ core_message = strjoin("MESSAGE=Process ", context->meta[CONTEXT_PID],
|
|
|
9a102d |
+ " (", context->meta[CONTEXT_COMM], ") of user ",
|
|
|
9a102d |
+ context->meta[CONTEXT_UID], " dumped core.",
|
|
|
9a102d |
journald_crash ? "\nCoredump diverted to " : "",
|
|
|
9a102d |
journald_crash ? filename : "",
|
|
|
9a102d |
"\n\n", stacktrace);
|
|
|
9a102d |
@@ -779,9 +783,9 @@ static int submit_coredump(
|
|
|
9a102d |
if (!core_message)
|
|
|
9a102d |
#endif
|
|
|
9a102d |
log:
|
|
|
9a102d |
- core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
|
|
|
9a102d |
- " (", context[CONTEXT_COMM], ") of user ",
|
|
|
9a102d |
- context[CONTEXT_UID], " dumped core.",
|
|
|
9a102d |
+ core_message = strjoin("MESSAGE=Process ", context->meta[CONTEXT_PID],
|
|
|
9a102d |
+ " (", context->meta[CONTEXT_COMM], ") of user ",
|
|
|
9a102d |
+ context->meta[CONTEXT_UID], " dumped core.",
|
|
|
9a102d |
journald_crash && filename ? "\nCoredump diverted to " : NULL,
|
|
|
9a102d |
journald_crash && filename ? filename : NULL);
|
|
|
9a102d |
if (!core_message)
|
|
|
9a102d |
@@ -826,7 +830,7 @@ log:
|
|
|
9a102d |
return 0;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
-static void map_context_fields(const struct iovec *iovec, const char* context[]) {
|
|
|
9a102d |
+static void map_context_fields(const struct iovec *iovec, Context *context) {
|
|
|
9a102d |
|
|
|
9a102d |
static const char * const context_field_names[] = {
|
|
|
9a102d |
[CONTEXT_PID] = "COREDUMP_PID=",
|
|
|
9a102d |
@@ -857,7 +861,7 @@ static void map_context_fields(const struct iovec *iovec, const char* context[])
|
|
|
9a102d |
|
|
|
9a102d |
/* Note that these strings are NUL terminated, because we made sure that a trailing NUL byte is in the
|
|
|
9a102d |
* buffer, though not included in the iov_len count. (see below) */
|
|
|
9a102d |
- context[i] = p;
|
|
|
9a102d |
+ context->meta[i] = p;
|
|
|
9a102d |
break;
|
|
|
9a102d |
}
|
|
|
9a102d |
}
|
|
|
9a102d |
@@ -866,7 +870,7 @@ static int process_socket(int fd) {
|
|
|
9a102d |
_cleanup_close_ int coredump_fd = -1;
|
|
|
9a102d |
struct iovec *iovec = NULL;
|
|
|
9a102d |
size_t n_iovec = 0, n_allocated = 0, i, k;
|
|
|
9a102d |
- const char *context[_CONTEXT_MAX] = {};
|
|
|
9a102d |
+ Context context = {};
|
|
|
9a102d |
int r;
|
|
|
9a102d |
|
|
|
9a102d |
assert(fd >= 0);
|
|
|
9a102d |
@@ -950,7 +954,7 @@ static int process_socket(int fd) {
|
|
|
9a102d |
iovec[n_iovec].iov_len = (size_t) n;
|
|
|
9a102d |
|
|
|
9a102d |
cmsg_close_all(&mh);
|
|
|
9a102d |
- map_context_fields(iovec + n_iovec, context);
|
|
|
9a102d |
+ map_context_fields(iovec + n_iovec, &context);
|
|
|
9a102d |
n_iovec++;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
@@ -960,24 +964,24 @@ static int process_socket(int fd) {
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
/* Make sure we got all data we really need */
|
|
|
9a102d |
- assert(context[CONTEXT_PID]);
|
|
|
9a102d |
- assert(context[CONTEXT_UID]);
|
|
|
9a102d |
- assert(context[CONTEXT_GID]);
|
|
|
9a102d |
- assert(context[CONTEXT_SIGNAL]);
|
|
|
9a102d |
- assert(context[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
- assert(context[CONTEXT_RLIMIT]);
|
|
|
9a102d |
- assert(context[CONTEXT_HOSTNAME]);
|
|
|
9a102d |
- assert(context[CONTEXT_COMM]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_PID]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_UID]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_GID]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_SIGNAL]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_RLIMIT]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_HOSTNAME]);
|
|
|
9a102d |
+ assert(context.meta[CONTEXT_COMM]);
|
|
|
9a102d |
assert(coredump_fd >= 0);
|
|
|
9a102d |
|
|
|
9a102d |
/* Small quirk: the journal fields contain the timestamp padded with six zeroes, so that the kernel-supplied 1s
|
|
|
9a102d |
* granularity timestamps becomes 1µs granularity, i.e. the granularity systemd usually operates in. Since we
|
|
|
9a102d |
* are reconstructing the original kernel context, we chop this off again, here. */
|
|
|
9a102d |
- k = strlen(context[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
+ k = strlen(context.meta[CONTEXT_TIMESTAMP]);
|
|
|
9a102d |
if (k > 6)
|
|
|
9a102d |
- context[CONTEXT_TIMESTAMP] = strndupa(context[CONTEXT_TIMESTAMP], k - 6);
|
|
|
9a102d |
+ context.meta[CONTEXT_TIMESTAMP] = strndupa(context.meta[CONTEXT_TIMESTAMP], k - 6);
|
|
|
9a102d |
|
|
|
9a102d |
- r = submit_coredump(context, iovec, n_allocated, n_iovec, coredump_fd);
|
|
|
9a102d |
+ r = submit_coredump(&context, iovec, n_allocated, n_iovec, coredump_fd);
|
|
|
9a102d |
|
|
|
9a102d |
finish:
|
|
|
9a102d |
for (i = 0; i < n_iovec; i++)
|
|
|
9a102d |
@@ -1062,7 +1066,7 @@ static char* set_iovec_field_free(struct iovec *iovec, size_t *n_iovec, const ch
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
static int gather_pid_metadata(
|
|
|
9a102d |
- char* context[_CONTEXT_MAX],
|
|
|
9a102d |
+ Context *context,
|
|
|
9a102d |
char **comm_fallback,
|
|
|
9a102d |
struct iovec *iovec, size_t *n_iovec) {
|
|
|
9a102d |
|
|
|
9a102d |
@@ -1077,65 +1081,69 @@ static int gather_pid_metadata(
|
|
|
9a102d |
const char *p;
|
|
|
9a102d |
int r, signo;
|
|
|
9a102d |
|
|
|
9a102d |
- r = parse_pid(context[CONTEXT_PID], &pid;;
|
|
|
9a102d |
+ r = parse_pid(context->meta[CONTEXT_PID], &pid;;
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
- return log_error_errno(r, "Failed to parse PID \"%s\": %m", context[CONTEXT_PID]);
|
|
|
9a102d |
+ return log_error_errno(r, "Failed to parse PID \"%s\": %m", context->meta[CONTEXT_PID]);
|
|
|
9a102d |
|
|
|
9a102d |
- r = get_process_comm(pid, &context[CONTEXT_COMM]);
|
|
|
9a102d |
+ r = get_process_comm(pid, &t);
|
|
|
9a102d |
if (r < 0) {
|
|
|
9a102d |
log_warning_errno(r, "Failed to get COMM, falling back to the command line: %m");
|
|
|
9a102d |
- context[CONTEXT_COMM] = strv_join(comm_fallback, " ");
|
|
|
9a102d |
- if (!context[CONTEXT_COMM])
|
|
|
9a102d |
+ context->meta[CONTEXT_COMM] = strv_join(comm_fallback, " ");
|
|
|
9a102d |
+ if (!context->meta[CONTEXT_COMM])
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
- }
|
|
|
9a102d |
+ } else
|
|
|
9a102d |
+ context->meta[CONTEXT_COMM] = t;
|
|
|
9a102d |
|
|
|
9a102d |
- r = get_process_exe(pid, &context[CONTEXT_EXE]);
|
|
|
9a102d |
+ r = get_process_exe(pid, &t);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
log_warning_errno(r, "Failed to get EXE, ignoring: %m");
|
|
|
9a102d |
+ else
|
|
|
9a102d |
+ context->meta[CONTEXT_EXE] = t;
|
|
|
9a102d |
|
|
|
9a102d |
- if (cg_pid_get_unit(pid, &context[CONTEXT_UNIT]) >= 0) {
|
|
|
9a102d |
- if (!is_journald_crash((const char**) context)) {
|
|
|
9a102d |
+ if (cg_pid_get_unit(pid, &t) >= 0) {
|
|
|
9a102d |
+ if (!is_journald_crash(context)) {
|
|
|
9a102d |
/* OK, now we know it's not the journal, hence we can make use of it now. */
|
|
|
9a102d |
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
|
|
|
9a102d |
log_open();
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */
|
|
|
9a102d |
- if (is_pid1_crash((const char**) context)) {
|
|
|
9a102d |
+ if (is_pid1_crash(context)) {
|
|
|
9a102d |
log_notice("Due to PID 1 having crashed coredump collection will now be turned off.");
|
|
|
9a102d |
disable_coredumps();
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
- set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context[CONTEXT_UNIT]);
|
|
|
9a102d |
- }
|
|
|
9a102d |
+ set_iovec_string_field(iovec, n_iovec, "COREDUMP_UNIT=", context->meta[CONTEXT_UNIT]);
|
|
|
9a102d |
+ } else
|
|
|
9a102d |
+ context->meta[CONTEXT_UNIT] = t;
|
|
|
9a102d |
|
|
|
9a102d |
if (cg_pid_get_user_unit(pid, &t) >= 0)
|
|
|
9a102d |
set_iovec_field_free(iovec, n_iovec, "COREDUMP_USER_UNIT=", t);
|
|
|
9a102d |
|
|
|
9a102d |
/* The next few are mandatory */
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context[CONTEXT_PID]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_PID=", context->meta[CONTEXT_PID]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context[CONTEXT_UID]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_UID=", context->meta[CONTEXT_UID]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context[CONTEXT_GID]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_GID=", context->meta[CONTEXT_GID]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL=", context->meta[CONTEXT_SIGNAL]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_RLIMIT=", context->meta[CONTEXT_RLIMIT]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context[CONTEXT_HOSTNAME]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_HOSTNAME=", context->meta[CONTEXT_HOSTNAME]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context[CONTEXT_COMM]))
|
|
|
9a102d |
+ if (!set_iovec_string_field(iovec, n_iovec, "COREDUMP_COMM=", context->meta[CONTEXT_COMM]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- if (context[CONTEXT_EXE] &&
|
|
|
9a102d |
- !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context[CONTEXT_EXE]))
|
|
|
9a102d |
+ if (context->meta[CONTEXT_EXE] &&
|
|
|
9a102d |
+ !set_iovec_string_field(iovec, n_iovec, "COREDUMP_EXE=", context->meta[CONTEXT_EXE]))
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
if (sd_pid_get_session(pid, &t) >= 0)
|
|
|
9a102d |
@@ -1198,11 +1206,11 @@ static int gather_pid_metadata(
|
|
|
9a102d |
if (get_process_environ(pid, &t) >= 0)
|
|
|
9a102d |
set_iovec_field_free(iovec, n_iovec, "COREDUMP_ENVIRON=", t);
|
|
|
9a102d |
|
|
|
9a102d |
- t = strjoin("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000");
|
|
|
9a102d |
+ t = strjoin("COREDUMP_TIMESTAMP=", context->meta[CONTEXT_TIMESTAMP], "000000");
|
|
|
9a102d |
if (t)
|
|
|
9a102d |
iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(t);
|
|
|
9a102d |
|
|
|
9a102d |
- if (safe_atoi(context[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo))
|
|
|
9a102d |
+ if (safe_atoi(context->meta[CONTEXT_SIGNAL], &signo) >= 0 && SIGNAL_VALID(signo))
|
|
|
9a102d |
set_iovec_string_field(iovec, n_iovec, "COREDUMP_SIGNAL_NAME=SIG", signal_to_string(signo));
|
|
|
9a102d |
|
|
|
9a102d |
return 0; /* we successfully acquired all metadata */
|
|
|
9a102d |
@@ -1210,7 +1218,7 @@ static int gather_pid_metadata(
|
|
|
9a102d |
|
|
|
9a102d |
static int process_kernel(int argc, char* argv[]) {
|
|
|
9a102d |
|
|
|
9a102d |
- char* context[_CONTEXT_MAX] = {};
|
|
|
9a102d |
+ Context context = {};
|
|
|
9a102d |
struct iovec iovec[29 + SUBMIT_COREDUMP_FIELDS];
|
|
|
9a102d |
size_t i, n_iovec, n_to_free = 0;
|
|
|
9a102d |
int r;
|
|
|
9a102d |
@@ -1222,15 +1230,15 @@ static int process_kernel(int argc, char* argv[]) {
|
|
|
9a102d |
return -EINVAL;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
- context[CONTEXT_PID] = argv[1 + CONTEXT_PID];
|
|
|
9a102d |
- context[CONTEXT_UID] = argv[1 + CONTEXT_UID];
|
|
|
9a102d |
- context[CONTEXT_GID] = argv[1 + CONTEXT_GID];
|
|
|
9a102d |
- context[CONTEXT_SIGNAL] = argv[1 + CONTEXT_SIGNAL];
|
|
|
9a102d |
- context[CONTEXT_TIMESTAMP] = argv[1 + CONTEXT_TIMESTAMP];
|
|
|
9a102d |
- context[CONTEXT_RLIMIT] = argv[1 + CONTEXT_RLIMIT];
|
|
|
9a102d |
- context[CONTEXT_HOSTNAME] = argv[1 + CONTEXT_HOSTNAME];
|
|
|
9a102d |
+ context.meta[CONTEXT_PID] = argv[1 + CONTEXT_PID];
|
|
|
9a102d |
+ context.meta[CONTEXT_UID] = argv[1 + CONTEXT_UID];
|
|
|
9a102d |
+ context.meta[CONTEXT_GID] = argv[1 + CONTEXT_GID];
|
|
|
9a102d |
+ context.meta[CONTEXT_SIGNAL] = argv[1 + CONTEXT_SIGNAL];
|
|
|
9a102d |
+ context.meta[CONTEXT_TIMESTAMP] = argv[1 + CONTEXT_TIMESTAMP];
|
|
|
9a102d |
+ context.meta[CONTEXT_RLIMIT] = argv[1 + CONTEXT_RLIMIT];
|
|
|
9a102d |
+ context.meta[CONTEXT_HOSTNAME] = argv[1 + CONTEXT_HOSTNAME];
|
|
|
9a102d |
|
|
|
9a102d |
- r = gather_pid_metadata(context, argv + 1 + CONTEXT_COMM, iovec, &n_to_free);
|
|
|
9a102d |
+ r = gather_pid_metadata(&context, argv + 1 + CONTEXT_COMM, iovec, &n_to_free);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
goto finish;
|
|
|
9a102d |
|
|
|
9a102d |
@@ -1243,8 +1251,8 @@ static int process_kernel(int argc, char* argv[]) {
|
|
|
9a102d |
|
|
|
9a102d |
assert(n_iovec <= ELEMENTSOF(iovec));
|
|
|
9a102d |
|
|
|
9a102d |
- if (is_journald_crash((const char**) context) || is_pid1_crash((const char**) context))
|
|
|
9a102d |
- r = submit_coredump((const char**) context,
|
|
|
9a102d |
+ if (is_journald_crash(&context) || is_pid1_crash(&context))
|
|
|
9a102d |
+ r = submit_coredump(&context,
|
|
|
9a102d |
iovec, ELEMENTSOF(iovec), n_iovec,
|
|
|
9a102d |
STDIN_FILENO);
|
|
|
9a102d |
else
|
|
|
9a102d |
@@ -1255,15 +1263,15 @@ static int process_kernel(int argc, char* argv[]) {
|
|
|
9a102d |
free(iovec[i].iov_base);
|
|
|
9a102d |
|
|
|
9a102d |
/* Those fields are allocated by gather_pid_metadata */
|
|
|
9a102d |
- free(context[CONTEXT_COMM]);
|
|
|
9a102d |
- free(context[CONTEXT_EXE]);
|
|
|
9a102d |
- free(context[CONTEXT_UNIT]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_COMM]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_EXE]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_UNIT]);
|
|
|
9a102d |
|
|
|
9a102d |
return r;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
static int process_backtrace(int argc, char *argv[]) {
|
|
|
9a102d |
- char *context[_CONTEXT_MAX] = {};
|
|
|
9a102d |
+ Context context = {};
|
|
|
9a102d |
_cleanup_free_ char *message = NULL;
|
|
|
9a102d |
_cleanup_free_ struct iovec *iovec = NULL;
|
|
|
9a102d |
size_t n_iovec, n_allocated, n_to_free = 0, i;
|
|
|
9a102d |
@@ -1279,13 +1287,13 @@ static int process_backtrace(int argc, char *argv[]) {
|
|
|
9a102d |
return -EINVAL;
|
|
|
9a102d |
}
|
|
|
9a102d |
|
|
|
9a102d |
- context[CONTEXT_PID] = argv[2 + CONTEXT_PID];
|
|
|
9a102d |
- context[CONTEXT_UID] = argv[2 + CONTEXT_UID];
|
|
|
9a102d |
- context[CONTEXT_GID] = argv[2 + CONTEXT_GID];
|
|
|
9a102d |
- context[CONTEXT_SIGNAL] = argv[2 + CONTEXT_SIGNAL];
|
|
|
9a102d |
- context[CONTEXT_TIMESTAMP] = argv[2 + CONTEXT_TIMESTAMP];
|
|
|
9a102d |
- context[CONTEXT_RLIMIT] = argv[2 + CONTEXT_RLIMIT];
|
|
|
9a102d |
- context[CONTEXT_HOSTNAME] = argv[2 + CONTEXT_HOSTNAME];
|
|
|
9a102d |
+ context.meta[CONTEXT_PID] = argv[2 + CONTEXT_PID];
|
|
|
9a102d |
+ context.meta[CONTEXT_UID] = argv[2 + CONTEXT_UID];
|
|
|
9a102d |
+ context.meta[CONTEXT_GID] = argv[2 + CONTEXT_GID];
|
|
|
9a102d |
+ context.meta[CONTEXT_SIGNAL] = argv[2 + CONTEXT_SIGNAL];
|
|
|
9a102d |
+ context.meta[CONTEXT_TIMESTAMP] = argv[2 + CONTEXT_TIMESTAMP];
|
|
|
9a102d |
+ context.meta[CONTEXT_RLIMIT] = argv[2 + CONTEXT_RLIMIT];
|
|
|
9a102d |
+ context.meta[CONTEXT_HOSTNAME] = argv[2 + CONTEXT_HOSTNAME];
|
|
|
9a102d |
|
|
|
9a102d |
n_allocated = 34 + COREDUMP_STORAGE_EXTERNAL;
|
|
|
9a102d |
/* 26 metadata, 2 static, +unknown input, 4 storage, rounded up */
|
|
|
9a102d |
@@ -1293,7 +1301,7 @@ static int process_backtrace(int argc, char *argv[]) {
|
|
|
9a102d |
if (!iovec)
|
|
|
9a102d |
return log_oom();
|
|
|
9a102d |
|
|
|
9a102d |
- r = gather_pid_metadata(context, argv + 2 + CONTEXT_COMM, iovec, &n_to_free);
|
|
|
9a102d |
+ r = gather_pid_metadata(&context, argv + 2 + CONTEXT_COMM, iovec, &n_to_free);
|
|
|
9a102d |
if (r < 0)
|
|
|
9a102d |
goto finish;
|
|
|
9a102d |
if (r > 0) {
|
|
|
9a102d |
@@ -1320,10 +1328,10 @@ static int process_backtrace(int argc, char *argv[]) {
|
|
|
9a102d |
if (journal_importer_eof(&importer)) {
|
|
|
9a102d |
log_warning("Did not receive a full journal entry on stdin, ignoring message sent by reporter");
|
|
|
9a102d |
|
|
|
9a102d |
- message = strjoin("MESSAGE=Process ", context[CONTEXT_PID],
|
|
|
9a102d |
- " (", context[CONTEXT_COMM], ")"
|
|
|
9a102d |
- " of user ", context[CONTEXT_UID],
|
|
|
9a102d |
- " failed with ", context[CONTEXT_SIGNAL]);
|
|
|
9a102d |
+ message = strjoin("MESSAGE=Process ", context.meta[CONTEXT_PID],
|
|
|
9a102d |
+ " (", context.meta[CONTEXT_COMM], ")"
|
|
|
9a102d |
+ " of user ", context.meta[CONTEXT_UID],
|
|
|
9a102d |
+ " failed with ", context.meta[CONTEXT_SIGNAL]);
|
|
|
9a102d |
if (!message) {
|
|
|
9a102d |
r = log_oom();
|
|
|
9a102d |
goto finish;
|
|
|
9a102d |
@@ -1349,9 +1357,9 @@ static int process_backtrace(int argc, char *argv[]) {
|
|
|
9a102d |
free(iovec[i].iov_base);
|
|
|
9a102d |
|
|
|
9a102d |
/* Those fields are allocated by gather_pid_metadata */
|
|
|
9a102d |
- free(context[CONTEXT_COMM]);
|
|
|
9a102d |
- free(context[CONTEXT_EXE]);
|
|
|
9a102d |
- free(context[CONTEXT_UNIT]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_COMM]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_EXE]);
|
|
|
9a102d |
+ free((char *) context.meta[CONTEXT_UNIT]);
|
|
|
9a102d |
|
|
|
9a102d |
return r;
|
|
|
9a102d |
}
|