/proc/[pid]: - status - maps - limits - cgroup - cwd - root - environ - fd/ & fdinfo/ joined in open_fds --- src/journal/coredump.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 2 deletions(-)
diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 26a2010..1b04105 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -461,18 +461,87 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s return 0; } +/* Joins /proc/[pid]/fd/ and /proc/[pid]/fdinfo/ into the following lines: + * + * 0:/dev/pts/23 + * pos: 0 + * flags: 0100002 + * 1:/dev/pts/23 + * pos: 0 + * flags: 0100002 + * 2:/dev/pts/23 + * + */ +static int compose_open_fds(pid_t pid, char **open_fds) { + const char *fd_name = NULL, *fdinfo_name = NULL; + char *outcome = NULL; + size_t len = 0, allocated = 0; + char line[LINE_MAX]; + unsigned fd = 0; + int r = 0; + + assert(pid >= 0); + + fd_name = alloca(strlen("/proc//fd/") + DECIMAL_STR_MAX(pid_t) + DECIMAL_STR_MAX(unsigned) + 1); + fdinfo_name = alloca(strlen("/proc//fdinfo/") + DECIMAL_STR_MAX(pid_t) + DECIMAL_STR_MAX(unsigned) + 1); + + while (fd <= 99999) { + _cleanup_free_ char *name = NULL; + _cleanup_fclose_ FILE *fdinfo = NULL; + + sprintf((char *)fd_name, "/proc/"PID_FMT"/fd/%u", pid, fd); + r = readlink_malloc(fd_name, &name); + if (r < 0) { + if (r == -ENOENT) { + *open_fds = outcome; + r = 0; + } + else + free(outcome); + + break; + } + + if (!GREEDY_REALLOC(outcome, allocated, len + strlen(name) + DECIMAL_STR_MAX(unsigned) + 3)) + return -ENOMEM; + + len += sprintf(outcome + len, "%u:%s\n", fd, name); + ++fd; + + sprintf((char *)fdinfo_name, "/proc/"PID_FMT"/fdinfo/%u", pid, fd); + fdinfo = fopen(fdinfo_name, "r"); + if (fdinfo == NULL) + continue; + + while(fgets(line, sizeof(line), fdinfo) != NULL) { + if (!GREEDY_REALLOC(outcome, allocated, len + strlen(line) + 2)) + return -ENOMEM; + + len += sprintf(outcome + len, "%s", line); + if (strchr(line, '\n') == NULL) { + outcome[len++] = '\n'; + outcome[len] = '\0'; + } + } + } + + return r; +} + int main(int argc, char* argv[]) { _cleanup_free_ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *coredump_data = NULL, - *core_slice = NULL, *core_cgroup = NULL, *core_owner_uid = NULL, + *core_slice = NULL, *core_cgroup = NULL, *core_owner_uid = NULL, *core_open_fds = NULL, + *core_proc_status = NULL, *core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, + *core_cwd = NULL, *core_root = NULL, *core_environ = NULL, *exe = NULL, *comm = NULL, *filename = NULL; const char *info[_INFO_LEN]; _cleanup_close_ int coredump_fd = -1; - struct iovec iovec[18]; + struct iovec iovec[26]; off_t coredump_size; int r, j = 0; uid_t uid, owner_uid; @@ -638,6 +707,70 @@ int main(int argc, char* argv[]) { IOVEC_SET_STRING(iovec[j++], core_cgroup); } + if (compose_open_fds(pid, &t) >= 0) { + core_open_fds = strappend("COREDUMP_OPEN_FDS=", t); + free(t); + + if (core_open_fds) + IOVEC_SET_STRING(iovec[j++], core_open_fds); + } + + if (get_process_status(pid, &t) >= 0) { + core_proc_status = strappend("COREDUMP_PROC_STATUS=", t); + free(t); + + if (core_proc_status) + IOVEC_SET_STRING(iovec[j++], core_proc_status); + } + + if (get_process_maps(pid, &t) >= 0) { + core_proc_maps = strappend("COREDUMP_PROC_MAPS=", t); + free(t); + + if (core_proc_maps) + IOVEC_SET_STRING(iovec[j++], core_proc_maps); + } + + if (get_process_limits(pid, &t) >= 0) { + core_proc_limits = strappend("COREDUMP_PROC_LIMITS=", t); + free(t); + + if (core_proc_limits) + IOVEC_SET_STRING(iovec[j++], core_proc_limits); + } + + if (get_process_cgroup(pid, &t) >=0) { + core_proc_cgroup = strappend("COREDUMP_PROC_CGROUP=", t); + free(t); + + if (core_proc_cgroup) + IOVEC_SET_STRING(iovec[j++], core_proc_cgroup); + } + + if (get_process_cwd(pid, &t) >= 0) { + core_cwd = strappend("COREDUMP_CWD=", t); + free(t); + + if (core_cwd) + IOVEC_SET_STRING(iovec[j++], core_cwd); + } + + if (get_process_root(pid, &t) >= 0) { + core_root = strappend("COREDUMP_ROOT=", t); + free(t); + + if (core_root) + IOVEC_SET_STRING(iovec[j++], core_root); + } + + if (get_process_environ(pid, &t) >= 0) { + core_environ = strappend("COREDUMP_ENVIRON=", t); + free(t); + + if (core_environ) + IOVEC_SET_STRING(iovec[j++], core_environ); + } + core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL); if (core_timestamp) IOVEC_SET_STRING(iovec[j++], core_timestamp); -- 1.8.3.1 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel