Merge commit 'fee9d083f74f' into kernel
[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_COMMON_EXEC:
97                 ai->tgid = 0;
98                 break;
99         case AT_PID: {
100                 u32 tgid;
101                 ret = str_to_u32(ta_id, &tgid);
102                 if (ret) {
103                         print_err("converting string to PID, str='%s'\n", ta_id);
104                         goto free_ai;
105                 }
106
107                 ai->tgid = tgid;
108                 break;
109         }
110         default:
111                 print_err("wrong application type(%u)\n", app_type);
112                 ret = -EINVAL;
113                 goto free_ai;
114         }
115
116         ai->app_type = (enum APP_TYPE)app_type;
117         ai->exec_path = exec_path;
118
119         put_string(ta_id);
120
121         return ai;
122
123 free_ai:
124         kfree(ai);
125
126 free_exec_path:
127         put_string(exec_path);
128
129 free_ta_id:
130         put_string(ta_id);
131
132         return NULL;
133 }
134
135 void destroy_app_info(struct app_info_data *ai)
136 {
137         put_string(ai->exec_path);
138         kfree(ai);
139 }
140
141
142
143
144
145 /* ============================================================================
146  * ==                                CONFIG                                  ==
147  * ============================================================================
148  */
149 struct conf_data *create_conf_data(struct msg_buf *mb)
150 {
151         struct conf_data *conf;
152         u64 use_features0, use_features1;
153         u32 stp, dmp;
154
155         print_parse_debug("conf_data:\n");
156
157         print_parse_debug("features:");
158         if (get_u64(mb, &use_features0)) {
159                 print_err("failed to read use_features\n");
160                 return NULL;
161         }
162
163         if (get_u64(mb, &use_features1)) {
164                 print_err("failed to read use_features\n");
165                 return NULL;
166         }
167
168         print_parse_debug("sys trace period:");
169         if (get_u32(mb, &stp)) {
170                 print_err("failed to read sys trace period\n");
171                 return NULL;
172         }
173
174         print_parse_debug("data msg period:");
175         if (get_u32(mb, &dmp)) {
176                 print_err("failed to read data message period\n");
177                 return NULL;
178         }
179
180         conf = kmalloc(sizeof(*conf), GFP_KERNEL);
181         if (conf == NULL) {
182                 print_err("out of memory\n");
183                 return NULL;
184         }
185
186         conf->use_features0 = use_features0;
187         conf->use_features1 = use_features1;
188         conf->sys_trace_period = stp;
189         conf->data_msg_period = dmp;
190
191         return conf;
192 }
193
194 void destroy_conf_data(struct conf_data *conf)
195 {
196         kfree(conf);
197 }
198
199
200
201
202
203 /* ============================================================================
204  * ==                               FUNC_INST                                ==
205  * ============================================================================
206  */
207 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
208 {
209         struct func_inst_data *fi;
210         u64 addr;
211         char *args;
212
213         print_parse_debug("func addr:");
214         if (get_u64(mb, &addr)) {
215                 print_err("failed to read data function address\n");
216                 return NULL;
217         }
218
219         print_parse_debug("funct args:");
220         if (get_string(mb, &args)) {
221                 print_err("failed to read data function arguments\n");
222                 return NULL;
223         }
224
225         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
226         if (fi == NULL) {
227                 print_err("out of memory\n");
228                 put_string(args);
229                 return NULL;
230         }
231
232         fi->addr = addr;
233         fi->args = args;
234
235         return fi;
236 }
237
238 void destroy_func_inst_data(struct func_inst_data *fi)
239 {
240         put_string(fi->args);
241         kfree(fi);
242 }
243
244
245
246
247
248 /* ============================================================================
249  * ==                               LIB_INST                                 ==
250  * ============================================================================
251  */
252 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
253 {
254         struct lib_inst_data *li;
255         struct func_inst_data *fi;
256         char *path;
257         u32 cnt, j, i = 0;
258
259         print_parse_debug("bin path:");
260         if (get_string(mb, &path)) {
261                 print_err("failed to read path of binary\n");
262                 return NULL;
263         }
264
265         print_parse_debug("func count:");
266         if (get_u32(mb, &cnt)) {
267                 print_err("failed to read count of functions\n");
268                 return NULL;
269         }
270
271         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
272                 print_err("to match count of functions(%u)\n", cnt);
273                 return NULL;
274         }
275
276         li = kmalloc(sizeof(*li), GFP_KERNEL);
277         if (li == NULL)
278         if (li == NULL) {
279                 print_err("out of memory\n");
280                 goto free_path;
281         }
282
283         li->func = kmalloc(sizeof(struct func_inst_data *) * cnt, GFP_KERNEL);
284         if (li->func == NULL)
285         if (li->func == NULL) {
286                 print_err("out of memory\n");
287                 goto free_li;
288         }
289
290         for (i = 0; i < cnt; ++i) {
291                 print_parse_debug("func #%d:\n", i + 1);
292                 fi = create_func_inst_data(mb);
293                 if (fi == NULL)
294                         goto free_func;
295
296                 li->func[i] = fi;
297         }
298
299         li->path = path;
300         li->cnt_func = cnt;
301
302         return li;
303
304 free_func:
305         for (j = 0; j < i; ++j)
306                 destroy_func_inst_data(li->func[j]);
307         kfree(li->func);
308
309 free_li:
310         kfree(li);
311
312 free_path:
313         put_string(path);
314
315         return NULL;
316 }
317
318 void destroy_lib_inst_data(struct lib_inst_data *li)
319 {
320         int i;
321
322         put_string(li->path);
323
324         for (i = 0; i < li->cnt_func; ++i)
325                 destroy_func_inst_data(li->func[i]);
326
327         kfree(li->func);
328         kfree(li);
329 }
330
331
332
333
334
335 /* ============================================================================
336  * ==                               APP_INST                                 ==
337  * ============================================================================
338  */
339 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
340 {
341         struct app_inst_data *app_inst;
342         struct app_info_data *app_info;
343         struct func_inst_data *func;
344         struct lib_inst_data *lib;
345         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
346
347         app_info = create_app_info(mb);
348         if (app_info == NULL)
349                 return NULL;
350
351         print_parse_debug("func count:");
352         if (get_u32(mb, &cnt_func)) {
353                 print_err("failed to read count of functions\n");
354                 goto free_app_info;
355         }
356
357         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
358                 print_err("to match count of functions(%u)\n", cnt_func);
359                 goto free_app_info;
360         }
361
362         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
363         if (app_inst == NULL) {
364                 print_err("out of memory\n");
365                 goto free_app_info;
366         }
367
368         app_inst->func = kmalloc(sizeof(struct func_inst_data *) * cnt_func,
369                                  GFP_KERNEL);
370         if (app_inst->func == NULL) {
371                 print_err("out of memory\n");
372                 goto free_app_inst;
373         }
374
375         for (i_func = 0; i_func < cnt_func; ++i_func) {
376                 print_parse_debug("func #%d:\n", i_func + 1);
377                 func = create_func_inst_data(mb);
378                 if (func == NULL)
379                         goto free_func;
380
381                 app_inst->func[i_func] = func;
382         }
383
384         print_parse_debug("lib count:");
385         if (get_u32(mb, &cnt_lib)) {
386                 print_err("failed to read count of libraries\n");
387                 goto free_func;
388         }
389
390         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
391                 print_err("to match count of libraries(%u)\n", cnt_lib);
392                 goto free_func;
393         }
394
395         app_inst->lib = kmalloc(sizeof(struct lib_inst_data *) * cnt_lib,
396                                 GFP_KERNEL);
397         if (app_inst->lib == NULL) {
398                 print_err("out of memory\n");
399                 goto free_func;
400         }
401
402         for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
403                 print_parse_debug("lib #%d:\n", i_lib + 1);
404                 lib = create_lib_inst_data(mb);
405                 if (lib == NULL)
406                         goto free_lib;
407
408                 app_inst->lib[i_lib] = lib;
409         }
410
411         app_inst->app_info = app_info;
412         app_inst->cnt_func = cnt_func;
413         app_inst->cnt_lib = cnt_lib;
414
415         return app_inst;
416
417 free_lib:
418         for (i = 0; i < i_lib; ++i)
419                 destroy_lib_inst_data(app_inst->lib[i]);
420         kfree(app_inst->lib);
421
422 free_func:
423         for (i = 0; i < i_func; ++i)
424                 destroy_func_inst_data(app_inst->func[i]);
425         kfree(app_inst->func);
426
427 free_app_inst:
428         kfree(app_inst);
429
430 free_app_info:
431         destroy_app_info(app_info);
432
433         return NULL;
434 }
435
436 void destroy_app_inst_data(struct app_inst_data *ai)
437 {
438         int i;
439
440         for (i = 0; i < ai->cnt_lib; ++i)
441                 destroy_lib_inst_data(ai->lib[i]);
442         kfree(ai->lib);
443
444         for (i = 0; i < ai->cnt_func; ++i)
445                 destroy_func_inst_data(ai->func[i]);
446         kfree(ai->func);
447
448         destroy_app_info(ai->app_info);
449         kfree(ai);
450 }
451
452
453
454
455
456 /* ============================================================================
457  * ==                                US_INST                                 ==
458  * ============================================================================
459  */
460 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
461 {
462         struct us_inst_data *ui;
463         struct app_inst_data *ai;
464         u32 cnt, j, i = 0;
465
466         print_parse_debug("us_inst_data:\n");
467
468         print_parse_debug("app count:");
469         if (get_u32(mb, &cnt)) {
470                 print_err("failed to read count of applications\n");
471                 return NULL;
472         }
473
474         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
475                 print_err("to match count of applications(%u)\n", cnt);
476                 return NULL;
477         }
478
479         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
480         if (ui == NULL) {
481                 print_err("out of memory\n");
482                 return NULL;
483         }
484
485         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
486                                GFP_KERNEL);
487         if (ui->app_inst == NULL) {
488                 print_err("out of memory\n");
489                 goto free_ui;
490         }
491
492         for (i = 0; i < cnt; ++i) {
493                 print_parse_debug("app #%d:\n",i+1);
494                 ai = create_app_inst_data(mb);
495                 if (ai == NULL)
496                         goto free_app_inst;
497
498                 ui->app_inst[i] = ai;
499         }
500
501         ui->cnt = cnt;
502
503         return ui;
504
505 free_app_inst:
506         for (j = 0; j < i; ++j)
507                 destroy_app_inst_data(ui->app_inst[j]);
508         kfree(ui->app_inst);
509
510 free_ui:
511         kfree(ui);
512
513         return NULL;
514 }
515
516 void destroy_us_inst_data(struct us_inst_data *ui)
517 {
518         int i;
519
520         for (i = 0; i < ui->cnt; ++i)
521                 destroy_app_inst_data(ui->app_inst[i]);
522
523         kfree(ui->app_inst);
524         kfree(ui);
525 }