Remove useless source code
[platform/core/system/resourced.git] / src / common / config-parser.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <assert.h>
23 #include <limits.h>
24
25 #include "util.h"
26 #include "trace.h"
27 #include "config-parser.h"
28 #include "proc-common.h"
29 #include "cpu-cgroup.h"
30 #include "swap-common.h"
31 #include "dedup-common.h"
32 #include "compact-common.h"
33
34 #define MAX_SECTION             64
35 #define CPU_INIT_PRIO   100
36
37 static int optimizer_config(struct parse_result *result, void *user_data)
38 {
39         if (!result)
40                 return RESOURCED_ERROR_INVALID_PARAMETER;
41
42         struct swap_conf *swap_conf = get_swap_conf();
43         if (swap_conf == NULL) {
44                 _E("[DEBUG] swap configuration is NULL");
45                 return RESOURCED_ERROR_FAIL;
46         }
47
48         struct dedup_conf *dedup_conf = get_dedup_conf();
49         if (dedup_conf == NULL) {
50                 _E("[DEBUG] dedup configuration is NULL");
51                 return RESOURCED_ERROR_FAIL;
52         }
53
54         struct compact_conf *compact_conf = get_compact_conf();
55         if (compact_conf == NULL) {
56                 _E("[DEBUG] compact configuration is NULL");
57                 return RESOURCED_ERROR_FAIL;
58         }
59
60         if (!strncmp(result->section, SWAP_SECTION, strlen(SWAP_SECTION)+1)) {
61                 if (!strncmp(result->name, ENABLE_CONF, strlen(ENABLE_CONF)+1)) {
62                         if (!strncmp(result->value, "yes", 4) ||
63                                 !strncmp(result->value, "1", 2) ||
64                                 !strncmp(result->value, "ok", 3))
65                                 swap_conf->enable = true;
66                         else if (!strncmp(result->value, "no", 3) ||
67                                 !strncmp(result->value, "0", 2))
68                                 swap_conf->enable = false;
69                         else {
70                                 _E("[DEBUG] Unknown value for %s", result->name);
71                                 return RESOURCED_ERROR_FAIL;
72                         }
73                 }
74                 else if (!strncmp(result->name, RECLAIM_AT_BOOT_CONF,
75                                         strlen(RECLAIM_AT_BOOT_CONF)+1)) {
76                         if (!strncmp(result->value, "yes", 4) ||
77                                 !strncmp(result->value, "1", 2) ||
78                                 !strncmp(result->value, "ok", 3))
79                                 swap_conf->boot_reclaim_enable = true;
80                         else if (!strncmp(result->value, "no", 3) ||
81                                 !strncmp(result->value, "0", 2))
82                                 swap_conf->boot_reclaim_enable = false;
83                         else {
84                                 _E("[DEBUG] Unknown value for %s", result->name);
85                                 return RESOURCED_ERROR_FAIL;
86                         }
87                 }
88                 else if (!strncmp(result->name, TYPE_CONF,
89                                         strlen(TYPE_CONF)+1)) {
90                         if (strlen(result->value) + 1 > sizeof(swap_conf->type)) {
91                                 _E("Size of swap_conf->type is not enough");
92                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
93                         }
94                         strncpy(swap_conf->type, result->value, sizeof(swap_conf->type) - 1);
95                 }
96                 else if (!strncmp(result->name, VIP_GROUP_SWAPPINESS_CONF,
97                                         strlen(VIP_GROUP_SWAPPINESS_CONF)+1)) {
98                         swap_conf->swappiness[CGROUP_VIP] = atoi(result->value);
99                 }
100                 else if (!strncmp(result->name, HIGH_GROUP_SWAPPINESS_CONF,
101                                         strlen(HIGH_GROUP_SWAPPINESS_CONF)+1)) {
102                         swap_conf->swappiness[CGROUP_HIGH] = atoi(result->value);
103                 }
104                 else if (!strncmp(result->name, MEDIUM_GROUP_SWAPPINESS_CONF,
105                                         strlen(MEDIUM_GROUP_SWAPPINESS_CONF)+1)) {
106                         swap_conf->swappiness[CGROUP_MEDIUM] = atoi(result->value);
107                 }
108                 else if (!strncmp(result->name, LOWEST_GROUP_SWAPPINESS_CONF,
109                                         strlen(LOWEST_GROUP_SWAPPINESS_CONF)+1)) {
110                         swap_conf->swappiness[CGROUP_LOW] = atoi(result->value);
111                 }
112                 else {
113                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
114                                         result->name, result->value, result->section);
115                 }
116         }
117         else if (!strncmp(result->section, ZRAM_SECTION, strlen(ZRAM_SECTION)+1)) {
118                 if (!strncmp(result->name, COMP_ALGORITHM_CONF, strlen(COMP_ALGORITHM_CONF)+1)) {
119                         if (strlen(result->value) + 1 > sizeof(swap_conf->zram.algorithm)) {
120                                 _E("Size of swap_conf->zram.algorithm is not enough");
121                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
122                         }
123                         strncpy(swap_conf->zram.algorithm, result->value,
124                                         sizeof(swap_conf->zram.algorithm) - 1);
125                 }
126                 else if (!strncmp(result->name, RATIO_CONF, strlen(RATIO_CONF)+1)) {
127                         swap_conf->zram.ratio = atof(result->value);
128                 }
129                 else {
130                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
131                                         result->name, result->value, result->section);
132                 }
133         }
134         else if (!strncmp(result->section, ZSWAP_SECTION, strlen(ZSWAP_SECTION)+1)) {
135                 if (!strncmp(result->name, CRYPT_TYPE_CONF, strlen(CRYPT_TYPE_CONF)+1)) {
136                         if (strlen(result->value) + 1 > sizeof(swap_conf->zswap.type)) {
137                                 _E("Size of swap_conf->zswap.type is not enough");
138                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
139                         }
140                         strncpy(swap_conf->zswap.type, result->value,
141                                         sizeof(swap_conf->zswap.type) - 1);
142                 }
143                 else if (!strncmp(result->name, FILE_SIZE_CONF, strlen(FILE_SIZE_CONF)+1)) {
144                         swap_conf->zswap.filesize = atol(result->value);
145                 }
146                 else if (!strncmp(result->name, POOL_RATIO_CONF, strlen(POOL_RATIO_CONF)+1)) {
147                         swap_conf->zswap.pool_ratio = atof(result->value);
148                 }
149                 else if (!strncmp(result->name, POOL_TYPE_CONF, strlen(POOL_TYPE_CONF)+1)) {
150                         if (strlen(result->value) + 1 > sizeof(swap_conf->zswap.pool_type)) {
151                                 _E("Size of swap_conf->zswap.pool_type is not enough");
152                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
153                         }
154                         strncpy(swap_conf->zswap.pool_type, result->value,
155                                         sizeof(swap_conf->zswap.pool_type) - 1);
156                 }
157                 else {
158                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
159                                         result->name, result->value, result->section);
160                 }
161         }
162         else if (!strncmp(result->section, FILE_SWAP_SECTION, strlen(FILE_SWAP_SECTION)+1)) {
163                 if (!strncmp(result->name, CRYPT_TYPE_CONF, strlen(CRYPT_TYPE_CONF)+1)) {
164                         if (strlen(result->value) + 1 > sizeof(swap_conf->fileswap.type)) {
165                                 _E("Size of swap_conf->fileswap.type is not enough");
166                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
167                         }
168                         strncpy(swap_conf->fileswap.type, result->value,
169                                         sizeof(swap_conf->fileswap.type) - 1);
170                 }
171                 else if (!strncmp(result->name, FILE_SIZE_CONF, strlen(FILE_SIZE_CONF)+1)) {
172                         swap_conf->fileswap.filesize = atol(result->value);
173                 }
174                 else {
175                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
176                                         result->name, result->value, result->section);
177                 }
178         }
179         else if (!strncmp(result->section, DEDUP_SECTION, strlen(DEDUP_SECTION)+1)) {
180                 if (!strncmp(result->name, ENABLE_CONF, strlen(ENABLE_CONF)+1)) {
181                         if (!strncmp(result->value, "yes", 4) ||
182                                 !strncmp(result->value, "1", 2) ||
183                                 !strncmp(result->value, "ok", 3))
184                                 dedup_conf->enable = true;
185                         else if (!strncmp(result->value, "no", 3) ||
186                                 !strncmp(result->value, "0", 2))
187                                 dedup_conf->enable = false;
188                         else {
189                                 _E("[DEBUG] Unknown value for %s", result->name);
190                                 return RESOURCED_ERROR_FAIL;
191                         }
192                 }
193                 else if (!strncmp(result->name, DEDUP_AT_BOOT_CONF, strlen(DEDUP_AT_BOOT_CONF)+1)) {
194                         if (!strncmp(result->value, "yes", 4) ||
195                                 !strncmp(result->value, "1", 2) ||
196                                 !strncmp(result->value, "ok", 3))
197                                 dedup_conf->boot_dedup_enable = true;
198                         else if (!strncmp(result->value, "no", 3) ||
199                                 !strncmp(result->value, "0", 2))
200                                 dedup_conf->boot_dedup_enable = false;
201                         else {
202                                 _E("[DEBUG] Unknown value for %s", result->name);
203                                 return RESOURCED_ERROR_FAIL;
204                         }
205                 }
206                 else if (!strncmp(result->name, SCAN_ON_LOWMEM_CONF, strlen(SCAN_ON_LOWMEM_CONF)+1)) {
207                         if (!strncmp(result->value, "yes", 4) ||
208                                 !strncmp(result->value, "1", 2) ||
209                                 !strncmp(result->value, "ok", 3) ||
210                                 !strncmp(result->value, "true", 5))
211                                 dedup_conf->scan_on_lowmem = true;
212                         else if (!strncmp(result->value, "no", 3) ||
213                                 !strncmp(result->value, "0", 2) ||
214                                 !strncmp(result->value, "false", 6))
215                                 dedup_conf->scan_on_lowmem = false;
216                         else {
217                                 _E("[DEBUG] Unknown value for %s", result->name);
218                                 return RESOURCED_ERROR_FAIL;
219                         }
220                 }
221                 else {
222                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
223                                         result->name, result->value, result->section);
224                 }
225         }
226         else if (!strncmp(result->section, KSM_SECTION, strlen(KSM_SECTION)+1)) {
227                 if (!strncmp(result->name, MODE_CONF, strlen(MODE_CONF)+1)) {
228                         if (strlen(result->value) + 1 > sizeof(dedup_conf->ksm.mode)) {
229                                 _E("Size of swap_conf->type is not enough");
230                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
231                         }
232                         strncpy(dedup_conf->ksm.mode, result->value,
233                                         sizeof(dedup_conf->ksm.mode) - 1);
234                 }
235                 else if (!strncmp(result->name, PAGES_TO_SCAN_CONF, strlen(PAGES_TO_SCAN_CONF)+1)) {
236                         dedup_conf->ksm.pages = atoi(result->value);
237                 }
238                 else if (!strncmp(result->name, PAGES_TO_SCAN_WITH_BOOST_CONF,
239                                         strlen(PAGES_TO_SCAN_WITH_BOOST_CONF)+1)) {
240                         dedup_conf->ksm.boost_pages = atoi(result->value);
241                 }
242                 else {
243                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
244                                         result->name, result->value, result->section);
245                 }
246         }
247         else if (!strncmp(result->section, COMPACTION_SECTION, strlen(COMPACTION_SECTION)+1)) {
248                 if (!strncmp(result->name, ENABLE_CONF, strlen(ENABLE_CONF)+1)) {
249                         if (!strncmp(result->value, "yes", 4) ||
250                                 !strncmp(result->value, "1", 2) ||
251                                 !strncmp(result->value, "ok", 3) ||
252                                 !strncmp(result->value, "true", 5))
253                                 compact_conf->enable = true;
254                         else if (!strncmp(result->value, "no", 3) ||
255                                 !strncmp(result->value, "0", 2) ||
256                                 !strncmp(result->value, "false", 6))
257                                 compact_conf->enable = false;
258                         else {
259                                 _E("[DEBUG] Unknown value for %s", result->name);
260                                 return RESOURCED_ERROR_FAIL;
261                         }
262                 }
263                 else if (!strncmp(result->name, FRAG_LEVEL_CONF, strlen(FRAG_LEVEL_CONF)+1)) {
264                         compact_conf->frag_level = atoi(result->value);
265                 }
266                 else {
267                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
268                                         result->name, result->value, result->section);
269                 }
270         }
271         else {
272                 _E("[DEBUG] Unknown section name (%s) and value (%s) on section (%s)",
273                                 result->name, result->value, result->section);
274         }
275
276         return RESOURCED_ERROR_NONE;
277 }
278
279
280 static int limiter_config(struct parse_result *result, void *user_data)
281 {
282         if (!result)
283                 return RESOURCED_ERROR_INVALID_PARAMETER;
284
285         struct memcg_conf *memcg_conf = get_memcg_conf();
286         if (memcg_conf == NULL) {
287                 _E("[DEBUG] memory cgroup configuration is NULL");
288                 return RESOURCED_ERROR_FAIL;
289         }
290
291         if (!strncmp(result->section, MEMORY_GROUP_LIMIT_SECTION,
292                                 strlen(MEMORY_GROUP_LIMIT_SECTION)+1)) {
293                 char *ptr = strchr(result->value, '%');
294                 if (ptr == NULL) {
295                         _E("[DEBUG] Cannot find '%%' in the string (%s)", result->value);
296                         return RESOURCED_ERROR_FAIL;
297                 }
298                 else
299                         *ptr = '\0';
300
301                 if (!strncmp(result->name, VIP_GROUP_LIMIT_CONF,
302                                         strlen(VIP_GROUP_LIMIT_CONF) + 1)) {
303                         memcg_conf->cgroup_limit[CGROUP_VIP] = atof(result->value);
304                 }
305                 else if (!strncmp(result->name, HIGH_GROUP_LIMIT_CONF,
306                                         strlen(HIGH_GROUP_LIMIT_CONF) + 1)) {
307                         memcg_conf->cgroup_limit[CGROUP_HIGH] = atof(result->value);
308                 }
309                 else if (!strncmp(result->name, MEDIUM_GROUP_LIMIT_CONF,
310                                         strlen(MEDIUM_GROUP_LIMIT_CONF) + 1)) {
311                         memcg_conf->cgroup_limit[CGROUP_MEDIUM] = atof(result->value);
312                 }
313                 else if (!strncmp(result->name, LOWEST_GROUP_LIMIT_CONF,
314                                         strlen(LOWEST_GROUP_LIMIT_CONF) + 1)) {
315                         memcg_conf->cgroup_limit[CGROUP_LOW] = atof(result->value);
316                 }
317                 else {
318                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
319                                         result->name, result->value, result->section);
320                 }
321         }
322         else if (!strncmp(result->section, MEMORY_LEVEL_THRESHOLD_SECTION,
323                                 strlen(MEMORY_LEVEL_THRESHOLD_SECTION)+1)) {
324
325                 if (!strncmp(result->name, OOM_POPUP_CONF,
326                                         strlen(OOM_POPUP_CONF) + 1)) {
327                         if (!strncmp(result->value, "yes", 4) ||
328                                 !strncmp(result->value, "1", 2) ||
329                                 !strncmp(result->value, "ok", 3))
330                                 memcg_conf->oom_popup = true;
331                         else if (!strncmp(result->value, "no", 3) ||
332                                 !strncmp(result->value, "0", 2))
333                                 memcg_conf->oom_popup = false;
334                         else {
335                                 _E("[DEBUG] Unknown value for %s", result->name);
336                                 return RESOURCED_ERROR_FAIL;
337                         }
338                 }
339                 else {
340                         char temp = '\0';
341                         int error = RESOURCED_ERROR_NONE;
342                         bool percent;
343                         char *ptr = strchr(result->value, '%');
344                         if (ptr == NULL) {
345                                 ptr = strchr(result->value, 'B');
346                                 if (ptr == NULL) {
347                                         _E("[DEBUG] Cannot find 'B' in the string (%s)", result->value);
348                                         return RESOURCED_ERROR_FAIL;
349                                 }
350
351                                 if (result->value > (ptr - 1)) {
352                                         _E("[DEBUG] Size of string should be larger than 1");
353                                         return RESOURCED_ERROR_FAIL;
354                                 }
355
356                                 temp = *(ptr - 1);
357                                 *(ptr - 1) = '\0';
358                                 percent = false;
359                         }
360                         else {
361                                 *ptr = '\0';
362                                 percent = true;
363                         }
364
365                         if (!strncmp(result->name, MEDIUM_LEVEL_CONF,
366                                                 strlen(MEDIUM_LEVEL_CONF) + 1)) {
367                                 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_MEDIUM, result->value);
368                         }
369                         else if (!strncmp(result->name, LOW_LEVEL_CONF,
370                                                 strlen(LOW_LEVEL_CONF) + 1)) {
371                                 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_LOW, result->value);
372                         }
373                         else if (!strncmp(result->name, CRITICAL_LEVEL_CONF,
374                                                 strlen(CRITICAL_LEVEL_CONF) + 1)) {
375                                 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_CRITICAL, result->value);
376                         }
377                         else if (!strncmp(result->name, OOM_LEVEL_CONF,
378                                                 strlen(OOM_LEVEL_CONF) + 1)) {
379                                 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_OOM, result->value);
380                         }
381
382                         else {
383                                 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
384                                                 result->name, result->value, result->section);
385                         }
386                         
387                         return error;
388                 }
389         }
390         else if (!strncmp(result->section, MEMORY_APP_TYPE_LIMIT_SECTION,
391                                 strlen(MEMORY_APP_TYPE_LIMIT_SECTION)+1)) {
392                 int error = RESOURCED_ERROR_NONE;
393
394                 if (!strncmp(result->name, SERVICE_PER_APP_LIMIT_ACTION,
395                                         strlen(SERVICE_PER_APP_LIMIT_ACTION) + 1)) {
396                         error = set_mem_action_conf(&memcg_conf->service, result->value);
397                 }
398                 else if (!strncmp(result->name, WIDGET_PER_APP_LIMIT_ACTION,
399                                         strlen(WIDGET_PER_APP_LIMIT_ACTION) + 1)) {
400                         error = set_mem_action_conf(&memcg_conf->widget, result->value);
401                 }
402                 else if (!strncmp(result->name, GUI_PER_APP_LIMIT_ACTION,
403                                         strlen(GUI_PER_APP_LIMIT_ACTION) + 1)) {
404                         error = set_mem_action_conf(&memcg_conf->guiapp, result->value);
405                 }
406                 else {
407                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
408                                         result->name, result->value, result->section);
409                 }
410
411                 return error;
412         }
413         else if (!strncmp(result->section, MEMORY_APP_STATUS_LIMIT_SECTION,
414                                 strlen(MEMORY_APP_STATUS_LIMIT_SECTION)+1)) {
415                 int error = RESOURCED_ERROR_NONE;
416
417                 if (!strncmp(result->name, BACKGROUND_PER_APP_LIMIT_ACTION,
418                                         strlen(BACKGROUND_PER_APP_LIMIT_ACTION) + 1)) {
419                         error = set_mem_action_conf(&memcg_conf->background, result->value);
420                 }
421                 else {
422                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
423                                         result->name, result->value, result->section);
424                 }
425
426                 return error;
427         }
428         else if (!strncmp(result->section, CPU_AFFINITY_SECTION,
429                                 strlen(CPU_AFFINITY_SECTION)+1)) {
430                 int error = RESOURCED_ERROR_NONE;
431
432                 if (!strncmp(result->name, FOREGROUND_APPS,
433                                         strlen(FOREGROUND_APPS) + 1)) {
434                         error = set_cpucg_conf(result->name, result->value);
435                 }
436                 else {
437                         _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
438                                         result->name, result->value, result->section);
439                 }
440
441                 return error;
442         }
443         else {
444                 _E("[DEBUG] Unknown section name (%s) and value (%s) on section (%s)",
445                                 result->name, result->value, result->section);
446         }
447         
448         return RESOURCED_ERROR_NONE;
449 }
450
451 static int vendor_config(struct parse_result *result, void *user_data)
452 {
453         int *config_type = (int *)user_data;
454         static struct proc_conf_info *pci = NULL;
455
456         if (!result || !user_data)
457                 return RESOURCED_ERROR_INVALID_PARAMETER;
458
459         if (strncmp(result->section, PER_PROCESS_SECTION, strlen(PER_PROCESS_SECTION)+1))
460                 return RESOURCED_ERROR_NONE;
461
462         if (!strncmp(result->name, SERVICE_NAME_CONF, strlen(SERVICE_NAME_CONF)+1) ||
463                 !strncmp(result->name, APP_NAME_CONF, strlen(APP_NAME_CONF)+1)) {
464                 pci = fixed_app_and_service_exist_check(result->value,
465                                 result->name[0] == 'A' ? APP_TYPE : SERVICE_TYPE);
466                 if (pci == NULL) {
467                         pci = (struct proc_conf_info *)calloc(1, sizeof(struct proc_conf_info));
468                         if (pci == NULL) {
469                                 _E("Failed to allocate memory during parsing vendor configurations");
470                                 return RESOURCED_ERROR_OUT_OF_MEMORY;
471                         }
472                         pci->mem_type = CGROUP_TOP;
473                         pci->cpu_type = CGROUP_TOP;
474                         pci->cpu_priority = CPU_INIT_PRIO;
475                         pci->watchdog_action = PROC_ACTION_KILL;
476                         pci->fail_action = PROC_ACTION_IGNORE;
477                         strncpy(pci->name, result->value, sizeof(pci->name)-1);
478
479                         if (result->name[0] == 'A') {
480                                 fixed_app_list_insert(pci);
481                         }
482                         else {
483                                 fixed_service_list_insert(pci);
484                         }
485                 }
486         }
487         else if (!strncmp(result->name, CPU_CGROUP_NAME_CONF, strlen(CPU_CGROUP_NAME_CONF)+1) &&
488                         *config_type == LIMITER_CONFIG) {
489                 if (!pci) {
490                         _E("process configuration information pointer should not be NULL");
491                         return RESOURCED_ERROR_FAIL;
492                 }
493
494                 if (!strncmp(result->value, CGROUP_VIP_VALUE_CONF,
495                         strlen(CGROUP_VIP_VALUE_CONF) +1)) {
496                         pci->cpu_type = CGROUP_VIP;
497                 }
498                 else if (!strncmp(result->value, CGROUP_HIGH_VALUE_CONF,
499                         strlen(CGROUP_HIGH_VALUE_CONF) +1)) {
500                         pci->cpu_type = CGROUP_HIGH;
501                 }
502                 else if (!strncmp(result->value, CGROUP_MEDIUM_VALUE_CONF,
503                         strlen(CGROUP_MEDIUM_VALUE_CONF) +1)) {
504                         pci->cpu_type = CGROUP_MEDIUM;
505                 }
506                 else if (!strncmp(result->value, CGROUP_LOW_VALUE_CONF,
507                         strlen(CGROUP_LOW_VALUE_CONF) +1)) {
508                         pci->cpu_type = CGROUP_LOW;
509                 }
510                 else {
511                         _E("invalid parameter (%s)", result->value);
512                         return RESOURCED_ERROR_INVALID_PARAMETER;
513                 }
514         }
515         else if (!strncmp(result->name, MEM_CGROUP_NAME_CONF, strlen(MEM_CGROUP_NAME_CONF)+1) &&
516                         *config_type == LIMITER_CONFIG) {
517                 if (!pci) {
518                         _E("process configuration information pointer should not be NULL");
519                         return RESOURCED_ERROR_FAIL;
520                 }
521
522                 if (!strncmp(result->value, CGROUP_VIP_VALUE_CONF,
523                         strlen(CGROUP_VIP_VALUE_CONF) +1)) {
524                         pci->mem_type = CGROUP_VIP;
525                 }
526                 else if (!strncmp(result->value, CGROUP_HIGH_VALUE_CONF,
527                         strlen(CGROUP_HIGH_VALUE_CONF) +1)) {
528                         pci->mem_type = CGROUP_HIGH;
529                 }
530                 else if (!strncmp(result->value, CGROUP_MEDIUM_VALUE_CONF,
531                         strlen(CGROUP_MEDIUM_VALUE_CONF) +1)) {
532                         pci->mem_type = CGROUP_MEDIUM;
533                 }
534                 else if (!strncmp(result->value, CGROUP_LOW_VALUE_CONF,
535                         strlen(CGROUP_LOW_VALUE_CONF) +1)) {
536                         pci->mem_type = CGROUP_LOW;
537                 }
538                 else {
539                         _E("invalid parameter (%s)", result->value);
540                         return RESOURCED_ERROR_INVALID_PARAMETER;
541                 }
542         }
543         else if (!strncmp(result->name, MEM_LIMIT_ACTION_NAME_CONF,
544                 strlen(MEM_LIMIT_ACTION_NAME_CONF)+1) && *config_type == LIMITER_CONFIG) {
545                 int error;
546
547                 if (!pci) {
548                         _E("process configuration information pointer should not be NULL");
549                         return RESOURCED_ERROR_FAIL;
550                 }
551                 
552                 error = set_mem_action_conf(&pci->mem_action, result->value);
553                 return error;   
554         }
555         else if (!strncmp(result->name, CPU_PRIORITY_NAME_CONF, strlen(CPU_PRIORITY_NAME_CONF)+1) &&
556                         *config_type == LIMITER_CONFIG) {
557                 if (!pci) {
558                         _E("process configuration information pointer should not be NULL");
559                         return RESOURCED_ERROR_FAIL;
560                 }
561                 pci->cpu_priority = atoi(result->value);
562         }
563         else if (!strncmp(result->name, ACTION_ON_FAILURE_NAME_CONF,
564                                 strlen(ACTION_ON_FAILURE_NAME_CONF)+1) && *config_type == PROCESS_CONFIG) {
565                 if (!pci) {
566                         _E("process configuration information pointer should not be NULL");
567                         return RESOURCED_ERROR_FAIL;
568                 }
569
570                 if (!strncmp(result->value, ACTION_REBOOT_VALUE_CONF,
571                                         strlen(ACTION_REBOOT_VALUE_CONF) +1)) {
572                         pci->fail_action = PROC_ACTION_REBOOT;
573                 }
574                 else {
575                         _E("invalid parameter (%s)", result->value);
576                         return RESOURCED_ERROR_INVALID_PARAMETER;
577                 }
578         }
579         else if (!strncmp(result->name, WATCHDOG_ACTION_NAME_CONF,
580                                 strlen(WATCHDOG_ACTION_NAME_CONF)+1) && *config_type == PROCESS_CONFIG) {
581                 if (!pci) {
582                         _E("process configuration information pointer should not be NULL");
583                         return RESOURCED_ERROR_FAIL;
584                 }
585
586                 if (!strncmp(result->value, ACTION_IGNORE_VALUE_CONF,
587                                         strlen(ACTION_IGNORE_VALUE_CONF) +1)) {
588                         pci->watchdog_action = PROC_ACTION_IGNORE;
589                 }
590                 else if (!strncmp(result->value, ACTION_KILL_VALUE_CONF,
591                                         strlen(ACTION_KILL_VALUE_CONF) +1)) {
592                         pci->watchdog_action = PROC_ACTION_KILL;
593                 }
594                 else {
595                         _E("invalid parameter (%s)", result->value);
596                         return RESOURCED_ERROR_INVALID_PARAMETER;
597                 }
598         }
599         else {
600                 _E("Unknown configuration name (%s) and value (%s) on section (%s)",
601                                 result->name, result->value, result->section);
602         }
603
604         return RESOURCED_ERROR_NONE;
605 }
606
607 static void load_per_vendor_configs(const char *dir, int func(struct parse_result *result,
608                                                                 void *user_data), void *user_data)
609 {
610         int count;
611         int idx;
612         struct dirent **namelist;
613
614         if ((count = scandir(dir, &namelist, NULL, alphasort)) == -1) {
615                 _W("failed to opendir (%s)", dir);
616                 return;
617         }
618
619         for (idx = 0; idx < count; idx++) {
620                 char path[PATH_MAX] = {0, };
621
622                 if (!strstr(namelist[idx]->d_name, CONF_FILE_SUFFIX))
623                         continue;
624
625                 snprintf(path, sizeof(path), "%s/%s", dir, namelist[idx]->d_name);
626                 config_parse(path, func, user_data);
627                 free(namelist[idx]);
628         }
629
630         free(namelist);
631 }
632
633 void resourced_parse_vendor_configs(void)
634 {
635         int config_type;
636
637         fixed_app_and_service_list_init();
638
639         /* Load configurations in limiter.conf and limiter.conf.d/ */
640         config_parse(LIMITER_CONF_FILE, limiter_config, NULL);
641         config_type = LIMITER_CONFIG;
642         load_per_vendor_configs(LIMITER_CONF_DIR, vendor_config, &config_type);
643
644         /* Load configurations in optimizer.conf */
645         config_parse(OPTIMIZER_CONF_FILE, optimizer_config, NULL);
646
647         config_type = PROCESS_CONFIG;
648         load_per_vendor_configs(PROC_CONF_DIR, vendor_config, &config_type);
649 }
650
651 void resourced_free_vendor_configs(void)
652 {
653         fixed_app_and_service_list_exit();
654 }
655
656 int config_parse(const char *file_name, int cb(struct parse_result *result,
657                         void *user_data), void *user_data)
658 {
659         FILE *f = NULL;
660         struct parse_result result;
661         /* use stack for parsing */
662         char line[LINE_MAX];
663         char section[MAX_SECTION];
664         char *start, *end, *name, *value;
665         int lineno = 0, ret = 0;
666
667         if (!file_name || !cb) {
668                 ret = -EINVAL;
669                 goto error;
670         }
671
672         /* open conf file */
673         f = fopen(file_name, "r");
674         if (!f) {
675                 _E("Failed to open file %s", file_name);
676                 ret = -EIO;
677                 goto error;
678         }
679
680         /* parsing line by line */
681         while (fgets(line, LINE_MAX, f) != NULL) {
682                 lineno++;
683
684                 start = line;
685                 truncate_nl(start);
686                 start = strstrip(start);
687
688                 if (*start == COMMENT) {
689                         continue;
690                 } else if (*start == '[') {
691                         /* parse section */
692                         end = strchr(start, ']');
693                         if (!end || *end != ']') {
694                                 ret = -EBADMSG;
695                                 goto error;
696                         }
697
698                         *end = '\0';
699                         strncpy(section, start + 1, sizeof(section)-1);
700                         section[MAX_SECTION-1] = '\0';
701                 } else if (*start) {
702                         /* parse name & value */
703                         end = strchr(start, '=');
704                         if (!end || *end != '=') {
705                                 ret = -EBADMSG;
706                                 goto error;
707                         }
708                         *end = '\0';
709                         name = strstrip(start);
710                         value = strstrip(end + 1);
711                         end = strchr(value, COMMENT);
712                         if (end && *end == COMMENT) {
713                                 *end = '\0';
714                                 value = strstrip(value);
715                         }
716
717                         result.section = section;
718                         result.name = name;
719                         result.value = value;
720                         /* callback with parse result */
721                         ret = cb(&result, user_data);
722                         if (ret < 0) {
723                                 ret = -EBADMSG;
724                                 goto error;
725                         }
726                 }
727         }
728         return 0;
729
730 error:
731         if (f)
732                 fclose(f);
733         _E("Failed to read %s:%d!", file_name, lineno);
734         return ret;
735 }