crash-manager: Add ExtraScript to config 25/208125/3
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Tue, 18 Jun 2019 10:57:48 +0000 (12:57 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Fri, 21 Jun 2019 18:26:02 +0000 (20:26 +0200)
ExtraScript will be called for report types >= FULL.  This will allow
attaching arbitrary data to crash report.  Script is called with report's
temporary directory as first and only argument, ie.

   exec("$ExtraScript", "/path/to/report/temp/dir", PID)

Change-Id: Icc38b92daae7a39b13063b2c45bffc1b863e72d6

packaging/crash-worker_system-tests.spec
src/crash-manager/crash-manager.c
src/crash-manager/crash-manager.conf
src/shared/config.c
src/shared/config.h
tests/system/CMakeLists.txt
tests/system/extra_script/extra_script.sh.template [new file with mode: 0644]

index 03dcd48..396c7e8 100644 (file)
@@ -72,6 +72,7 @@ cd tests/system
 %{_libdir}/crash-worker_system-tests/without_core/without_core.sh
 %{_libdir}/crash-worker_system-tests/crash_root_path/crash_root_path.sh
 %{_libdir}/crash-worker_system-tests/dump_systemstate_extras/dump_systemstate_extras.sh
+%{_libdir}/crash-worker_system-tests/extra_script/extra_script.sh
 %{_libdir}/crash-worker_system-tests/utils/btee
 %{_libdir}/crash-worker_system-tests/utils/kenny
 %{_libdir}/crash-worker_system-tests/utils/minicore-utils.sh
index 64f538e..f505834 100644 (file)
@@ -659,6 +659,22 @@ end:
 #define SNPRINTF_OR_EXIT_W(name, format, member) if (snprintf(name##_str, sizeof(name##_str), format, cinfo->member) < 0) goto out;
 #define SNPRINTF_OR_EXIT(name, format) SNPRINTF_OR_EXIT_W(name, format, name##_info)
 
+static bool extra_script(const struct crash_info *cinfo, pid_t *pid)
+{
+       if (!config.extra_script)
+               return false;
+
+       char pid_str[11];
+       SNPRINTF_OR_EXIT(pid, "%d")
+
+       char *av[] = { config.extra_script, cinfo->pfx, pid_str, NULL };
+       spawn_param_s param = { .fn = spawn_setstdout, .u.int_val = STDERR_FILENO };
+       return spawn(av, NULL, &param, pid, NULL);
+
+out:
+       return false;
+}
+
 static void launch_dbus_notify(struct crash_info *cinfo)
 {
        assert(cinfo);
@@ -1198,8 +1214,8 @@ int main(int argc, char *argv[])
 {
        struct crash_info cinfo = {.prstatus_fd = -1};
 
-       /* Execute dump_systemstate in parallel */
-       static pid_t dump_state_pid;
+       /* Execute processes in parallel */
+       static pid_t dump_state_pid = 0, extra_script_pid = 0;
        int debug_mode = access(DEBUGMODE_PATH, F_OK) == 0;
        int res = 0;
 
@@ -1248,6 +1264,9 @@ int main(int argc, char *argv[])
                        _E("Failed to get system state report");
                        goto exit;
                }
+
+               if (config.extra_script && !extra_script(&cinfo, &extra_script_pid))
+                       _W("Failed to call extra script from config");
        }
 
        /* Exec crash modules */
@@ -1261,8 +1280,10 @@ int main(int argc, char *argv[])
                /* Save shared objects info (file names, bulid IDs, rpm package names) */
                save_so_info(&cinfo);
 
-               /* Wait dump_system_state */
+               /* Wait misc. pids */
                wait_for_pid(dump_state_pid, NULL);
+               if (extra_script_pid > 0)
+                       wait_for_pid(extra_script_pid, NULL);
 
                /* Tar compression */
                if (config.allow_zip)
index 82f5b91..c485527 100644 (file)
@@ -14,3 +14,8 @@ AllowZip=yes
 # Dump coredump - 1 to enable (default), 0 to disable
 # This option applies to ReportType=FULL only!
 # DumpCore=1
+
+# Extra script to run whose output will be attached to generated report
+# Script will be called with two arguments, in pseudo-code:
+#   sh -c "$ExtraScript /path/to/report/temp/directory PID"
+# ExtraScript=/path/to/script
index 617a151..2bd7c7c 100644 (file)
@@ -68,6 +68,11 @@ bool config_init(config_t *c, const char *const path)
        if (!c->crash_root_path)
                goto out;
 
+       /* strdup() can technically fail, but we don't mind. It is better to
+        * create a report without the extra script than to abort completely. */
+       char *extrascript = GET(string, "ExtraScript", NULL);
+       c->extra_script = extrascript ? strdup(extrascript) : NULL;
+
        char *reptype = GET(string, "ReportType", (char *)report_type_strmap[REP_TYPE_FULL]);
        c->report_type = report_type_from_str(reptype);
        if (!report_type_to_str(c->report_type))
index 7105341..5c3ea1f 100644 (file)
@@ -46,6 +46,7 @@ typedef struct config {
        int dump_core;
        enum ReportType report_type;
        char *crash_root_path;
+       char *extra_script;
 } config_t;
 
 
index 07a676b..da31257 100644 (file)
@@ -37,6 +37,7 @@ configure_test("log_dump_normal")
 configure_test("log_dump_crash_root_path")
 configure_test("dump_systemstate_extras")
 configure_test("livedumper")
+configure_test("extra_script")
 
 get_property(TESTS_LIST GLOBAL PROPERTY TMP_TESTS_LIST)
 
diff --git a/tests/system/extra_script/extra_script.sh.template b/tests/system/extra_script/extra_script.sh.template
new file mode 100644 (file)
index 0000000..1c8fe5e
--- /dev/null
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# Custom report path test
+
+if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then
+    CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@"
+fi
+
+. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh
+
+CRASH_MANAGER_CONF=/etc/crash-manager.conf
+
+S=$(mktemp /tmp/extra.XXXXXX)
+cat >$S <<EOF
+#!/bin/sh
+echo pid is \$2 > \$1/cookie
+EOF
+
+chmod 755 $S
+
+mount -o rw,remount /
+mount -o exec,remount /tmp
+backup_file ${CRASH_MANAGER_CONF}
+cat ${CRASH_MANAGER_CONF}.backup | sed "s|#[ ]\+ExtraScript=.*|ExtraScript=${S}|" > ${CRASH_MANAGER_CONF}
+
+clean_crash_dump
+
+{
+    ${CRASH_WORKER_SYSTEM_TESTS}/utils/kenny &
+    sleep 1
+    kill -6 $!
+} 1> /dev/null 2>&1
+
+sleep 2
+
+restore_file ${CRASH_MANAGER_CONF}
+
+wait_for_app crash-manager
+
+dumpfile="$(echo $CRASH_DUMP_PATH/kenny_*.zip)"
+check_file_exists "$dumpfile"
+check_zip_contains "$dumpfile" '.*log$'
+check_zip_contains "$dumpfile" '.*info$'
+check_zip_contains "$dumpfile" '.*cookie$'
+
+exit_with_code "SUCCESS" ${SUCCESS_CODE}