4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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 #include "cpu-sched-common.h"
35 #define MAX_SECTION 64
36 #define CPU_INIT_PRIO 100
38 static int config_parse_swap_types(
42 enum swap_type *type = data;
51 FOREACH_WORD_SEPARATOR(word, l, rvalue, "+|", state) {
52 if (strneq(word, "zram", l))
53 *type |= SWAP_TYPE_ZRAM;
54 else if (strneq(word, "file", l))
55 *type |= SWAP_TYPE_FILE;
56 else if (strneq(word, "zswap", l))
57 *type |= SWAP_TYPE_ZSWAP;
65 static int config_parse_cpu_sched_features(const char *value)
67 int cpu_sched_type = CPU_SCHED_UNINITIALIZED;
72 return cpu_sched_type;
74 FOREACH_WORD_SEPARATOR(word, l, value, ",", state) {
75 if (strneq(word, RT_RUNTIME_SHARE, l))
76 cpu_sched_type |= CPU_SCHED_RUNTIME_SHARE;
77 else if (strneq(word, NO_RT_RUNTIME_SHARE, l))
78 cpu_sched_type |= CPU_SCHED_NO_RUNTIME_SHARE;
79 else if (strneq(word, RT_RUNTIME_GREED, l))
80 cpu_sched_type |= CPU_SCHED_RUNTIME_GREED;
82 return CPU_SCHED_UNINITIALIZED;
85 return cpu_sched_type;
88 static int config_parse_time_us(const char *value)
91 char *ptr = strchr(value, 's');
93 _E("[DEBUG] Cannot find 's' in the string (%s)", value);
97 if (value > (ptr - 1)) {
98 _E("[DEBUG] Size of string should be larger than 1");
106 return atoi(value) * 1000 * 1000;
108 else if (size == 'm') {
109 return atoi(value) * 1000;
111 else if (size == 'u') {
115 _E("[DEBUG] Unknown unit of time");
120 static int optimizer_config(struct parse_result *result, void *user_data)
123 return RESOURCED_ERROR_INVALID_PARAMETER;
125 struct swap_conf *swap_conf = get_swap_conf();
126 if (swap_conf == NULL) {
127 _E("[DEBUG] swap configuration is NULL");
128 return RESOURCED_ERROR_FAIL;
131 struct dedup_conf *dedup_conf = get_dedup_conf();
132 if (dedup_conf == NULL) {
133 _E("[DEBUG] dedup configuration is NULL");
134 return RESOURCED_ERROR_FAIL;
137 struct compact_conf *compact_conf = get_compact_conf();
138 if (compact_conf == NULL) {
139 _E("[DEBUG] compact configuration is NULL");
140 return RESOURCED_ERROR_FAIL;
143 struct cpu_sched_conf *cpu_sched_conf = get_cpu_sched_conf();
144 if (cpu_sched_conf == NULL) {
145 _E("[DEBUG] cpu_sched configuration is NULL");
146 return RESOURCED_ERROR_FAIL;
149 if (!strncmp(result->section, SWAP_SECTION, strlen(SWAP_SECTION)+1)) {
150 if (!strncmp(result->name, SWAP_ENABLE_CONF, strlen(SWAP_ENABLE_CONF)+1)) {
151 if (!strncmp(result->value, "yes", 4) ||
152 !strncmp(result->value, "1", 2) ||
153 !strncmp(result->value, "ok", 3))
154 swap_conf->enable = true;
155 else if (!strncmp(result->value, "no", 3) ||
156 !strncmp(result->value, "0", 2))
157 swap_conf->enable = false;
159 _E("[DEBUG] Unknown value for %s", result->name);
160 return RESOURCED_ERROR_FAIL;
163 else if (!strncmp(result->name, RECLAIM_AT_BOOT_CONF,
164 strlen(RECLAIM_AT_BOOT_CONF)+1)) {
165 if (!strncmp(result->value, "yes", 4) ||
166 !strncmp(result->value, "1", 2) ||
167 !strncmp(result->value, "ok", 3))
168 swap_conf->boot_reclaim_enable = true;
169 else if (!strncmp(result->value, "no", 3) ||
170 !strncmp(result->value, "0", 2))
171 swap_conf->boot_reclaim_enable = false;
173 _E("[DEBUG] Unknown value for %s", result->name);
174 return RESOURCED_ERROR_FAIL;
177 else if (!strncmp(result->name, SWAP_TYPE_CONF,
178 strlen(SWAP_TYPE_CONF)+1)) {
179 if (config_parse_swap_types(result->value, &swap_conf->swap_type) < 0) {
180 _E("[DEBUG] Failed to parse type of swap, so use default zram type");
181 swap_conf->swap_type = SWAP_TYPE_ZRAM;
183 /* if (strlen(result->value) + 1 > sizeof(swap_conf->type)) {
184 _E("Size of swap_conf->type is not enough");
185 return RESOURCED_ERROR_OUT_OF_MEMORY;
187 strncpy(swap_conf->type, result->value, sizeof(swap_conf->type) - 1);*/
189 else if (!strncmp(result->name, VIP_GROUP_SWAPPINESS_CONF,
190 strlen(VIP_GROUP_SWAPPINESS_CONF)+1)) {
191 swap_conf->swappiness[CGROUP_VIP] = atoi(result->value);
193 else if (!strncmp(result->name, HIGH_GROUP_SWAPPINESS_CONF,
194 strlen(HIGH_GROUP_SWAPPINESS_CONF)+1)) {
195 swap_conf->swappiness[CGROUP_HIGH] = atoi(result->value);
197 else if (!strncmp(result->name, MEDIUM_GROUP_SWAPPINESS_CONF,
198 strlen(MEDIUM_GROUP_SWAPPINESS_CONF)+1)) {
199 swap_conf->swappiness[CGROUP_MEDIUM] = atoi(result->value);
201 else if (!strncmp(result->name, LOWEST_GROUP_SWAPPINESS_CONF,
202 strlen(LOWEST_GROUP_SWAPPINESS_CONF)+1)) {
203 swap_conf->swappiness[CGROUP_LOW] = atoi(result->value);
206 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
207 result->name, result->value, result->section);
210 else if (!strncmp(result->section, ZRAM_SECTION, strlen(ZRAM_SECTION)+1)) {
211 if (!strncmp(result->name, COMP_ALGORITHM_CONF, strlen(COMP_ALGORITHM_CONF)+1)) {
212 if (strlen(result->value) + 1 > sizeof(swap_conf->zram.algorithm)) {
213 _E("Size of swap_conf->zram.algorithm is not enough");
214 return RESOURCED_ERROR_OUT_OF_MEMORY;
216 strncpy(swap_conf->zram.algorithm, result->value,
217 sizeof(swap_conf->zram.algorithm) - 1);
219 else if (!strncmp(result->name, ZRAM_RATIO_CONF, strlen(ZRAM_RATIO_CONF)+1)) {
220 swap_conf->zram.ratio = atof(result->value);
223 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
224 result->name, result->value, result->section);
227 else if (!strncmp(result->section, ZSWAP_SECTION, strlen(ZSWAP_SECTION)+1)) {
228 if (!strncmp(result->name, POOL_RATIO_CONF, strlen(POOL_RATIO_CONF)+1)) {
229 swap_conf->zswap.pool_ratio = atof(result->value);
231 else if (!strncmp(result->name, POOL_TYPE_CONF, strlen(POOL_TYPE_CONF)+1)) {
232 if (strlen(result->value) + 1 > sizeof(swap_conf->zswap.pool_type)) {
233 _E("Size of swap_conf->zswap.pool_type is not enough");
234 return RESOURCED_ERROR_OUT_OF_MEMORY;
236 strncpy(swap_conf->zswap.pool_type, result->value,
237 sizeof(swap_conf->zswap.pool_type) - 1);
240 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
241 result->name, result->value, result->section);
244 else if (!strncmp(result->section, DEDUP_SECTION, strlen(DEDUP_SECTION)+1)) {
245 if (!strncmp(result->name, DEDUP_ENABLE_CONF, strlen(DEDUP_ENABLE_CONF)+1)) {
246 if (!strncmp(result->value, "yes", 4) ||
247 !strncmp(result->value, "1", 2) ||
248 !strncmp(result->value, "ok", 3))
249 dedup_conf->enable = true;
250 else if (!strncmp(result->value, "no", 3) ||
251 !strncmp(result->value, "0", 2))
252 dedup_conf->enable = false;
254 _E("[DEBUG] Unknown value for %s", result->name);
255 return RESOURCED_ERROR_FAIL;
258 else if (!strncmp(result->name, DEDUP_AT_BOOT_CONF, strlen(DEDUP_AT_BOOT_CONF)+1)) {
259 if (!strncmp(result->value, "yes", 4) ||
260 !strncmp(result->value, "1", 2) ||
261 !strncmp(result->value, "ok", 3))
262 dedup_conf->boot_dedup_enable = true;
263 else if (!strncmp(result->value, "no", 3) ||
264 !strncmp(result->value, "0", 2))
265 dedup_conf->boot_dedup_enable = false;
267 _E("[DEBUG] Unknown value for %s", result->name);
268 return RESOURCED_ERROR_FAIL;
271 else if (!strncmp(result->name, SCAN_ON_LOWMEM_CONF, strlen(SCAN_ON_LOWMEM_CONF)+1)) {
272 if (!strncmp(result->value, "yes", 4) ||
273 !strncmp(result->value, "1", 2) ||
274 !strncmp(result->value, "ok", 3) ||
275 !strncmp(result->value, "true", 5))
276 dedup_conf->scan_on_lowmem = true;
277 else if (!strncmp(result->value, "no", 3) ||
278 !strncmp(result->value, "0", 2) ||
279 !strncmp(result->value, "false", 6))
280 dedup_conf->scan_on_lowmem = false;
282 _E("[DEBUG] Unknown value for %s", result->name);
283 return RESOURCED_ERROR_FAIL;
287 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
288 result->name, result->value, result->section);
291 else if (!strncmp(result->section, KSM_SECTION, strlen(KSM_SECTION)+1)) {
292 if (!strncmp(result->name, KSM_MODE_CONF, strlen(KSM_MODE_CONF)+1)) {
293 if (strlen(result->value) + 1 > sizeof(dedup_conf->ksm.mode)) {
294 _E("Size of swap_conf->type is not enough");
295 return RESOURCED_ERROR_OUT_OF_MEMORY;
297 strncpy(dedup_conf->ksm.mode, result->value,
298 sizeof(dedup_conf->ksm.mode) - 1);
300 else if (!strncmp(result->name, PAGES_TO_SCAN_CONF, strlen(PAGES_TO_SCAN_CONF)+1)) {
301 dedup_conf->ksm.pages = atoi(result->value);
303 else if (!strncmp(result->name, PAGES_TO_SCAN_WITH_BOOST_CONF,
304 strlen(PAGES_TO_SCAN_WITH_BOOST_CONF)+1)) {
305 dedup_conf->ksm.boost_pages = atoi(result->value);
308 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
309 result->name, result->value, result->section);
312 else if (!strncmp(result->section, COMPACTION_SECTION, strlen(COMPACTION_SECTION)+1)) {
313 if (!strncmp(result->name, COMPACTION_ENABLE_CONF, strlen(COMPACTION_ENABLE_CONF)+1)) {
314 if (!strncmp(result->value, "yes", 4) ||
315 !strncmp(result->value, "1", 2) ||
316 !strncmp(result->value, "ok", 3) ||
317 !strncmp(result->value, "true", 5))
318 compact_conf->enable = true;
319 else if (!strncmp(result->value, "no", 3) ||
320 !strncmp(result->value, "0", 2) ||
321 !strncmp(result->value, "false", 6))
322 compact_conf->enable = false;
324 _E("[DEBUG] Unknown value for %s", result->name);
325 return RESOURCED_ERROR_FAIL;
328 else if (!strncmp(result->name, FRAG_LEVEL_CONF, strlen(FRAG_LEVEL_CONF)+1)) {
329 compact_conf->frag_level = atoi(result->value);
332 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
333 result->name, result->value, result->section);
336 else if (!strncmp(result->section, CPU_SCHED_SECTION,
337 strlen(CPU_SCHED_SECTION)+1)) {
338 if (!strncmp(result->name, CPU_SCHED_FEATURE_CONF,
339 strlen(CPU_SCHED_FEATURE_CONF) + 1)) {
340 cpu_sched_conf->cpu_sched_flag = config_parse_cpu_sched_features(result->value);
342 else if (!strncmp(result->name, CPU_RT_RUN_TIME_CONF,
343 strlen(CPU_RT_RUN_TIME_CONF) + 1)) {
344 cpu_sched_conf->rt_runtime_us = config_parse_time_us(result->value);
346 else if (!strncmp(result->name, CPU_RT_PERIOD_CONF,
347 strlen(CPU_RT_PERIOD_CONF) + 1)) {
348 cpu_sched_conf->rt_period_us = config_parse_time_us(result->value);
351 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
352 result->name, result->value, result->section);
355 else if (!strncmp(result->section, CPU_AFFINITY_SECTION,
356 strlen(CPU_AFFINITY_SECTION)+1)) {
357 int error = RESOURCED_ERROR_NONE;
359 if (!strncmp(result->name, FOREGROUND_APPS,
360 strlen(FOREGROUND_APPS) + 1)) {
361 error = set_cpucg_conf(result->name, result->value);
364 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
365 result->name, result->value, result->section);
371 _E("[DEBUG] Unknown section name (%s) and value (%s) on section (%s)",
372 result->name, result->value, result->section);
375 return RESOURCED_ERROR_NONE;
379 static int limiter_config(struct parse_result *result, void *user_data)
382 return RESOURCED_ERROR_INVALID_PARAMETER;
384 struct memcg_conf *memcg_conf = get_memcg_conf();
385 if (memcg_conf == NULL) {
386 _E("[DEBUG] memory cgroup configuration is NULL");
387 return RESOURCED_ERROR_FAIL;
390 if (!strncmp(result->section, MEMORY_GROUP_LIMIT_SECTION,
391 strlen(MEMORY_GROUP_LIMIT_SECTION)+1)) {
392 char *ptr = strchr(result->value, '%');
394 _E("[DEBUG] Cannot find '%%' in the string (%s)", result->value);
395 return RESOURCED_ERROR_FAIL;
400 if (!strncmp(result->name, VIP_GROUP_LIMIT_CONF,
401 strlen(VIP_GROUP_LIMIT_CONF) + 1)) {
402 memcg_conf->cgroup_limit[CGROUP_VIP] = atof(result->value);
404 else if (!strncmp(result->name, HIGH_GROUP_LIMIT_CONF,
405 strlen(HIGH_GROUP_LIMIT_CONF) + 1)) {
406 memcg_conf->cgroup_limit[CGROUP_HIGH] = atof(result->value);
408 else if (!strncmp(result->name, MEDIUM_GROUP_LIMIT_CONF,
409 strlen(MEDIUM_GROUP_LIMIT_CONF) + 1)) {
410 memcg_conf->cgroup_limit[CGROUP_MEDIUM] = atof(result->value);
412 else if (!strncmp(result->name, LOWEST_GROUP_LIMIT_CONF,
413 strlen(LOWEST_GROUP_LIMIT_CONF) + 1)) {
414 memcg_conf->cgroup_limit[CGROUP_LOW] = atof(result->value);
417 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
418 result->name, result->value, result->section);
421 else if (!strncmp(result->section, MEMORY_LEVEL_THRESHOLD_SECTION,
422 strlen(MEMORY_LEVEL_THRESHOLD_SECTION)+1)) {
424 if (!strncmp(result->name, OOM_POPUP_CONF,
425 strlen(OOM_POPUP_CONF) + 1)) {
426 if (!strncmp(result->value, "yes", 4) ||
427 !strncmp(result->value, "1", 2) ||
428 !strncmp(result->value, "ok", 3))
429 memcg_conf->oom_popup = true;
430 else if (!strncmp(result->value, "no", 3) ||
431 !strncmp(result->value, "0", 2))
432 memcg_conf->oom_popup = false;
434 _E("[DEBUG] Unknown value for %s", result->name);
435 return RESOURCED_ERROR_FAIL;
440 int error = RESOURCED_ERROR_NONE;
442 char *ptr = strchr(result->value, '%');
444 ptr = strchr(result->value, 'B');
446 _E("[DEBUG] Cannot find 'B' in the string (%s)", result->value);
447 return RESOURCED_ERROR_FAIL;
450 if (result->value > (ptr - 1)) {
451 _E("[DEBUG] Size of string should be larger than 1");
452 return RESOURCED_ERROR_FAIL;
464 if (!strncmp(result->name, MEDIUM_LEVEL_CONF,
465 strlen(MEDIUM_LEVEL_CONF) + 1)) {
466 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_MEDIUM, result->value);
468 else if (!strncmp(result->name, LOW_LEVEL_CONF,
469 strlen(LOW_LEVEL_CONF) + 1)) {
470 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_LOW, result->value);
472 else if (!strncmp(result->name, CRITICAL_LEVEL_CONF,
473 strlen(CRITICAL_LEVEL_CONF) + 1)) {
474 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_CRITICAL, result->value);
476 else if (!strncmp(result->name, OOM_LEVEL_CONF,
477 strlen(OOM_LEVEL_CONF) + 1)) {
478 error = set_memcg_conf_threshold(percent, temp, MEM_LEVEL_OOM, result->value);
482 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
483 result->name, result->value, result->section);
489 else if (!strncmp(result->section, MEMORY_APP_TYPE_LIMIT_SECTION,
490 strlen(MEMORY_APP_TYPE_LIMIT_SECTION)+1)) {
491 int error = RESOURCED_ERROR_NONE;
493 if (!strncmp(result->name, SERVICE_PER_APP_LIMIT_ACTION,
494 strlen(SERVICE_PER_APP_LIMIT_ACTION) + 1)) {
495 error = set_mem_action_conf(&memcg_conf->service, result->value);
497 else if (!strncmp(result->name, WIDGET_PER_APP_LIMIT_ACTION,
498 strlen(WIDGET_PER_APP_LIMIT_ACTION) + 1)) {
499 error = set_mem_action_conf(&memcg_conf->widget, result->value);
501 else if (!strncmp(result->name, GUI_PER_APP_LIMIT_ACTION,
502 strlen(GUI_PER_APP_LIMIT_ACTION) + 1)) {
503 error = set_mem_action_conf(&memcg_conf->guiapp, result->value);
506 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
507 result->name, result->value, result->section);
512 else if (!strncmp(result->section, MEMORY_APP_STATUS_LIMIT_SECTION,
513 strlen(MEMORY_APP_STATUS_LIMIT_SECTION)+1)) {
514 int error = RESOURCED_ERROR_NONE;
516 if (!strncmp(result->name, BACKGROUND_PER_APP_LIMIT_ACTION,
517 strlen(BACKGROUND_PER_APP_LIMIT_ACTION) + 1)) {
518 error = set_mem_action_conf(&memcg_conf->background, result->value);
521 _E("[DEBUG] Unknown configuration name (%s) and value (%s) on section (%s)",
522 result->name, result->value, result->section);
528 _E("[DEBUG] Unknown section name (%s) and value (%s) on section (%s)",
529 result->name, result->value, result->section);
532 return RESOURCED_ERROR_NONE;
535 static int vendor_config(struct parse_result *result, void *user_data)
537 int *config_type = (int *)user_data;
538 static struct proc_conf_info *pci = NULL;
540 if (!result || !user_data)
541 return RESOURCED_ERROR_INVALID_PARAMETER;
543 if (strncmp(result->section, PER_PROCESS_SECTION, strlen(PER_PROCESS_SECTION)+1))
544 return RESOURCED_ERROR_NONE;
546 if (!strncmp(result->name, SERVICE_NAME_CONF, strlen(SERVICE_NAME_CONF)+1) ||
547 !strncmp(result->name, APP_NAME_CONF, strlen(APP_NAME_CONF)+1)) {
548 pci = fixed_app_and_service_exist_check(result->value,
549 result->name[0] == 'A' ? APP_TYPE : SERVICE_TYPE);
551 pci = (struct proc_conf_info *)calloc(1, sizeof(struct proc_conf_info));
553 _E("Failed to allocate memory during parsing vendor configurations");
554 return RESOURCED_ERROR_OUT_OF_MEMORY;
556 pci->mem_type = CGROUP_TOP;
557 pci->cpu_type = CGROUP_TOP;
558 pci->cpu_priority = CPU_INIT_PRIO;
559 pci->watchdog_action = PROC_ACTION_KILL;
560 pci->fail_action = PROC_ACTION_IGNORE;
561 strncpy(pci->name, result->value, sizeof(pci->name)-1);
563 if (result->name[0] == 'A') {
564 fixed_app_list_insert(pci);
567 fixed_service_list_insert(pci);
571 else if (!strncmp(result->name, CPU_CGROUP_NAME_CONF, strlen(CPU_CGROUP_NAME_CONF)+1) &&
572 *config_type == LIMITER_CONFIG) {
574 _E("process configuration information pointer should not be NULL");
575 return RESOURCED_ERROR_FAIL;
578 if (!strncmp(result->value, CGROUP_VIP_VALUE_CONF,
579 strlen(CGROUP_VIP_VALUE_CONF) +1)) {
580 pci->cpu_type = CGROUP_VIP;
582 else if (!strncmp(result->value, CGROUP_HIGH_VALUE_CONF,
583 strlen(CGROUP_HIGH_VALUE_CONF) +1)) {
584 pci->cpu_type = CGROUP_HIGH;
586 else if (!strncmp(result->value, CGROUP_MEDIUM_VALUE_CONF,
587 strlen(CGROUP_MEDIUM_VALUE_CONF) +1)) {
588 pci->cpu_type = CGROUP_MEDIUM;
590 else if (!strncmp(result->value, CGROUP_LOW_VALUE_CONF,
591 strlen(CGROUP_LOW_VALUE_CONF) +1)) {
592 pci->cpu_type = CGROUP_LOW;
595 _E("invalid parameter (%s)", result->value);
596 return RESOURCED_ERROR_INVALID_PARAMETER;
599 else if (!strncmp(result->name, MEM_CGROUP_NAME_CONF, strlen(MEM_CGROUP_NAME_CONF)+1) &&
600 *config_type == LIMITER_CONFIG) {
602 _E("process configuration information pointer should not be NULL");
603 return RESOURCED_ERROR_FAIL;
606 if (!strncmp(result->value, CGROUP_VIP_VALUE_CONF,
607 strlen(CGROUP_VIP_VALUE_CONF) +1)) {
608 pci->mem_type = CGROUP_VIP;
610 else if (!strncmp(result->value, CGROUP_HIGH_VALUE_CONF,
611 strlen(CGROUP_HIGH_VALUE_CONF) +1)) {
612 pci->mem_type = CGROUP_HIGH;
614 else if (!strncmp(result->value, CGROUP_MEDIUM_VALUE_CONF,
615 strlen(CGROUP_MEDIUM_VALUE_CONF) +1)) {
616 pci->mem_type = CGROUP_MEDIUM;
618 else if (!strncmp(result->value, CGROUP_LOW_VALUE_CONF,
619 strlen(CGROUP_LOW_VALUE_CONF) +1)) {
620 pci->mem_type = CGROUP_LOW;
623 _E("invalid parameter (%s)", result->value);
624 return RESOURCED_ERROR_INVALID_PARAMETER;
627 else if (!strncmp(result->name, MEM_LIMIT_ACTION_NAME_CONF,
628 strlen(MEM_LIMIT_ACTION_NAME_CONF)+1) && *config_type == LIMITER_CONFIG) {
632 _E("process configuration information pointer should not be NULL");
633 return RESOURCED_ERROR_FAIL;
636 error = set_mem_action_conf(&pci->mem_action, result->value);
639 else if (!strncmp(result->name, CPU_PRIORITY_NAME_CONF, strlen(CPU_PRIORITY_NAME_CONF)+1) &&
640 *config_type == LIMITER_CONFIG) {
642 _E("process configuration information pointer should not be NULL");
643 return RESOURCED_ERROR_FAIL;
645 pci->cpu_priority = atoi(result->value);
647 else if (!strncmp(result->name, ACTION_ON_FAILURE_NAME_CONF,
648 strlen(ACTION_ON_FAILURE_NAME_CONF)+1) && *config_type == PROCESS_CONFIG) {
650 _E("process configuration information pointer should not be NULL");
651 return RESOURCED_ERROR_FAIL;
654 if (!strncmp(result->value, ACTION_REBOOT_VALUE_CONF,
655 strlen(ACTION_REBOOT_VALUE_CONF) +1)) {
656 pci->fail_action = PROC_ACTION_REBOOT;
659 _E("invalid parameter (%s)", result->value);
660 return RESOURCED_ERROR_INVALID_PARAMETER;
663 else if (!strncmp(result->name, WATCHDOG_ACTION_NAME_CONF,
664 strlen(WATCHDOG_ACTION_NAME_CONF)+1) && *config_type == PROCESS_CONFIG) {
666 _E("process configuration information pointer should not be NULL");
667 return RESOURCED_ERROR_FAIL;
670 if (!strncmp(result->value, ACTION_IGNORE_VALUE_CONF,
671 strlen(ACTION_IGNORE_VALUE_CONF) +1)) {
672 pci->watchdog_action = PROC_ACTION_IGNORE;
674 else if (!strncmp(result->value, ACTION_KILL_VALUE_CONF,
675 strlen(ACTION_KILL_VALUE_CONF) +1)) {
676 pci->watchdog_action = PROC_ACTION_KILL;
679 _E("invalid parameter (%s)", result->value);
680 return RESOURCED_ERROR_INVALID_PARAMETER;
684 _E("Unknown configuration name (%s) and value (%s) on section (%s)",
685 result->name, result->value, result->section);
688 return RESOURCED_ERROR_NONE;
691 static void load_per_vendor_configs(const char *dir, int func(struct parse_result *result,
692 void *user_data), void *user_data)
696 struct dirent **namelist;
698 if ((count = scandir(dir, &namelist, NULL, alphasort)) == -1) {
699 _W("failed to opendir (%s)", dir);
703 for (idx = 0; idx < count; idx++) {
704 char path[PATH_MAX] = {0, };
706 if (!strstr(namelist[idx]->d_name, CONF_FILE_SUFFIX))
709 snprintf(path, sizeof(path), "%s/%s", dir, namelist[idx]->d_name);
710 config_parse(path, func, user_data);
717 void resourced_parse_vendor_configs(void)
721 fixed_app_and_service_list_init();
723 /* Load configurations in limiter.conf and limiter.conf.d/ */
724 config_parse(LIMITER_CONF_FILE, limiter_config, NULL);
725 config_type = LIMITER_CONFIG;
726 load_per_vendor_configs(LIMITER_CONF_DIR, vendor_config, &config_type);
728 /* Load configurations in optimizer.conf and optimizer.conf.d */
729 config_parse(OPTIMIZER_CONF_FILE, optimizer_config, NULL);
730 config_type = OPTIMIZER_CONFIG;
731 load_per_vendor_configs(OPTIMIZER_CONF_DIR, vendor_config, &config_type);
733 /* Load configuration in process.conf */
734 config_type = PROCESS_CONFIG;
735 load_per_vendor_configs(PROC_CONF_DIR, vendor_config, &config_type);
738 void resourced_free_vendor_configs(void)
740 fixed_app_and_service_list_exit();
743 int config_parse(const char *file_name, int cb(struct parse_result *result,
744 void *user_data), void *user_data)
747 struct parse_result result;
748 /* use stack for parsing */
750 char section[MAX_SECTION];
751 char *start, *end, *name, *value;
752 int lineno = 0, ret = 0;
754 if (!file_name || !cb) {
760 f = fopen(file_name, "r");
762 _E("Failed to open file %s", file_name);
767 /* parsing line by line */
768 while (fgets(line, LINE_MAX, f) != NULL) {
773 start = strstrip(start);
775 if (*start == COMMENT) {
777 } else if (*start == '[') {
779 end = strchr(start, ']');
780 if (!end || *end != ']') {
786 strncpy(section, start + 1, sizeof(section)-1);
787 section[MAX_SECTION-1] = '\0';
789 /* parse name & value */
790 end = strchr(start, '=');
791 if (!end || *end != '=') {
796 name = strstrip(start);
797 value = strstrip(end + 1);
798 end = strchr(value, COMMENT);
799 if (end && *end == COMMENT) {
801 value = strstrip(value);
804 result.section = section;
806 result.value = value;
807 /* callback with parse result */
808 ret = cb(&result, user_data);
820 _E("Failed to read %s:%d!", file_name, lineno);