mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
updated binaries to new vtable system (tests are pending)
This commit is contained in:
parent
1f9d2880dc
commit
ce8bec51e4
5 changed files with 167 additions and 222 deletions
|
@ -38,7 +38,8 @@ int main(int argc, char *argv[])
|
|||
printf(" VALUES is the number of values a message contains\n");
|
||||
printf(" RATE how many messages per second\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s %s)\n", BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
printf("Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Steffen Vogel <stvogel@eonerc.rwth-aachen.de>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,32 +17,37 @@
|
|||
#include <netdb.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cfg.h"
|
||||
#include "utils.h"
|
||||
#include "node.h"
|
||||
#include "msg.h"
|
||||
|
||||
int sd;
|
||||
static struct settings set;
|
||||
static struct msg msg = MSG_INIT(0);
|
||||
extern struct node *nodes;
|
||||
static struct node *node;
|
||||
|
||||
void quit(int sig, siginfo_t *si, void *ptr)
|
||||
{
|
||||
close(sd);
|
||||
node_stop(node);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct config_t config;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s LOCAL\n", argv[0]);
|
||||
printf(" LOCAL is a IP:PORT combination of the local host\n\n");
|
||||
printf("Usage: %s CONFIG NODE\n", argv[0]);
|
||||
printf(" CONFIG path to a configuration file\n");
|
||||
printf(" NODE name of the node which shoud be used\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s %s)\n",
|
||||
BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
printf("Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Steffen Vogel <stvogel@eonerc.rwth-aachen.de>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct node n = NODE_INIT("remote");
|
||||
struct msg m;
|
||||
|
||||
/* Setup signals */
|
||||
struct sigaction sa_quit = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
|
@ -53,22 +58,25 @@ int main(int argc, char *argv[])
|
|||
sigaction(SIGTERM, &sa_quit, NULL);
|
||||
sigaction(SIGINT, &sa_quit, NULL);
|
||||
|
||||
/* Resolve addresses */
|
||||
int ret = resolve_addr(argv[1], &n.local, 0);
|
||||
if (ret)
|
||||
error("Failed to resolve local address '%s': %s", argv[1], gai_strerror(ret));
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &set, &nodes, NULL);
|
||||
|
||||
node = node_lookup_name(argv[2], nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[2]);
|
||||
|
||||
node_connect(&n);
|
||||
node_start(node);
|
||||
node_start_defer(node);
|
||||
|
||||
/* Print header */
|
||||
fprintf(stderr, "# %-6s %-8s %-12s\n", "dev_id", "seq_no", "data");
|
||||
|
||||
while (1) {
|
||||
msg_recv(&m, &n);
|
||||
node_read(node, &msg);
|
||||
|
||||
if (m.version != MSG_VERSION)
|
||||
if (msg.version != MSG_VERSION)
|
||||
continue;
|
||||
if (m.type != MSG_TYPE_DATA)
|
||||
if (msg.type != MSG_TYPE_DATA)
|
||||
continue;
|
||||
|
||||
#if 1
|
||||
|
@ -77,7 +85,7 @@ int main(int argc, char *argv[])
|
|||
fprintf(stdout, "%17.6f", ts.tv_sec + ts.tv_nsec / 1e9);
|
||||
#endif
|
||||
|
||||
msg_fprint(stdout, &m);
|
||||
msg_fprint(stdout, &msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -18,33 +18,38 @@
|
|||
#include <netdb.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cfg.h"
|
||||
#include "utils.h"
|
||||
#include "node.h"
|
||||
#include "msg.h"
|
||||
#include "socket.h"
|
||||
|
||||
int sd;
|
||||
static struct settings set;
|
||||
static struct msg msg = MSG_INIT(0);
|
||||
static struct node *node;
|
||||
extern struct node *nodes;
|
||||
|
||||
void quit(int sig, siginfo_t *si, void *ptr)
|
||||
{
|
||||
close(sd);
|
||||
node_stop(node);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2 && argc != 3) {
|
||||
printf("Usage: %s REMOTE [LOCAL]\n", argv[0]);
|
||||
printf(" REMOTE is a IP:PORT combination of the remote host\n");
|
||||
printf(" LOCAL is an optional IP:PORT combination of the local host\n");
|
||||
struct config_t config;
|
||||
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s CONFIG NODE\n", argv[0]);
|
||||
printf(" CONFIG path to a configuration file\n");
|
||||
printf(" NODE name of the node which shoud be used\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s %s)\n",
|
||||
BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
printf("Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Steffen Vogel <stvogel@eonerc.rwth-aachen.de>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct node n = NODE_INIT("remote");
|
||||
struct msg m = MSG_INIT(0);
|
||||
|
||||
/* Setup signals */
|
||||
struct sigaction sa_quit = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
|
@ -55,26 +60,18 @@ int main(int argc, char *argv[])
|
|||
sigaction(SIGTERM, &sa_quit, NULL);
|
||||
sigaction(SIGINT, &sa_quit, NULL);
|
||||
|
||||
/* Resolve addresses */
|
||||
int ret = resolve_addr(argv[1], &n.remote, 0);
|
||||
if (ret)
|
||||
error("Failed to resolve remote address '%s': %s", argv[1], gai_strerror(ret));
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &set, &nodes, NULL);
|
||||
|
||||
node = node_lookup_name(argv[2], nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[2]);
|
||||
|
||||
if (argc == 3) {
|
||||
ret = resolve_addr(argv[2], &n.local, AI_PASSIVE);
|
||||
if (ret)
|
||||
error("Failed to resolve local address '%s': %s", argv[2], gai_strerror(ret));
|
||||
}
|
||||
else {
|
||||
n.local.sin_family = AF_INET;
|
||||
n.local.sin_addr.s_addr = INADDR_ANY; /* all local interfaces */
|
||||
n.local.sin_port = 0; /* random port */
|
||||
}
|
||||
|
||||
node_connect(&n);
|
||||
node_start(node);
|
||||
node_start_defer(node);
|
||||
|
||||
while (!feof(stdin)) {
|
||||
msg_fscan(stdin, &m);
|
||||
msg_fscan(stdin, &msg);
|
||||
|
||||
#if 1 /* Preprend timestamp */
|
||||
struct timespec ts;
|
||||
|
@ -82,8 +79,8 @@ int main(int argc, char *argv[])
|
|||
fprintf(stdout, "%17.3f\t", ts.tv_sec + ts.tv_nsec / 1e9);
|
||||
#endif
|
||||
|
||||
msg_fprint(stdout, &m);
|
||||
msg_send(&m, &n);
|
||||
msg_fprint(stdout, &msg);
|
||||
node_write(node, &msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
|
@ -22,129 +23,32 @@
|
|||
#include "node.h"
|
||||
|
||||
/** Linked list of nodes */
|
||||
static struct node *nodes;
|
||||
extern struct node *nodes;
|
||||
/** Linked list of paths */
|
||||
static struct path *paths;
|
||||
extern struct path *paths;
|
||||
/** Linked list of interfaces */
|
||||
static struct interface *interfaces;
|
||||
extern struct interface *interfaces;
|
||||
|
||||
/** The global configuration */
|
||||
static struct settings settings;
|
||||
static config_t config;
|
||||
|
||||
static void start()
|
||||
{
|
||||
/* Connect and bind nodes to their sockets, set socket options */
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
if (!n->refcnt) continue;
|
||||
|
||||
/* Determine outgoing interface */
|
||||
int index = if_getegress(&n->remote);
|
||||
if (index < 0)
|
||||
error("Failed to get egress interface for node '%s'", n->name);
|
||||
|
||||
n->interface = if_lookup_index(index, interfaces);
|
||||
|
||||
/* Create new interface */
|
||||
if (!n->interface) {
|
||||
struct interface *i = malloc(sizeof(struct interface));
|
||||
if (!i)
|
||||
error("Failed to allocate memory for interface");
|
||||
else
|
||||
memset(i, 0, sizeof(struct interface));
|
||||
|
||||
i->index = index;
|
||||
if_indextoname(index, i->name);
|
||||
|
||||
debug(3, "Setup interface '%s'", i->name,
|
||||
i->index, i->refcnt);
|
||||
|
||||
/* Set affinity for network interfaces */
|
||||
if (settings.affinity && i->index) {
|
||||
if_getirqs(i);
|
||||
if_setaffinity(i, settings.affinity);
|
||||
}
|
||||
|
||||
list_add(interfaces, i);
|
||||
n->interface = i;
|
||||
}
|
||||
|
||||
node_connect(n);
|
||||
|
||||
/* Set fwmark for outgoing packets */
|
||||
if (n->netem) {
|
||||
n->mark = 1 + n->interface->refcnt++;
|
||||
|
||||
if (setsockopt(n->sd, SOL_SOCKET, SO_MARK, &n->mark, sizeof(n->mark)))
|
||||
perror("Failed to set fwmark for outgoing packets");
|
||||
else
|
||||
debug(4, "Set fwmark of outgoing packets of node '%s' to %u",
|
||||
n->name, n->mark);
|
||||
}
|
||||
|
||||
#if 0 /* Set QoS or TOS IP options */
|
||||
int prio = SOCKET_PRIO;
|
||||
if (setsockopt(n->sd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))
|
||||
perror("Failed to set socket priority");
|
||||
else
|
||||
debug(4, "Set socket priority for node '%s' to %u", n->name, prio);
|
||||
#else
|
||||
int tos = IPTOS_LOWDELAY;
|
||||
if (setsockopt(n->sd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
|
||||
perror("Failed to set type of service (QoS)");
|
||||
else
|
||||
debug(4, "Set QoS/TOS IP option for node '%s' to %#x", n->name, tos);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Setup network emulation */
|
||||
for (struct interface *i = interfaces; i; i = i->next) {
|
||||
if (!i->refcnt) continue;
|
||||
|
||||
tc_prio(i, TC_HDL(4000, 0), i->refcnt);
|
||||
}
|
||||
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
if (n->netem) {
|
||||
tc_mark(n->interface, TC_HDL(4000, n->mark), n->mark);
|
||||
tc_netem(n->interface, TC_HDL(4000, n->mark), n->netem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start on thread per path for asynchronous processing */
|
||||
for (struct path *p = paths; p; p = p->next) {
|
||||
path_start(p);
|
||||
|
||||
info("Path started: %12s " GRN("=>") " %-12s",
|
||||
p->in->name, p->out->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void stop()
|
||||
{
|
||||
/* Join all threads and print statistics */
|
||||
for (struct path *p = paths; p; p = p->next) {
|
||||
path_stop(p);
|
||||
|
||||
info("Path stopped: %12s " RED("=>") " %-12s",
|
||||
p->in->name, p->out->name);
|
||||
}
|
||||
|
||||
/* Close all sockets we listen on */
|
||||
for (struct node *n = nodes; n; n = n->next) {
|
||||
node_disconnect(n);
|
||||
}
|
||||
|
||||
/* Reset interface queues and affinity */
|
||||
for (struct interface *i = interfaces; i; i = i->next) {
|
||||
if_setaffinity(i, -1);
|
||||
tc_reset(i);
|
||||
}
|
||||
}
|
||||
struct settings settings;
|
||||
config_t config;
|
||||
|
||||
static void quit()
|
||||
{
|
||||
stop();
|
||||
{ _indent = 0;
|
||||
info("Stopping paths:");
|
||||
for (struct path *p = paths; p; p = p->next) { INDENT
|
||||
path_stop(p);
|
||||
}
|
||||
|
||||
info("Stopping nodes:");
|
||||
for (struct node *n = nodes; n; n = n->next) { INDENT
|
||||
node_stop(n);
|
||||
}
|
||||
|
||||
info("Stopping interfaces:");
|
||||
for (struct interface *i = interfaces; i; i = i->next) { INDENT
|
||||
if_stop(i);
|
||||
}
|
||||
|
||||
/** @todo Free nodes and paths */
|
||||
|
||||
|
@ -153,42 +57,8 @@ static void quit()
|
|||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* Check arguments */
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s CONFIG\n", argv[0]);
|
||||
printf(" CONFIG is a required path to a configuration file\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s, %s)\n",
|
||||
BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Steffen Vogel <stvogel@eonerc.rwth-aachen.de>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
info("This is %s %s", BLU("s2ss"), BLU(VERSION));
|
||||
|
||||
/* Setup exit handler */
|
||||
struct sigaction sa_quit = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
.sa_sigaction = quit
|
||||
};
|
||||
|
||||
sigemptyset(&sa_quit.sa_mask);
|
||||
sigaction(SIGTERM, &sa_quit, NULL);
|
||||
sigaction(SIGINT, &sa_quit, NULL);
|
||||
atexit(&quit);
|
||||
|
||||
/* Parse configuration file */
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &settings, &nodes, &paths);
|
||||
|
||||
debug(1, "Running with debug level: %u", settings.debug);
|
||||
|
||||
/* Check priviledges */
|
||||
if (getuid() != 0)
|
||||
error("The server requires superuser privileges!");
|
||||
|
||||
void realtime_init()
|
||||
{ INDENT
|
||||
/* Check for realtime kernel patch */
|
||||
struct stat st;
|
||||
if (stat("/sys/kernel/realtime", &st))
|
||||
|
@ -213,10 +83,75 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
debug(3, "Set affinity to %#x", settings.affinity);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup exit handler */
|
||||
void signals_init()
|
||||
{ INDENT
|
||||
struct sigaction sa_quit = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
.sa_sigaction = quit
|
||||
};
|
||||
|
||||
sigemptyset(&sa_quit.sa_mask);
|
||||
sigaction(SIGTERM, &sa_quit, NULL);
|
||||
sigaction(SIGINT, &sa_quit, NULL);
|
||||
atexit(&quit);
|
||||
}
|
||||
|
||||
void usage(const char *name)
|
||||
{
|
||||
printf("Usage: %s CONFIG\n", name);
|
||||
printf(" CONFIG is a required path to a configuration file\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s, %s)\n",
|
||||
BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
epoch_reset();
|
||||
info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s)",
|
||||
BLD(YEL(VERSION)), BLD(MAG(__DATE__)), BLD(MAG(__TIME__)));
|
||||
|
||||
/* Check arguments */
|
||||
if (argc != 2)
|
||||
usage(argv[0]);
|
||||
|
||||
/* Check priviledges */
|
||||
if (getuid() != 0)
|
||||
error("The server requires superuser privileges!");
|
||||
|
||||
/* Start initialization */
|
||||
info("Initialize realtime system:");
|
||||
realtime_init();
|
||||
info("Setup signals:");
|
||||
signals_init();
|
||||
info("Parsing configuration:");
|
||||
config_init(&config);
|
||||
|
||||
/* Parse configuration and create nodes/paths */
|
||||
config_parse(argv[1], &config, &settings, &nodes, &paths);
|
||||
|
||||
|
||||
/* Connect all nodes and start one thread per path */
|
||||
start();
|
||||
info("Starting nodes:");
|
||||
for (struct node *n = nodes; n; n = n->next) { INDENT
|
||||
node_start(n);
|
||||
}
|
||||
|
||||
info("Starting interfaces:");
|
||||
for (struct interface *i = interfaces; i; i = i->next) { INDENT
|
||||
if_start(i, settings.affinity);
|
||||
}
|
||||
|
||||
info("Starting pathes:");
|
||||
for (struct path *p = paths; p; p = p->next) { INDENT
|
||||
path_start(p);
|
||||
}
|
||||
|
||||
/* Run! */
|
||||
if (settings.stats > 0) {
|
||||
struct path *p = paths;
|
||||
|
||||
|
@ -235,5 +170,7 @@ int main(int argc, char *argv[])
|
|||
else
|
||||
pause();
|
||||
|
||||
/* Note: quit() is called by exit handler! */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,11 +15,15 @@
|
|||
#include <netdb.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cfg.h"
|
||||
#include "msg.h"
|
||||
#include "node.h"
|
||||
#include "utils.h"
|
||||
|
||||
int sd;
|
||||
static struct settings set;
|
||||
static struct node *node;
|
||||
extern struct node *nodes;
|
||||
|
||||
int running = 1;
|
||||
|
||||
#define CLOCK_ID CLOCK_MONOTONIC_RAW
|
||||
|
@ -36,19 +40,19 @@ void quit(int sig, siginfo_t *si, void *ptr)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
config_t config;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("Usage: %s TEST LOCAL REMOTE\n", argv[0]);
|
||||
printf(" TEST has to be 'rtt' for now\n");
|
||||
printf(" LOCAL is a IP:PORT combination of the local host\n");
|
||||
printf(" REMOTE is a IP:PORT combination of the remote host\n\n");
|
||||
printf("Usage: %s CONFIG NODE\n", argv[0]);
|
||||
printf(" CONFIG path to a configuration file\n");
|
||||
printf(" NODE name of the node which shoud be used\n\n");
|
||||
printf("Simulator2Simulator Server %s (built on %s %s)\n",
|
||||
BLU(VERSION), MAG(__DATE__), MAG(__TIME__));
|
||||
printf("Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n");
|
||||
printf(" Steffen Vogel <stvogel@eonerc.rwth-aachen.de>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct node n = NODE_INIT("remote");
|
||||
|
||||
/* Setup signals */
|
||||
struct sigaction sa_quit = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
|
@ -59,16 +63,15 @@ int main(int argc, char *argv[])
|
|||
sigaction(SIGTERM, &sa_quit, NULL);
|
||||
sigaction(SIGINT, &sa_quit, NULL);
|
||||
|
||||
/* Resolve addresses */
|
||||
int ret = resolve_addr(argv[2], &n.local, AI_PASSIVE);
|
||||
if (ret)
|
||||
error("Failed to resolve local address '%s': %s", argv[1], gai_strerror(ret));
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &set, &nodes, NULL);
|
||||
|
||||
node = node_lookup_name(argv[2], nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[2]);
|
||||
|
||||
ret = resolve_addr(argv[3], &n.remote, 0);
|
||||
if (ret)
|
||||
error("Failed to resolve remote address '%s': %s", argv[1], gai_strerror(ret));
|
||||
|
||||
node_connect(&n);
|
||||
node_start(node);
|
||||
node_start_defer(node);
|
||||
|
||||
if (!strcmp(argv[1], "rtt")) {
|
||||
struct msg m = MSG_INIT(sizeof(struct timespec) / sizeof(float));
|
||||
|
@ -91,10 +94,9 @@ int main(int argc, char *argv[])
|
|||
fprintf(stdout, "%5s%10s%10s%10s%10s\n", "seq", "rtt", "min", "max", "avg");
|
||||
|
||||
while (running) {
|
||||
|
||||
clock_gettime(CLOCK_ID, ts1);
|
||||
msg_send(&m, &n);
|
||||
msg_recv(&m, &n);
|
||||
node_write(node, &m);
|
||||
node_read(node, &m);
|
||||
clock_gettime(CLOCK_ID, ts2);
|
||||
|
||||
rtt = timespec_delta(ts1, ts2);
|
||||
|
@ -127,7 +129,7 @@ int main(int argc, char *argv[])
|
|||
hist_dump(hist, RTT_HIST);
|
||||
}
|
||||
|
||||
close(sd);
|
||||
node_stop(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue