proc-stat : write appinfo into the file and exploit for restoring 87/94787/8
authorKichan Kwon <k_c.kwon@samsung.com>
Tue, 1 Nov 2016 07:11:14 +0000 (16:11 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Mon, 7 Nov 2016 04:54:25 +0000 (13:54 +0900)
- Current app information will be stored to /run/resourced/appinfo
- In there, each app has their own directory and store current state
- When resourced is restarted, proc module will read it and restore app information

Change-Id: I71b5a814615b928fd97194ebdae00cb15e902e65
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
src/common/file-helper.c
src/common/file-helper.h
src/common/proc-common.h
src/proc-stat/proc-main.c
src/resourced/init.c

index 055ed67..a5ff38e 100644 (file)
@@ -79,6 +79,22 @@ int fwrite_uint(const char *path, const u_int32_t number)
        return fwrite_str(path, digit_buf);
 }
 
+int fread_str(const char *path, char **str)
+{
+       _cleanup_fclose_ FILE *f = NULL;
+       int ret;
+
+       f = fopen(path, "r");
+       ret_value_errno_msg_if(!f, -errno,
+                       "Fail to open %s file.", path);
+
+       ret = fscanf(f, "%s", *str);
+       ret_value_errno_msg_if(ret == EOF, -errno,
+                       "Fail to read file\n");
+
+       return RESOURCED_ERROR_NONE;
+}
+
 int fread_int(const char *path, int32_t *number)
 {
        _cleanup_fclose_ FILE *f = NULL;
index e8cb7c8..96da0bc 100644 (file)
@@ -39,6 +39,8 @@ int fwrite_int(const char *path, const int number);
 
 int fwrite_uint(const char *path, const u_int32_t number);
 
+int fread_str(const char *path, char **str);
+
 int fread_int(const char *path, int32_t *number);
 
 int fread_uint(const char *path, u_int32_t *number);
index 5b89719..ec749a5 100644 (file)
@@ -33,6 +33,8 @@
 #include "const.h"
 #include "memory-common.h"
 
+#define RUNTIME_APP_INFO_DIR RUNTIME_RESOURCED_DIR"/appinfo"
+
 #define GPOINTER_TO_PID(x) (pid_t)GPOINTER_TO_INT((x))
 #define PID_TO_GPOINTER(x) GINT_TO_POINTER((pid_t)(x))
 
index 24cd325..32cc4c1 100644 (file)
  *
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #include <Ecore.h>
 #include <Ecore_File.h>
 #include <pthread.h>
@@ -43,6 +47,7 @@
 #include "procfs.h"
 #include "appinfo-list.h"
 #include "util.h"
+#include "file-helper.h"
 #include "config-parser.h"
 
 static GHashTable *proc_exclude_list;
@@ -65,8 +70,219 @@ static bool is_ui_app(enum application_type type)
        return false;
 }
 
+static char *proc_get_runtime_app_info_path(const struct proc_app_info *pai)
+{
+       char *p = NULL;
+
+       assert(pai);
+       assert(pai->appid);
+
+       if (asprintf(&p, RUNTIME_APP_INFO_DIR "/%s", pai->appid) < 0)
+               return NULL;
+
+       return p;
+}
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_WRITE_STR(node)                   \
+       int proc_runtime_app_info_write_##node(const char *path,        \
+                                              const char *data)        \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+               assert(data);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fwrite_str(app_info_node, data);                 \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_READ_STR(node)                    \
+       int proc_runtime_app_info_read_##node(const char *path,         \
+                                             char **data)              \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+               assert(data);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fread_str(app_info_node, data);  \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(node)                 \
+       int proc_runtime_app_info_write_##node(const char *path,        \
+                                              int32_t data)            \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fwrite_int(app_info_node, data);                 \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(node)                  \
+       int proc_runtime_app_info_read_##node(const char *path,         \
+                                             int32_t *data)            \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+               assert(data);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fread_int(app_info_node, data);  \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_WRITE_UINT32(node)                        \
+       int proc_runtime_app_info_write_##node(const char *path,        \
+                                              uint32_t data)           \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fwrite_uint(app_info_node, data);                \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_READ_UINT32(node)                 \
+       int proc_runtime_app_info_read_##node(const char *path,         \
+                                             uint32_t *data)           \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+                                                                       \
+               assert(path);                                           \
+               assert(data);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               return fread_uint(app_info_node, data); \
+       }
+
+#define DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(node)                      \
+       int proc_runtime_app_info_remove_##node(const char *path)       \
+       {                                                               \
+               char app_info_node[PATH_MAX] = "";                      \
+               int ret;                                                \
+                                                                       \
+               assert(path);                                           \
+                                                                       \
+               snprintf(app_info_node, PATH_MAX, "%s/"#node"", path);  \
+                                                                       \
+               ret = unlink(app_info_node);                            \
+               if (ret < 0)                                            \
+                       return -errno;                                  \
+                                                                       \
+               return ret;                                             \
+       }
+
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_STR(appid);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_STR(appid);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_UINT32(main_pid);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_UINT32(main_pid);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(runtime_exclude);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(runtime_exclude);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(flags);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(flags);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(lru_state);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(lru_state);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(categories);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(categories);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(state);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(state);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_INT32(type);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_INT32(type);
+DEFINE_PROC_RUNTIME_APP_INFO_WRITE_STR(pkgname);
+DEFINE_PROC_RUNTIME_APP_INFO_READ_STR(pkgname);
+
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(appid);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(procs);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(main_pid);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(runtime_exclude);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(flags);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(lru_state);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(categories);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(state);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(type);
+DEFINE_PROC_RUNTIME_APP_INFO_REMOVE(pkgname);
+
+static int proc_runtime_app_info_write_procs(const char *path, pid_list child_list)
+{
+       char app_info_node[PATH_MAX] = "";
+       _cleanup_fclose_ FILE *f = NULL;
+       pid_list list = child_list;
+
+       assert(path);
+
+       if (!child_list)
+               return 0;
+
+       snprintf(app_info_node, PATH_MAX, "%s/procs", path);
+
+       f = fopen(app_info_node, "w");
+       if (!f)
+               return -errno;
+
+       (void) fprintf(f, "%d", GPOINTER_TO_PID(child_list->data));
+
+       for (list = g_slist_next(list); list; list = g_slist_next(list))
+               (void) fprintf(f, " %d", GPOINTER_TO_PID(list->data));
+
+       return 0;
+}
+
+static int proc_runtime_app_info_read_procs(const char *path, pid_list *child_list)
+{
+       char app_info_node[PATH_MAX] = "";
+       _cleanup_free_ char *buf = NULL;
+       pid_list list = NULL;
+       char *word, *state;
+       size_t len;
+       int ret;
+
+       assert(path);
+       assert(child_list);
+
+       snprintf(app_info_node, PATH_MAX, "%s/procs", path);
+
+       ret = fread_str(app_info_node, &buf);
+       if (ret < 0)
+               return ret;
+
+       FOREACH_WORD(word, len, buf, state) {
+               _cleanup_free_ char *pid_s = NULL;
+               pid_t pid;
+
+               pid_s = strndup(word, len);
+               if (!pid_s)
+                       goto on_error;
+
+               pid = atoi(pid_s);
+
+               list = g_slist_prepend(list, PID_TO_GPOINTER(pid));
+       }
+
+       *child_list = list;
+
+       return 0;
+
+on_error:
+       g_slist_free(list);
+
+       return -ENOMEM;
+}
+
 void proc_add_child_pid(struct proc_app_info *pai, pid_t pid)
 {
+       _cleanup_free_ char *runtime_app_info_path = NULL;
+       int ret;
+
        assert(pai);
        assert(pid > 0);
 
@@ -75,6 +291,17 @@ void proc_add_child_pid(struct proc_app_info *pai, pid_t pid)
                return;
 
        pai->childs = g_slist_prepend(pai->childs, PID_TO_GPOINTER(pid));
+
+       runtime_app_info_path = proc_get_runtime_app_info_path(pai);
+       if (!runtime_app_info_path) {
+               _E("Failed to get runtime appinfo path: %s", strerror(ENOMEM));
+               return;
+       }
+
+       ret = proc_runtime_app_info_write_procs(runtime_app_info_path, pai->childs);
+       if (ret < 0)
+               _E("Failed to write appinfo children '%s': %s",
+                  runtime_app_info_path, strerror(-ret));
 }
 
 void proc_set_process_memory_state(struct proc_app_info *pai,
@@ -140,8 +367,10 @@ struct proc_program_info *find_program_info(const char *pkgname)
 
 resourced_ret_c proc_set_runtime_exclude_list(const int pid, int type)
 {
+       _cleanup_free_ char *runtime_app_info_path = NULL;
        struct proc_app_info *pai = NULL;
        struct proc_status ps = {0};
+       int ret;
 
        pai = find_app_info(pid);
        if (!pai)
@@ -163,6 +392,14 @@ resourced_ret_c proc_set_runtime_exclude_list(const int pid, int type)
        _D("pid %d set proc exclude list, type = %d, exclude = %d",
                    pid, type, pai->runtime_exclude);
 
+       runtime_app_info_path = proc_get_runtime_app_info_path(pai);
+       if (!runtime_app_info_path)
+               return RESOURCED_ERROR_OUT_OF_MEMORY;
+
+       ret = proc_runtime_app_info_write_runtime_exclude(runtime_app_info_path, pai->runtime_exclude);
+       if (ret < 0)
+               return RESOURCED_ERROR_FAIL;
+
        return RESOURCED_ERROR_NONE;
 }
 
@@ -215,6 +452,7 @@ struct proc_program_info *proc_add_program_list(const int type,
                        }
                }
                proc_program_list = g_slist_prepend(proc_program_list, ppi);
+               _I("%s is added in the program info", pkgname);
        }
        if (is_ui_app(type))
                ppi->app_list = g_slist_prepend(ppi->app_list, pai);
@@ -225,10 +463,134 @@ struct proc_program_info *proc_add_program_list(const int type,
        return ppi;
 }
 
+static int proc_runtime_write_app_info(const struct proc_app_info *pai)
+{
+       _cleanup_free_ char *runtime_app_info_path = NULL;
+       int ret;
+
+       assert(pai);
+       assert(pai->appid);
+
+       runtime_app_info_path = proc_get_runtime_app_info_path(pai);
+       if (!runtime_app_info_path)
+               return -ENOMEM;
+
+       ret = mkdir(runtime_app_info_path, S_IRWXU | S_IRGRP | S_IXGRP);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_appid(runtime_app_info_path, pai->appid);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_main_pid(runtime_app_info_path, pai->main_pid);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_procs(runtime_app_info_path, pai->childs);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_runtime_exclude(runtime_app_info_path, pai->runtime_exclude);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_flags(runtime_app_info_path, pai->flags);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_lru_state(runtime_app_info_path, pai->lru_state);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_categories(runtime_app_info_path, pai->categories);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_state(runtime_app_info_path, pai->state);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_write_type(runtime_app_info_path, pai->type);
+       if (ret < 0)
+               return ret;
+
+       if (!pai->program)
+               return 0;
+
+       return proc_runtime_app_info_write_pkgname(runtime_app_info_path, pai->program->pkgname);
+}
+
+static int proc_runtime_remove_app_info(const struct proc_app_info *pai)
+{
+       _cleanup_free_ char *runtime_app_info_path = NULL;
+       int ret;
+       DIR *dir;
+
+       assert(pai);
+       assert(pai->appid);
+
+       runtime_app_info_path = proc_get_runtime_app_info_path(pai);
+       if (!runtime_app_info_path)
+               return -ENOMEM;
+
+       dir = opendir(runtime_app_info_path);
+       if (!dir)
+               return -ENOTDIR;
+       closedir(dir);
+
+       ret = proc_runtime_app_info_remove_appid(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_main_pid(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_procs(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_runtime_exclude(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_flags(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_lru_state(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_categories(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_state(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_type(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+       ret = proc_runtime_app_info_remove_pkgname(runtime_app_info_path);
+       if (ret < 0 && ret != -ENOENT)
+               goto finish;
+
+finish:
+       if (rmdir(runtime_app_info_path) < 0)
+               return -errno;
+
+       return ret == -ENOENT ? 0 : ret;
+}
+
 struct proc_app_info *proc_add_app_list(const int type, const pid_t pid,
            const char *appid, const char *pkgname)
 {
        struct proc_app_info *pai;
+       int ret;
 
        if (!appid)
                return NULL;
@@ -250,13 +612,20 @@ struct proc_app_info *proc_add_app_list(const int type, const pid_t pid,
        pai->main_pid = pid;
        pai->program = proc_add_program_list(type, pai, pkgname);
        pai->state = PROC_STATE_FOREGROUND;
+
+       ret = proc_runtime_write_app_info(pai);
+       if (ret < 0)
+               _E("Failed to add runtime app info: %s", strerror(ret));
+
        return pai;
 }
 
 static void _remove_child_pids(struct proc_app_info *pai, pid_t pid)
 {
+       _cleanup_free_ char *runtime_app_info_path = NULL;
        GSList *iter, *next;
        pid_t *child;
+       int ret;
 
        assert(pai);
        assert(pid >= 0);
@@ -278,6 +647,37 @@ static void _remove_child_pids(struct proc_app_info *pai, pid_t pid)
 
        if (!g_slist_find(pai->childs, PID_TO_GPOINTER(pid)))
                return;
+
+       runtime_app_info_path = proc_get_runtime_app_info_path(pai);
+       if (!runtime_app_info_path) {
+               _E("Failed to get runtime appinfo path: %s", strerror(ENOMEM));
+               return;
+       }
+
+       if (pid == 0)
+               goto remove_all;
+
+       pai->childs = g_slist_remove(pai->childs, PID_TO_GPOINTER(pid));
+       if (!g_slist_length(pai->childs))
+               goto remove_all;
+
+       ret = proc_runtime_app_info_write_procs(runtime_app_info_path, pai->childs);
+       if (ret < 0)
+               _E("Failed to write appinfo children '%s': %s",
+                  runtime_app_info_path, strerror(-ret));
+
+       return;
+
+remove_all:
+       g_slist_free(pai->childs);
+       pai->childs = NULL;
+
+       ret = proc_runtime_app_info_remove_procs(runtime_app_info_path);
+       if (ret < 0)
+               _E("Failed to remove appinfo children '%s': %s",
+                  runtime_app_info_path, strerror(-ret));
+
+       return;
 }
 
 int proc_remove_app_list(const pid_t pid)
@@ -288,10 +688,17 @@ int proc_remove_app_list(const pid_t pid)
 
        gslist_for_each_item(iter, proc_app_list) {
                pai = (struct proc_app_info *)iter->data;
+               int ret;
+
                if (!pai->main_pid)
                        continue;
 
                if (pai->main_pid == pid) {
+                       ret = proc_runtime_remove_app_info(pai);
+                       if (ret < 0)
+                               _E("Failed to remove appinfo '%s': %s",
+                                  pai->appid, strerror(-ret));
+
                        _remove_child_pids(pai, 0);
                        ppi = pai->program;
                        if (ppi) {
@@ -627,8 +1034,114 @@ static void proc_module_exit(void *data)
        }
 }
 
+static int proc_restore_runtime_app_info(const char *path)
+{
+       _cleanup_free_ char *appid = NULL, *pkgname = NULL;
+       struct proc_app_info *pai;
+       int oom_score_adj = 0, ret;
+
+       ret = proc_runtime_app_info_read_appid(path, &appid);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_pkgname(path, &pkgname);
+       if (ret < 0)
+               return ret;
+
+       pai = proc_create_app_list(appid, pkgname);
+       if (!pai)
+               return ret;
+
+       ret = proc_runtime_app_info_read_main_pid(path, (uint32_t *) &pai->main_pid);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_get_oom_score_adj(pai->main_pid, &oom_score_adj);
+       if (ret < 0) {
+               _I("pid %d is already terminated. remove it", pai->main_pid);
+               proc_app_list = g_slist_remove(proc_app_list, pai);
+               resourced_appinfo_put(pai->ai);
+               free(pai);
+               return ret;
+       }
+       pai->memory.oom_score_adj = oom_score_adj;
+
+       ret = proc_runtime_app_info_read_runtime_exclude(path, &pai->runtime_exclude);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_flags(path, &pai->flags);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_lru_state(path, &pai->lru_state);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_categories(path, &pai->categories);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_state(path, (int32_t *) &pai->state);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_type(path, (int32_t *) &pai->type);
+       if (ret < 0)
+               return ret;
+
+       ret = proc_runtime_app_info_read_procs(path, &pai->childs);
+       if (ret < 0 && ret != -ENOENT)
+               return ret;
+
+       pai->program = proc_add_program_list(pai->type, pai, pkgname);
+
+       _I("runtime appinfo restored: %s, %s", appid, pkgname);
+
+       return 0;
+}
+
+static void proc_restore_runtime_app_list(void)
+{
+       _cleanup_closedir_ DIR *dp = NULL;
+       struct dirent dentry;
+       struct dirent *dir;
+
+       dp = opendir(RUNTIME_APP_INFO_DIR);
+       if (!dp)
+               return;
+
+       while (!readdir_r(dp, &dentry, &dir) && dir != NULL) {
+               _cleanup_free_ char *path = NULL;
+               int ret;
+
+               if (dir->d_name[0] == '.')
+                       continue;
+
+               if (dir->d_type != DT_DIR)
+                       continue;
+
+               ret = asprintf(&path, RUNTIME_APP_INFO_DIR "/%s", dir->d_name);
+               if (ret < 0) {
+                       _E("Failed to allocate memory");
+                       return;
+               }
+
+               ret = proc_restore_runtime_app_info(path);
+               if (ret < 0)
+                       _E("Failed to restore runtime appinfo '%s': %s",
+                          dir->d_name, strerror(-ret));
+       }
+}
+
 static int resourced_proc_init(void* data)
 {
+       int ret = mkdir(RUNTIME_APP_INFO_DIR, S_IRWXU | S_IRGRP | S_IXGRP);
+       if (ret < 0 && errno != EEXIST) {
+               _E("Failed to create directory %s: %s", RUNTIME_APP_INFO_DIR, strerror(-ret));
+               return RESOURCED_ERROR_FAIL;
+       }
+
        proc_exclude_init();
        proc_module_init(data);
        return RESOURCED_ERROR_NONE;
@@ -643,6 +1156,12 @@ static int resourced_proc_exit(void* data)
        return RESOURCED_ERROR_NONE;
 }
 
+static int resourced_proc_restore(void *data)
+{
+       proc_restore_runtime_app_list();
+       return RESOURCED_ERROR_NONE;
+}
+
 int proc_get_freezer_status()
 {
        int ret = CGROUP_FREEZER_DISABLED;
@@ -1123,6 +1642,7 @@ static struct module_ops proc_modules_ops = {
        .name           = "PROC",
        .init           = resourced_proc_init,
        .exit           = resourced_proc_exit,
+       .restore        = resourced_proc_restore,
 };
 
 MODULE_REGISTER(&proc_modules_ops)
index f464b40..b312ace 100644 (file)
@@ -71,8 +71,8 @@ static int resourced_write_state(void)
 
        ret = mkdir(RUNTIME_RESOURCED_DIR, S_IRWXU | S_IRGRP | S_IXGRP);
        if (ret < 0 && errno != EEXIST)
-               _E("Failed to create %s dir : %s",
-                  RUNTIME_RESOURCED_DIR, strerror(-ret));
+               _E("Failed to create directory %s: %s",
+                               RUNTIME_RESOURCED_DIR, strerror(-ret));
 
        if (access(RUNTIME_RESOURCED_PID_PATH, F_OK) < 0)
                goto write_pid;