From a4d9a232ea31e841a3713191cc58e05d7e1f901c Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 29 Nov 2015 22:45:46 +0100 Subject: [PATCH] improved handling of node and path names / printing --- include/node.h | 29 +++++++++++++++++++---------- include/path.h | 4 ++-- lib/file.c | 4 ++-- lib/ngsi.c | 12 ++++++------ lib/node.c | 25 ++++++++++++++++++------- lib/opal.c | 11 +++++------ lib/socket.c | 24 ++++++++++++------------ src/cfg.c | 2 +- src/hooks.c | 10 +++------- src/path.c | 27 +++++++++++++-------------- src/server.c | 4 ++-- 11 files changed, 83 insertions(+), 69 deletions(-) diff --git a/include/node.h b/include/node.h index 58fe0938a..686b54044 100644 --- a/include/node.h +++ b/include/node.h @@ -36,12 +36,11 @@ extern struct list node_types; /** C++ like vtable construct for node_types */ struct node_type { - /** The unique name of this node. This must be allways the first member! */ - const char *name; - /** A short description of this node type. Will be shown in help text. */ - const char *description; - /** A list of all existing nodes of this type. */ - struct list instances; + const char *name; /**< The unique name of this node. This must be allways the first member! */ + const char *description; /**< A short description of this node type. Will be shown in help text. */ + + struct list instances; /**< A list of all existing nodes of this type. */ + size_t size; /**< Size of private data bock. @see node::_vd */ /** Global initialization per node type. * @@ -158,7 +157,9 @@ struct node_type { struct node { const char *name; /**< A short identifier of the node, only used for configuration and logging */ - char *_print; /**< A string used to print to screen. */ + + char *_name; /**< Singleton: A string used to print to screen. */ + char *_name_long; /**< Singleton: A string used to print to screen. */ int combine; /**< Number of messages to send / recv at once (scatter / gather) */ int affinity; /**< CPU Affinity of this node */ @@ -228,10 +229,18 @@ int node_parse(struct node *n, config_setting_t *cfg); /** Return a pointer to a string which should be used to print this node * - * @see node_type::print - * @param i A pointer to the interface structure. + * @see node::_name‚ + * @param n A pointer to the node structure. */ -char * node_print(struct node *n); +const char * node_name(struct node *n); + +/** Return a pointer to a string which should be used to print this node + * + * @see node::_name_short + * @see node_type::print + * @param n A pointer to the node structure. + */ +const char * node_name_long(struct node *n); /** Receive multiple messages at once. * diff --git a/include/path.h b/include/path.h index 7abd5a9b8..efdbb12d2 100644 --- a/include/path.h +++ b/include/path.h @@ -61,7 +61,7 @@ struct path config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this path */ - char *_print; /**< A string which is used to print this path to screen. */ + char *_name; /**< Singleton: A string which is used to print this path to screen. */ /** The following fields are mostly managed by hook_ functions @{ */ @@ -124,7 +124,7 @@ void path_print_stats(struct path *p); * @param p A pointer to the path structure. * @return A pointer to a string containing a textual representation of the path. */ -char * path_print(struct path *p); +const char * path_name(struct path *p); /** Conditionally execute the hooks * diff --git a/lib/file.c b/lib/file.c index b6523d8df..eb00a2814 100644 --- a/lib/file.c +++ b/lib/file.c @@ -77,7 +77,7 @@ int file_parse(struct node *n, config_setting_t *cfg) cfg_out = config_setting_get_member(cfg, "out"); if (cfg_out) { if (file_parse_direction(cfg_out, f, FILE_WRITE)) - cerror(cfg_out, "Failed to parse output file for node '%s'", n->name); + cerror(cfg_out, "Failed to parse output file for node %s", node_name(n)); /* More write specific settings */ if (!config_setting_lookup_int(cfg_out, "split", &f->write.split)) @@ -87,7 +87,7 @@ int file_parse(struct node *n, config_setting_t *cfg) cfg_in = config_setting_get_member(cfg, "in"); if (cfg_in) { if (file_parse_direction(cfg_in, f, FILE_READ)) - cerror(cfg_in, "Failed to parse input file for node '%s'", n->name); + cerror(cfg_in, "Failed to parse input file for node %s", node_name(n)); /* More read specific settings */ if (!config_setting_lookup_bool(cfg_in, "splitted", &f->read.split)) diff --git a/lib/ngsi.c b/lib/ngsi.c index c80fc4b83..b1f22bbca 100644 --- a/lib/ngsi.c +++ b/lib/ngsi.c @@ -436,13 +436,13 @@ int ngsi_parse(struct node *n, config_setting_t *cfg) i->access_token = NULL; /* disabled by default */ if (!config_setting_lookup_string(cfg, "endpoint", &i->endpoint)) - cerror(cfg, "Missing NGSI endpoint for node '%s'", n->name); + cerror(cfg, "Missing NGSI endpoint for node %s", node_name(n)); if (!config_setting_lookup_string(cfg, "entity_id", &i->entity_id)) - cerror(cfg, "Missing NGSI entity ID for node '%s'", n->name); + cerror(cfg, "Missing NGSI entity ID for node %s", node_name(n)); if (!config_setting_lookup_string(cfg, "entity_type", &i->entity_type)) - cerror(cfg, "Missing NGSI entity type for node '%s'", n->name); + cerror(cfg, "Missing NGSI entity type for node %s", node_name(n)); if (!config_setting_lookup_bool(cfg, "ssl_verify", &i->ssl_verify)) i->ssl_verify = 1; /* verify by default */ @@ -455,12 +455,12 @@ int ngsi_parse(struct node *n, config_setting_t *cfg) config_setting_t *cfg_mapping = config_setting_get_member(cfg, "mapping"); if (!cfg_mapping) - cerror(cfg, "Missing mapping for node '%s", n->name); + cerror(cfg, "Missing mapping for node %s", node_name(n)); if (ngsi_parse_mapping(&i->mapping, cfg_mapping)) - cerror(cfg_mapping, "Invalid mapping for NGSI node '%s'", n->name); n->ngsi = i; + cerror(cfg_mapping, "Invalid mapping for node %s", node_name(n)); return 0; } @@ -528,7 +528,7 @@ int ngsi_open(struct node *n) ret = ngsi_request_context_update(i->curl, i->endpoint, "APPEND", entity); if (ret) - error("Failed to create NGSI context for node '%s'", n->name); + error("Failed to create NGSI context for node %s", node_name(n)); json_decref(entity); diff --git a/lib/node.c b/lib/node.c index 62480ca6e..5120c4ab8 100644 --- a/lib/node.c +++ b/lib/node.c @@ -72,7 +72,7 @@ int node_start(struct node *n) { INDENT int ret; - info("Starting node '%s' of type '%s' (%s)", n->name, n->_vt->name, node_print(n)); + info("Starting node %s", node_name_long(n)); { INDENT ret = node_open(n); } @@ -87,7 +87,10 @@ int node_stop(struct node *n) { INDENT int ret; - info("Stopping node '%s'", n->name); + if (n->state != NODE_RUNNING) + return -1; + + info("Stopping node %s", node_name(n)); { INDENT ret = node_close(n); @@ -99,12 +102,20 @@ int node_stop(struct node *n) return ret; } -char * node_print(struct node *n) +const char * node_name(struct node *n) { - if (!n->_print) - n->_print = n->_vt->print(n); + if (!n->_name) + strcatf(&n->_name, YEL("%s") GRY("(%s)"), n->name, n->_vt->name); + + return n->_name; +} - return n->_print; +const char * node_name_long(struct node *n) +{ + if (!n->_name_long) + n->_name_long = n->_vt->print(n); + + return n->_name_long; } int node_reverse(struct node *n) @@ -129,7 +140,7 @@ void node_destroy(struct node *n) if (n->_vt->destroy) n->_vt->destroy(n); - free(n->_print); free(n->socket); + free(n->_name); free(n); } diff --git a/lib/opal.c b/lib/opal.c index 29a28cb2e..01378cfa2 100644 --- a/lib/opal.c +++ b/lib/opal.c @@ -168,9 +168,9 @@ int opal_open(struct node *n) rfound += og->send_ids[i] == o->send_id; if (!sfound) - error("Invalid send_id '%u' for node '%s'", o->send_id, n->name); + error("Invalid send_id '%u' for node %s", o->send_id, node_name(n)); if (!rfound) - error("Invalid recv_id '%u' for node '%s'", o->recv_id, n->name); + error("Invalid recv_id '%u' for node %s", o->recv_id, node_name(n)); /* Get some more informations and paramters from OPAL-RT */ OpalGetAsyncSendIconMode(&o->mode, o->send_id); @@ -217,8 +217,8 @@ int opal_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt /* Get the size of the data being sent by the unblocking SendID */ OpalGetAsyncSendIconDataLength(&len, o->send_id); if (len > sizeof(data)) { - warn("Ignoring the last %u of %u values for OPAL node '%s' (send_id=%u).", - len / sizeof(double) - MSG_VALUES, len / sizeof(double), n->name, o->send_id); + warn("Ignoring the last %u of %u values for OPAL node %s (send_id=%u).", + len / sizeof(double) - MSG_VALUES, len / sizeof(double), node_name(n), o->send_id); len = sizeof(data); } @@ -273,8 +273,7 @@ int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cn /* Get the number of signals to send back to the model */ OpalGetAsyncRecvIconDataLength(&len, o->recv_id); if (len > sizeof(data)) - warn("OPAL node '%s' is expecting more signals (%u) than values in message (%u)", - n->name, len / sizeof(double), m->length); + warn("Node %s is expecting more signals (%u) than values in message (%u)", node_name(n), len / sizeof(double), m->length); for (int i = 0; i < m->length; i++) data[i] = (double) m->data[i].f; /* OPAL expects double precission */ diff --git a/lib/socket.c b/lib/socket.c index 20a4aec7b..65afc106b 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -144,7 +144,7 @@ int socket_open(struct node *n) if (setsockopt(s->sd, IPPROTO_IP, IP_TOS, &prio, sizeof(prio))) serror("Failed to set type of service (QoS)"); else - debug(4, "Set QoS/TOS IP option for node '%s' to %#x", n->name, prio); + debug(4, "Set QoS/TOS IP option for node %s to %#x", node_name(n), prio); break; default: @@ -152,7 +152,7 @@ int socket_open(struct node *n) if (setsockopt(s->sd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) serror("Failed to set socket priority"); else - debug(4, "Set socket priority for node '%s' to %u", n->name, prio); + debug(4, "Set socket priority for node %s to %d", node_name(n), prio); break; } @@ -220,7 +220,7 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c /* Receive message from socket */ bytes = recvmsg(s->sd, &mhdr, 0); if (bytes == 0) - error("Remote node '%s' closed the connection", n->name); + error("Remote node %s closed the cnode_name", node_name(n)); else if (bytes < 0) serror("Failed recv"); @@ -235,7 +235,7 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c /* Check integrity of packet */ if (bytes / cnt != MSG_LEN(m)) - error("Invalid message len: %u for node '%s'", MSG_LEN(m), n->name); + error("Invalid message len: %u for node %s", MSG_LEN(m), node_name(n)); bytes -= MSG_LEN(m); } @@ -299,7 +299,7 @@ int socket_parse(struct node *n, config_setting_t *cfg) struct socket *s = alloc(sizeof(struct socket)); if (!config_setting_lookup_string(cfg, "layer", &layer)) - cerror(cfg, "Missing layer setting for node '%s'", n->name); + cerror(cfg, "Missing layer for node %s", node_name(n)); if (!strcmp(layer, "eth")) s->layer = LAYER_ETH; @@ -308,24 +308,24 @@ int socket_parse(struct node *n, config_setting_t *cfg) else if (!strcmp(layer, "udp")) s->layer = LAYER_UDP; else - cerror(cfg, "Invalid layer '%s' for node '%s'", layer, n->name); + cerror(cfg, "Invalid layer '%s' for node %s", layer, node_name(n)); if (!config_setting_lookup_string(cfg, "remote", &remote)) - cerror(cfg, "Missing remote address for node '%s'", n->name); + cerror(cfg, "Missing remote address for node %s", node_name(n)); if (!config_setting_lookup_string(cfg, "local", &local)) - cerror(cfg, "Missing local address for node '%s'", n->name); + cerror(cfg, "Missing local address for node %s", node_name(n)); ret = socket_parse_addr(local, (struct sockaddr *) &s->local, s->layer, AI_PASSIVE); if (ret) { - cerror(cfg, "Failed to resolve local address '%s' of node '%s': %s", - local, n->name, gai_strerror(ret)); + cerror(cfg, "Failed to resolve local address '%s' of node %s: %s", + local, node_name(n), gai_strerror(ret)); } ret = socket_parse_addr(remote, (struct sockaddr *) &s->remote, s->layer, 0); if (ret) { - cerror(cfg, "Failed to resolve remote address '%s' of node '%s': %s", - remote, n->name, gai_strerror(ret)); + cerror(cfg, "Failed to resolve remote address '%s' of node %s: %s", + remote, node_name(n), gai_strerror(ret)); } config_setting_t *cfg_netem = config_setting_get_member(cfg, "netem"); diff --git a/src/cfg.c b/src/cfg.c index 9d2a582be..d1fd7e305 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -229,7 +229,7 @@ int config_parse_node(config_setting_t *cfg, struct list *nodes, struct settings ret = node_parse(n, cfg); if (ret) - cerror(cfg, "Failed to parse node '%s'", n->name); + cerror(cfg, "Failed to parse node '%s'", node_name(n)); if (!config_setting_lookup_int(cfg, "combine", &n->combine)) n->combine = 1; diff --git a/src/hooks.c b/src/hooks.c index 40b21115b..867650b4a 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -274,7 +274,7 @@ int hook_restart(struct path *p, struct hook *h, int when) if (p->current->sequence == 0 && p->previous->sequence <= UINT32_MAX - 32) { warn("Simulation for path %s restarted (prev->seq=%u, current->seq=%u)", - path_print(p), p->previous->sequence, p->current->sequence); + path_name(p), p->previous->sequence, p->current->sequence); p->sent = p->invalid = @@ -372,19 +372,15 @@ int hook_stats(struct path *p, struct hook *h, int when) break; case HOOK_PERIODIC: { - char *buf = path_print(p); - if (p->received > 1) - stats("%-40.40s|%10.2g|%10.2f|%10u|%10u|%10u|%10u|%10u|%10u|%10u|", path_print(p), + stats("%-40.40s|%10.2g|%10.2f|%10u|%10u|%10u|%10u|%10u|%10u|%10u|", path_name(p), p->hist_owd.last, 1 / p->hist_gap_msg.last, p->sent, p->received, p->dropped, p->skipped, p->invalid, p->overrun, list_length(p->current) ); else - stats("%-40.40s|%10s|%10s|%10u|%10u|%10u|%10u|%10u|%10u|%10s|", buf, "", "", + stats("%-40.40s|%10s|%10s|%10u|%10u|%10u|%10u|%10u|%10u|%10s|", path_name(p), "", "", p->sent, p->received, p->dropped, p->skipped, p->invalid, p->overrun, "" ); - - free(buf); break; } } diff --git a/src/path.c b/src/path.c index 78ab92e42..5580266ad 100644 --- a/src/path.c +++ b/src/path.c @@ -32,7 +32,7 @@ static void path_write(struct path *p) n->combine /* Number of messages which should be sent */ ); - debug(15, "Sent %u messages to node '%s'", sent, n->name); + debug(15, "Sent %u messages to node %s", sent, node_name(n)); p->sent += sent; p->ts_sent = time_now(); /** @todo use hardware timestamps for socket node type */ @@ -93,7 +93,7 @@ static void * path_run(void *arg) /* Receive message */ int recv = node_read(p->in, p->pool, p->poolsize, p->received, p->in->combine); if (recv < 0) - error("Failed to receive message from node '%s'", p->in->name); + error("Failed to receive message from node %s", node_name(p->in)); else if (recv == 0) continue; @@ -101,7 +101,7 @@ static void * path_run(void *arg) p->ts_last = p->ts_recv; p->ts_recv = time_now(); - debug(15, "Received %u messages from node '%s'", recv, p->in->name); + debug(15, "Received %u messages from node %s", recv, node_name(p->in)); /* Run preprocessing hooks */ if (path_run_hook(p, HOOK_PRE)) { @@ -140,7 +140,7 @@ static void * path_run(void *arg) int path_start(struct path *p) { INDENT info("Starting path: %s (poolsize=%u, msgsize=%u, #hooks=%zu, rate=%.1f)", - path_print(p), p->poolsize, p->msgsize, list_length(&p->hooks), p->rate); + path_name(p), p->poolsize, p->msgsize, list_length(&p->hooks), p->rate); /* We sort the hooks according to their priority before starting the path */ list_sort(&p->hooks, ({int cmp(const void *a, const void *b) { @@ -174,7 +174,7 @@ int path_start(struct path *p) int path_stop(struct path *p) { INDENT - info("Stopping path: %s", path_print(p)); + info("Stopping path: %s", path_name(p)); pthread_cancel(p->recv_tid); pthread_join(p->recv_tid, NULL); @@ -194,18 +194,17 @@ int path_stop(struct path *p) return 0; } -char * path_print(struct path *p) +const char * path_name(struct path *p) { - if (!p->_print) { - char *buf = alloc(64); - - strcatf(&buf, "%s " MAG("=>"), p->in->name); + if (!p->_name) { + strcatf(&p->_name, "%s " MAG("=>"), p->in->name); - list_foreach(struct node *n, &p->destinations) - strcatf(&buf, " %s", n->name); + list_foreach(struct node *n, &p->destinations) { + strcatf(&p->_name, " %s", n->name); + } } - return p->_print; + return p->_name; } struct path * path_create() @@ -232,7 +231,7 @@ void path_destroy(struct path *p) list_destroy(&p->destinations); list_destroy(&p->hooks); - free(p->_print); + free(p->_name); free(p->pool); free(p); } diff --git a/src/server.c b/src/server.c index d7c5cda6a..af850eda7 100644 --- a/src/server.c +++ b/src/server.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) if (refs) node_start(n); else - warn("Node '%s' is unused. Skipping...", n->name); + warn("Node %s is unused. Skipping...", node_name(n)); } info("Starting paths"); @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) if (p->enabled) path_start(p); else - warn("Path %s is disabled. Skipping...", path_print(p)); + warn("Path %s is disabled. Skipping...", path_name(p)); } /* Run! */