[PROTO] config is preserved between stop and start
[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 static struct conf_data config;
200 void save_config(const struct conf_data *conf)
201 {
202         memcpy(&config, conf, sizeof(config));
203 }
204
205 void restore_config(struct conf_data *conf)
206 {
207         memcpy(conf, &config, sizeof(*conf));
208 }
209
210
211
212 /* ============================================================================
213  * ==                               FUNC_INST                                ==
214  * ============================================================================
215  */
216 struct func_inst_data *create_func_inst_data(struct msg_buf *mb)
217 {
218         struct func_inst_data *fi;
219         u64 addr;
220         char *args;
221
222         print_parse_debug("func addr:");
223         if (get_u64(mb, &addr)) {
224                 print_err("failed to read data function address\n");
225                 return NULL;
226         }
227
228         print_parse_debug("funct args:");
229         if (get_string(mb, &args)) {
230                 print_err("failed to read data function arguments\n");
231                 return NULL;
232         }
233
234         fi = kmalloc(sizeof(*fi), GFP_KERNEL);
235         if (fi == NULL) {
236                 print_err("out of memory\n");
237                 put_string(args);
238                 return NULL;
239         }
240
241         fi->addr = addr;
242         fi->args = args;
243
244         return fi;
245 }
246
247 void destroy_func_inst_data(struct func_inst_data *fi)
248 {
249         put_string(fi->args);
250         kfree(fi);
251 }
252
253
254
255
256
257 /* ============================================================================
258  * ==                               LIB_INST                                 ==
259  * ============================================================================
260  */
261 struct lib_inst_data *create_lib_inst_data(struct msg_buf *mb)
262 {
263         struct lib_inst_data *li;
264         struct func_inst_data *fi;
265         char *path;
266         u32 cnt, j, i = 0;
267
268         print_parse_debug("bin path:");
269         if (get_string(mb, &path)) {
270                 print_err("failed to read path of binary\n");
271                 return NULL;
272         }
273
274         print_parse_debug("func count:");
275         if (get_u32(mb, &cnt)) {
276                 print_err("failed to read count of functions\n");
277                 return NULL;
278         }
279
280         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt) {
281                 print_err("to match count of functions(%u)\n", cnt);
282                 return NULL;
283         }
284
285         li = kmalloc(sizeof(*li), GFP_KERNEL);
286         if (li == NULL)
287         if (li == NULL) {
288                 print_err("out of memory\n");
289                 goto free_path;
290         }
291
292         li->func = kmalloc(sizeof(struct func_inst_data *) * cnt, GFP_KERNEL);
293         if (li->func == NULL)
294         if (li->func == NULL) {
295                 print_err("out of memory\n");
296                 goto free_li;
297         }
298
299         for (i = 0; i < cnt; ++i) {
300                 print_parse_debug("func #%d:\n", i + 1);
301                 fi = create_func_inst_data(mb);
302                 if (fi == NULL)
303                         goto free_func;
304
305                 li->func[i] = fi;
306         }
307
308         li->path = path;
309         li->cnt_func = cnt;
310
311         return li;
312
313 free_func:
314         for (j = 0; j < i; ++j)
315                 destroy_func_inst_data(li->func[j]);
316         kfree(li->func);
317
318 free_li:
319         kfree(li);
320
321 free_path:
322         put_string(path);
323
324         return NULL;
325 }
326
327 void destroy_lib_inst_data(struct lib_inst_data *li)
328 {
329         int i;
330
331         put_string(li->path);
332
333         for (i = 0; i < li->cnt_func; ++i)
334                 destroy_func_inst_data(li->func[i]);
335
336         kfree(li->func);
337         kfree(li);
338 }
339
340
341
342
343
344 /* ============================================================================
345  * ==                               APP_INST                                 ==
346  * ============================================================================
347  */
348 struct app_inst_data *create_app_inst_data(struct msg_buf *mb)
349 {
350         struct app_inst_data *app_inst;
351         struct app_info_data *app_info;
352         struct func_inst_data *func;
353         struct lib_inst_data *lib;
354         u32 cnt_func, i_func = 0, cnt_lib, i_lib = 0, i;
355
356         app_info = create_app_info(mb);
357         if (app_info == NULL)
358                 return NULL;
359
360         print_parse_debug("func count:");
361         if (get_u32(mb, &cnt_func)) {
362                 print_err("failed to read count of functions\n");
363                 goto free_app_info;
364         }
365
366         if (remained_mb(mb) / MIN_SIZE_FUNC_INST < cnt_func) {
367                 print_err("to match count of functions(%u)\n", cnt_func);
368                 goto free_app_info;
369         }
370
371         app_inst = kmalloc(sizeof(*app_inst), GFP_KERNEL);
372         if (app_inst == NULL) {
373                 print_err("out of memory\n");
374                 goto free_app_info;
375         }
376
377         app_inst->func = kmalloc(sizeof(struct func_inst_data *) * cnt_func,
378                                  GFP_KERNEL);
379         if (app_inst->func == NULL) {
380                 print_err("out of memory\n");
381                 goto free_app_inst;
382         }
383
384         for (i_func = 0; i_func < cnt_func; ++i_func) {
385                 print_parse_debug("func #%d:\n", i_func + 1);
386                 func = create_func_inst_data(mb);
387                 if (func == NULL)
388                         goto free_func;
389
390                 app_inst->func[i_func] = func;
391         }
392
393         print_parse_debug("lib count:");
394         if (get_u32(mb, &cnt_lib)) {
395                 print_err("failed to read count of libraries\n");
396                 goto free_func;
397         }
398
399         if (remained_mb(mb) / MIN_SIZE_LIB_INST < cnt_lib) {
400                 print_err("to match count of libraries(%u)\n", cnt_lib);
401                 goto free_func;
402         }
403
404         app_inst->lib = kmalloc(sizeof(struct lib_inst_data *) * cnt_lib,
405                                 GFP_KERNEL);
406         if (app_inst->lib == NULL) {
407                 print_err("out of memory\n");
408                 goto free_func;
409         }
410
411         for (i_lib = 0; i_lib < cnt_lib; ++i_lib) {
412                 print_parse_debug("lib #%d:\n", i_lib + 1);
413                 lib = create_lib_inst_data(mb);
414                 if (lib == NULL)
415                         goto free_lib;
416
417                 app_inst->lib[i_lib] = lib;
418         }
419
420         app_inst->app_info = app_info;
421         app_inst->cnt_func = cnt_func;
422         app_inst->cnt_lib = cnt_lib;
423
424         return app_inst;
425
426 free_lib:
427         for (i = 0; i < i_lib; ++i)
428                 destroy_lib_inst_data(app_inst->lib[i]);
429         kfree(app_inst->lib);
430
431 free_func:
432         for (i = 0; i < i_func; ++i)
433                 destroy_func_inst_data(app_inst->func[i]);
434         kfree(app_inst->func);
435
436 free_app_inst:
437         kfree(app_inst);
438
439 free_app_info:
440         destroy_app_info(app_info);
441
442         return NULL;
443 }
444
445 void destroy_app_inst_data(struct app_inst_data *ai)
446 {
447         int i;
448
449         for (i = 0; i < ai->cnt_lib; ++i)
450                 destroy_lib_inst_data(ai->lib[i]);
451         kfree(ai->lib);
452
453         for (i = 0; i < ai->cnt_func; ++i)
454                 destroy_func_inst_data(ai->func[i]);
455         kfree(ai->func);
456
457         destroy_app_info(ai->app_info);
458         kfree(ai);
459 }
460
461
462
463
464
465 /* ============================================================================
466  * ==                                US_INST                                 ==
467  * ============================================================================
468  */
469 struct us_inst_data *create_us_inst_data(struct msg_buf *mb)
470 {
471         struct us_inst_data *ui;
472         struct app_inst_data *ai;
473         u32 cnt, j, i = 0;
474
475         print_parse_debug("us_inst_data:\n");
476
477         print_parse_debug("app count:");
478         if (get_u32(mb, &cnt)) {
479                 print_err("failed to read count of applications\n");
480                 return NULL;
481         }
482
483         if (remained_mb(mb) / MIN_SIZE_APP_INST < cnt) {
484                 print_err("to match count of applications(%u)\n", cnt);
485                 return NULL;
486         }
487
488         ui = kmalloc(sizeof(struct us_inst_data), GFP_KERNEL);
489         if (ui == NULL) {
490                 print_err("out of memory\n");
491                 return NULL;
492         }
493
494         ui->app_inst = kmalloc(sizeof(struct app_inst_data *) * cnt,
495                                GFP_KERNEL);
496         if (ui->app_inst == NULL) {
497                 print_err("out of memory\n");
498                 goto free_ui;
499         }
500
501         for (i = 0; i < cnt; ++i) {
502                 print_parse_debug("app #%d:\n",i+1);
503                 ai = create_app_inst_data(mb);
504                 if (ai == NULL)
505                         goto free_app_inst;
506
507                 ui->app_inst[i] = ai;
508         }
509
510         ui->cnt = cnt;
511
512         return ui;
513
514 free_app_inst:
515         for (j = 0; j < i; ++j)
516                 destroy_app_inst_data(ui->app_inst[j]);
517         kfree(ui->app_inst);
518
519 free_ui:
520         kfree(ui);
521
522         return NULL;
523 }
524
525 void destroy_us_inst_data(struct us_inst_data *ui)
526 {
527         int i;
528
529         for (i = 0; i < ui->cnt; ++i)
530                 destroy_app_inst_data(ui->app_inst[i]);
531
532         kfree(ui->app_inst);
533         kfree(ui);
534 }