Merge "[REFACTOR] Buffer: move getting next queue element into separate function"
[kernel/swap-modules.git] / parser / msg_parser.c
1 /*
2  *  SWAP Parser
3  *  modules/parser/msg_parser.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Vyacheslav Cherkashin, Vitaliy Cherepanov: SWAP Parser implement
22  *
23  */
24
25
26 #include <linux/slab.h>
27 #include "msg_parser.h"
28 #include "msg_buf.h"
29 #include "parser_defs.h"
30
31
32 static int str_to_u32(const char* str, u32 *val)
33 {
34         u32 result;
35         if(!str || !*str)
36                 return -EINVAL;
37
38         for (result = 0 ; *str; ++str) {
39                 if (*str < '0' || *str> '9')
40                         return -EINVAL;
41
42                 result = result * 10 + (*str - '0');
43         }
44
45         *val = result;
46
47         return 0;
48 }
49
50
51
52
53
54 /* ============================================================================
55  * ==                               APP_INFO                                 ==
56  * ============================================================================
57  */
58 struct app_info_data *create_app_info(struct msg_buf *mb)
59 {
60         int ret;
61         struct app_info_data *ai;
62         u32 app_type;
63         char *ta_id, *exec_path;
64
65         print_parse_debug("app_info:\n");
66
67         print_parse_debug("type:");
68         ret = get_u32(mb, &app_type);
69         if (ret) {
70                 print_err("failed to read target application type\n");
71                 return NULL;
72         }
73
74         print_parse_debug("id:");
75         ret = get_string(mb, &ta_id);
76         if (ret) {
77                 print_err("failed to read target application ID\n");
78                 return NULL;
79         }
80
81         print_parse_debug("exec path:");
82         ret = get_string(mb, &exec_path);
83         if (ret) {
84                 print_err("failed to read executable path\n");
85                 goto free_ta_id;
86         }
87
88         ai = kmalloc(sizeof(*ai), GFP_KERNEL);
89         if (ai == NULL) {
90                 print_err("out of memory\n");
91                 goto free_exec_path;
92         }
93
94         switch (app_type) {
95         case AT_TIZEN_NATIVE_APP:
96         case AT_TIZEN_WEB_APP:
97         case AT_COMMON_EXEC:
98                 ai->tgid = 0;
99                 break;
100         case AT_PID: {
101                 u32 tgid = 0;
102
103                 if (*ta_id != '\0') {
104                         ret = str_to_u32(ta_id, &tgid);
105                         if (ret) {
106                                 print_err("converting string to PID, "
107                                           "str='%s'\n", ta_id);
108                                 goto free_ai;
109                         }
110                 }
111
112                 ai->tgid = tgid;
113                 break;
114         }
115         default:
116                 print_err("wrong application type(%u)\n", app_type);
117                 ret = -EINVAL;
118                 goto free_ai;
119         }
120
121         ai->app_type = (enum APP_TYPE)app_type;
122         ai->exec_path = exec_path;
123
124         put_string(ta_id);
125
126         return ai;
127
128 free_ai:
129         kfree(ai);
130
131 free_exec_path:
132         put_string(exec_path);
133
134 free_ta_id:
135         put_string(ta_id);
136
137         return NULL;
138 }
139
140 void destroy_app_info(struct app_info_data *ai)
141 {
142         put_string(ai->exec_path);
143         kfree(ai);
144 }
145
146
147
148
149
150 /* ============================================================================
151  * ==                                CONFIG                                  ==
152  * ============================================================================
153  */
154 struct conf_data *create_conf_data(struct msg_buf *mb)
155 {
156         struct conf_data *conf;
157         u64 use_features0, use_features1;
158         u32 stp, dmp;
159
160         print_parse_debug("conf_data:\n");
161
162         print_parse_debug("features:");
163         if (get_u64(mb, &use_features0)) {
164                 print_err("failed to read use_features\n");
165                 return NULL;
166         }
167
168         if (get_u64(mb, &use_features1)) {
169                 print_err("failed to read use_features\n");
170                 return NULL;
171         }
172
173         print_parse_debug("sys trace period:");
174         if (get_u32(mb, &stp)) {
175                 print_err("failed to read sys trace period\n");
176                 return NULL;
177         }
178
179         print_parse_debug("data msg period:");
180         if (get_u32(mb, &dmp)) {
181                 print_err("failed to read data message period\n");
182                 return NULL;
183         }
184
185         conf = kmalloc(sizeof(*conf), GFP_KERNEL);
186         if (conf == NULL) {
187                 print_err("out of memory\n");
188                 return NULL;
189         }
190
191         conf->use_features0 = use_features0;
192         conf->use_features1 = use_features1;
193         conf->sys_trace_period = stp;
194         conf->data_msg_period = dmp;
195
196         return conf;
197 }
198
199 void destroy_conf_data(struct conf_data *conf)
200 {
201         kfree(conf);
202 }
203
204 static struct conf_data config;
205 void save_config(const struct conf_data *conf)
206 {
207         memcpy(&config, conf, sizeof(config));
208 }
209
210 void restore_config(struct conf_data *conf)
211 {
212         memcpy(conf, &config, sizeof(*conf));
213 }
214
215
216
217 /* ============================================================================
218  * ==                               FUNC_INST                                ==
219  * ============================================================================
220  */
221 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
222 {
223         struct func_inst_data *fi;
224         u64 addr;
225         char *args;
226         char ret_type;
227
228         print_parse_debug("func addr:");
229         if (get_u64(mb, &addr)) {
230                 print_err("failed to read data function address\n");
231                 return NULL;
232         }
233
234         print_parse_debug("funct args:");
235         if (get_string(mb, &args)) {
236                 print_err("failed to read data function arguments\n");
237                 return NULL;
238         }
239
240         print_parse_debug("funct ret type:");
241         if (get_u8(mb, (u8 *)&ret_type)) {
242                 print_err("failed to read data function arguments\n");
243                 goto free_args;
244         }
245
246         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
247         if (fi == NULL) {
248                 print_err("out of memory\n");
249                 goto free_args;
250         }
251
252         fi->addr = addr;
253         fi->args = args;
254         fi->ret_type = ret_type;
255
256         return fi;
257
258 free_args:
259         put_string(args);
260         return NULL;
261 }
262
263 void destroy_func_inst_data(struct func_inst_data *fi)
264 {
265         put_string(fi->args);
266         kfree(fi);
267 }
268
269
270
271
272
273 /* ============================================================================
274  * ==                               LIB_INST                                 ==
275  * ============================================================================
276  */
277 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
278 {
279         struct lib_inst_data *li;
280         struct func_inst_data *fi;
281         char *path;
282         u32 cnt, j, i = 0;
283
284         print_parse_debug("bin path:");
285         if (get_string(mb, &path)) {
286                 print_err("failed to read path of binary\n");
287                 return NULL;
288         }
289
290         print_parse_debug("func count:");
291         if (get_u32(mb, &cnt)) {
292                 print_err("failed to read count of functions\n");
293                 goto free_path;
294         }
295
296         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
297                 print_err("to match count of functions(%u)\n", cnt);
298                 goto free_path;
299         }
300
301         li = kmalloc(sizeof(*li), GFP_KERNEL);
302         if (li == NULL)
303         if (li == NULL) {
304                 print_err("out of memory\n");
305                 goto free_path;
306         }
307
308         li->func = kmalloc(sizeof(struct func_inst_data *) * cnt, GFP_KERNEL);
309         if (li->func == NULL)
310         if (li->func == NULL) {
311                 print_err("out of memory\n");
312                 goto free_li;
313         }
314
315         for (i = 0; i < cnt; ++i) {
316                 print_parse_debug("func #%d:\n", i + 1);
317                 fi = create_func_inst_data(mb);
318                 if (fi == NULL)
319                         goto free_func;
320
321                 li->func[i] = fi;
322         }
323
324         li->path = path;
325         li->cnt_func = cnt;
326
327         return li;
328
329 free_func:
330         for (j = 0; j < i; ++j)
331                 destroy_func_inst_data(li->func[j]);
332         kfree(li->func);
333
334 free_li:
335         kfree(li);
336
337 free_path:
338         put_string(path);
339
340         return NULL;
341 }
342
343 void destroy_lib_inst_data(struct lib_inst_data *li)
344 {
345         int i;
346
347         put_string(li->path);
348
349         for (i = 0; i < li->cnt_func; ++i)
350                 destroy_func_inst_data(li->func[i]);
351
352         kfree(li->func);
353         kfree(li);
354 }
355
356
357
358
359
360 /* ============================================================================
361  * ==                               APP_INST                                 ==
362  * ============================================================================
363  */
364 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
365 {
366         struct app_inst_data *app_inst;
367         struct app_info_data *app_info;
368         struct func_inst_data *func;
369         struct lib_inst_data *lib;
370         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
371
372         app_info = create_app_info(mb);
373         if (app_info == NULL)
374                 return NULL;
375
376         print_parse_debug("func count:");
377         if (get_u32(mb, &cnt_func)) {
378                 print_err("failed to read count of functions\n");
379                 goto free_app_info;
380         }
381
382         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
383                 print_err("to match count of functions(%u)\n", cnt_func);
384                 goto free_app_info;
385         }
386
387         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
388         if (app_inst == NULL) {
389                 print_err("out of memory\n");
390                 goto free_app_info;
391         }
392
393         app_inst->func = kmalloc(sizeof(struct func_inst_data *) * cnt_func,
394                                  GFP_KERNEL);
395         if (app_inst->func == NULL) {
396                 print_err("out of memory\n");
397                 goto free_app_inst;
398         }
399
400         for (i_func = 0; i_func < cnt_func; ++i_func) {
401                 print_parse_debug("func #%d:\n", i_func + 1);
402                 func = create_func_inst_data(mb);
403                 if (func == NULL)
404                         goto free_func;
405
406                 app_inst->func[i_func] = func;
407         }
408
409         print_parse_debug("lib count:");
410         if (get_u32(mb, &cnt_lib)) {
411                 print_err("failed to read count of libraries\n");
412                 goto free_func;
413         }
414
415         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
416                 print_err("to match count of libraries(%u)\n", cnt_lib);
417                 goto free_func;
418         }
419
420         app_inst->lib = kmalloc(sizeof(struct lib_inst_data *) * cnt_lib,
421                                 GFP_KERNEL);
422         if (app_inst->lib == NULL) {
423                 print_err("out of memory\n");
424                 goto free_func;
425         }
426
427         for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
428                 print_parse_debug("lib #%d:\n", i_lib + 1);
429                 lib = create_lib_inst_data(mb);
430                 if (lib == NULL)
431                         goto free_lib;
432
433                 app_inst->lib[i_lib] = lib;
434         }
435
436         app_inst->app_info = app_info;
437         app_inst->cnt_func = cnt_func;
438         app_inst->cnt_lib = cnt_lib;
439
440         return app_inst;
441
442 free_lib:
443         for (i = 0; i < i_lib; ++i)
444                 destroy_lib_inst_data(app_inst->lib[i]);
445         kfree(app_inst->lib);
446
447 free_func:
448         for (i = 0; i < i_func; ++i)
449                 destroy_func_inst_data(app_inst->func[i]);
450         kfree(app_inst->func);
451
452 free_app_inst:
453         kfree(app_inst);
454
455 free_app_info:
456         destroy_app_info(app_info);
457
458         return NULL;
459 }
460
461 void destroy_app_inst_data(struct app_inst_data *ai)
462 {
463         int i;
464
465         for (i = 0; i < ai->cnt_lib; ++i)
466                 destroy_lib_inst_data(ai->lib[i]);
467         kfree(ai->lib);
468
469         for (i = 0; i < ai->cnt_func; ++i)
470                 destroy_func_inst_data(ai->func[i]);
471         kfree(ai->func);
472
473         destroy_app_info(ai->app_info);
474         kfree(ai);
475 }
476
477
478
479
480
481 /* ============================================================================
482  * ==                                US_INST                                 ==
483  * ============================================================================
484  */
485 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
486 {
487         struct us_inst_data *ui;
488         struct app_inst_data *ai;
489         u32 cnt, j, i = 0;
490
491         print_parse_debug("us_inst_data:\n");
492
493         print_parse_debug("app count:");
494         if (get_u32(mb, &cnt)) {
495                 print_err("failed to read count of applications\n");
496                 return NULL;
497         }
498
499         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
500                 print_err("to match count of applications(%u)\n", cnt);
501                 return NULL;
502         }
503
504         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
505         if (ui == NULL) {
506                 print_err("out of memory\n");
507                 return NULL;
508         }
509
510         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
511                                GFP_KERNEL);
512         if (ui->app_inst == NULL) {
513                 print_err("out of memory\n");
514                 goto free_ui;
515         }
516
517         for (i = 0; i < cnt; ++i) {
518                 print_parse_debug("app #%d:\n",i+1);
519                 ai = create_app_inst_data(mb);
520                 if (ai == NULL)
521                         goto free_app_inst;
522
523                 ui->app_inst[i] = ai;
524         }
525
526         ui->cnt = cnt;
527
528         return ui;
529
530 free_app_inst:
531         for (j = 0; j < i; ++j)
532                 destroy_app_inst_data(ui->app_inst[j]);
533         kfree(ui->app_inst);
534
535 free_ui:
536         kfree(ui);
537
538         return NULL;
539 }
540
541 void destroy_us_inst_data(struct us_inst_data *ui)
542 {
543         int i;
544
545         for (i = 0; i < ui->cnt; ++i)
546                 destroy_app_inst_data(ui->app_inst[i]);
547
548         kfree(ui->app_inst);
549         kfree(ui);
550 }