From df53824815d965f54a082a361b97fd94d605c918 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Mon, 22 Feb 2016 18:11:30 +0100 Subject: [PATCH] crash-pipe: Add utility to process core sent to stdin This is going to be used as systemd-coredump replacement. Change-Id: Ib7074ba5e10990d8487b1693a8c92431cdee6964 --- CMakeLists.txt | 1 + packaging/crash-worker.spec | 5 +- src/crash-pipe/CMakeLists.txt | 5 ++ src/crash-pipe/crash-pipe.c | 145 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/crash-pipe/CMakeLists.txt create mode 100644 src/crash-pipe/crash-pipe.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e1fb00..9e407b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,6 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) # Sub modules ADD_SUBDIRECTORY(src/crash-manager) +ADD_SUBDIRECTORY(src/crash-pipe) ADD_SUBDIRECTORY(src/dump_systemstate) diff --git a/packaging/crash-worker.spec b/packaging/crash-worker.spec index 9fc9b36..4631c8d 100644 --- a/packaging/crash-worker.spec +++ b/packaging/crash-worker.spec @@ -35,7 +35,9 @@ export CFLAGS+=" -Werror" -DTZ_SYS_BIN=%{TZ_SYS_BIN} \ -DUNIT_DIR=%{_unitdir} \ -DCRASH_PATH=%{crash_path} \ - -DCRASH_TEMP=%{crash_temp} + -DCRASH_TEMP=%{crash_temp} \ + -DCRASH_PIPE_PATH=%{_libexecdir}/crash-pipe + make %{?jobs:-j%jobs} %install @@ -57,6 +59,7 @@ mkdir -p %{buildroot}%{crash_temp} %attr(0755,system,system) %{_bindir}/dump_systemstate %{_bindir}/crash-manager.sh %{_bindir}/crash-init.sh +%{_libexecdir}/crash-pipe %{_prefix}/lib/sysctl.d/99-crash-manager.conf %{_unitdir}/crash-init.service %{_unitdir}/sysinit.target.wants/crash-init.service diff --git a/src/crash-pipe/CMakeLists.txt b/src/crash-pipe/CMakeLists.txt new file mode 100644 index 0000000..7405769 --- /dev/null +++ b/src/crash-pipe/CMakeLists.txt @@ -0,0 +1,5 @@ +set(CRASH_PIPE_BIN "crash-pipe") +set(CRASH_PIPE_SRCS crash-pipe.c) + +add_executable(${CRASH_PIPE_BIN} ${CRASH_PIPE_SRCS}) +install(TARGETS ${CRASH_PIPE_BIN} DESTINATION libexec) diff --git a/src/crash-pipe/crash-pipe.c b/src/crash-pipe/crash-pipe.c new file mode 100644 index 0000000..21bec53 --- /dev/null +++ b/src/crash-pipe/crash-pipe.c @@ -0,0 +1,145 @@ +/* crash-pipe: handle core file passed from stdin + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author: Karol Lewandowski + */ +#define _GNU_SOURCE 1 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define NELEMS(arr) (sizeof(arr)/sizeof(arr[0])) + +enum { + OPT_HELP, + OPT_REPORT, + OPT_SAVE_CORE, +}; + +const struct option opts[] = { + { "help", no_argument, 0, OPT_HELP }, + { "report", no_argument, 0, OPT_REPORT }, + { "save-core", required_argument, 0, OPT_SAVE_CORE }, + { 0, 0, 0, 0 } +}; + +static char *argv0 = ""; + +static void usage(void) +{ + fprintf(stderr, "usage: %s [--help] [--save-core FILE_NAME] [--report] PID UID GID SIGNAL DUMPTIME EXE\n", + argv0); +} + +static void report(int argc, char *argv[]) +{ + const char *pidstr = argv[0]; + + + printf("Process crash report: %s\n" + "\tpid: %s\n" + "\tuid: %s\n" + "\tgid: %s\n" + "\tsignal: %s\n" + "\ttimestamp of crash: %s\n", + argv[5], pidstr, argv[1], argv[2], argv[3], argv[4]); + +} + +static int save_core(const char *core_path) +{ + int fd; + static char buf[4096]; + int readb, remaining; + + fd = open(core_path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if (fd == -1) { + syslog(LOG_ERR, "crash-pipe: Unable to save core file to %s: %s\n", + core_path, strerror(errno)); + return -1; + } + + while ((readb = read(STDIN_FILENO, buf, sizeof(buf))) > 0) { + int n; + + for (n = 0, remaining = readb ; remaining > 0; remaining -= n) { + n = write(fd, buf, remaining); + if (n == -1) { + syslog(LOG_ERR, "crash-pipe: Error while saving core file %s: %s. Removing core.\n", + core_path, strerror(errno)); + (void)unlink(core_path); // XXX check errors here too + return 0; + } + } + } + + close(fd); + + return 0; +} + + +int main(int argc, char *argv[]) +{ + int c; + int opt_report = 0; + char *opt_save_core = NULL; + _Bool ret = 1; + + prctl(PR_SET_DUMPABLE, 0); + + argv0 = argv[0]; + + + while ((c = getopt_long_only(argc, argv, "", opts, NULL)) != -1) { + + if (c == OPT_HELP) { + usage(); + exit(EXIT_SUCCESS); + } + else if (c == OPT_REPORT) { + opt_report = 1; + } + else if (c == OPT_SAVE_CORE) { + opt_save_core = strdup(optarg); + if (!opt_save_core) { + syslog(LOG_CRIT, "Out of memory. Exiting."); + exit(EXIT_FAILURE); + } + } + } + + argc -= optind; + argv += optind; + + if (opt_report) + report(argc, argv); + + if (opt_save_core) + ret = save_core(opt_save_core); + + return ret >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} -- 2.7.4