#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 */
#include "stc-db.h"
-#define STC_BACKGROUND_APP_NAME "BACKGROUND"
-#define NETWORK_RESTRICTION_APP_NAME "NETWORKRESTRICTION"
-
struct counter_arg {
int sock;
int ans_len;
#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 " \
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);
+}
#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
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__*/
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;
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);
}
#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
gboolean rstns_tree_updated;
GTree *apps; /**< monitored applications */
gboolean apps_tree_updated;
- GSList *background_pids; /**< list of background pids */
} stc_system_s;
/**
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:
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:
#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"
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)
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;
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);
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,
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);
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;
/* 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;
}
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);
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;
}
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;
#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[])
{