2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "helper-cgroup.h"
26 #include "helper-file.h"
27 #include "helper-net-cls.h"
29 #define CUR_CLASSID_PATH "/var/lib/stc/cur_classid"
30 #define CLASSID_FILE_NAME "net_cls.classid"
32 typedef GArray task_classid_array;
34 static uint32_t __produce_classid(check_classid_used_cb check_classid_cb)
36 uint32_t classid = STC_RESERVED_CLASSID_MAX;
37 int ret = fread_uint(CUR_CLASSID_PATH, &classid);
39 STC_LOGI("Can not read current classid"); //LCOV_EXCL_LINE
43 if (check_classid_cb) {
44 int classid_test_count = 0;
45 for (classid_test_count = 0; classid_test_count < INT32_MAX;
47 if (!check_classid_cb(classid))
52 ret = fwrite_uint(CUR_CLASSID_PATH, ++classid);
54 STC_LOGE("Can not write classid"); //LCOV_EXCL_LINE
59 static int __place_classid_to_cgroup(const char *cgroup, const char *subdir,
61 check_classid_used_cb cb)
63 char buf[MAX_PATH_LENGTH];
64 uint32_t result_classid = (classid && *classid) ? *classid :
65 __produce_classid(cb);
67 /* set classid as out argument */
68 if (classid && !*classid)
69 *classid = result_classid;
71 snprintf(buf, sizeof(buf), "%s/%s", cgroup, subdir);
72 return cgroup_write_node_uint32(buf, CLASSID_FILE_NAME, result_classid);
75 static stc_error_e __get_classid_from_cgroup(const char *cgroup,
76 const char *subdir, uint32_t *classid)
78 char buf[MAX_PATH_LENGTH];
79 snprintf(buf, sizeof(buf), "%s/%s", cgroup, subdir);
81 int ret = cgroup_read_node_uint32(buf, CLASSID_FILE_NAME, classid);
83 STC_LOGE("Can't read classid from cgroup %s", buf); //LCOV_EXCL_LINE
84 *classid = STC_UNKNOWN_CLASSID;
85 return STC_ERROR_NO_DATA;
88 return STC_ERROR_NONE;
91 stc_error_e init_current_classid(void)
96 if (stat(STC_CGROUP_NETWORK, &stat_buf) != 0) {
97 uint32_t classid = STC_RESERVED_CLASSID_MAX;
98 ret = fwrite_uint(CUR_CLASSID_PATH, classid);
100 STC_LOGE("Can not init current classid"); //LCOV_EXCL_LINE
101 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
105 return STC_ERROR_NONE;
108 API uint32_t get_classid_by_app_id(const char *app_id, int create)
111 int ret = STC_ERROR_NONE;
112 uint32_t classid = STC_UNKNOWN_CLASSID;
113 const char *path_to_net_cgroup_dir = NULL;
115 if (app_id == NULL) {
116 STC_LOGE("app_id must be not empty"); //LCOV_EXCL_LINE
117 return STC_UNKNOWN_CLASSID; //LCOV_EXCL_LINE
120 if (!strcmp(app_id, STC_TOTAL_BACKGROUND))
121 return STC_BACKGROUND_APP_CLASSID;
123 if (!strcmp(app_id, STC_TOTAL_DATACALL))
124 return STC_TOTAL_DATACALL_CLASSID;
126 if (!strcmp(app_id, STC_TOTAL_WIFI))
127 return STC_TOTAL_WIFI_CLASSID;
129 if (!strcmp(app_id, STC_TOTAL_BLUETOOTH))
130 return STC_TOTAL_BLUETOOTH_CLASSID;
132 if (!strcmp(app_id, STC_TOTAL_IPV4))
133 return STC_TOTAL_IPV4_CLASSID;
135 if (!strcmp(app_id, STC_TOTAL_IPV6))
136 return STC_TOTAL_IPV6_CLASSID;
138 if (!strcmp(app_id, STC_TOTAL_TETHERING))
139 return STC_TETHERING_APP_CLASSID;
141 if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
142 path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
143 else if (strstr(app_id, STC_TETHERING_APP_SUFFIX))
144 path_to_net_cgroup_dir = TETHERING_CGROUP_NETWORK;
146 path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK;
150 ret = __get_classid_from_cgroup(path_to_net_cgroup_dir, //LCOV_EXCL_LINE
153 if (ret != STC_ERROR_NONE)
154 return STC_UNKNOWN_CLASSID;
156 if (classid != STC_UNKNOWN_CLASSID)
159 ret = cgroup_make_subdir(path_to_net_cgroup_dir, (char *)app_id,
165 ret = __get_classid_from_cgroup(path_to_net_cgroup_dir,
168 ret = __place_classid_to_cgroup(path_to_net_cgroup_dir,
169 (char *)app_id, &classid, NULL);
171 goto handle_error; //LCOV_EXCL_LINE
177 STC_LOGE("error_code: [%d]", ret); //LCOV_EXCL_LINE
178 return STC_UNKNOWN_CLASSID; //LCOV_EXCL_LINE
181 stc_error_e place_pids_to_net_cgroup(const int pid, const char *app_id)
183 char child_buf[21 + MAX_DEC_SIZE(int) + MAX_DEC_SIZE(int) + 1];
184 const char *path_to_net_cgroup_dir = NULL;
186 snprintf(child_buf, sizeof(child_buf), PROC_TASK_CHILDREN, pid, pid);
188 if (app_id == NULL) {
189 STC_LOGE("package name must be not empty"); //LCOV_EXCL_LINE
190 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
193 if (strstr(app_id, STC_BACKGROUND_APP_SUFFIX))
194 path_to_net_cgroup_dir = BACKGROUND_CGROUP_NETWORK;
195 else if (strstr(app_id, STC_TETHERING_APP_SUFFIX))
196 path_to_net_cgroup_dir = TETHERING_CGROUP_NETWORK;
198 path_to_net_cgroup_dir = FOREGROUND_CGROUP_NETWORK; //LCOV_EXCL_LINE
200 if (access(child_buf, F_OK))
201 return cgroup_write_pid(path_to_net_cgroup_dir, app_id, pid);
203 return cgroup_write_pidtree(path_to_net_cgroup_dir, app_id, pid); //LCOV_EXCL_LINE