mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
rewrite of config parsing to use linked lists
git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@65 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
parent
2307913bc2
commit
ee57014ec4
7 changed files with 122 additions and 115 deletions
|
@ -23,58 +23,53 @@ struct settings {
|
|||
int affinity;
|
||||
/** Protocol version of UDP packages */
|
||||
int protocol;
|
||||
/// Number of parsed paths
|
||||
int path_count;
|
||||
/// Number of parsed nodes
|
||||
int node_count;
|
||||
|
||||
/** A libconfig object pointing to the root of the config file */
|
||||
config_setting_t *cfg;
|
||||
|
||||
/// Array of nodes
|
||||
struct node *nodes;
|
||||
/// Array of paths
|
||||
struct path *paths;
|
||||
};
|
||||
|
||||
/** Parse configuration file and store settings in supplied struct settings.
|
||||
*
|
||||
* @param c A libconfig object
|
||||
* @param g The global configuration structure (also contains the config filename)
|
||||
* @param cfg A libconfig object
|
||||
* @param set The global configuration structure (also contains the config filename)
|
||||
* @param nodes A pointer to a linked list of nodes which should be parsed
|
||||
* @param paths A pointer to a linked list of paths which should be parsed
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - otherwise an error occured
|
||||
*/
|
||||
int config_parse(const char *filename, config_t *c, struct settings *g);
|
||||
int config_parse(const char *filename, config_t *cfg,
|
||||
struct settings *set, struct node **nodes, struct path **paths);
|
||||
|
||||
/** Parse the global section of a configuration file.
|
||||
*
|
||||
* @param c A libconfig object pointing to the root of the file
|
||||
* @param g The global configuration file
|
||||
* @param cfg A libconfig object pointing to the root of the file
|
||||
* @param set The global configuration file
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - otherwise an error occured
|
||||
*/
|
||||
int config_parse_global(config_setting_t *c, struct settings *g);
|
||||
int config_parse_global(config_setting_t *cfg, struct settings *set);
|
||||
|
||||
/** Parse a single path and add it to the global configuration.
|
||||
*
|
||||
* @param c A libconfig object pointing to the path
|
||||
* @param g The global configuration file
|
||||
*
|
||||
* @param cfg A libconfig object pointing to the path
|
||||
* @param path A pointer to the new path
|
||||
* @param nodes A linked list of all existing nodes
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - otherwise an error occured
|
||||
*/
|
||||
int config_parse_path(config_setting_t *c, struct settings *g);
|
||||
int config_parse_path(config_setting_t *cfg, struct path *path, struct node *nodes);
|
||||
|
||||
/** Parse a single node and add it to the global configuration.
|
||||
*
|
||||
* @param c A libconfig object pointing to the node
|
||||
* @param g The global configuration file
|
||||
*
|
||||
* @param cfg A libconfig object pointing to the node
|
||||
* @param node A pointer to the new node
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - otherwise an error occured
|
||||
*/
|
||||
int config_parse_node(config_setting_t *c, struct settings *g);
|
||||
int config_parse_node(config_setting_t *cfg, struct node *node);
|
||||
|
||||
#endif /* _CFG_H_ */
|
||||
|
|
|
@ -61,6 +61,9 @@ struct node
|
|||
|
||||
/** A pointer to the libconfig object which instantiated this node */
|
||||
config_setting_t *cfg;
|
||||
|
||||
/** Linked list pointer */
|
||||
struct node *next;
|
||||
};
|
||||
|
||||
/** Create a new node.
|
||||
|
@ -109,10 +112,9 @@ enum node_type node_lookup_type(const char *str);
|
|||
/** Search list of nodes for a name.
|
||||
*
|
||||
* @param str The name of the wanted node
|
||||
* @param nodes A pointer to the first list element
|
||||
* @param len Length of the node list
|
||||
* @param nodes A linked list of all nodes
|
||||
* @return A pointer to the node or NULL if not found
|
||||
*/
|
||||
struct node* node_lookup_name(const char *str, struct node *nodes, int len);
|
||||
struct node* node_lookup_name(const char *str, struct node *nodes);
|
||||
|
||||
#endif /* _NODE_H_ */
|
||||
|
|
|
@ -46,6 +46,9 @@ struct path
|
|||
pthread_t tid;
|
||||
/** A pointer to the libconfig object which instantiated this path */
|
||||
config_setting_t *cfg;
|
||||
|
||||
/** Linked list pointer */
|
||||
struct path *next;
|
||||
};
|
||||
|
||||
/** Setup a new path.
|
||||
|
|
|
@ -69,6 +69,12 @@ void init_realtime(struct settings *g);
|
|||
*/
|
||||
int sockaddr_cmp(struct sockaddr *a, struct sockaddr *b);
|
||||
|
||||
/** Append an element to a single linked list */
|
||||
#define list_add(list, elm) do { \
|
||||
elm->next = list; \
|
||||
list = elm; \
|
||||
} while (0)
|
||||
|
||||
/** Check assertion and exit if failed. */
|
||||
#define assert(exp) do { \
|
||||
if (!(exp)) { \
|
||||
|
|
132
src/cfg.c
132
src/cfg.c
|
@ -15,7 +15,8 @@
|
|||
#include "path.h"
|
||||
#include "utils.h"
|
||||
|
||||
int config_parse(const char *filename, config_t *cfg, struct settings *g)
|
||||
int config_parse(const char *filename, config_t *cfg,
|
||||
struct settings *g, struct node **n, struct path **p)
|
||||
{
|
||||
if (!config_read_file(cfg, filename)) {
|
||||
error("Failed to parse configuration: %s in %s:%d",
|
||||
|
@ -38,49 +39,60 @@ int config_parse(const char *filename, config_t *cfg, struct settings *g)
|
|||
if (!cfg_paths || !config_setting_is_list(cfg_paths))
|
||||
error("Missing path section in config file: %s", filename);
|
||||
|
||||
/* Read global settings */
|
||||
/* Parse global settings */
|
||||
config_parse_global(cfg_root, g);
|
||||
|
||||
int node_count = config_setting_length(cfg_nodes);
|
||||
int path_count = config_setting_length(cfg_paths);
|
||||
|
||||
g->nodes = malloc(node_count * sizeof(struct node));
|
||||
if (!g->nodes)
|
||||
error("Failed to allocate memory for nodes");
|
||||
|
||||
g->paths = malloc(path_count * sizeof(struct path));
|
||||
if (!g->paths)
|
||||
error("Failed to allocate memory for paths");
|
||||
|
||||
|
||||
/* Parse nodes */
|
||||
for (int i=0; i < node_count; i++) {
|
||||
config_parse_node(config_setting_get_elem(cfg_nodes, i), g);
|
||||
for (int i = 0; i < config_setting_length(cfg_nodes); i++) {
|
||||
config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i);
|
||||
|
||||
struct node *node = (struct node *) malloc(sizeof(struct node));
|
||||
if (!node)
|
||||
error("Failed to allocate memory for node");
|
||||
|
||||
if (!config_parse_node(cfg_node, node)) {
|
||||
free(node);
|
||||
cerror(cfg_node, "Failed to parse node");
|
||||
}
|
||||
|
||||
list_add(*n, node);
|
||||
}
|
||||
|
||||
/* Parse paths */
|
||||
for (int i=0; i < path_count; i++) {
|
||||
config_parse_path(config_setting_get_elem(cfg_paths, i), g);
|
||||
for (int i = 0; i < config_setting_length(cfg_paths); i++) {
|
||||
config_setting_t *cfg_path = config_setting_get_elem(cfg_paths, i);
|
||||
|
||||
struct path *path = (struct path *) malloc(sizeof(struct path));
|
||||
if (!path)
|
||||
error("Failed to allocate memory for path");
|
||||
|
||||
if (!config_parse_path(cfg_path, path, *n)) {
|
||||
free(path);
|
||||
cerror(cfg_path, "Failed to parse path");
|
||||
}
|
||||
|
||||
list_add(*p, path);
|
||||
}
|
||||
|
||||
return CONFIG_TRUE;
|
||||
}
|
||||
|
||||
int config_parse_global(config_setting_t *c, struct settings *g)
|
||||
int config_parse_global(config_setting_t *cfg, struct settings *set)
|
||||
{
|
||||
if (!config_setting_lookup_string(c, "name", &g->name))
|
||||
cerror(c, "Missing node name");
|
||||
if (!config_setting_lookup_string(cfg, "name", &set->name))
|
||||
cerror(cfg, "Missing node name");
|
||||
|
||||
config_setting_lookup_int(c, "affinity", &g->affinity);
|
||||
config_setting_lookup_int(c, "priority", &g->priority);
|
||||
config_setting_lookup_int(c, "protocol", &g->protocol);
|
||||
config_setting_lookup_int(cfg, "affinity", &set->affinity);
|
||||
config_setting_lookup_int(cfg, "priority", &set->priority);
|
||||
config_setting_lookup_int(cfg, "protocol", &set->protocol);
|
||||
|
||||
g->cfg = c;
|
||||
set->cfg = cfg;
|
||||
|
||||
return CONFIG_TRUE;
|
||||
}
|
||||
|
||||
int config_parse_path(config_setting_t *c, struct settings *g)
|
||||
int config_parse_path(config_setting_t *cfg,
|
||||
struct path *path, struct node *nodes)
|
||||
{
|
||||
struct node *in, *out;
|
||||
const char *in_str = NULL;
|
||||
|
@ -89,45 +101,43 @@ int config_parse_path(config_setting_t *c, struct settings *g)
|
|||
int reverse = 0;
|
||||
|
||||
/* Optional settings */
|
||||
config_setting_lookup_bool(c, "enabled", &enabled);
|
||||
config_setting_lookup_bool(c, "reverse", &reverse);
|
||||
config_setting_lookup_bool(cfg, "enabled", &enabled);
|
||||
config_setting_lookup_bool(cfg, "reverse", &reverse);
|
||||
|
||||
/* Required settings */
|
||||
if (!config_setting_lookup_string(c, "in", &in_str))
|
||||
cerror(c, "Missing input node for path");
|
||||
if (!config_setting_lookup_string(cfg, "in", &in_str))
|
||||
cerror(cfg, "Missing input node for path");
|
||||
|
||||
if (!config_setting_lookup_string(c, "out", &out_str))
|
||||
cerror(c, "Missing output node for path");
|
||||
if (!config_setting_lookup_string(cfg, "out", &out_str))
|
||||
cerror(cfg, "Missing output node for path");
|
||||
|
||||
info("Loading path from '%s' to '%s'", in_str, out_str);
|
||||
|
||||
in = node_lookup_name(in_str, g->nodes, g->node_count);
|
||||
in = node_lookup_name(in_str, nodes);
|
||||
if (!in)
|
||||
cerror(c, "Invalid input node '%s'");
|
||||
cerror(cfg, "Invalid input node '%s'");
|
||||
|
||||
out = node_lookup_name(out_str, g->nodes, g->node_count);
|
||||
out = node_lookup_name(out_str, nodes);
|
||||
if (!out)
|
||||
cerror(c, "Invalid output node '%s'", out_str);
|
||||
cerror(cfg, "Invalid output node '%s'", out_str);
|
||||
|
||||
if (enabled) {
|
||||
if (path_create(&g->paths[g->path_count], in, out))
|
||||
cerror(c, "Failed to parse path");
|
||||
if (path_create(path, in, out))
|
||||
cerror(cfg, "Failed to parse path");
|
||||
|
||||
g->cfg = c;
|
||||
g->path_count++;
|
||||
path->cfg = cfg;
|
||||
|
||||
if (reverse) {
|
||||
if (path_create(&g->paths[g->path_count], out, in))
|
||||
// TODO
|
||||
/*if (reverse) {
|
||||
if (path_create(path, out, in))
|
||||
cerror(c, "Failed to parse path");
|
||||
|
||||
g->path_count++;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
warn(" Path is not enabled");
|
||||
}
|
||||
|
||||
int config_parse_node(config_setting_t *c, struct settings *g)
|
||||
int config_parse_node(config_setting_t *cfg, struct node *node)
|
||||
{
|
||||
const char *name = NULL;
|
||||
const char *type_str = NULL;
|
||||
|
@ -138,35 +148,33 @@ int config_parse_node(config_setting_t *c, struct settings *g)
|
|||
enum node_type type;
|
||||
|
||||
/* Required settings */
|
||||
name = config_setting_name(c);
|
||||
name = config_setting_name(cfg);
|
||||
if (!name)
|
||||
cerror(c, "Missing node name");
|
||||
cerror(cfg, "Missing node name");
|
||||
|
||||
if (!config_setting_lookup_string(c, "type", &type_str))
|
||||
cerror(c, "Missing node type");
|
||||
if (!config_setting_lookup_string(cfg, "type", &type_str))
|
||||
cerror(cfg, "Missing node type");
|
||||
|
||||
if (!config_setting_lookup_string(c, "remote", &remote_str))
|
||||
cerror(c, "Missing node remote address");
|
||||
if (!config_setting_lookup_string(cfg, "remote", &remote_str))
|
||||
cerror(cfg, "Missing node remote address");
|
||||
|
||||
if (!config_setting_lookup_string(c, "local", &local_str))
|
||||
cerror(c, "Missing node local address");
|
||||
if (!config_setting_lookup_string(cfg, "local", &local_str))
|
||||
cerror(cfg, "Missing node local address");
|
||||
|
||||
type = node_lookup_type(type_str);
|
||||
if (type == NODE_INVALID)
|
||||
cerror(c, "Invalid node type '%s'", type);
|
||||
|
||||
cerror(cfg, "Invalid node type '%s'", type);
|
||||
|
||||
info("Loading %s node '%s'", type_str, name);
|
||||
|
||||
if (resolve_addr(local_str, &local, 0))
|
||||
cerror(c, "Failed to resolve local address '%s' of node '%s'", local_str, name);
|
||||
cerror(cfg, "Failed to resolve local address '%s' of node '%s'", local_str, name);
|
||||
|
||||
if (resolve_addr(remote_str, &remote, 0))
|
||||
cerror(c, "Failed to resolve remote address '%s' of node '%s'", remote_str, name);
|
||||
cerror(cfg, "Failed to resolve remote address '%s' of node '%s'", remote_str, name);
|
||||
|
||||
if (node_create(&g->nodes[g->node_count], name, type, local, remote))
|
||||
cerror(c, "Failed to parse node");
|
||||
if (node_create(node, name, type, local, remote))
|
||||
cerror(cfg, "Failed to parse node");
|
||||
|
||||
g->cfg = c;
|
||||
g->node_count++;
|
||||
node->cfg = cfg;
|
||||
}
|
||||
|
|
|
@ -85,11 +85,11 @@ enum node_type node_lookup_type(const char *str)
|
|||
return NODE_INVALID;
|
||||
}
|
||||
|
||||
struct node* node_lookup_name(const char *str, struct node *nodes, int len)
|
||||
struct node* node_lookup_name(const char *str, struct node *nodes)
|
||||
{
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (!strcmp(str, nodes[i].name)) {
|
||||
return &nodes[i];
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
if (!strcmp(str, n->name)) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
39
src/server.c
39
src/server.c
|
@ -20,6 +20,12 @@
|
|||
#include "path.h"
|
||||
#include "node.h"
|
||||
|
||||
/** Linked list of nodes */
|
||||
static struct node *nodes;
|
||||
|
||||
/** Linked list of paths */
|
||||
static struct path *paths;
|
||||
|
||||
/** Default settings */
|
||||
static struct settings settings = {
|
||||
.priority = 0,
|
||||
|
@ -32,9 +38,7 @@ static config_t config;
|
|||
static void start()
|
||||
{
|
||||
/* Connect and bind nodes to their sockets, set socket options */
|
||||
for (int i = 0; i < settings.node_count; i++) {
|
||||
struct node *n = &settings.nodes[i];
|
||||
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
node_connect(n);
|
||||
|
||||
debug(1, " We listen for node '%s' at %s:%u", n->name, inet_ntoa(n->local.sin_addr), ntohs(n->local.sin_port));
|
||||
|
@ -42,9 +46,7 @@ static void start()
|
|||
}
|
||||
|
||||
/* Start on thread per path for asynchronous processing */
|
||||
for (int i = 0; i < settings.path_count; i++) {
|
||||
struct path *p = &settings.paths[i];
|
||||
|
||||
for (struct path *p = paths; p; p = p->next) {
|
||||
path_start(p);
|
||||
|
||||
info("Starting path: %12s => %s => %-12s", p->in->name, settings.name, p->out->name);
|
||||
|
@ -54,9 +56,7 @@ static void start()
|
|||
static void stop()
|
||||
{
|
||||
/* Join all threads and print statistics */
|
||||
for (int i = 0; i < settings.path_count; i++) {
|
||||
struct path *p = &settings.paths[i];
|
||||
|
||||
for (struct path *p = paths; p; p = p->next) {
|
||||
path_stop(p);
|
||||
|
||||
info("Stopping path: %12s => %s => %-12s", p->in->name, settings.name, p->out->name);
|
||||
|
@ -66,9 +66,7 @@ static void stop()
|
|||
}
|
||||
|
||||
/* Close all sockets we listing on */
|
||||
for (int i = 0; i < settings.node_count; i++) {
|
||||
struct node *n = &settings.nodes[i];
|
||||
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
node_disconnect(n);
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +75,8 @@ static void quit()
|
|||
{
|
||||
stop();
|
||||
|
||||
free(settings.paths);
|
||||
free(settings.nodes);
|
||||
// TODO: free nodes and paths
|
||||
|
||||
config_destroy(&config);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
@ -111,24 +109,19 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* Parse configuration file */
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &settings);
|
||||
config_parse(argv[1], &config, &settings, &nodes, &paths);
|
||||
|
||||
if (!settings.path_count)
|
||||
if (!paths)
|
||||
error("No paths found. Terminating...");
|
||||
else
|
||||
info("Parsed %u nodes and %u paths", settings.node_count, settings.path_count);
|
||||
|
||||
/* Setup various realtime related things */
|
||||
init_realtime(&settings);
|
||||
|
||||
/* Connect all nodes to their sockets and start one thread per path */
|
||||
/* Connect all nodes and start one thread per path */
|
||||
start();
|
||||
|
||||
/* Main thread is sleeping */
|
||||
while (1) pause();
|
||||
|
||||
/* Stop and free ressources */
|
||||
quit();
|
||||
pause();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue