diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-09-14 18:33:57 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-09-14 18:33:57 -0400 |
commit | 3c72c8d3ee67388336aca58c5afa3fb93a9c24c0 (patch) | |
tree | d072df7fee0f5906fad88c08398b2fe887cbc064 /src/grp-coredump | |
parent | e51613a3291342c6006edda8783755fb8994fd75 (diff) | |
parent | 6ba6ca19507add38549e07058c57489a8cd98cd1 (diff) |
Merge branch 'notsystemd/postmove' into notsystemd/master
# Conflicts:
# src/grp-journal/systemd-journald/Makefile
# src/grp-login/systemd-logind/Makefile
# src/grp-machine/grp-import/systemd-export/Makefile
# src/grp-machine/grp-import/systemd-import/Makefile
# src/grp-machine/grp-import/systemd-pull/Makefile
# src/grp-machine/systemd-machined/Makefile
# src/grp-network/libnetworkd-core/Makefile
# src/grp-resolve/libbasic-dns/Makefile
# src/grp-resolve/systemd-resolved/Makefile
# src/grp-utils/systemd-path/Makefile
# src/libshared/src/Makefile
# src/libsystemd-network/include/systemd-network/sd-ndisc.h
# src/libsystemd/Makefile
# src/libsystemd/src/test.mk
# src/libudev/Makefile
# src/systemd-dbus1-generator/Makefile
# src/systemd-nspawn/nspawn.c
Signed-off-by: Luke Shumaker <lukeshu@sbcglobal.net>
Diffstat (limited to 'src/grp-coredump')
-rw-r--r-- | src/grp-coredump/coredumpctl/Makefile | 2 | ||||
-rw-r--r-- | src/grp-coredump/systemd-coredump/Makefile | 9 | ||||
-rw-r--r-- | src/grp-coredump/systemd-coredump/coredump.c | 66 |
3 files changed, 59 insertions, 18 deletions
diff --git a/src/grp-coredump/coredumpctl/Makefile b/src/grp-coredump/coredumpctl/Makefile index 47a4397fa4..25a0ee29f2 100644 --- a/src/grp-coredump/coredumpctl/Makefile +++ b/src/grp-coredump/coredumpctl/Makefile @@ -27,7 +27,7 @@ coredumpctl_SOURCES = \ src/coredump/coredumpctl.c coredumpctl_LDADD = \ - libshared.la + libsystemd-shared.la bin_PROGRAMS += \ coredumpctl diff --git a/src/grp-coredump/systemd-coredump/Makefile b/src/grp-coredump/systemd-coredump/Makefile index 108186488c..f294760802 100644 --- a/src/grp-coredump/systemd-coredump/Makefile +++ b/src/grp-coredump/systemd-coredump/Makefile @@ -29,8 +29,13 @@ systemd_coredump_SOURCES = \ src/coredump/coredump-vacuum.c \ src/coredump/coredump-vacuum.h +systemd_coredump_CFLAGS = \ + $(AM_CFLAGS) \ + $(ACL_CFLAGS) + systemd_coredump_LDADD = \ - libshared.la + libsystemd-shared.la \ + $(ACL_LIBS) ifneq ($(HAVE_ELFUTILS),) systemd_coredump_SOURCES += \ @@ -65,7 +70,7 @@ test_coredump_vacuum_SOURCES = \ src/coredump/coredump-vacuum.h test_coredump_vacuum_LDADD = \ - libshared.la + libsystemd-shared.la nodist_sysctl_DATA = \ sysctl.d/50-coredump.conf diff --git a/src/grp-coredump/systemd-coredump/coredump.c b/src/grp-coredump/systemd-coredump/coredump.c index b1da8eaba4..dd05326ce0 100644 --- a/src/grp-coredump/systemd-coredump/coredump.c +++ b/src/grp-coredump/systemd-coredump/coredump.c @@ -158,10 +158,8 @@ static int fix_acl(int fd, uid_t uid) { if (acl_create_entry(&acl, &entry) < 0 || acl_set_tag_type(entry, ACL_USER) < 0 || - acl_set_qualifier(entry, &uid) < 0) { - log_error_errno(errno, "Failed to patch ACL: %m"); - return -errno; - } + acl_set_qualifier(entry, &uid) < 0) + return log_error_errno(errno, "Failed to patch ACL: %m"); if (acl_get_permset(entry, &permset) < 0 || acl_add_perm(permset, ACL_READ) < 0) @@ -757,7 +755,6 @@ static int process_socket(int fd) { iovec[n_iovec].iov_len = l; iovec[n_iovec].iov_base = malloc(l + 1); - if (!iovec[n_iovec].iov_base) { r = log_oom(); goto finish; @@ -812,7 +809,7 @@ static int process_socket(int fd) { goto finish; } - /* Make sure we we got all data we really need */ + /* Make sure we got all data we really need */ assert(context[CONTEXT_PID]); assert(context[CONTEXT_UID]); assert(context[CONTEXT_GID]); @@ -853,12 +850,42 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd) return log_error_errno(errno, "Failed to connect to coredump service: %m"); for (i = 0; i < n_iovec; i++) { - ssize_t n; - assert(iovec[i].iov_len > 0); + struct msghdr mh = { + .msg_iov = (struct iovec*) iovec + i, + .msg_iovlen = 1, + }; + struct iovec copy[2]; + + for (;;) { + if (sendmsg(fd, &mh, MSG_NOSIGNAL) >= 0) + break; + + if (errno == EMSGSIZE && mh.msg_iov[0].iov_len > 0) { + /* This field didn't fit? That's a pity. Given that this is just metadata, + * let's truncate the field at half, and try again. We append three dots, in + * order to show that this is truncated. */ + + if (mh.msg_iov != copy) { + /* We don't want to modify the caller's iovec, hence let's create our + * own array, consisting of two new iovecs, where the first is a + * (truncated) copy of what we want to send, and the second one + * contains the trailing dots. */ + copy[0] = iovec[i]; + copy[1] = (struct iovec) { + .iov_base = (char[]) { '.', '.', '.' }, + .iov_len = 3, + }; + + mh.msg_iov = copy; + mh.msg_iovlen = 2; + } + + copy[0].iov_len /= 2; /* halve it, and try again */ + continue; + } - n = send(fd, iovec[i].iov_base, iovec[i].iov_len, MSG_NOSIGNAL); - if (n < 0) return log_error_errno(errno, "Failed to send coredump datagram: %m"); + } } r = send_one_fd(fd, input_fd, 0); @@ -868,7 +895,7 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd) return 0; } -static int process_journald_crash(const char *context[], int input_fd) { +static int process_special_crash(const char *context[], int input_fd) { _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1; _cleanup_free_ char *filename = NULL; uint64_t coredump_size; @@ -877,7 +904,7 @@ static int process_journald_crash(const char *context[], int input_fd) { assert(context); assert(input_fd >= 0); - /* If we are journald, we cut things short, don't write to the journal, but still create a coredump. */ + /* If we are pid1 or journald, we cut things short, don't write to the journal, but still create a coredump. */ if (arg_storage != COREDUMP_STORAGE_NONE) arg_storage = COREDUMP_STORAGE_EXTERNAL; @@ -890,7 +917,8 @@ static int process_journald_crash(const char *context[], int input_fd) { if (r < 0) return r; - log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename); + log_notice("Detected coredump of the journal daemon or PID 1, diverted to %s.", filename); + return 0; } @@ -950,9 +978,17 @@ static int process_kernel(int argc, char* argv[]) { if (cg_pid_get_unit(pid, &t) >= 0) { - if (streq(t, SPECIAL_JOURNALD_SERVICE)) { + /* If this is PID 1 disable coredump collection, we'll unlikely be able to process it later on. */ + if (streq(t, SPECIAL_INIT_SCOPE)) { + log_notice("Due to PID 1 having crashed coredump collection will now be turned off."); + (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0); + } + + /* Let's avoid dead-locks when processing journald and init crashes, as socket activation and logging + * are unlikely to work then. */ + if (STR_IN_SET(t, SPECIAL_JOURNALD_SERVICE, SPECIAL_INIT_SCOPE)) { free(t); - return process_journald_crash(context, STDIN_FILENO); + return process_special_crash(context, STDIN_FILENO); } core_unit = strjoina("COREDUMP_UNIT=", t); |