%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
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)
* 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"
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);
return false;
}
+ (void)config_load_from_dir_prefix(c, path);
+
config_dump(c);
return true;
. ${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}
}
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 &
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