config: Search for configuration also under crash-manager.conf.d directory 73/220173/5
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 18 Dec 2019 09:41:09 +0000 (10:41 +0100)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 18 Dec 2019 14:57:36 +0000 (15:57 +0100)
Change-Id: I9c5680eafb467a0514feec5225cb794609ba1823

packaging/crash-worker.spec
src/crash-manager/CMakeLists.txt
src/crash-manager/crash-manager.conf.d.example [new file with mode: 0644]
src/shared/config.c
tests/system/crash_root_path/crash_root_path.sh.template

index 08bcafb..1557f20 100644 (file)
@@ -161,6 +161,7 @@ mkdir -p %{buildroot}%{crash_temp}
 %dir %{crash_path}
 %dir %{crash_temp}
 %{_sysconfdir}/crash-manager.conf
+%{_sysconfdir}/crash-manager.conf.d/crash-manager.conf.example
 %attr(-,root,root) %{_prefix}/lib/sysctl.d/70-crash-manager.conf
 %attr(0750,crash_worker,crash_worker) %{_bindir}/crash-manager
 %attr(0750,crash_worker,crash_worker) %{_bindir}/dump_systemstate
index 591a3ad..2fdf2a2 100644 (file)
@@ -69,6 +69,11 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.conf
                DESTINATION /etc
                PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
 
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.conf.d.example
+               DESTINATION /etc/crash-manager.conf.d/
+               PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
+               RENAME crash-manager.conf.example)
+
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/${PROJECT_NAME}/crash-manager.pc
                DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
                PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
diff --git a/src/crash-manager/crash-manager.conf.d.example b/src/crash-manager/crash-manager.conf.d.example
new file mode 100644 (file)
index 0000000..b50dbff
--- /dev/null
@@ -0,0 +1,3 @@
+# Rename this file to end with .conf for it to be read by crash-manager
+[CrashManager]
+DumpCore=0
index 1e728c4..901bab0 100644 (file)
  * limitations under the License.
  */
 #include <assert.h>
+#include <dirent.h>
+#include <fcntl.h>
 #include <iniparser.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include "config.h"
 #include "defs.h"
@@ -112,6 +116,63 @@ static bool config_load_from_path(config_t *c, const char *const path)
        return ret;
 }
 
+static int entry_filter(const struct dirent *e)
+{
+       assert(e);
+
+       const char *const conf_suffix = ".conf";
+       const char *const name = e->d_name;
+       int len = strlen(name);
+
+       if (e->d_type != DT_REG || len <= strlen(conf_suffix))
+               return 0;
+
+       // accept only files ending with predefined suffix
+       return strcmp(name + len - strlen(conf_suffix), conf_suffix) == 0;
+}
+
+static bool config_load_from_dir_prefix(config_t *c, const char *const dir_prefix)
+{
+       assert(dir_prefix);
+
+       char dir_path[PATH_MAX];
+       int ret = snprintf(dir_path, sizeof(dir_path), "%s.d", dir_prefix);
+       if (ret < 0 || ret >= PATH_MAX) {
+               _W("config: internal error while trying to prepare config dir path");
+               return false;
+       }
+
+       int fd = open(dir_path, O_RDONLY | O_DIRECTORY);
+       if (fd < 0 && errno == ENOENT)
+               return true;
+       if (fd < 0) {
+               _E("config: Unable to access config directory at %s: %m", dir_path);
+               return false;
+       }
+
+       struct dirent **entries = NULL;
+       int n = scandirat(fd, ".", &entries, entry_filter, alphasort);
+       if (n < 0)
+               goto out;
+
+       for (int i = 0; i < n; ++i) {
+               char file_path[PATH_MAX];
+               const char *fname = entries[i]->d_name;
+               ret = snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, fname);
+               if (ret < 0 || ret >= PATH_MAX) {
+                       _W("config: internal error while trying to prepare for reading %s config file", fname);
+                       continue;
+               }
+               _D("config: reading additional configuration file from %s", file_path);
+               (void)config_load_from_path(c, file_path);
+       }
+
+out:
+       free(entries);
+       close(fd);
+       return true;
+}
+
 static bool config_apply_defaults(config_t *c)
 {
        assert(c);
@@ -161,6 +222,8 @@ bool config_init(config_t *c, const char *const path)
                return false;
        }
 
+       (void)config_load_from_dir_prefix(c, path);
+
        config_dump(c);
 
        return true;
index 0f59b55..7fe5e96 100644 (file)
@@ -8,7 +8,9 @@ fi
 
 . ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh
 
-CRASH_MANAGER_CONF=/etc/crash-manager.conf
+CONF_DIR=/etc/crash-manager.conf.d
+CONF_FILE=${CONF_DIR}/crash-root-path-test.conf
+
 NEW_PATH=/tmp/crash_path_test/
 if [ ! -d ${NEW_PATH} ]; then
     mkdir ${NEW_PATH}
@@ -23,8 +25,13 @@ function check_file_exists {
 }
 
 mount -o rw,remount /
-backup_file ${CRASH_MANAGER_CONF}
-cat ${CRASH_MANAGER_CONF}.backup | sed "s|#[ ]\+CrashRootPath=.*|CrashRootPath=${NEW_PATH}|" > ${CRASH_MANAGER_CONF}
+
+mkdir -p $CONF_DIR
+rm -f $CONF_FILE || :
+cat <<EOF >$CONF_FILE
+[CrashManager]
+CrashRootPath=${NEW_PATH}
+EOF
 
 {
     ${CRASH_WORKER_SYSTEM_TESTS}/utils/kenny &
@@ -34,10 +41,10 @@ cat ${CRASH_MANAGER_CONF}.backup | sed "s|#[ ]\+CrashRootPath=.*|CrashRootPath=$
 
 sleep 2
 
-restore_file ${CRASH_MANAGER_CONF}
-
 wait_for_app crash-manager
 
+rm -f ${CONF_FILE} || :
+
 pushd ${NEW_PATH}/dump
 if ! unzip kenny*zip > /dev/null; then
     popd