#include #include #include #include #include #include #include #include #define NETPERF_CMD "netperf" #define NETPERF_PATH "/usr/local/bin/" NETPERF_CMD struct netperf_child { int pipes[2]; }; 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; 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]); 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) err(1, "calloc failed"); null_fd = open("/dev/null", O_RDWR); if (null_fd < 0) err(1, "open null failed"); for (i = 0; i < ninst; ++i) { if (pipe(instance[i].pipes) < 0) err(1, "pipe %dth failed", i); } for (i = 0; i < ninst; ++i) { pid_t pid; pid = vfork(); if (pid == 0) { int ret; dup2(instance[i].pipes[1], STDOUT_FILENO); dup2(null_fd, STDERR_FILENO); ret = execv(NETPERF_PATH, args); if (ret < 0) { warn("execv %d failed", i); _exit(1); } /* Never reached */ abort(); } else if (pid < 0) { err(1, "vfork %d failed", i); } close(instance[i].pipes[1]); instance[i].pipes[1] = -1; } ninst_done = 0; while (ninst_done < ninst) { pid_t pid; pid = waitpid(-1, NULL, 0); if (pid < 0) err(1, "waitpid failed"); ++ninst_done; } result = 0.0; for (i = 0; i < ninst; ++i) { char line[128]; FILE *fp; fp = fdopen(instance[i].pipes[0], "r"); if (fp == NULL) err(1, "fdopen %dth failed\n", i); 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); } printf("TCP_CC %.2f conns/s\n", result); exit(0); }