Move crash-manager config handling to shared/ 29/203429/6
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Fri, 12 Apr 2019 10:25:31 +0000 (12:25 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Thu, 18 Apr 2019 10:24:34 +0000 (12:24 +0200)
Certain configuration variables are needed by (at least) log_dump.

Change-Id: Ic4b2732b261c1d03215cf0ac14db5264c9b517fb

src/crash-manager/CMakeLists.txt
src/crash-manager/crash-manager.c
src/shared/config.c [new file with mode: 0644]
src/shared/config.h [new file with mode: 0644]

index 49ae92b..b06e32a 100644 (file)
@@ -8,6 +8,7 @@ SET(CRASH_MANAGER_SRCS
        dbus_notify.c
        ${CMAKE_SOURCE_DIR}/src/shared/util.c
        ${CMAKE_SOURCE_DIR}/src/shared/spawn.c
+       ${CMAKE_SOURCE_DIR}/src/shared/config.c
    )
 
 INCLUDE(FindPkgConfig)
index 0198901..f82ab25 100644 (file)
 #include "defs.h"
 #include "dbus_notify.h"
 #include "shared/log.h"
+#include "shared/config.h"
 #include "shared/spawn.h"
 #include "shared/util.h"
 #include "so-info.h"
 
 /* Parsing */
 #define KEY_MAX              255
-#define CRASH_SECTION        "CrashManager"
 
 /* Crash-popup dbus */
 #define POPUP_BUS_NAME       "org.tizen.system.popup"
 #define POPUP_INTERFACE_NAME POPUP_BUS_NAME".Crash"
 #define POPUP_METHOD         "PopupLaunch"
 
-/* Configuration default values */
-/* note: 0 means unlimited */
-#define SYSTEM_MAX_USE       0
-#define SYSTEM_KEEP_FREE     0
-#define MAX_RETENTION_SEC    0
-#define MAX_CRASH_DUMP       0
-#define DUMP_CORE            1
-#define ALLOW_ZIP            true
-
 #define APPID_MAX                   128
 #define PKGNAME_MAX                 128
 
@@ -85,16 +76,6 @@ enum {
        USAGE_EXCEED
 };
 
-enum {
-       REP_TYPE_INFO = 0,
-       REP_TYPE_FULL
-};
-
-#define REP_DEFAULT_TYPE REP_TYPE_FULL
-
-#define REP_TYPE_FULL_STR "FULL"
-#define REP_TYPE_INFO_STR "INFO"
-
 struct file_info {
        bool   isdir;
        size_t size;
@@ -103,16 +84,9 @@ struct file_info {
 };
 
 /* Configuration variables */
-static int system_max_use;
-static int system_keep_free;
-static int max_retention_sec;
-static int max_crash_dump;
-static int dump_core;
-static bool allow_zip;
-static char* crash_root_path;
+config_t config;
 static char* crash_crash_path;
 static char* crash_temp_path;
-static int report_type;
 
 /* Paths and variables */
 struct crash_info {
@@ -228,176 +202,24 @@ out:
 static int prepare_paths(void)
 {
        int tmp_len;
-       tmp_len = strlen(crash_root_path) + strlen(CRASH_PATH_SUBDIR);
+       tmp_len = strlen(config.crash_root_path) + strlen(CRASH_PATH_SUBDIR);
        crash_crash_path = (char*)malloc(tmp_len + 1);
        if (crash_crash_path == NULL) {
                _E("Couldn't allocate memory for crash_crash_path: %m\n");
                return 0;
        }
-       snprintf(crash_crash_path, tmp_len + 1, "%s%s", crash_root_path, CRASH_PATH_SUBDIR);
+       snprintf(crash_crash_path, tmp_len + 1, "%s%s", config.crash_root_path, CRASH_PATH_SUBDIR);
 
-       tmp_len = strlen(crash_root_path) + strlen(CRASH_TEMP_SUBDIR);
+       tmp_len = strlen(config.crash_root_path) + strlen(CRASH_TEMP_SUBDIR);
        crash_temp_path = (char*)malloc(tmp_len + 1);
        if (crash_temp_path == NULL) {
                _E("Couldn't allocate memory for crash_temp_path: %m\n");
                return 0;
        }
-       snprintf(crash_temp_path, tmp_len + 1, "%s%s", crash_root_path, CRASH_TEMP_SUBDIR);
+       snprintf(crash_temp_path, tmp_len + 1, "%s%s", config.crash_root_path, CRASH_TEMP_SUBDIR);
        return 1;
 }
 
-static const char* report_type_to_str(const int report_type)
-{
-       switch (report_type) {
-       case REP_TYPE_INFO:
-               return REP_TYPE_INFO_STR;
-               break;
-       case REP_TYPE_FULL:
-               return REP_TYPE_FULL_STR;
-       default:
-               return NULL;
-               break;
-       }
-}
-
-static int report_type_from_str(const char* report_type_str)
-{
-       if (report_type_str == NULL)
-               return -1;
-
-       if (strncmp(report_type_str, REP_TYPE_FULL_STR, strlen(REP_TYPE_FULL_STR)) == 0)
-               return REP_TYPE_FULL;
-       else if (strncmp(report_type_str, REP_TYPE_INFO_STR, strlen(REP_TYPE_INFO_STR)) == 0)
-               return REP_TYPE_INFO;
-
-       return -1;
-}
-
-static int get_config(void)
-{
-       dictionary *ini = NULL;
-       char key[KEY_MAX];
-       int value;
-       int result = 1;
-       char *value_str;
-
-       system_max_use = SYSTEM_MAX_USE;
-       system_keep_free = SYSTEM_KEEP_FREE;
-       max_retention_sec = MAX_RETENTION_SEC;
-       max_crash_dump = MAX_CRASH_DUMP;
-       dump_core = DUMP_CORE;
-       allow_zip = ALLOW_ZIP;
-       crash_root_path = strdup(CRASH_ROOT_PATH);
-       if (crash_root_path == NULL) {
-               _E("strdup error: %m\n");
-               return -1;
-       }
-       report_type = REP_DEFAULT_TYPE;
-
-       ini = iniparser_load(CRASH_MANAGER_CONFIG_PATH);
-       if (!ini) {
-               _E("Failed to load conf file %s", CRASH_MANAGER_CONFIG_PATH);
-               return 0;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "SystemMaxUse");
-       value = iniparser_getint(ini, key, -1);
-       if (value < 0) {
-               _D("Invalid value for SystemMaxUse. Use default value [ %d kbyte]",
-                               SYSTEM_MAX_USE);
-       } else {
-               _D("SystemMaxUse [ %d kbyte]", value);
-               system_max_use = value;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "SystemKeepFree");
-       value = iniparser_getint(ini, key, -1);
-       if (value < 0) {
-               _D("Invalid value for SystemKeepFree. Use default value [ %d kbyte]",
-                               SYSTEM_KEEP_FREE);
-       } else {
-               _D("SystemKeepFree [ %d kbyte]", value);
-               system_keep_free = value;
-       }
-
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "MaxRetentionSec");
-       value = iniparser_getint(ini, key, -1);
-       if (value < 0) {
-               _D("Invalid value for MaxRetentionSec. Use default value [ %d ]",
-                               MAX_RETENTION_SEC);
-       } else {
-               _D("MaxRetentionSec [ %d ]", value);
-               max_retention_sec = value;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "MaxCrashDump");
-       value = iniparser_getint(ini, key, -1);
-       if (value < 0) {
-               _D("Invalid value for MaxCrashDump. Use default value [ %d ]",
-                               MAX_CRASH_DUMP);
-       } else {
-               _D("MaxCrashDump [ %d ]", value);
-               max_crash_dump = value;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "DumpCore");
-       value = iniparser_getint(ini, key, -1);
-       if (value != 0 && value != 1) {
-               _D("Invalid value for DumpCore default value [ %d ]",
-                               DUMP_CORE);
-       } else {
-               _D("DumpCore [ %d ]", value);
-               dump_core = value;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "AllowZip");
-       value = iniparser_getboolean(ini, key, -1);
-       if (value < 0) {
-               _D("Invalid value for AllowZip. Use default value [ %s ]",
-                               ALLOW_ZIP ? "true" : "false");
-       } else {
-               _D("AllowZip [ %s ]", value ? "true" : "false");
-               allow_zip = value;
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "CrashRootPath");
-       value_str = iniparser_getstring(ini, key, NULL);
-       if (value_str == NULL) {
-               _D("Invalid value for CrashRootPath. Use default value [ %s ]",
-                               CRASH_ROOT_PATH);
-       } else {
-               _D("CrashRootPath [ %s ]", value_str);
-               free(crash_root_path);
-               crash_root_path = strdup(value_str);
-               if (crash_root_path == NULL) {
-                       _E("strdup error: %m\n");
-                       result = -1;
-                       goto out;
-               }
-       }
-
-       snprintf(key, sizeof(key), "%s:%s", CRASH_SECTION, "ReportType");
-       value_str = iniparser_getstring(ini, key, NULL);
-       if (value_str == NULL) {
-               _D("Invalid value for ReportType. Use default value [ %s ]",
-                               report_type_to_str(report_type));
-       } else {
-               _D("ReportType [ %s ]", value_str);
-               report_type = report_type_from_str(value_str);
-
-               if (report_type < 0) {
-                       _E("Unknown ReportType %s. Fallback to default: %s",
-                          value_str, report_type_to_str(REP_DEFAULT_TYPE));
-                       report_type = REP_DEFAULT_TYPE;
-               }
-       }
-
-out:
-       iniparser_freedict(ini);
-       return result;
-}
-
 static int make_dump_dir(void)
 {
        struct stat st;
@@ -534,7 +356,7 @@ static int set_crash_info(struct crash_info *cinfo, int argc, char *argv[])
                goto rm_temp;
        }
 
-       if (allow_zip)
+       if (config.allow_zip)
                ret = asprintf(&cinfo->result_path,
                                "%s/%s.zip", crash_crash_path, cinfo->name);
        else
@@ -784,7 +606,7 @@ static bool execute_minicoredump(struct crash_info *cinfo, int *exit_code)
 
        /* Minicoredumper must be executed to dump at least PRSTATUS for
           other tools, coredump, however, might have been disabled. */
-       if (!dump_core) {
+       if (!config.dump_core) {
                if (remove_file_in_dir(cinfo->pfx, coredump_name) != 0)
                        _E("Saving core disabled - removing coredump %s/%s failed: %m",
                           cinfo->pfx, coredump_name);
@@ -1039,32 +861,32 @@ static void clean_dump(void)
                remove_flag = 0;
 
                /* Retention time check */
-               if (max_retention_sec &&
+               if (config.max_retention_sec &&
                        dump_list[i].mtime > 0 &&
-                       dump_list[i].mtime + max_retention_sec < cur_time)
+                       dump_list[i].mtime + config.max_retention_sec < cur_time)
                        remove_flag = RET_EXCEED;
                /* Check the number of dumps */
-               else if (max_crash_dump &&
-                       0 < dump_num && max_crash_dump < dump_num)
+               else if (config.max_crash_dump &&
+                       0 < dump_num && config.max_crash_dump < dump_num)
                        remove_flag = NUM_EXCEED;
                /* Check the max system use size */
-               else if (system_max_use &&
-                       0 < dump_num && system_max_use < usage / 1024)
+               else if (config.system_max_use &&
+                       0 < dump_num && config.system_max_use < usage / 1024)
                        remove_flag = USAGE_EXCEED;
 
                switch (remove_flag) {
                case RET_EXCEED:
                        _I("Reached the maximum retention time %d, so remove (%s)",
-                                       max_retention_sec, dump_list[i].path);
+                                       config.max_retention_sec, dump_list[i].path);
                        break;
                case NUM_EXCEED:
                        _I("Reached the maximum number of dump %d/%d, so remove (%s)",
-                                       dump_num, max_crash_dump,
+                                       dump_num, config.max_crash_dump,
                                        dump_list[i].path);
                        break;
                case USAGE_EXCEED:
                        _I("Reached the maximum disk usage %" PRId64 "/%d kb, so remove (%s)",
-                                       usage / 1024, system_max_use,
+                                       usage / 1024, config.system_max_use,
                                        dump_list[i].path);
                        break;
                default:
@@ -1083,11 +905,11 @@ static void clean_dump(void)
        }
 
        /* Check disk free space to keep */
-       if (system_keep_free &&
-                       check_disk_available(crash_root_path,
-                                            system_keep_free) < 0) {
+       if (config.system_keep_free &&
+                       check_disk_available(config.crash_root_path,
+                                            config.system_keep_free) < 0) {
                _I("Disk is not available! so set the maximum number of dump to 1");
-               max_crash_dump = 1;
+               config.max_crash_dump = 1;
        }
 
        for (i = 0; i < dump_num; i++)
@@ -1152,14 +974,14 @@ static int wait_for_opt(unsigned int timeout)
 {
        unsigned int count = 0;
 
-       while (check_disk_available(crash_root_path, 0) < 0 && count < timeout) {
-               log_kmsg("crash-manager: path %s is not available\n", crash_root_path);
+       while (check_disk_available(config.crash_root_path, 0) < 0 && count < timeout) {
+               log_kmsg("crash-manager: path %s is not available\n", config.crash_root_path);
                sleep(1);
                count++;
        }
        if (count >= timeout) {
                log_kmsg("crash-manager: timeout (%ds) while waiting for %s."
-                       "Probably /opt is not mounted.\n", timeout, crash_root_path);
+                       "Probably /opt is not mounted.\n", timeout, config.crash_root_path);
                return 0;
        }
 
@@ -1197,13 +1019,11 @@ int main(int argc, char *argv[])
         * value that prevents from running crash-manager recursively.
         */
 
-       /* Get Configuration */
-       if (get_config() < 0) {
+       if (!config_init(&config, CRASH_MANAGER_CONFIG_PATH)) {
                res = EXIT_FAILURE;
                goto exit;
        }
 
-       /* Prepare paths */
        if (!prepare_paths()) {
                res = EXIT_FAILURE;
                goto exit;
@@ -1231,7 +1051,7 @@ int main(int argc, char *argv[])
        get_sysassert_cs(&cinfo);
 #endif
 
-       if (report_type >= REP_TYPE_FULL) {
+       if (config.report_type >= REP_TYPE_FULL) {
                /* Exec dump_systemstate */
                if (!dump_system_state(&cinfo, &dump_state_pid)) {
                        res = EXIT_FAILURE;
@@ -1247,7 +1067,7 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       if (report_type >= REP_TYPE_FULL) {
+       if (config.report_type >= REP_TYPE_FULL) {
                /* Save shared objects info (file names, bulid IDs, rpm package names) */
                save_so_info(&cinfo);
 
@@ -1255,7 +1075,7 @@ int main(int argc, char *argv[])
                wait_for_pid(dump_state_pid, NULL);
 
                /* Tar compression */
-               if (allow_zip)
+               if (config.allow_zip)
                        compress(&cinfo);
                else
                        move_dump_data(cinfo.pfx, &cinfo);
@@ -1306,8 +1126,8 @@ exit:
        if (cinfo.prstatus_fd >= 0)
                close(cinfo.prstatus_fd);
        free(crash_temp_path);
-       free(crash_root_path);
        free(crash_crash_path);
+       config_free(&config);
 
        free_crash_info(&cinfo);
 
diff --git a/src/shared/config.c b/src/shared/config.c
new file mode 100644 (file)
index 0000000..617a151
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * crash-manager
+ * Copyright (c) 2019 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.
+ */
+#include <assert.h>
+#include <iniparser.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "defs.h"
+#include "log.h"
+#include "util.h"
+
+static const char *const report_type_strmap[] = {
+       [REP_TYPE_INFO] = "INFO",
+       [REP_TYPE_FULL] = "FULL",
+};
+
+static const char *report_type_to_str(enum ReportType report_type)
+{
+       if (report_type < 0 || report_type >= ARRAY_SIZE(report_type_strmap))
+               return NULL;
+       return report_type_strmap[report_type];
+}
+
+enum ReportType report_type_from_str(const char *report_type_str)
+{
+       assert(report_type_str);
+
+       for (int i = 0; i < (int)ARRAY_SIZE(report_type_strmap); i++) {
+               if (0 == strcmp(report_type_str, report_type_strmap[i]))
+                       return (enum ReportType)i;
+       }
+
+       return REP_TYPE_INVALID;
+}
+
+bool config_init(config_t *c, const char *const path)
+{
+       assert(c);
+       assert(path);
+
+       dictionary *ini = iniparser_load(path);
+       if (!ini) {
+               _E("Failed to load config file %s", path);
+               return false;
+       }
+
+       bool ret = false;
+
+#define GET(type, key, defval) iniparser_get##type(ini, CRASH_SECTION ":" key, defval)
+
+       c->crash_root_path = strdup(GET(string, "CrashRootPath", CRASH_ROOT_PATH));
+       if (!c->crash_root_path)
+               goto out;
+
+       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))
+               goto out;
+
+       c->system_max_use = GET(int, "SystemMaxUse", SYSTEM_MAX_USE);
+       c->system_keep_free = GET(int, "SystemKeepFree", SYSTEM_KEEP_FREE);
+       c->max_retention_sec = GET(int, "MaxRetentionSec", SYSTEM_MAX_USE);
+       c->max_crash_dump = GET(int, "MaxCrashDump", MAX_CRASH_DUMP);
+       c->dump_core = GET(boolean, "DumpCore", DUMP_CORE);
+       c->allow_zip = GET(boolean, "AllowZip", ALLOW_ZIP);
+
+#undef GET
+
+       ret = true;
+out:
+       iniparser_freedict(ini);
+       return ret;
+}
+
+void config_free(config_t *c)
+{
+       assert(c);
+
+       free(c->crash_root_path);
+}
diff --git a/src/shared/config.h b/src/shared/config.h
new file mode 100644 (file)
index 0000000..7105341
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * crash-manager
+ * Copyright (c) 2019 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.
+ */
+#ifndef __DEF_CONFIG_H_
+#define __DEF_CONFIG_H_
+
+#include <stdbool.h>
+
+/* Configuration default values */
+/* note: 0 means unlimited */
+#define SYSTEM_MAX_USE       0
+#define SYSTEM_KEEP_FREE     0
+#define MAX_RETENTION_SEC    0
+#define MAX_CRASH_DUMP       0
+#define DUMP_CORE            1
+#define ALLOW_ZIP            1
+
+#define CRASH_SECTION        "CrashManager"
+
+enum ReportType {
+       REP_TYPE_INVALID = -1,
+       REP_TYPE_INFO = 0,
+       REP_TYPE_FULL,
+       REP_TYPE_DEFAULT = REP_TYPE_FULL,
+};
+
+typedef struct config {
+       bool allow_zip;
+       int system_max_use;
+       int system_keep_free;
+       int max_retention_sec;
+       int max_crash_dump;
+       int dump_core;
+       enum ReportType report_type;
+       char *crash_root_path;
+} config_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool config_init(config_t *c, const char *const path);
+void config_free(config_t *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+#endif