1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/server/src/cfg.c

298 lines
7.3 KiB
C
Raw Normal View History

/** Configuration parser.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
2015-06-02 21:53:04 +02:00
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
2015-08-07 01:11:43 +02:00
* Unauthorized copying of this file, via any medium is strictly prohibited.
2015-06-02 21:53:04 +02:00
*********************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "utils.h"
#include "list.h"
#include "if.h"
#include "cfg.h"
#include "node.h"
#include "path.h"
#include "hooks.h"
2015-06-03 10:13:35 +02:00
#include "file.h"
#ifdef ENABLE_SOCKET
#include "socket.h"
#endif
2015-03-31 14:28:00 +02:00
#ifdef ENABLE_GTFPGA
2015-08-21 10:19:32 +02:00
#include "gtfpga.h"
2015-03-31 14:28:00 +02:00
#endif
#ifdef ENABLE_OPAL_ASYNC
2015-08-21 10:19:32 +02:00
#include "opal.h"
#endif
int config_parse(const char *filename, config_t *cfg, struct settings *set,
struct list *nodes, struct list *paths)
{
config_set_auto_convert(cfg, 1);
int ret = strcmp("-", filename) ? config_read_file(cfg, filename)
: config_read(cfg, stdin);
if (ret != CONFIG_TRUE)
error("Failed to parse configuration: %s in %s:%d",
config_error_text(cfg),
config_error_file(cfg) ? config_error_file(cfg) : filename,
config_error_line(cfg)
);
2015-08-07 01:11:43 +02:00
config_setting_t *cfg_root = config_root_setting(cfg);
/* Parse global settings */
2014-12-05 12:39:52 +01:00
if (set) {
if (!cfg_root || !config_setting_is_group(cfg_root))
error("Missing global section in config file: %s", filename);
2014-12-05 12:39:52 +01:00
config_parse_global(cfg_root, set);
}
2015-08-07 01:11:43 +02:00
/* Parse nodes */
2014-12-05 12:39:52 +01:00
if (nodes) {
config_setting_t *cfg_nodes = config_setting_get_member(cfg_root, "nodes");
if (!cfg_nodes || !config_setting_is_group(cfg_nodes))
error("Missing node section in config file: %s", filename);
2015-08-07 01:11:43 +02:00
2014-12-05 12:39:52 +01:00
for (int i = 0; i < config_setting_length(cfg_nodes); i++) {
config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i);
2015-09-17 01:33:19 +02:00
config_parse_node(cfg_node, nodes, set);
2014-12-05 12:39:52 +01:00
}
}
/* Parse paths */
2014-12-05 12:39:52 +01:00
if (paths) {
config_setting_t *cfg_paths = config_setting_get_member(cfg_root, "paths");
if (!cfg_paths || !config_setting_is_list(cfg_paths))
error("Missing path section in config file: %s", filename);
for (int i = 0; i < config_setting_length(cfg_paths); i++) {
config_setting_t *cfg_path = config_setting_get_elem(cfg_paths, i);
2015-09-17 01:33:19 +02:00
config_parse_path(cfg_path, paths, nodes, set);
2014-12-05 12:39:52 +01:00
}
}
return 0;
}
int config_parse_global(config_setting_t *cfg, struct settings *set)
{
config_setting_lookup_int(cfg, "affinity", &set->affinity);
config_setting_lookup_int(cfg, "priority", &set->priority);
config_setting_lookup_int(cfg, "debug", &set->debug);
config_setting_lookup_float(cfg, "stats", &set->stats);
2015-05-06 11:43:05 +02:00
log_setlevel(set->debug);
return 0;
}
int config_parse_path(config_setting_t *cfg,
2015-09-17 01:33:19 +02:00
struct list *paths, struct list *nodes, struct settings *set)
{
const char *in;
int enabled;
int reverse;
2015-08-07 01:11:43 +02:00
struct path *p = path_create();
/* Input node */
struct config_setting_t *cfg_in = config_setting_get_member(cfg, "in");
if (!cfg_in || config_setting_type(cfg_in) != CONFIG_TYPE_STRING)
cerror(cfg, "Invalid input node for path");
2015-08-07 01:11:43 +02:00
in = config_setting_get_string(cfg_in);
p->in = list_lookup(nodes, in);
if (!p->in)
cerror(cfg_in, "Invalid input node '%s'", in);
/* Output node(s) */
struct config_setting_t *cfg_out = config_setting_get_member(cfg, "out");
if (cfg_out)
config_parse_nodelist(cfg_out, &p->destinations, nodes);
if (list_length(&p->destinations) >= 1)
p->out = list_first(&p->destinations)->node;
else
cerror(cfg, "Missing output node for path");
/* Optional settings */
struct config_setting_t *cfg_hook = config_setting_get_member(cfg, "hook");
if (cfg_hook)
config_parse_hooklist(cfg_hook, p->hooks);
2015-08-07 01:11:43 +02:00
if (!config_setting_lookup_bool(cfg, "enabled", &enabled))
enabled = 1;
if (!config_setting_lookup_bool(cfg, "reverse", &reverse))
reverse = 0;
if (!config_setting_lookup_float(cfg, "rate", &p->rate))
p->rate = 0; /* disabled */
if (!config_setting_lookup_int(cfg, "poolsize", &p->poolsize))
p->poolsize = DEFAULT_POOLSIZE;
p->cfg = cfg;
if (enabled) {
p->in->refcnt++;
p->in->vt->refcnt++;
2015-08-07 01:11:43 +02:00
FOREACH(&p->destinations, it) {
it->node->refcnt++;
it->node->vt->refcnt++;
}
2015-08-07 01:11:43 +02:00
if (reverse) {
if (list_length(&p->destinations) > 1)
2015-03-31 14:28:00 +02:00
error("Can't reverse path with multiple destination nodes");
struct path *r = path_create();
r->in = p->out; /* Swap in/out */
r->out = p->in;
2015-08-07 01:11:43 +02:00
list_push(&r->destinations, r->out);
r->in->refcnt++;
r->out->refcnt++;
r->in->vt->refcnt++;
r->out->vt->refcnt++;
list_push(paths, r);
}
2015-08-07 01:11:43 +02:00
list_push(paths, p);
}
else {
2015-05-07 13:01:18 +02:00
char buf[128];
path_print(p, buf, sizeof(buf));
2015-08-07 01:11:43 +02:00
warn("Path %s is not enabled", buf);
path_destroy(p);
}
return 0;
}
2015-09-19 15:28:28 +02:00
int config_parse_nodelist(config_setting_t *cfg, struct list *list, struct list *all) {
const char *str;
struct node *node;
2015-08-07 01:11:43 +02:00
switch (config_setting_type(cfg)) {
case CONFIG_TYPE_STRING:
str = config_setting_get_string(cfg);
2015-09-19 15:28:28 +02:00
if (str) {
2015-09-19 18:46:04 +02:00
node = list_lookup(all, str);
2015-09-19 15:28:28 +02:00
if (node)
list_push(list, node);
else
cerror(cfg, "Unknown outgoing node '%s'", str);
}
else
cerror(cfg, "Invalid outgoing node");
break;
2015-08-07 01:11:43 +02:00
case CONFIG_TYPE_ARRAY:
2015-09-19 15:28:28 +02:00
for (int i = 0; i < config_setting_length(cfg); i++) {
config_setting_t *elm = config_setting_get_elem(cfg, i);
str = config_setting_get_string(elm);
if (str) {
node = list_lookup(all, str);
if (node)
list_push(list, node);
else
cerror(elm, "Unknown outgoing node '%s'", str);
}
else
cerror(cfg, "Invalid outgoing node");
}
break;
2015-08-07 01:11:43 +02:00
default:
cerror(cfg, "Invalid output node(s)");
}
2015-08-07 01:11:43 +02:00
return 0;
}
2015-09-19 15:28:28 +02:00
int config_parse_hooklist(config_setting_t *cfg, struct list *list) {
const char *str;
const struct hook *hook;
switch (config_setting_type(cfg)) {
case CONFIG_TYPE_STRING:
str = config_setting_get_string(cfg);
2015-09-19 15:28:28 +02:00
if (str) {
hook = list_lookup(&hooks, str);
if (hook)
list_insert(&list[hook->type], hook->priority, hook->callback);
else
cerror(cfg, "Unknown hook function '%s'", str);
}
else
cerror(cfg, "Invalid hook function");
break;
2015-08-07 01:11:43 +02:00
case CONFIG_TYPE_ARRAY:
2015-09-19 15:28:28 +02:00
for (int i = 0; i<config_setting_length(cfg); i++) {
config_setting_t *elm = config_setting_get_elem(cfg, i);
str = config_setting_get_string(elm);
if (str) {
hook = list_lookup(&hooks, str);
if (hook)
list_insert(&list[hook->type], hook->priority, hook->callback);
else
cerror(elm, "Invalid hook function '%s'", str);
}
else
cerror(cfg, "Invalid hook function");
}
break;
2015-08-07 01:11:43 +02:00
default:
cerror(cfg, "Invalid hook functions");
}
2015-08-07 01:11:43 +02:00
return 0;
}
2015-09-17 01:33:19 +02:00
int config_parse_node(config_setting_t *cfg, struct list *nodes, struct settings *set)
{
2014-12-05 12:39:52 +01:00
const char *type;
int ret;
struct node *n = node_create();
/* Required settings */
2014-12-05 12:39:52 +01:00
n->cfg = cfg;
n->name = config_setting_name(cfg);
if (!n->name)
cerror(cfg, "Missing node name");
2015-03-21 15:29:00 +01:00
if (!config_setting_lookup_string(cfg, "type", &type))
cerror(cfg, "Missing node type");
2015-08-07 01:11:43 +02:00
if (!config_setting_lookup_int(cfg, "combine", &n->combine))
n->combine = 1;
2015-08-07 01:11:43 +02:00
2015-09-17 01:33:19 +02:00
if (!config_setting_lookup_int(cfg, "affinity", &n->combine))
n->affinity = set->affinity;
2015-09-19 15:28:28 +02:00
n->vt = list_lookup(&node_types, type);
2015-03-21 15:29:00 +01:00
if (!n->vt)
cerror(cfg, "Invalid type for node '%s'", n->name);
2014-12-05 12:39:52 +01:00
ret = n->vt->parse(cfg, n);
if (!ret)
list_push(nodes, n);
2014-12-05 12:39:52 +01:00
return ret;
}