cleanup: Add "target" option for cleanup config 03/230603/5 accepted/tizen/unified/20200422.123202 submit/tizen/20200421.052338
authorYunmi Ha <yunmi.ha@samsung.com>
Mon, 13 Apr 2020 03:40:30 +0000 (12:40 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Thu, 16 Apr 2020 01:25:28 +0000 (10:25 +0900)
target has 3 options.
- all : delete all subfiles including the root path
- file : delete all subfiles excluding the root path
- oldfile : delete all old files which has "*.[0-9]" format

Change-Id: I4213be3c764272ebf2bed5e50c05f0d541ac88cc
Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
Signed-off-by: Hyotaek Shim <hyotaek.shim@samsung.com>
src/storage/cleanup.c
src/storage/cleanup_config.c
src/storage/cleanup_config.h
src/storage/sample-cleanup-storage.conf

index 55b61bf..5206aa8 100644 (file)
@@ -23,6 +23,7 @@
 #include <sys/stat.h>
 #include <gmodule.h>
 #include <limits.h>
+#include <regex.h>
 
 #include "log.h"
 #include "cleanup.h"
@@ -87,7 +88,7 @@ static int find_sub_except_item(const char *item, const char *path)
        return -1;
 }
 
-static int remove_path(const char *path, GList *except)
+static int remove_dir(const char *path, GList *except)
 {
        if (!path)
                return -EINVAL;
@@ -100,7 +101,31 @@ static int remove_path(const char *path, GList *except)
        return 0;
 }
 
-static int cleanup_recursive(const char *path, GList *except)
+static int remove_oldfile(const char *path)
+{
+       regex_t regex;
+       int ret = 0;
+
+       if (!path)
+               return -EINVAL;
+
+       ret = regcomp(&regex, "\\.[0-9]+$", REG_EXTENDED);
+       if (ret)
+               return -EINVAL;
+
+       if (!regexec(&regex, path, 0, NULL, 0)) {
+               if(remove(path) != 0) {
+                       _E("Failed to remove(%s): %d", path, errno);
+                       ret = -errno;
+               } else
+                       _D("Remove (%s)", path);
+       }
+       regfree(&regex);
+
+       return ret;
+}
+
+static int cleanup_recursive(const char *path, GList *except, int target)
 {
        DIR *dir = NULL;
        struct dirent *dent;
@@ -146,14 +171,16 @@ static int cleanup_recursive(const char *path, GList *except)
                        }
 
                        snprintf(sub_path, PATH_MAX, "%s/%s", path, dent->d_name);
-                       ret = cleanup_recursive(sub_path, except);
+                       ret = cleanup_recursive(sub_path, except, (target == CLEANUP_TARGET_OLDFILE)? target: CLEANUP_TARGET_ALL);
                        if (ret != 0)
                                break;
                }
                closedir(dir);
-               if (!ret)
-                       ret = remove_path(path, except);
-       } else
+               if (!ret && (target == CLEANUP_TARGET_ALL))
+                       ret = remove_dir(path, except);
+       } else if (target == CLEANUP_TARGET_OLDFILE)
+               remove_oldfile(path);
+       else
                REMOVE(path);
 
        return ret;
@@ -242,10 +269,10 @@ void *cleanup_storage_start(void *arg)
                list_config = get_cleanup_config(request->cleanup_mode);
                for (list= g_list_first(list_config); NULL != list; list = g_list_next(list)) {
                        config = list->data;
+                       _D("config path:%s, target:%d", config->path, config->target);
                        if (request->level <= config->level)
-                               cleanup_recursive(config->path, config->exclusion_list);
+                               cleanup_recursive(config->path, config->exclusion_list, config->target);
                }
-
                remove_request_queue(request);
        }
        cleanup_th = 0;
@@ -264,7 +291,7 @@ void cleanup_storage(enum tzplatform_variable path_id, int level)
        else if (path_id == TZ_SYS_USER)
                type = CLEANUP_TYPE_USER;
        else {
-               _D("Not supported path type: %d", path_id);
+               _D("Not supported path type: %s", tzplatform_getname(path_id));
                return ;
        }
 
index 2717992..8a1d82b 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <unistd.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <json-c/json.h>
 #include <tzplatform_config.h>
 
@@ -29,6 +30,12 @@ char *cleanup_level_str[] = {
        "normal"
 };
 
+char *cleanup_target_str[] = {
+       "all",
+       "file",
+       "oldfile"
+};
+
 #define DEF_CLEANUP_CONFIG_FILE     "/etc/storaged/cleanup-storage.conf"
 #define RESULT(ret, val)       \
 { \
@@ -36,6 +43,13 @@ char *cleanup_level_str[] = {
                *ret = val;                     \
 }
 
+#define FREE(x)                \
+{ \
+       if (x)                  \
+               free(x);        \
+       x = NULL;               \
+}
+
 static GList *cleanup_list_system = NULL;
 static GList *cleanup_list_user = NULL;
 
@@ -44,7 +58,7 @@ static void free_config_item(void *data)
        struct cleanup_config *item = data;
 
        if (item->path) {
-               free(item->path);
+               free((void *)item->path);
                item->path = NULL;
        }
 
@@ -69,14 +83,18 @@ void free_cleanup_config()
        }
 }
 
-static int get_config_string_field(struct json_object *root, const char *key, char** value)
+static int get_config_string_field(struct json_object *root, const char *key, const char** value, bool optional)
 {
        struct json_object *node = NULL;
        const char *node_value;
 
        if (!json_object_object_get_ex(root, key, &node)) {
-               _D("Config doesn't contain path param.");
-               return 0;
+               if (optional)
+                       _D("Config doesn't contain '%s' param.", key);
+               else
+                       _E("Config doesn't contain '%s' param.", key);
+
+               return (optional)? 0: -EINVAL;
        }
 
        if (!json_object_is_type(node, json_type_string)) {
@@ -94,7 +112,7 @@ static int get_config_string_field(struct json_object *root, const char *key, ch
        return 0;
 }
 
-static GList *get_config_array_field(struct json_object *root, const char *key, int *ret)
+static GList *get_config_array_field(struct json_object *root, const char *key, int *ret, bool optional)
 {
        struct json_object *node = NULL, *obj;
        int i, len;
@@ -103,8 +121,12 @@ static GList *get_config_array_field(struct json_object *root, const char *key,
        GList *list = NULL;
 
        if (!json_object_object_get_ex(root, key, &node)) {
-               _D("Config doesn't contain '%s' param.", key);
-               RESULT(ret, 0);
+               if (optional)
+                       _D("Config doesn't contain '%s' param.", key);
+               else
+                       _E("Config doesn't contain '%s' param.", key);
+
+               RESULT(ret, (optional)? 0: -EINVAL);
                return NULL;
        }
 
@@ -152,12 +174,29 @@ static int get_cleanup_level(const char *level_str)
                return -EINVAL;
 
        for (i = 0; i< CLEANUP_LEVEL_NONE; i++) {
-               if (strcmp(level_str, cleanup_level_str[i]) == 0)
+               if (strcasecmp(level_str, cleanup_level_str[i]) == 0) {
+                       ret = i;
                        break;
+               }
        }
 
-       if (i < CLEANUP_LEVEL_NONE)
-               ret = i;
+       return ret;
+}
+
+static int get_cleanup_target(const char *target_str)
+{
+       int ret = -EINVAL;
+       int i;
+
+       if (target_str == NULL)
+               return -EINVAL;
+
+       for (i = 0; i< CLEANUP_TARGET_END; i++) {
+               if (strcasecmp(target_str, cleanup_target_str[i]) == 0) {
+                       ret = i;
+                       break;
+               }
+       }
 
        return ret;
 }
@@ -172,26 +211,36 @@ static int add_config_item(struct json_object *obj, struct cleanup_config *item)
                return -EINVAL;
        }
 
-       if (get_config_string_field(obj, "level", &temp) != 0) {
-               _E("There is no level node.");
-               return -EINVAL;
+       if ((ret = get_config_string_field(obj, "level", (const char **)&temp, false)) != 0) {
+               return ret;
        }
 
        item->level = get_cleanup_level(temp);
-       free(temp);
+       FREE(temp);
 
        if (item->level < 0) {
                _E("Invalid level value.");
                return -EINVAL;
        }
 
-       if (get_config_string_field(obj, "path", &item->path) != 0)
-               return -EINVAL;
+       if ((ret = get_config_string_field(obj, "path", &item->path, false)) != 0)
+               return ret;
 
-       //todo.
-       //check duplicated path
+       if ((ret = get_config_string_field(obj, "target", (const char **)&temp, true)) != 0) {
+               return ret;
+       }
+
+       if (temp) {
+               item->target = get_cleanup_target(temp);
+               if((item->target < CLEANUP_TARGET_ALL) || (item->target >= CLEANUP_TARGET_END))
+                       item->target = CLEANUP_TARGET_ALL;
+               FREE(temp);
+       } else {
+               //_D("Use default 'target' : ALL");
+               item->target = CLEANUP_TARGET_ALL;
+       }
 
-       item->exclusion_list = get_config_array_field(obj, "except", &ret);
+       item->exclusion_list = get_config_array_field(obj, "except", &ret, true);
        if (ret != 0)
                return -EINVAL;
 
index c7614eb..c6595a6 100644 (file)
 #include <gmodule.h>
 
 enum cleanup_level {
-    CLEANUP_LEVEL_FULL = 0,
-    CLEANUP_LEVEL_CRITICAL,
-    CLEANUP_LEVEL_WARNING,
-    CLEANUP_LEVEL_NORMAL,
-    CLEANUP_LEVEL_NONE
+       CLEANUP_LEVEL_FULL = 0,
+       CLEANUP_LEVEL_CRITICAL,
+       CLEANUP_LEVEL_WARNING,
+       CLEANUP_LEVEL_NORMAL,
+       CLEANUP_LEVEL_NONE
+};
+
+enum cleanup_target {
+       CLEANUP_TARGET_ALL = 0,
+       CLEANUP_TARGET_FILE,
+       CLEANUP_TARGET_OLDFILE,
+       CLEANUP_TARGET_END
 };
 
 struct cleanup_config {
-    int     level;
-    char    *path;
-    GList   *exclusion_list;
+       int     level;
+       const char *path;
+       int     target;
+       GList   *exclusion_list;
 };
 
 int load_cleanup_config();
index 5325515..47302f3 100644 (file)
@@ -3,6 +3,7 @@
                {
                        "level":"critical",
                        "path":"/opt/val/test",
+                       "target":"all",
                        "except":[
                                "/opt/val/test/except1",
                                "/opt/val/test/except2"
        ],
        "/opt/usr":[
                {
-                       "level":"full",
-                       "path":"/opt/usr/logtest"
+                       "level":"warning",
+                       "path":"/opt/usr/etc/test/remain_root",
+                       "target":"file"
                },
                {
-                       "level":"full",
-                       "path":"/opt/usr/etc/test"
+                       "level":"warning",
+                       "path":"/opt/usr/etc/test/journal",
+                       "target":"all",
+                       "except":[
+                               "/opt/usr/etc/test/journal/except_dir",
+                               "/opt/usr/etc/test/journal/except_file"
+                       ]
                },
                {
-                       "level":"full",
-                       "path":"/opt/usr/etc/test_crash"
+                       "level":"warning",
+                       "path":"/opt/usr/etc/test/delete"
                },
                {
                        "level":"critical",
-                       "path":"/opt/usr/data/test_GL"
+                       "path":"/opt/usr/etc/test/critical"
+               },
+               {
+                       "level":"warning",
+                       "path":"/opt/usr/etc/test/log",
+                       "target":"oldfile",
+                       "except":[
+                               "/opt/usr/etc/test/log/exceptlog.1"
+                       ]
                }
        ]
 }