_E("Failed to read %s:%d!", file_name, lineno);
return ret;
}
-
-static int config_table_lookup(void *table,
- const char *section,
- const char *lvalue,
- ConfigParserCallback *func,
- int *ltype,
- void **data)
-{
- ConfigTableItem *t;
-
- assert(table);
- assert(lvalue);
- assert(func);
- assert(ltype);
- assert(data);
-
- for (t = table; t->lvalue; t++) {
-
- if (!streq(lvalue, t->lvalue))
- continue;
-
- if (!streq_ptr(section, t->section))
- continue;
-
- *func = t->cb;
- *ltype = t->ltype;
- *data = t->data;
- return 1;
- }
-
- return 0;
-}
-
-/* Run the user supplied parser for an assignment */
-static int config_parse_table(const char *filename,
- unsigned line,
- void *table,
- const char *section,
- const char *lvalue,
- const char *rvalue)
-{
- ConfigParserCallback cb = NULL;
- int ltype = 0;
- void *data = NULL;
- int r;
-
- assert(filename);
- assert(section);
- assert(lvalue);
- assert(rvalue);
-
- r = config_table_lookup(table,
- section,
- lvalue,
- &cb,
- <ype,
- &data);
- if (r <= 0)
- return r;
-
- if (cb)
- return cb(filename,
- line,
- section,
- lvalue,
- ltype,
- rvalue,
- data);
-
- return 0;
-}
-
-int config_parse_new(const char *filename, void *table)
-{
- _cleanup_fclose_ FILE *f = NULL;
- char *sections[MAX_SECTION] = { 0 };
- char *section = NULL, *n, *e, l[LINE_MAX];
- size_t len;
- int i, r, num_section = 0;
- bool already;
- unsigned line = 0;
-
- assert(filename);
-
- f = fopen(filename, "r");
- if (!f) {
- _E("Failed to open file %s", filename);
- return -errno;
- }
-
- while (!feof(f)) {
- _cleanup_free_ char *lvalue = NULL, *rvalue = NULL;
- char *rs = NULL;
-
- if (fgets(l, LINE_MAX, f) == NULL) {
- if (feof(f))
- break;
-
- _E("Failed to parse configuration file '%s': %m", filename);
- r = -errno;
- goto finish;
- }
-
- line++;
- truncate_nl(l);
-
- if (strchr(COMMENTS NEWLINE, *l))
- continue;
-
- if (*l == '[') {
- len = strlen(l);
- if (l[len-1] != ']') {
- _E("Error: Invalid section header: %s", l);
- r = -EBADMSG;
- goto finish;
- }
-
- n = strndup(l+1, len-2);
- if (!n) {
- r = -ENOMEM;
- goto finish;
- }
-
- already = false;
- for (i = 0; i < num_section; i++) {
- if (streq(n, sections[i])) {
- section = sections[i];
- already = true;
- free(n);
- break;
- }
- }
-
- if (already)
- continue;
-
- section = n;
- sections[num_section] = n;
- num_section++;
- if (num_section > MAX_SECTION) {
- _E("Error: max number of section reached: %d", num_section);
- r = -EOVERFLOW;
- goto finish;
- }
-
- continue;
- }
-
- if (!section)
- continue;
-
- e = strchr(l, '=');
- if (e == NULL) {
- _D("Warning: config: no '=' character in line '%s'.", l);
- continue;
- }
-
- lvalue = strndup(l, e-l);
- strstrip(lvalue);
-
- rs = strstrip(e+1);
- rvalue = strndup(rs, strlen(rs));
- strstrip(rvalue);
-
- r = config_parse_table(filename,
- line,
- table,
- section,
- lvalue,
- rvalue);
- if (r < 0)
- goto finish;
- }
-
- r = 0;
-
-finish:
- for (i = 0; i < num_section; i++)
- if (sections[i])
- free(sections[i]);
-
- return r;
-}
-
-int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data)
-{
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent de;
- struct dirent *result;
-
- d = opendir(dir);
- if (!d) {
- _E("Failed to open dir: %s", dir);
- return errno;
- }
-
- FOREACH_DIRENT(de, d, result, return -errno) {
- _cleanup_free_ char *path = NULL;
- int r;
-
- if (de.d_type != DT_REG)
- continue;
-
- r = asprintf(&path, "%s/%s", dir, de.d_name);
- if (r < 0)
- return -ENOMEM;
-
- r = fp(path, data);
- /* Do not just break loop until parse all file of
- * dir. Just only put log */
- if (r < 0)
- _D("Failed to parse config: %s", de.d_name);
- }
-
- return 0;
-}
-
-int config_parse_bool(const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data)
-{
- int k;
- bool *b = data;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- k = parse_boolean(rvalue);
- if (k < 0) {
- _E("Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
- }
-
- *b = !!k;
-
- return 0;
-}
-
-
-int config_parse_int(const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data)
-{
- int *i = data;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- *i = atoi(rvalue);
-
- return 0;
-}
-
-int config_parse_string(const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data)
-{
- char **s = data, *n;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (is_empty(rvalue))
- n = NULL;
- else {
- n = strndup(rvalue, strlen(rvalue));
- if (!n)
- return -ENOMEM;
- }
-
- free(*s);
- *s = n;
-
- return 0;
-}
-
-int config_parse_bytes(const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data)
-{
- size_t *s = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (is_empty(rvalue))
- *s = 0;
- else {
- r = parse_bytes(rvalue, s);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int config_parse_strv(const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data)
-{
- char ***strv = data;
- char **o = NULL, **v = NULL, **vv = NULL;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (is_empty(rvalue))
- return 0;
-
- r = str_to_strv(rvalue, &v, WHITESPACE);
- if (r < 0)
- return r;
-
- o = *strv;
-
- r = strv_attach(o, v, &vv, true);
- if (r < 0)
- return r;
-
- *strv = vv;
-
- return 0;
-}
*/
int config_parse(const char *file_name, int cb(struct parse_result *result,
void *user_data), void *user_data);
-
-/* Prototype for a parser for a specific configuration setting */
-typedef int (*ConfigParserCallback)(
- const char *filename,
- unsigned line,
- const char *section,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data);
-
-typedef int (*ConfigParseFunc)(const char *path, void *data);
-
-/* Wraps information for parsing a specific configuration variable, to
- * be stored in a simple array */
-typedef struct ConfigTableItem {
- const char *section; /* Section */
- const char *lvalue; /* Name of the variable */
- ConfigParserCallback cb; /* Function that is called to
- * parse the variable's
- * value */
- int ltype; /* Distinguish different
- * variables passed to the
- * same callback */
- void *data; /* Where to store the
- * variable's data */
-} ConfigTableItem;
-
-int config_parse_new(const char *filename, void *table);
-int config_parse_dir(const char *dir, ConfigParseFunc fp, void *data);
-
-int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
-int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
-int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
-int config_parse_bytes(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
-int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data);
#endif
-
static bool quite = false;
static size_t arg_size = 0;
-static int parse_config_file(void)
+static int mem_stress_load_config(struct parse_result *result, void *user_data)
{
- const ConfigTableItem items[] = {
- { "MemStress", "Size", config_parse_bytes, 0, &arg_size },
- { NULL, NULL, NULL, 0, NULL }
- };
+ if (strncmp(result->section, "MemStress", sizeof("MemStress") + 1)) {
+ fprintf(stdout, "Invalid section name %s", result->section);
+ return -1;
+ }
+
+ if (strncmp(result->name, "Size", sizeof("Size") + 1)) {
+ fprintf(stdout, "Invalid lvalue %s", result->name);
+ return -1;
+ }
+
+ if (!result->value) {
+ fprintf(stdout, "rvalue is empty");
+ return -1;
+ }
+
+ if (parse_bytes(result->value, &arg_size)) {
+ fprintf(stdout, "Fail to parse rvalue %s", result->value);
+ return -1;
+ }
- return config_parse_new(MEM_STRESS_CONF, (void*) items);
+ return 0;
}
static void mem_stress_signal_handler(int signo)
if (r < 0)
return EXIT_FAILURE;
- r = parse_config_file();
+ r = config_parse(MEM_STRESS_CONF, mem_stress_load_config, NULL);
if (r < 0)
return EXIT_FAILURE;
static char **arg_vip_proc_names = NULL;
static char **arg_vip_systemd_services = NULL;
-static int vip_parse_config_file(void)
+static int vip_load_config(struct parse_result *result, void *user_data)
{
- const ConfigTableItem items[] = {
- { "VIP_PROCESS", "VIP_PROC_NAME",
- config_parse_strv, 0, &arg_vip_proc_names },
- { "VIP_PROCESS", "VIP_SYSTEMD_SERVICE",
- config_parse_strv, 0, &arg_vip_systemd_services },
- { NULL, NULL,
- NULL, 0, NULL }
- };
-
- return config_parse_new(VIP_CONF_FILE, (void*) items);
+ char ***strv;
+ char **temp, **templist;
+
+ if (strncmp(result->section, "VIP_PROCESS", sizeof("VIP_PROCESS") + 1)) {
+ _E("Invalid section name %s", result->section);
+ return -1;
+ }
+
+ if (!result->name || !result->value) {
+ _E("lvalue or rvalue is empty");
+ return -1;
+ }
+
+ if (!strncmp(result->name, "VIP_PROC_NAME", sizeof("VIP_PROC_NAME") + 1))
+ strv = &arg_vip_proc_names;
+ else if (!strncmp(result->name, "VIP_SYSTEMD_SERVICE", sizeof("VIP_SYSTEMD_SERVICE") + 1))
+ strv = &arg_vip_systemd_services;
+ else {
+ _E("Invalid lvalue %s", result->name);
+ return -1;
+ }
+
+ if (str_to_strv(result->value, &temp, WHITESPACE) < 0) {
+ _E("Failed to convert str to strv");
+ return -1;
+ }
+
+ if (strv_attach(*strv, temp, &templist, true) < 0) {
+ _E("Failed to add %s to VIP list", result->value);
+ return -1;
+ }
+
+ *strv = templist;
+ return 0;
}
static int vip_create_sub_cgroup(const char *name, pid_t pid)
_E("failed to remove %s: %m", CHECK_RELEASE_PROGRESS);
}
- r = vip_parse_config_file();
+ r = config_parse(VIP_CONF_FILE, vip_load_config, NULL);
if (r < 0) {
_E("failed to parse vip config file: %s", strerror_r(-r, buf, sizeof(buf)));
return RESOURCED_ERROR_FAIL;