Add gitlab issue/merge request templates
[staging/basesystem.git] / service / native / common_library / client / src / cl_cgroup.c
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include "cl_cgroup.h"
27
28 #define CL_CGROOT "/sys/fs/cgroup/"
29
30 static char *cl_cgroup_base(cl_cgroup_t cgroup) {
31   switch (cgroup) { // LCOV_EXCL_BR_LINE 200: internal interface,code make sure
32     case CL_CGROUP_MEMORY:
33       return CL_CGROOT "/memory";
34     case CL_CGROUP_CPU:
35       return CL_CGROOT "/cpu";
36   }
37   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
38
39   return NULL;// LCOV_EXCL_LINE 200:internal interface,code make sure nerver run
40 }
41
42 static char *cl_cgroup_create_path(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler) {
43   char *path = malloc(FILENAME_MAX);
44
45   if (path == NULL) { // LCOV_EXCL_BR_LINE 5:fail safe for libc  malloc
46     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
47
48     errno = ENOMEM; // LCOV_EXCL_LINE 5:fail safe for libc  malloc
49     goto error; // LCOV_EXCL_LINE 5:fail safe for libc  malloc
50   }
51
52   if (cgroup != CL_CGROUP_MEMORY && cgroup != CL_CGROUP_CPU) { // LCOV_EXCL_BR_LINE 200: internal interface,code make sure
53     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
54
55     errno = EINVAL; // LCOV_EXCL_LINE 200: internal interface,code make sure
56     goto error; // LCOV_EXCL_LINE 200: internal interface,code make sure
57   }
58
59   if (cgroup_name == NULL) { // LCOV_EXCL_BR_LINE 200: internal interface,code make sure
60     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
61
62     errno = EINVAL; // LCOV_EXCL_LINE 200: internal interface,code make sure
63     goto error; // LCOV_EXCL_LINE 200: internal interface,code make sure
64   }
65
66   if (controler) {
67     snprintf(path, FILENAME_MAX, "%s/%s/%s", cl_cgroup_base(cgroup), cgroup_name, controler);
68   } else {
69     snprintf(path, FILENAME_MAX, "%s/%s", cl_cgroup_base(cgroup), cgroup_name);
70   }
71
72   return path;
73
74 error:
75   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
76
77   free(path); // LCOV_EXCL_LINE 200: internal interface,code make sure
78   return NULL; // LCOV_EXCL_LINE 200: internal interface,code make sure
79 }
80
81 int cl_cgroup_make(cl_cgroup_t cgroup, const char *cgroup_name) {
82   int r = -1;
83   char *path = cl_cgroup_create_path(cgroup, cgroup_name, NULL);
84
85   if (path == NULL) {  // LCOV_EXCL_BR_LINE 6: double check
86     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
87
88     goto exit;  // LCOV_EXCL_LINE 6: double check
89   }
90
91   if (mkdir(path, 0777) < 0) { // LCOV_EXCL_BR_LINE 5:fail safe for libc mkdir
92     goto exit;
93   }
94
95   r = 0;
96
97 exit:
98   if (path) {// LCOV_EXCL_BR_LINE 6: double check
99     free(path);
100   }
101   return r;
102 }
103
104 int cl_cgroup_remove(cl_cgroup_t cgroup, const char *cgroup_name) {
105   int r = -1;
106   char *path = cl_cgroup_create_path(cgroup, cgroup_name, NULL);
107
108   if (path == NULL) { // LCOV_EXCL_BR_LINE 6: double check
109     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
110
111     goto exit; // LCOV_EXCL_LINE 6: double check
112   }
113
114   if (rmdir(path) < 0) { // LCOV_EXCL_BR_LINE 5:fail safe for libc rmdir
115     goto exit;
116   }
117
118   r = 0;
119
120 exit:
121   if (path) { // LCOV_EXCL_BR_LINE 6: double check
122     free(path);
123   }
124   return r;
125 }
126
127 int cl_cgroup_exist(cl_cgroup_t cgroup, const char *cgroup_name) {
128   int r = -1;
129   char *path = cl_cgroup_create_path(cgroup, cgroup_name, NULL);
130
131   if (path == NULL) { // LCOV_EXCL_BR_LINE 6: double check
132     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
133
134     goto exit; // LCOV_EXCL_LINE 6: double check
135   }
136
137   r = access(path, F_OK);
138
139 exit:
140   if (path) { // LCOV_EXCL_BR_LINE 6: double check
141     free(path);
142   }
143   return r;
144 }
145
146 int cl_cgroup_open(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler, int flags) {
147   int r = -1;
148   char *path = cl_cgroup_create_path(cgroup, cgroup_name, controler);
149   int fd = -1;
150
151   if (path == NULL) { // LCOV_EXCL_BR_LINE 6: double check
152     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
153
154     goto exit; // LCOV_EXCL_LINE 6: double check
155   }
156
157   if (controler == NULL) { // LCOV_EXCL_BR_LINE 6: double check
158     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
159
160     errno = EINVAL;  // LCOV_EXCL_LINE 6: double check
161     goto exit;  // LCOV_EXCL_LINE 6: double check
162   }
163
164   if ((fd = open(path, flags | O_CLOEXEC)) < 0) {  // LCOV_EXCL_BR_LINE 5:fail safe for libc open
165     goto exit;
166   }
167
168   r = fd;
169
170 exit:
171   if (path) { // LCOV_EXCL_BR_LINE 6: double check
172     free(path);
173   }
174   return r;
175 }
176
177 int cl_cgroup_set_string(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler, const char *string) {
178   int r = -1;
179   int fd = -1;
180
181   if (controler == NULL || string == NULL) { // LCOV_EXCL_BR_LINE 6: double check
182     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
183
184     errno = EINVAL;// LCOV_EXCL_LINE 6: double check
185     goto exit;// LCOV_EXCL_LINE 6: double check
186   }
187
188   fd = cl_cgroup_open(cgroup, cgroup_name, controler, O_WRONLY);
189   if (fd < 0) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc funtion open
190     goto exit;
191   }
192
193   if (write(fd, string, strlen(string)) < 0) {  // LCOV_EXCL_BR_LINE 5:fail safe for libc write
194     goto exit;
195   }
196
197   r = 0;
198
199 exit:
200   if (fd >= 0) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc funtion open
201     int save_err = errno;
202     close(fd);
203     errno = save_err;
204   }
205   return r;
206 }
207
208 int cl_cgroup_set_num(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler, int64_t value) {
209   char num_str[22];
210
211   snprintf(num_str, sizeof(num_str), "%" PRId64, value);
212
213   return cl_cgroup_set_string(cgroup, cgroup_name, controler, num_str);
214 }
215
216 int cl_cgroup_get_string(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler, char *string, size_t length) {  // LCOV_EXCL_START 8: dead code  // NOLINT (readability/nolint)
217   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
218
219   int r = -1;
220   int fd = -1;
221
222   if (controler == NULL || string == NULL) {
223     errno = EINVAL;
224     goto exit;
225   }
226
227   fd = cl_cgroup_open(cgroup, cgroup_name, controler, O_RDONLY);
228   if (fd < 0) {
229     goto exit;
230   }
231
232   if (read(fd, string, length) < 0) {
233     goto exit;
234   }
235
236   r = 0;
237
238 exit:
239   if (fd >= 0) {
240     int save_err = errno;
241     close(fd);
242     errno = save_err;
243   }
244   return r;
245 }
246 // LCOV_EXCL_STOP
247
248 int64_t cl_cgroup_get_num(cl_cgroup_t cgroup, const char *cgroup_name, const char *controler) {  // LCOV_EXCL_START 8: dead code  // NOLINT (readability/nolint)
249   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
250
251   int r;
252   char num_str[22];
253
254   if ((r = cl_cgroup_get_string(cgroup, cgroup_name, controler, num_str, sizeof(num_str))) < 0) {
255     return r;
256   }
257
258   return atoll(num_str);
259 }
260 // LCOV_EXCL_STOP