Monitoring application wise background data usage. 14/133614/1
authorNishant Chaprana <n.chaprana@samsung.com>
Fri, 9 Jun 2017 08:11:44 +0000 (13:41 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Tue, 13 Jun 2017 02:33:34 +0000 (08:03 +0530)
Description: This patch updates logic to monitor application wise
background data usage.
When background data usage is notified, app_id will be appended with "_BACKGROUND".

Below is the test result performed using stc_test application.
=================================================================
 Main >> STC >> [Statistics] >> [Stats]
-----------------------------------------------------------------
 [  1] [Set] stats rule                                        >
 [  2] [Get] stats
 [  3] [Get] all stats
 [  4] [Get] total stats
 ---------------------------------------------------------------
 [ p ] Previous Menu
 [ m ] Show Menu
 [ q ] Quit
=================================================================
( 1354) >> 3
Success to set time interval
Success to request stats all info
( 1354) >> -----------------------------------------------------------------
App_id:   [org.tizen.browser]
Ifname:   []
Imsi:     [noneimsi]
Iftype:   [Undefined]
Received: [2182136]
Sent:     [102681]
Roaming:  [Unknown]
Protocol: [Unknown]
Process:  [Unknown]
From:     [0]
To:       [0]
-----------------------------------------------------------------
-----------------------------------------------------------------
App_id:   [org.tizen.browser_BACKGROUND]
Ifname:   []
Imsi:     [noneimsi]
Iftype:   [Undefined]
Received: [1872]
Sent:     [1872]
Roaming:  [Unknown]
Protocol: [Unknown]
Process:  [Unknown]
From:     [0]
To:       [0]
-----------------------------------------------------------------

Change-Id: Id8175494e559790e2959e5a6e7164de24e00a548
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
include/stc-manager.h
src/configure/include/counter.h
src/database/tables/table-statistics.c
src/helper/helper-cgroup.c
src/helper/helper-cgroup.h
src/helper/helper-net-cls.c
src/monitor/include/stc-monitor.h
src/monitor/stc-application-lifecycle.c
src/monitor/stc-monitor.c
src/utils/net-cls-release.c

index 6df86af..73b7370 100755 (executable)
 #define NET_RELEASE_AGENT "/usr/bin/net-cls-release"
 #define NET_CLS_SUBSYS "net_cls"
 
-#define STC_BACKGROUND_APP_NAME "BACKGROUND"
-#define NETWORK_RESTRICTION_APP_NAME "NETWORKRESTRICTION"
-
-#define STC_ALL_APP "STC_ALL_APPLICATION_IDENTIFIER"
-#define TETHERING_APP_NAME "STC_TETHERING_APPLICATION_IDENTIFIER"
+#define STC_BACKGROUND_APP_SUFFIX "_BACKGROUND"
 
 typedef enum {
        STC_CANCEL = 0,    /**< cancel */
index 760a56a..95bc0ce 100755 (executable)
@@ -19,9 +19,6 @@
 
 #include "stc-db.h"
 
-#define STC_BACKGROUND_APP_NAME "BACKGROUND"
-#define NETWORK_RESTRICTION_APP_NAME "NETWORKRESTRICTION"
-
 struct counter_arg {
        int sock;
        int ans_len;
index 05e66f6..e16059a 100755 (executable)
 #define SELECT_TOTAL "select iftype, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, sum(sent) as sent, " \
        "ifname, imsi, ground from statistics " \
-       " where binpath='STC_ALL_APPLICATION_IDENTIFIER' AND (time_stamp between ? and ?) " \
+       " where (time_stamp between ? and ?) " \
        "group by iftype, ifname, imsi, hw_net_protocol_type, is_roaming " \
        "order by time_stamp, iftype, ifname, imsi, hw_net_protocol_type, " \
        "is_roaming"
 #define SELECT_TOTAL_IFACE "select iftype, hw_net_protocol_type, " \
        "is_roaming, sum(received) as received, sum(sent) as sent, " \
        "ifname, imsi, ground from statistics " \
-       " where binpath='STC_ALL_APPLICATION_IDENTIFIER' AND (time_stamp between ? and ?) " \
+       " where (time_stamp between ? and ?) " \
        "and iftype=? " \
        "group by hw_net_protocol_type, is_roaming, " \
        "iftype, ifname, imsi " \
index fe05ea1..a725dcc 100755 (executable)
@@ -273,3 +273,17 @@ int cgroup_set_release_agent(const char *cgroup_subsys,
 
        return cgroup_write_node_str(buf, NOTIFY_ON_RELEASE, "1");
 }
+
+void cgroup_init(void)
+{
+       /* create stc cgroup directory */
+       cgroup_make_subdir(CGROUP_NETWORK, STC_CGROUP_NAME, NULL);
+
+       /* create background cgroup directory */
+       cgroup_make_subdir(STC_CGROUP_NETWORK, STC_BACKGROUND_CGROUP_NAME,
+                          NULL);
+
+       /* create foreground cgroup directory */
+       cgroup_make_subdir(STC_CGROUP_NETWORK, STC_FOREGROUND_CGROUP_NAME,
+                          NULL);
+}
index e3398af..a358066 100755 (executable)
 #include "stc-manager.h"
 #include "helper-file.h"
 
-#define DEFAULT_CGROUP       "/sys/fs/cgroup"
-#define CGROUP_NETWORK       DEFAULT_CGROUP "/net_cls"
-#define PROC_TASK_CHILDREN   "/proc/%d/task/%d/children"
+#define DEFAULT_CGROUP                  "/sys/fs/cgroup"
+#define CGROUP_NETWORK                  DEFAULT_CGROUP "/net_cls"
+#define STC_CGROUP_NETWORK              CGROUP_NETWORK "/stc"
+#define BACKGROUND_CGROUP_NETWORK       STC_CGROUP_NETWORK "/background"
+#define FOREGROUND_CGROUP_NETWORK       STC_CGROUP_NETWORK "/foreground"
+#define PROC_TASK_CHILDREN              "/proc/%d/task/%d/children"
+#define STC_CGROUP_NAME                 "stc"
+#define STC_BACKGROUND_CGROUP_NAME      "background"
+#define STC_FOREGROUND_CGROUP_NAME      "foreground"
 
 /**
  * @desc Get one unsigned int32 value from cgroup
@@ -116,4 +122,9 @@ int cgroup_get_pids(const char *name, GArray **pids);
 int cgroup_remove_pid(const char *cgroup_subsystem, const char *cgroup_name,
                      const int pid);
 
+/**
+ * @desc initializes cgroups.
+ */
+void cgroup_init(void);
+
 #endif /*__STC_HELPER_CGROUP_H__*/
index d08f559..8f3f5d0 100755 (executable)
@@ -82,81 +82,41 @@ static uint32_t __get_classid_from_cgroup(const char *cgroup,
        return classid;
 }
 
-/* TODO: background tasks update from list */
-static void __add_background_apps(GSList *background_pid_list)
-{
-       if (background_pid_list == NULL)
-               return;
-
-       /* remove old list */
-       /* add new list */
-}
-
-static stc_error_e __make_net_cls_cgroup(const char *pkg_name, uint32_t classid,
-                                        check_classid_used_cb cb)
-{
-       stc_error_e ret = STC_ERROR_NONE;
-       bool exists = false;
-
-       if (pkg_name == NULL) {
-               STC_LOGE("package name must be not empty");
-               return STC_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = cgroup_make_subdir(PATH_TO_NET_CGROUP_DIR, (char *)pkg_name,
-                                &exists);
-       ret_value_if(ret < 0, STC_ERROR_FAIL);
-
-       if (!exists) {
-               ret = __place_classid_to_cgroup(PATH_TO_NET_CGROUP_DIR,
-                                               pkg_name,
-                                               classid ? &classid : NULL, cb);
-               ret_value_if(ret < 0, STC_ERROR_FAIL);
-       }
-       return ret;
-}
-
 uint32_t get_classid_by_app_id(const char *app_id, int create)
 {
        int ret = 0;
        bool exists;
        uint32_t classid = STC_UNKNOWN_CLASSID;
+       const char *path_to_net_cgroup_dir = NULL;
 
        if (app_id == NULL) {
                STC_LOGE("app_id  must be not empty");
                return STC_UNKNOWN_CLASSID;
        }
 
-       if (!strcmp(app_id, STC_ALL_APP))
-               return STC_ALL_APP_CLASSID;
-
-       if (!strcmp(app_id, TETHERING_APP_NAME))
-               return STC_TETHERING_APP_CLASSID;
-
-       if (!strcmp(app_id, STC_BACKGROUND_APP_NAME))
-               return STC_BACKGROUND_APP_CLASSID;
-
-       if (!strcmp(app_id, NETWORK_RESTRICTION_APP_NAME))
-               return STC_NETWORK_RESTRICTION_APP_CLASSID;
+       if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
+               path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
+       else
+               path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK;
 
        /* just read */
        if (!create)
-               classid = __get_classid_from_cgroup(PATH_TO_NET_CGROUP_DIR,
+               classid = __get_classid_from_cgroup(path_to_net_cgroup_dir,
                                                    app_id);
 
        if (classid != STC_UNKNOWN_CLASSID)
                return classid;
 
-       ret = cgroup_make_subdir(PATH_TO_NET_CGROUP_DIR, (char *)app_id,
+       ret = cgroup_make_subdir(path_to_net_cgroup_dir, (char *)app_id,
                                 &exists);
        if (ret)
                goto handle_error;
 
        if (exists)
-               classid = __get_classid_from_cgroup(PATH_TO_NET_CGROUP_DIR,
+               classid = __get_classid_from_cgroup(path_to_net_cgroup_dir,
                                                    app_id);
        else
-               ret = __place_classid_to_cgroup(PATH_TO_NET_CGROUP_DIR,
+               ret = __place_classid_to_cgroup(path_to_net_cgroup_dir,
                                                (char *)app_id, &classid, NULL);
        if (ret)
                goto handle_error;
@@ -169,41 +129,27 @@ handle_error:
        return STC_UNKNOWN_CLASSID;
 }
 
-stc_error_e place_pids_to_net_cgroup(const int pid, const char *pkg_name)
+stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id)
 {
        char child_buf[21 + MAX_DEC_SIZE(int) + MAX_DEC_SIZE(int)];
+       const char *path_to_net_cgroup_dir = NULL;
+
        snprintf(child_buf, sizeof(child_buf), PROC_TASK_CHILDREN, pid, pid);
 
-       if (pkg_name == NULL) {
+       if (app_id == NULL) {
                STC_LOGE("package name must be not empty");
                return STC_ERROR_INVALID_PARAMETER;
        }
 
-       if (access(child_buf, F_OK)) {
-               STC_LOGD("%s of %s is not existed", child_buf, pkg_name);
-               return cgroup_write_pid(PATH_TO_NET_CGROUP_DIR, pkg_name, pid);
-       }
-
-       return cgroup_write_pidtree(PATH_TO_NET_CGROUP_DIR, pkg_name, pid);
-}
-
-void create_net_background_cgroup(GSList *background_pid_list)
-{
-       stc_error_e ret = __make_net_cls_cgroup(STC_BACKGROUND_APP_NAME,
-                                               STC_BACKGROUND_APP_CLASSID,
-                                               NULL);
-       if (ret == STC_ERROR_NONE)
-               __add_background_apps(background_pid_list);
+       if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
+               path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
        else
-               STC_LOGD("Could not support quota for background applications");
-}
+               path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK;
 
-void add_pid_to_background_cgroup(pid_t pid)
-{
-       place_pids_to_net_cgroup(pid, STC_BACKGROUND_APP_NAME);
-}
+       if (access(child_buf, F_OK)) {
+               STC_LOGD("%s of %s is not existed", child_buf, app_id);
+               return cgroup_write_pid(path_to_net_cgroup_dir, app_id, pid);
+       }
 
-void remove_pid_from_background_cgroup(pid_t pid)
-{
-       cgroup_remove_pid(PATH_TO_NET_CGROUP_DIR, STC_BACKGROUND_APP_NAME, pid);
+       return cgroup_write_pidtree(path_to_net_cgroup_dir, app_id, pid);
 }
index 385c9fb..feb0f12 100644 (file)
@@ -26,8 +26,8 @@
 #include "helper-nl.h"
 #include "netlink-restriction.h"
 
-/* 10 seconds */
-#define CONTR_TIMER_INTERVAL 10
+/* 1 seconds */
+#define CONTR_TIMER_INTERVAL 1
 
 /**
  * @brief key for processes tree
@@ -102,7 +102,6 @@ typedef struct {
        gboolean rstns_tree_updated;
        GTree *apps;  /**< monitored applications */
        gboolean apps_tree_updated;
-       GSList *background_pids; /**< list of background pids */
 } stc_system_s;
 
 /**
index 2b1243c..a0fb931 100755 (executable)
@@ -148,11 +148,19 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd,
 
                proc_value.ground = STC_APP_STATE_UNKNOWN;
 
+               /* create foreground cgroup */
                stc_monitor_application_add(app_key, app_value);
                stc_monitor_process_add(app_key, proc_key, proc_value);
 
-               FREE(app_key.pkg_id);
+               /* create background cgroup */
                FREE(app_key.app_id);
+
+               app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX,
+                                            NULL);
+               stc_monitor_application_add(app_key, app_value);
+
+               FREE(app_key.pkg_id);
+               g_free(app_key.app_id);
                break;
        }
        case STC_CMD_SET_SERVICE_LAUNCHED:
@@ -168,20 +176,22 @@ static stc_error_e __stc_manager_app_status_changed(stc_cmd_type_e cmd,
                memset(&proc_value, 0, sizeof(stc_process_value_s));
 
                app_key.pkg_id = g_strdup(pkg_id);
-               app_key.app_id = g_strdup(app_id);
+               app_key.app_id = g_strconcat(app_id, STC_BACKGROUND_APP_SUFFIX,
+                                            NULL);
 
                app_value.type = app_type;
                app_value.processes = NULL;
 
                proc_key.pid = pid;
 
+               /* services will run always in background. */
                proc_value.ground = STC_APP_STATE_BACKGROUND;
 
                stc_monitor_application_add(app_key, app_value);
                stc_monitor_process_add(app_key, proc_key, proc_value);
 
                FREE(app_key.pkg_id);
-               FREE(app_key.app_id);
+               g_free(app_key.app_id);
                break;
        }
        case STC_CMD_SET_TERMINATED:
index b12920e..3015b51 100755 (executable)
@@ -20,6 +20,7 @@
 #include "helper-nl.h"
 #include "helper-nfacct-rule.h"
 #include "helper-net-cls.h"
+#include "helper-cgroup.h"
 #include "counter.h"
 #include "table-statistics.h"
 #include "table-counters.h"
@@ -210,10 +211,12 @@ static gboolean __apps_tree_foreach_print(gpointer key, gpointer value,
        return FALSE;
 }
 
+#if 0
 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)
@@ -1094,10 +1097,8 @@ static stc_cb_ret_e __insert_restriction_cb(const table_restrictions_info *info,
        value.rst_state = info->rst_state;
        value.restriction_id = info->restriction_id;
 
-       if (value.rst_state != STC_RESTRICTION_EXCLUDED)
-               value.classid = get_classid_by_app_id(info->app_id ?
-                                                     info->app_id :
-                                                     STC_ALL_APP, TRUE);
+       if (value.rst_state != STC_RESTRICTION_EXCLUDED && info->app_id)
+               value.classid = get_classid_by_app_id(info->app_id, TRUE);
        else
                value.classid = STC_UNKNOWN_CLASSID;
 
@@ -1158,34 +1159,6 @@ static void __add_rstns_for_application(gchar *app_id)
                       app_id);
 }
 
-/* used only for (STC_ALL_APP/STC_BACKGROUND_APP_NAME) */
-static void __stc_monitor_add_application_by_app_id(const char *app_id)
-{
-       stc_app_key_s app_key;
-       stc_app_value_s app_value;
-
-       if (app_id == NULL)
-               return;
-
-       memset(&app_key, 0, sizeof(stc_app_key_s));
-       memset(&app_value, 0, sizeof(stc_app_value_s));
-
-       app_key.pkg_id = g_strdup(app_id);
-       app_key.app_id = g_strdup(app_id);
-
-       app_value.type = STC_APP_TYPE_NONE;
-       app_value.processes = NULL;
-       app_value.counter.in_bytes = 0;
-       app_value.counter.out_bytes = 0;
-
-       stc_monitor_application_add(app_key, app_value);
-
-       FREE(app_key.pkg_id);
-       FREE(app_key.app_id);
-
-       __apps_tree_printall();
-}
-
 stc_error_e stc_monitor_init(void)
 {
        stc_system_s *system = MALLOC0(stc_system_s, 1);
@@ -1193,6 +1166,9 @@ stc_error_e stc_monitor_init(void)
 
        ret_value_msg_if(system == NULL, STC_ERROR_OUT_OF_MEMORY, "stc_system_s malloc fail!");
 
+       /* initializing cgroups */
+       cgroup_init();
+
        /* creating monitored application tree */
        system->apps = g_tree_new_full(__apps_tree_key_compare, NULL,
                                       __apps_tree_key_free,
@@ -1219,16 +1195,6 @@ stc_error_e stc_monitor_init(void)
 
        g_system = system;
 
-       /* create entry for STC_ALL_APP */
-       __stc_monitor_add_application_by_app_id(STC_ALL_APP);
-
-       /* create entry for STC_BACKGROUND_APP_NAME */
-       __stc_monitor_add_application_by_app_id(STC_BACKGROUND_APP_NAME);
-
-       /* create background cgroup */
-       g_system->background_pids = NULL;
-       create_net_background_cgroup(g_system->background_pids);
-
        /* creating restriction rules tree */
        __update_contr_cb(NULL);
 
@@ -1260,10 +1226,6 @@ stc_error_e stc_monitor_deinit(void)
                g_system->contr_timer_id = 0;
        }
 
-       /* free background pid list */
-       g_slist_free(g_system->background_pids);
-       g_system->background_pids = NULL;
-
        /* destroy monitored application tree */
        g_tree_destroy(g_system->apps);
        g_system->apps = NULL;
@@ -1375,10 +1337,6 @@ 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);
 
-       /* add pid to background cgroup if gound state is background */
-       if (proc_value.ground == STC_APP_STATE_BACKGROUND)
-               add_pid_to_background_cgroup(proc_key.pid);
-
        return ret;
 }
 
@@ -1397,9 +1355,6 @@ stc_error_e stc_monitor_process_remove(pid_t pid)
 
        ret_value_msg_if(g_system == NULL, STC_ERROR_FAIL, "stc monitor not initialized!");
 
-       /* remove pid from background cgroup */
-       remove_pid_from_background_cgroup(pid);
-
        g_tree_foreach(g_system->apps, __apps_tree_foreach_remove_pid,
                       &context);
 
@@ -1434,10 +1389,15 @@ stc_error_e stc_monitor_process_update_ground(const stc_app_key_s app_key,
        if (proc_lookup->ground != ground)
                proc_lookup->ground = ground;
 
-       if (ground == STC_APP_STATE_BACKGROUND)
-               add_pid_to_background_cgroup(proc_key.pid);
-       else
+       if (ground == STC_APP_STATE_BACKGROUND) {
+               char *background_app_id = g_strconcat(app_key.app_id,
+                                                    STC_BACKGROUND_APP_SUFFIX,
+                                                    NULL);
+               place_pids_to_net_cgroup(proc_key.pid, background_app_id);
+               g_free(background_app_id);
+       } else {
                place_pids_to_net_cgroup(proc_key.pid, app_key.app_id);
+       }
 
        return ret;
 }
@@ -1500,10 +1460,8 @@ stc_error_e stc_monitor_rstns_tree_add(const table_restrictions_info *info)
        value.rst_state = info->rst_state;
        value.restriction_id = info->restriction_id;
 
-       if (value.rst_state != STC_RESTRICTION_EXCLUDED)
-               value.classid = get_classid_by_app_id(info->app_id ?
-                                                     info->app_id :
-                                                     STC_ALL_APP, TRUE);
+       if (value.rst_state != STC_RESTRICTION_EXCLUDED && info->app_id)
+               value.classid = get_classid_by_app_id(info->app_id, TRUE);
        else
                value.classid = STC_UNKNOWN_CLASSID;
 
index 11f5040..7d41deb 100755 (executable)
@@ -2,10 +2,11 @@
 #include <stdio.h>
 #include <unistd.h>
 
-#define MAX_PATH_LENGTH 512
-#define DEFAULT_CGROUP       "/sys/fs/cgroup"
-#define CGROUP_NETWORK       DEFAULT_CGROUP "/net_cls"
-#define PATH_TO_NET_CGROUP_DIR CGROUP_NETWORK
+#define MAX_PATH_LENGTH         512
+#define DEFAULT_CGROUP          "/sys/fs/cgroup"
+#define CGROUP_NETWORK          DEFAULT_CGROUP "/net_cls"
+#define STC_CGROUP_NETWORK      CGROUP_NETWORK "/stc"
+#define PATH_TO_NET_CGROUP_DIR  STC_CGROUP_NETWORK
 
 int main(int argc, char *argv[])
 {