Added information config with inotify 00/154400/3 accepted/tizen/4.0/unified/20171012.230309 submit/tizen_4.0/20171011.035617 tizen_4.0.IoT.p1_release
authorhyunuktak <hyunuk.tak@samsung.com>
Tue, 10 Oct 2017 05:48:27 +0000 (14:48 +0900)
committerhyunuktak <hyunuk.tak@samsung.com>
Wed, 11 Oct 2017 01:21:46 +0000 (10:21 +0900)
Change-Id: If6faf890e69fa7a2de05d362aada815c29778411
Signed-off-by: hyunuktak <hyunuk.tak@samsung.com>
13 files changed:
include/stc-manager-util.h
include/stc-manager.h
packaging/stc-manager.spec
plugin/stc-plugin.c
src/helper/helper-cgroup.c
src/helper/helper-inotify.c [new file with mode: 0755]
src/helper/helper-inotify.h [new file with mode: 0755]
src/helper/helper-net-cls.c
src/helper/helper-nfacct-rule.c
src/monitor/stc-app-lifecycle.c
src/monitor/stc-monitor.c
src/stc-manager-util.c [new file with mode: 0755]
src/stc-manager.c

index 708f67c..d504cf3 100755 (executable)
@@ -327,6 +327,10 @@ static inline bool strstart_with(const char *str, const char *with)
 #define CGROUP_FILE_NAME "cgroup.procs"
 #define UNKNOWN_APP "(unknown)"
 
+#define INFO_STORAGE_DIR "/var/lib/stc"
+#define INFO_CONFIG "info.config"
+#define INFO_DEBUGLOG "debuglog"
+
 #define MAX_PATH_LENGTH 512
 #define MAX_NAME_LENGTH 256
 #define MAX_IFACE_LENGTH 32
@@ -381,4 +385,13 @@ enum stc_counter_state {
        STC_UPDATE_REQUESTED = 1 << 5,
 };
 
+gboolean stc_util_get_config_bool(char *key);
+gchar * stc_util_get_config_str(char *key);
+int stc_util_get_config_int(char *key);
+
+void stc_util_set_debuglog(int debuglog);
+int stc_util_get_debuglog(void);
+
+void stc_util_initialize_config(void);
+
 #endif /* __STC_MANAGER_UTIL_H__ */
index 37e5d97..2766a60 100755 (executable)
@@ -31,7 +31,7 @@
 #define STC_TOTAL_IPV4 "TOTAL_IPV4"
 #define STC_TOTAL_IPV6 "TOTAL_IPV6"
 
-#define STC_DEBUG_LOG 0
+#define STC_DEBUG_LOG (stc_util_get_debuglog())
 
 typedef enum {
        STC_CANCEL = 0,    /**< cancel */
index d0e6065..cf69262 100644 (file)
@@ -1,6 +1,6 @@
 Name:       stc-manager
 Summary:    STC(Smart Traffic Control) manager
-Version:    0.0.35
+Version:    0.0.36
 Release:    0
 Group:      Network & Connectivity/Other
 License:    Apache-2.0
index db83094..916a75e 100755 (executable)
@@ -91,11 +91,11 @@ static void __stc_gdbus_handle_aul_changestate(GDBusConnection *connection,
        else
                apptype = STC_APP_TYPE_GUI;
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG) {
                STC_LOGD("\033[1;36mAPP STATUS\033[0;m: Pkg ID [\033[0;34m%s\033[0;m], "
                        "App ID [\033[0;32m%s\033[0;m], PID [\033[1;33m%d\033[0;m], Status [%s], Type [%s]",
                        pkgid, appid, pid, statstr, pkgtype);
-#endif
+       }
 
        if (state_changed_cb)
                state_changed_cb(status, pid, appid, pkgid, apptype);
index c636bc2..8c258a5 100755 (executable)
@@ -116,9 +116,10 @@ int cgroup_write_node_uint32(const char *cgroup_name,
 {
        char buf[MAX_PATH_LENGTH];
        snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name);
-#if STC_DEBUG_LOG
-       STC_LOGD("cgroup_buf %s, value %d\n", buf, value);
-#endif
+
+       if (STC_DEBUG_LOG)
+               STC_LOGD("cgroup_buf %s, value %d\n", buf, value);
+
        return fwrite_uint(buf, value);
 }
 
@@ -127,9 +128,10 @@ int cgroup_write_node_str(const char *cgroup_name,
 {
        char buf[MAX_PATH_LENGTH];
        snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name);
-#if STC_DEBUG_LOG
-       STC_LOGD("cgroup_buf %s, string %s\n", buf, string);
-#endif
+
+       if (STC_DEBUG_LOG)
+               STC_LOGD("cgroup_buf %s, string %s\n", buf, string);
+
        return fwrite_str(buf, string);
 }
 
@@ -140,9 +142,10 @@ int cgroup_read_node_uint32(const char *cgroup_name,
        int ret;
        snprintf(buf, sizeof(buf), "%s/%s", cgroup_name, file_name);
        ret = fread_uint(buf, value);
-#if STC_DEBUG_LOG
-       STC_LOGD("cgroup_buf %s, value %d\n", buf, *value);
-#endif
+
+       if (STC_DEBUG_LOG)
+               STC_LOGD("cgroup_buf %s, value %d\n", buf, *value);
+
        return ret;
 }
 
diff --git a/src/helper/helper-inotify.c b/src/helper/helper-inotify.c
new file mode 100755 (executable)
index 0000000..71e30e2
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2016 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 <glib.h>
+
+#include "helper-inotify.h"
+#include "stc-manager-util.h"
+
+typedef struct {
+       GIOChannel *channel;
+       uint watch;
+       int wd;
+
+       inotify_event_cb cb;
+} stc_inotify_s;
+
+static GHashTable *g_inotify_hash;
+
+static gboolean __inotify_data(GIOChannel *channel, GIOCondition cond,
+                                                       gpointer user_data)
+{
+       stc_inotify_s *inotify = user_data;
+       char buffer[sizeof(struct inotify_event) + NAME_MAX + 1];
+       char *next_event;
+       gsize bytes_read;
+       GIOStatus status;
+
+       if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               inotify->watch = 0;
+               return FALSE;
+       }
+
+       status = g_io_channel_read_chars(channel, buffer,
+                                       sizeof(buffer), &bytes_read, NULL);
+
+       switch (status) {
+       case G_IO_STATUS_NORMAL:
+               break;
+       case G_IO_STATUS_AGAIN:
+               return TRUE;
+       default:
+               STC_LOGE("Reading from inotify channel failed");
+               inotify->watch = 0;
+               return FALSE;
+       }
+
+       next_event = buffer;
+
+       while (bytes_read > 0) {
+               struct inotify_event *event;
+               gchar *ident;
+               gsize len;
+               inotify_event_cb callback = inotify->cb;
+
+               event = (struct inotify_event *) next_event;
+               if (event->len)
+                       ident = next_event + sizeof(struct inotify_event);
+               else
+                       ident = NULL;
+
+               len = sizeof(struct inotify_event) + event->len;
+               if (len > bytes_read)
+                       break;
+
+               next_event += len;
+               bytes_read -= len;
+
+               (*callback)(event, ident);
+       }
+
+       return TRUE;
+}
+
+static void __remove_watch(stc_inotify_s *inotify)
+{
+       int fd;
+
+       if (!inotify->channel)
+               return;
+
+       if (inotify->watch > 0)
+               g_source_remove(inotify->watch);
+
+       fd = g_io_channel_unix_get_fd(inotify->channel);
+
+       if (inotify->wd >= 0)
+               inotify_rm_watch(fd, inotify->wd);
+
+       g_io_channel_unref(inotify->channel);
+}
+
+static int __create_watch(const char *path, stc_inotify_s *inotify)
+{
+       int fd;
+
+       STC_LOGD("Add directory watch for [%s]", path);
+
+       fd = inotify_init();
+       if (fd < 0)
+               return -EIO;
+
+       inotify->wd = inotify_add_watch(fd, path,
+                                       IN_MODIFY | IN_CREATE | IN_DELETE |
+                                       IN_MOVED_TO | IN_MOVED_FROM);
+       if (inotify->wd < 0) {
+               STC_LOGE("Creation of [%s] watch failed", path);
+               close(fd);
+               return -EIO;
+       }
+
+       inotify->channel = g_io_channel_unix_new(fd);
+       if (!inotify->channel) {
+               STC_LOGE("Creation of inotify channel failed");
+               inotify_rm_watch(fd, inotify->wd);
+               inotify->wd = 0;
+
+               close(fd);
+               return -EIO;
+       }
+
+       g_io_channel_set_close_on_unref(inotify->channel, TRUE);
+       g_io_channel_set_encoding(inotify->channel, NULL, NULL);
+       g_io_channel_set_buffered(inotify->channel, FALSE);
+
+       inotify->watch = g_io_add_watch(inotify->channel,
+                               G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
+                               __inotify_data, inotify);
+
+       return 0;
+}
+
+static void __inotify_destroy(gpointer user_data)
+{
+       stc_inotify_s *inotify = user_data;
+
+       __remove_watch(inotify);
+       FREE(inotify);
+}
+
+int inotify_register(const char *path, inotify_event_cb callback)
+{
+       int err;
+       stc_inotify_s *inotify;
+
+       if (!callback)
+               return -EINVAL;
+
+       inotify = g_hash_table_lookup(g_inotify_hash, path);
+       if (inotify)
+               goto update;
+
+       inotify = g_try_new0(stc_inotify_s, 1);
+       if (!inotify)
+               return -ENOMEM;
+
+       inotify->wd = -1;
+
+       err = __create_watch(path, inotify);
+       if (err < 0) {
+               FREE(inotify);
+               return err;
+       }
+
+       g_hash_table_replace(g_inotify_hash, g_strdup(path), inotify);
+
+update:
+       inotify->cb = callback;
+
+       return 0;
+}
+
+void inotify_deregister(const char *path)
+{
+       stc_inotify_s *inotify;
+
+       inotify = g_hash_table_lookup(g_inotify_hash, path);
+       if (!inotify)
+               return;
+
+       g_hash_table_remove(g_inotify_hash, path);
+}
+
+int inotify_initialize(void)
+{
+       g_inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                               g_free, __inotify_destroy);
+       return 0;
+}
+
+void inotify_deinitialize(void)
+{
+       g_hash_table_destroy(g_inotify_hash);
+}
diff --git a/src/helper/helper-inotify.h b/src/helper/helper-inotify.h
new file mode 100755 (executable)
index 0000000..1fe9d66
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 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 __STC_HELPER_INOTIFY_H__
+#define __STC_HELPER_INOTIFY_H__
+
+#include <sys/inotify.h>
+
+struct inotify_event;
+typedef void (* inotify_event_cb) (struct inotify_event *event,
+                                       const char *ident);
+
+int inotify_register(const char *path, inotify_event_cb callback);
+void inotify_deregister(const char *path);
+
+int inotify_initialize(void);
+void inotify_deinitialize(void);
+
+#endif  /*__STC_HELPER_INOTIFY_H__*/
index ef5e4b3..6be717a 100755 (executable)
@@ -187,7 +187,8 @@ stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id)
                path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK;
 
        if (access(child_buf, F_OK)) {
-               STC_LOGD("%s of %s is not existed", child_buf, app_id);
+               if (STC_DEBUG_LOG)
+                       STC_LOGD("%s of %s is not existed", child_buf, app_id);
                return cgroup_write_pid(path_to_net_cgroup_dir, app_id, pid);
        }
 
index bd86b01..ca3a7a9 100755 (executable)
@@ -136,7 +136,8 @@ static stc_error_e nfacct_send_new(nfacct_rule_s *counter)
        prepare_netlink_msg(&req, NFNL_MSG_ACCT_NEW, NLM_F_CREATE | NLM_F_ACK);
        add_string_attr(&req, counter->name, NFACCT_NAME);
 
-       STC_LOGD("counter name %s", counter->name);
+       if (STC_DEBUG_LOG)
+               STC_LOGD("counter name %s", counter->name);
 
        /* padding */
        add_uint64_attr(&req, 0, NFACCT_PKTS);
@@ -156,9 +157,8 @@ stc_error_e nfacct_send_del(nfacct_rule_s *counter)
 {
        struct genl req;
 
-#if STC_DEBUG_LOG
-       STC_LOGD("send remove request for %s", counter->name);
-#endif
+       if (STC_DEBUG_LOG)
+               STC_LOGD("send remove request for %s", counter->name);
 
        prepare_netlink_msg(&req, NFNL_MSG_ACCT_DEL, NLM_F_ACK);
        add_string_attr(&req, counter->name, NFACCT_NAME);
@@ -418,9 +418,8 @@ stc_error_e exec_iptables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                int ret;
                char *save_ptr = NULL;
 
-#if STC_DEBUG_LOG
-               STC_LOGD("executing iptables cmd %s in forked process", cmd_buf);
-#endif
+               if (STC_DEBUG_LOG)
+                       STC_LOGD("executing iptables cmd %s in forked process", cmd_buf);
 
                args[0] = "iptables";
                cmd = strtok_r((char *)cmd_buf, " ", &save_ptr);
@@ -464,9 +463,8 @@ stc_error_e exec_ip6tables_cmd(const char *cmd_buf, pid_t *cmd_pid)
                int ret;
                char *save_ptr = NULL;
 
-#if STC_DEBUG_LOG
-               STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf);
-#endif
+               if (STC_DEBUG_LOG)
+                       STC_LOGD("executing ip6tables cmd %s in forked process", cmd_buf);
 
                args[0] = "ip6tables";
                cmd = strtok_r((char *)cmd_buf, " ", &save_ptr);
index 235dc04..eb18816 100755 (executable)
@@ -101,7 +101,6 @@ static proc_value_s * __proc_tree_lookup(const proc_key_s *key)
        return lookup;
 }
 
-#if STC_DEBUG_LOG
 static gboolean __proc_tree_foreach_print(gpointer key, gpointer value,
                                          gpointer data)
 {
@@ -119,7 +118,6 @@ static void __proc_tree_printall(void)
 {
        g_tree_foreach(proc_tree, __proc_tree_foreach_print, NULL);
 }
-#endif
 
 static proc_value_s * __proc_tree_find_parent(proc_value_s *value)
 {
@@ -134,14 +132,14 @@ static proc_value_s * __proc_tree_find_parent(proc_value_s *value)
                        parent = lookup;
        } while (lookup);
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG) {
                if (parent != NULL)
                        STC_LOGD("\033[0;35mPARENT\033[0;m: tgid[\033[1;33m%s\033[0;m] pid[%s] "
                                "ppid[\033[1;35m%s\033[0;m] cmdline[\033[0;34m%s\033[0;m] name[%s]",
                                parent->status[PROC_STATUS_TGID], parent->status[PROC_STATUS_PID],
                                parent->status[PROC_STATUS_PPID], parent->cmdline,
                                parent->status[PROC_STATUS_NAME]);
-#endif
+       }
 
        return parent;
 }
@@ -159,12 +157,11 @@ static void __proc_tree_add(proc_key_s *key,
 
        lookup = g_tree_lookup(proc_tree, key);
        if (lookup) {
-#if STC_DEBUG_LOG
+               if (STC_DEBUG_LOG)
                        STC_LOGD("LOOKUP: tgid[\033[1;33m%s\033[0;m] pid[%s] ppid[\033[1;35m%s\033[0;m] "
                                "cmdline[\033[0;34m%s\033[0;m] name[%s]", lookup->status[PROC_STATUS_TGID],
                                lookup->status[PROC_STATUS_PID], lookup->status[PROC_STATUS_PPID],
                                lookup->cmdline, lookup->status[PROC_STATUS_NAME]);
-#endif
                return;
        }
 
@@ -173,9 +170,8 @@ static void __proc_tree_add(proc_key_s *key,
 
        g_tree_insert(proc_tree, key, value);
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG)
                __proc_tree_printall();
-#endif
 
        parent = __proc_tree_find_parent(value);
        if (parent != NULL)
@@ -195,11 +191,11 @@ static void __proc_tree_remove(const proc_key_s *key)
 
        stc_manager_app_status_changed(STC_CMD_SET_TERMINATED, key->pid, NULL,
                                       NULL, STC_APP_TYPE_NONE);
+
        g_tree_remove(proc_tree, key);
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG)
                __proc_tree_printall();
-#endif
 }
 
 static gboolean __check_excn(char *cmdline)
@@ -403,9 +399,8 @@ static void __process_event_fork(int tgid, int pid)
            STC_ERROR_NONE == proc_get_status(pid, status)) {
 
                if (__check_excn(cmdline)) {
-#if STC_DEBUG_LOG
+                       if (STC_DEBUG_LOG)
                                STC_LOGD("[%s] monitoring is excepted", cmdline);
-#endif
                        return;
                }
 
@@ -431,13 +426,13 @@ static void __process_event_fork(int tgid, int pid)
                        g_strlcpy(value->status[i], status[i], sizeof(value->status[i]));
                g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline));
 
-#if STC_DEBUG_LOG
+               if (STC_DEBUG_LOG) {
                        STC_LOGD("\033[1;34mFORK\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] "
                                "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid);
                        STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]",
                                status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID],
                                status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]);
-#endif
+               }
 
                __proc_tree_add(key, value);
        }
@@ -452,9 +447,8 @@ static void __process_event_exec(int tgid, int pid)
            STC_ERROR_NONE == proc_get_status(pid, status)) {
 
                if (__check_excn(cmdline)) {
-#if STC_DEBUG_LOG
+                       if (STC_DEBUG_LOG)
                                STC_LOGD("[%s] monitoring is excepted", cmdline);
-#endif
                        return;
                }
 
@@ -480,13 +474,13 @@ static void __process_event_exec(int tgid, int pid)
                        g_strlcpy(value->status[i], status[i], sizeof(value->status[i]));
                g_strlcpy(value->cmdline, cmdline, sizeof(value->cmdline));
 
-#if STC_DEBUG_LOG
+               if (STC_DEBUG_LOG) {
                        STC_LOGD("\033[1;32mEXEC\033[0;m: tgid[\033[1;33m%d\033[0;m] ppid=[\033[1;35m%s\033[0;m] "
                                "cmdline[\033[0;34m%s\033[0;m] pid[%d]", tgid, status[PROC_STATUS_PPID], cmdline, pid);
                        STC_LOGD("STATUS: tgid[%s] pid[%s] ppid[%s] name[%s] state[%s] tracerpid[%s]",
                                status[PROC_STATUS_TGID], status[PROC_STATUS_PID], status[PROC_STATUS_PPID],
                                status[PROC_STATUS_NAME], status[PROC_STATUS_STATE], status[PROC_STATUS_TRACERPID]);
-#endif
+               }
 
                __proc_tree_add(key, value);
        }
@@ -505,10 +499,9 @@ static void __process_event_exit(int tgid, int pid, int exit_code)
        if (lookup == NULL) /* unmonitored process */
                return;
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG)
                STC_LOGD("\033[1;31mEXIT\033[0;m: tgid[\033[1;33m%d\033[0;m] "
                        "pid[%d] exitcode[\033[0;31m%d\033[0;m]", tgid, pid, exit_code);
-#endif
 
        __proc_tree_remove(&key);
 }
index 522a615..1cc0b5e 100755 (executable)
@@ -276,7 +276,6 @@ static void __rstns_tree_key_free(gpointer data)
        FREE(key);
 }
 
-#if STC_DEBUG_LOG
 static gboolean __processes_tree_foreach_print(gpointer key, gpointer value,
                                               gpointer data)
 {
@@ -314,7 +313,6 @@ static void __apps_tree_printall(void)
 {
        g_tree_foreach(g_system->apps, __apps_tree_foreach_print, NULL);
 }
-#endif
 
 static gboolean __apps_tree_foreach_remove_pid(gpointer key, gpointer value,
                                               gpointer data)
@@ -323,9 +321,8 @@ static gboolean __apps_tree_foreach_remove_pid(gpointer key, gpointer value,
        stc_app_value_s *app_value = (stc_app_value_s *)value;
 
        if (!g_tree_remove(app_value->processes, context->proc_key)) {
-#if STC_DEBUG_LOG
-               STC_LOGD("key not found");
-#endif
+               if (STC_DEBUG_LOG)
+                       STC_LOGD("key not found");
                return FALSE;
        }
 
@@ -966,18 +963,16 @@ static void __app_counter_update(stc_app_key_s *app_key,
                app_value->counter.in_bytes = context->bytes;
                g_system->apps_tree_updated = TRUE;
 
-#if STC_DEBUG_LOG
-               __apps_tree_foreach_print(app_key, app_value, NULL);
-#endif
+               if (STC_DEBUG_LOG)
+                       __apps_tree_foreach_print(app_key, app_value, NULL);
                break;
        case NFACCT_COUNTER_OUT:
                app_value->data_usage.out_bytes += context->bytes;
                app_value->counter.out_bytes = context->bytes;
                g_system->apps_tree_updated = TRUE;
 
-#if STC_DEBUG_LOG
-               __apps_tree_foreach_print(app_key, app_value, NULL);
-#endif
+               if (STC_DEBUG_LOG)
+                       __apps_tree_foreach_print(app_key, app_value, NULL);
                break;
        default:
                STC_LOGE("unknown iotype");
@@ -1036,7 +1031,8 @@ static void __fill_nfacct_result(char *cnt_name, int64_t bytes,
                .data_limit_reached = FALSE,
        };
 
-       STC_LOGD("cnt_name %s", cnt_name);
+       if (STC_DEBUG_LOG)
+               STC_LOGD("cnt_name %s", cnt_name);
 
        if (!recreate_counter_by_name(cnt_name, &counter)) {
                STC_LOGE("Can't parse counter name %s", cnt_name);
@@ -1780,9 +1776,8 @@ stc_error_e stc_monitor_process_add(const stc_app_key_s app_key,
        /* add pid to application cgroup */
        place_pids_to_net_cgroup(proc_key.pid, app_key.app_id);
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG)
                __apps_tree_printall();
-#endif
 
        return ret;
 }
@@ -1808,9 +1803,8 @@ stc_error_e stc_monitor_process_remove(pid_t pid)
        if (context.entry_removed)
                __application_remove_if_empty(context.app_key);
 
-#if STC_DEBUG_LOG
+       if (STC_DEBUG_LOG)
                __apps_tree_printall();
-#endif
 
        return ret;
 }
diff --git a/src/stc-manager-util.c b/src/stc-manager-util.c
new file mode 100755 (executable)
index 0000000..1c97e81
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016 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 "stc-manager-util.h"
+
+static int g_debuglog = -1;
+
+static void __sync_file_to_disk(const char *path)
+{
+       FILE *fp = NULL;
+       fp = fopen(path, "a+");
+       if (fp) {
+               fflush(fp);
+               fsync(fp->_fileno);
+               fclose(fp);
+               STC_LOGD("Sync the file to disk");
+       }
+}
+
+static GKeyFile *__load_key_file(const char *path)
+{
+       GKeyFile *keyfile = NULL;
+       GError *error = NULL;
+
+       STC_LOGD("Loading [%s]", path);
+
+       keyfile = g_key_file_new();
+
+       if (!g_key_file_load_from_file(keyfile, path, 0, &error)) {
+               STC_LOGD("Unable to load [%s] : %s", path, error->message);
+               g_clear_error(&error);
+               g_key_file_free(keyfile);
+               keyfile = NULL;
+       }
+
+       return keyfile;
+}
+
+static int __save_key_file(GKeyFile *keyfile, char *path)
+{
+       gchar *data = NULL;
+       gsize length = 0;
+       GError *error = NULL;
+       int ret = 0;
+
+       data = g_key_file_to_data(keyfile, &length, NULL);
+
+       if (!g_file_set_contents(path, data, length, &error)) {
+               STC_LOGD("Failed to save information : %s", error->message);
+               g_error_free(error);
+               ret = -EIO;
+       }
+
+       __sync_file_to_disk(path);
+
+       g_free(data);
+       return ret;
+}
+
+gboolean stc_util_get_config_bool(char *key)
+{
+       char path[MAX_PATH_LENGTH];
+       GKeyFile *keyfile;
+
+       snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG);
+
+       keyfile = __load_key_file(path);
+       if (!keyfile)
+               keyfile = g_key_file_new();
+
+       return g_key_file_get_boolean(keyfile, path, key, NULL);
+}
+
+gchar * stc_util_get_config_str(char *key)
+{
+       char path[MAX_PATH_LENGTH];
+       GKeyFile *keyfile;
+
+       snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG);
+
+       keyfile = __load_key_file(path);
+       if (!keyfile)
+               keyfile = g_key_file_new();
+
+       return g_key_file_get_string(keyfile, path, key, NULL);
+}
+
+int stc_util_get_config_int(char *key)
+{
+       char path[MAX_PATH_LENGTH];
+       GKeyFile *keyfile;
+
+       snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG);
+
+       keyfile = __load_key_file(path);
+       if (!keyfile)
+               keyfile = g_key_file_new();
+
+       return g_key_file_get_integer(keyfile, path, key, NULL);
+}
+
+API void stc_util_set_debuglog(int debuglog)
+{
+       g_debuglog = debuglog;
+}
+
+API int stc_util_get_debuglog(void)
+{
+       if (g_debuglog == -1)
+               g_debuglog = stc_util_get_config_int(INFO_DEBUGLOG);
+
+       return g_debuglog;
+}
+
+void stc_util_initialize_config(void)
+{
+       char path[MAX_PATH_LENGTH];
+       GKeyFile *keyfile;
+
+       snprintf(path, sizeof(path), "%s/%s", INFO_STORAGE_DIR, INFO_CONFIG);
+
+       keyfile = __load_key_file(path);
+       if (!keyfile)
+               keyfile = g_key_file_new();
+
+       g_key_file_set_integer(keyfile, path, INFO_DEBUGLOG, 0);
+
+       __save_key_file(keyfile, path);
+}
index cfee380..d6e8521 100755 (executable)
 #include "table-restrictions.h"
 #include "helper-cgroup.h"
 #include "helper-nfacct-rule.h"
+#include "helper-inotify.h"
 #include "stc-monitor.h"
 #include "stc-manager-plugin.h"
 #include "stc-app-lifecycle.h"
 
 static stc_s *g_stc = NULL;
 
+static gboolean __validate_ident(const char *ident)
+{
+       unsigned int i;
+
+       if (!ident)
+               return FALSE;
+
+       for (i = 0; i < strlen(ident); ++i)
+               if (!g_ascii_isprint(ident[i]))
+                       return FALSE;
+
+       return TRUE;
+}
+
+static void __stc_inotify_handler(struct inotify_event *event, const char *ident)
+{
+       if (!ident)
+               return;
+
+       if (!__validate_ident(ident)) {
+               STC_LOGE("Invalid ident [%s]", ident);
+               return;
+       }
+
+       if (event->mask & IN_MODIFY) {
+               if (!g_strcmp0(ident, INFO_CONFIG)) {
+                       int debug = 0;
+                       debug = stc_util_get_config_int(INFO_DEBUGLOG);
+                       stc_util_set_debuglog(debug);
+               }
+       }
+}
+
 static void __stc_manager_deinit(void)
 {
        __STC_LOG_FUNC_ENTER__;
@@ -46,6 +80,9 @@ static void __stc_manager_deinit(void)
        stc_app_lifecycle_monitor_deinit();
        stc_manager_plugin_deinit();
 
+       inotify_deregister(INFO_STORAGE_DIR);
+       inotify_deinitialize();
+
        STC_LOGI("stc manager deinitialized");
        FREE(g_stc);
        __STC_LOG_FUNC_EXIT__;
@@ -64,6 +101,11 @@ static stc_s *__stc_manager_init(void)
        }
        g_stc = stc;
 
+       stc_util_initialize_config();
+
+       inotify_initialize();
+       inotify_register(INFO_STORAGE_DIR, __stc_inotify_handler);
+
        cgroup_set_release_agent(NET_CLS_SUBSYS, NET_RELEASE_AGENT);
 
        EXEC(STC_ERROR_NONE, stc_db_initialize());