From 691866f94e28f7db3f89610ea790593b8f59e99d Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 13 Jun 2013 19:46:22 +0800 Subject: [PATCH] tools/netrate: Add simple tools to calculated multiple netperf results netperf itself must be installed through dports. --- tools/tools/netrate/netperf/tcp_cc/Makefile | 10 + tools/tools/netrate/netperf/tcp_cc/tcp_cc.c | 172 +++++++++++++++++ .../tools/netrate/netperf/tcp_stream/Makefile | 10 + .../netrate/netperf/tcp_stream/tcp_stream.c | 180 ++++++++++++++++++ 4 files changed, 372 insertions(+) create mode 100644 tools/tools/netrate/netperf/tcp_cc/Makefile create mode 100644 tools/tools/netrate/netperf/tcp_cc/tcp_cc.c create mode 100644 tools/tools/netrate/netperf/tcp_stream/Makefile create mode 100644 tools/tools/netrate/netperf/tcp_stream/tcp_stream.c diff --git a/tools/tools/netrate/netperf/tcp_cc/Makefile b/tools/tools/netrate/netperf/tcp_cc/Makefile new file mode 100644 index 0000000000..93e5d92fac --- /dev/null +++ b/tools/tools/netrate/netperf/tcp_cc/Makefile @@ -0,0 +1,10 @@ +PROG= tcp_cc + +COPTS += -fno-common + +WARNS = 6 +NOMAN = yes + +BINDIR= /usr/local/bin + +.include diff --git a/tools/tools/netrate/netperf/tcp_cc/tcp_cc.c b/tools/tools/netrate/netperf/tcp_cc/tcp_cc.c new file mode 100644 index 0000000000..455eb5eaaf --- /dev/null +++ b/tools/tools/netrate/netperf/tcp_cc/tcp_cc.c @@ -0,0 +1,172 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#define NETPERF_CMD "netperf" +#define NETPERF_PATH "/usr/local/bin/" NETPERF_CMD + +#define TCP_CC_FILENAME "/tmp/tcp_cc.%d.%d" + +struct netperf_child { + int fd; +}; + +static void +usage(const char *cmd) +{ + fprintf(stderr, "%s -H host [-l len_s] [-i instances]\n", cmd); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct netperf_child *instance; + char len_str[32]; + char *args[32]; + const char *host; + volatile int ninst; + int len, ninst_done; + int opt, i, null_fd; + double result; + pid_t mypid; + + host = NULL; + ninst = 2; + len = 10; + + while ((opt = getopt(argc, argv, "i:H:l:")) != -1) { + switch (opt) { + case 'i': + ninst = strtoul(optarg, NULL, 10); + break; + + case 'H': + host = optarg; + break; + + case 'l': + len = strtoul(optarg, NULL, 10); + break; + + default: + usage(argv[0]); + } + } + if (ninst <= 0 || host == NULL || len <= 0) + usage(argv[0]); + + mypid = getpid(); + + snprintf(len_str, sizeof(len_str), "%d", len); + + i = 0; + args[i++] = __DECONST(char *, NETPERF_CMD); + args[i++] = __DECONST(char *, "-P0"); + args[i++] = __DECONST(char *, "-H"); + args[i++] = __DECONST(char *, host); + args[i++] = __DECONST(char *, "-l"); + args[i++] = __DECONST(char *, len_str); + args[i++] = __DECONST(char *, "-t"); + args[i++] = __DECONST(char *, "TCP_CC"); + args[i] = NULL; + + instance = calloc(ninst, sizeof(struct netperf_child)); + if (instance == NULL) { + fprintf(stderr, "calloc failed\n"); + exit(1); + } + + null_fd = open("/dev/null", O_RDWR); + if (null_fd < 0) { + fprintf(stderr, "open null failed: %d\n", errno); + exit(1); + } + + for (i = 0; i < ninst; ++i) { + char filename[128]; + + snprintf(filename, sizeof(filename), TCP_CC_FILENAME, + (int)mypid, i); + instance[i].fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, + S_IWUSR | S_IRUSR); + if (instance[i].fd < 0) { + fprintf(stderr, "open %s failed: %d\n", + filename, errno); + exit(1); + } + } + + for (i = 0; i < ninst; ++i) { + pid_t pid; + + pid = vfork(); + if (pid == 0) { + int ret; + + dup2(instance[i].fd, STDOUT_FILENO); + dup2(null_fd, STDERR_FILENO); + ret = execv(NETPERF_PATH, args); + if (ret < 0) { + fprintf(stderr, "execv %d failed: %d\n", + i, errno); + _exit(1); + } + /* Never reached */ + abort(); + } else if (pid < 0) { + fprintf(stderr, "vfork %d failed: %d\n", i, errno); + exit(1); + } + } + + ninst_done = 0; + while (ninst_done < ninst) { + pid_t pid; + + pid = waitpid(-1, NULL, 0); + if (pid < 0) { + fprintf(stderr, "waitpid failed: %d\n", errno); + exit(1); + } + ++ninst_done; + } + + result = 0.0; + for (i = 0; i < ninst; ++i) { + char line[128], filename[128]; + FILE *fp; + + close(instance[i].fd); + snprintf(filename, sizeof(filename), TCP_CC_FILENAME, + (int)mypid, i); + fp = fopen(filename, "r"); + if (fp == NULL) { + fprintf(stderr, "fopen %s failed\n", filename); + exit(1); + } + + while (fgets(line, sizeof(line), fp) != NULL) { + int n, arg1, arg2, arg3, arg4; + double res, arg5; + + n = sscanf(line, "%d%d%d%d%lf%lf", + &arg1, &arg2, &arg3, &arg4, &arg5, &res); + if (n == 6) { + result += res; + break; + } + } + fclose(fp); + unlink(filename); + } + printf("TCP_CC %f conns/s\n", result); + + exit(0); +} diff --git a/tools/tools/netrate/netperf/tcp_stream/Makefile b/tools/tools/netrate/netperf/tcp_stream/Makefile new file mode 100644 index 0000000000..5ea028ac1b --- /dev/null +++ b/tools/tools/netrate/netperf/tcp_stream/Makefile @@ -0,0 +1,10 @@ +PROG= tcp_stream + +COPTS += -fno-common + +WARNS = 6 +NOMAN = yes + +BINDIR= /usr/local/bin + +.include diff --git a/tools/tools/netrate/netperf/tcp_stream/tcp_stream.c b/tools/tools/netrate/netperf/tcp_stream/tcp_stream.c new file mode 100644 index 0000000000..8adb893b85 --- /dev/null +++ b/tools/tools/netrate/netperf/tcp_stream/tcp_stream.c @@ -0,0 +1,180 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#define NETPERF_CMD "netperf" +#define NETPERF_PATH "/usr/local/bin/" NETPERF_CMD + +#define TCP_STRM_FILENAME "/tmp/tcp_strm.%d.%d" + +struct netperf_child { + int fd; +}; + +static void +usage(const char *cmd) +{ + fprintf(stderr, "%s -H host [-l len_s] [-i instances] [-r]\n", cmd); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct netperf_child *instance; + char len_str[32]; + char *args[32]; + const char *host; + volatile int ninst; + int len, ninst_done; + int opt, i, null_fd; + volatile int reverse = 0; + double result; + pid_t mypid; + + host = NULL; + ninst = 2; + len = 10; + + while ((opt = getopt(argc, argv, "i:H:l:r")) != -1) { + switch (opt) { + case 'i': + ninst = strtoul(optarg, NULL, 10); + break; + + case 'H': + host = optarg; + break; + + case 'l': + len = strtoul(optarg, NULL, 10); + break; + + case 'r': + reverse = 1; + break; + + default: + usage(argv[0]); + } + } + if (ninst <= 0 || host == NULL || len <= 0) + usage(argv[0]); + + mypid = getpid(); + + snprintf(len_str, sizeof(len_str), "%d", len); + + i = 0; + args[i++] = __DECONST(char *, NETPERF_CMD); + args[i++] = __DECONST(char *, "-P0"); + args[i++] = __DECONST(char *, "-H"); + args[i++] = __DECONST(char *, host); + args[i++] = __DECONST(char *, "-l"); + args[i++] = __DECONST(char *, len_str); + args[i++] = __DECONST(char *, "-t"); + if (reverse) + args[i++] = __DECONST(char *, "TCP_MAERTS"); + else + args[i++] = __DECONST(char *, "TCP_STREAM"); + args[i] = NULL; + + instance = calloc(ninst, sizeof(struct netperf_child)); + if (instance == NULL) { + fprintf(stderr, "calloc failed\n"); + exit(1); + } + + null_fd = open("/dev/null", O_RDWR); + if (null_fd < 0) { + fprintf(stderr, "open null failed: %d\n", errno); + exit(1); + } + + for (i = 0; i < ninst; ++i) { + char filename[128]; + + snprintf(filename, sizeof(filename), TCP_STRM_FILENAME, + (int)mypid, i); + instance[i].fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, + S_IWUSR | S_IRUSR); + if (instance[i].fd < 0) { + fprintf(stderr, "open %s failed: %d\n", + filename, errno); + exit(1); + } + } + + for (i = 0; i < ninst; ++i) { + pid_t pid; + + pid = vfork(); + if (pid == 0) { + int ret; + + dup2(instance[i].fd, STDOUT_FILENO); + dup2(null_fd, STDERR_FILENO); + ret = execv(NETPERF_PATH, args); + if (ret < 0) { + fprintf(stderr, "execv %d failed: %d\n", + i, errno); + _exit(1); + } + /* Never reached */ + abort(); + } else if (pid < 0) { + fprintf(stderr, "vfork %d failed: %d\n", i, errno); + exit(1); + } + } + + ninst_done = 0; + while (ninst_done < ninst) { + pid_t pid; + + pid = waitpid(-1, NULL, 0); + if (pid < 0) { + fprintf(stderr, "waitpid failed: %d\n", errno); + exit(1); + } + ++ninst_done; + } + + result = 0.0; + for (i = 0; i < ninst; ++i) { + char line[128], filename[128]; + FILE *fp; + + close(instance[i].fd); + snprintf(filename, sizeof(filename), TCP_STRM_FILENAME, + (int)mypid, i); + fp = fopen(filename, "r"); + if (fp == NULL) { + fprintf(stderr, "fopen %s failed\n", filename); + exit(1); + } + + while (fgets(line, sizeof(line), fp) != NULL) { + int n, arg1, arg2, arg3; + double res, arg4; + + n = sscanf(line, "%d%d%d%lf%lf", + &arg1, &arg2, &arg3, &arg4, &res); + if (n == 5) { + result += res; + break; + } + } + fclose(fp); + unlink(filename); + } + printf("%s %f Mbps\n", reverse ? "TCP_MAERTS" : "TCP_STREAM", result); + + exit(0); +} -- 2.41.0