aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce A. Mah <bmah@es.net>2014-01-24 16:42:10 -0800
committerBruce A. Mah <bmah@es.net>2014-01-24 16:42:10 -0800
commit441d8b75a0c8f3ab3b95c88376ff153a5a569d99 (patch)
treea91ff5a0cbe836a509001562fe8e6522cd03d042
parent343c14187403e7d8d034ac0129ac47719c24b389 (diff)
downloadiperf3-441d8b75a0c8f3ab3b95c88376ff153a5a569d99.tar.gz
Add support for writing the PID to a file in server mode.
This is specified with the -I or --pidfile option. Issue: 120 (PID file support)
-rw-r--r--RELEASE_NOTES3
-rw-r--r--src/iperf.h1
-rw-r--r--src/iperf3.13
-rw-r--r--src/iperf_api.c40
-rw-r--r--src/iperf_api.h5
-rw-r--r--src/iperf_error.c7
-rw-r--r--src/locale.c1
-rw-r--r--src/main.c5
8 files changed, 62 insertions, 3 deletions
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 954529e..4a8f641 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,5 +1,8 @@
== iperf 3.?.? ????-??-?? ==
* Setting CPU affinity now works on FreeBSD.
+ * Added -I flag for server to write a PID file, mostly useful for
+ daemon mode.
+ * Bug fixes.
== iperf 3.0.1 2014-01-10 ==
* Added the following new flags
diff --git a/src/iperf.h b/src/iperf.h
index f391ea8..188f06a 100644
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -172,6 +172,7 @@ struct iperf_test
#endif
char *title; /* -T option */
char *congestion; /* -C option */
+ char *pidfile; /* -P option */
int ctrl_sck;
int listener;
diff --git a/src/iperf3.1 b/src/iperf3.1
index c835028..f56d279 100644
--- a/src/iperf3.1
+++ b/src/iperf3.1
@@ -69,6 +69,9 @@ run in server mode
.TP
.BR -D ", " --daemon " "
run the server in background as a daemon
+.TP
+.BR -I ", " --pidfile " \fIfile\fR"
+write a file with the process ID, most useful when running as a daemon.
.SH "CLIENT SPECIFIC OPTIONS"
.TP
diff --git a/src/iperf_api.c b/src/iperf_api.c
index d27c9c1..47b011a 100644
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -545,6 +545,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
#if defined(linux) && defined(TCP_CONGESTION)
{"linux-congestion", required_argument, NULL, 'C'},
#endif
+ {"pidfile", required_argument, NULL, 'I'},
{"debug", no_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
@@ -559,7 +560,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
blksize = 0;
server_flag = client_flag = rate_flag = duration_flag = 0;
- while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dh", longopts, NULL)) != -1) {
+ while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:h", longopts, NULL)) != -1) {
switch (flag) {
case 'p':
test->server_port = atoi(optarg);
@@ -762,6 +763,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
case 'd':
test->debug = 1;
break;
+ case 'I':
+ test->pidfile = strdup(optarg);
+ server_flag = 1;
+ break;
case 'h':
default:
usage_long();
@@ -2383,6 +2388,39 @@ iperf_got_sigend(struct iperf_test *test)
iperf_errexit(test, "interrupt - %s", iperf_strerror(i_errno));
}
+/* Try to write a PID file if requested, return -1 on an error. */
+int
+iperf_create_pidfile(struct iperf_test *test)
+{
+ if (test->pidfile) {
+ int fd;
+ char buf[8];
+ fd = open(test->pidfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ return -1;
+ }
+ snprintf(buf, sizeof(buf), "%d", getpid()); /* no trailing newline */
+ if (write(fd, buf, strlen(buf) + 1) < 0) {
+ return -1;
+ }
+ if (close(fd) < 0) {
+ return -1;
+ };
+ }
+ return 0;
+}
+
+/* Get rid of a PID file, return -1 on error. */
+int
+iperf_delete_pidfile(struct iperf_test *test)
+{
+ if (test->pidfile) {
+ if (unlink(test->pidfile) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
int
iperf_json_start(struct iperf_test *test)
diff --git a/src/iperf_api.h b/src/iperf_api.h
index 1982836..bc68b96 100644
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2013, The Regents of the University of California,
+ * Copyright (c) 2009-2014, The Regents of the University of California,
* through Lawrence Berkeley National Laboratory (subject to receipt of any
* required approvals from the U.S. Dept. of Energy). All rights reserved.
*
@@ -207,6 +207,8 @@ int iperf_server_listen(struct iperf_test *);
int iperf_accept(struct iperf_test *);
int iperf_handle_message_server(struct iperf_test *);
void iperf_test_reset(struct iperf_test *);
+int iperf_create_pidfile(struct iperf_test *);
+int iperf_delete_pidfile(struct iperf_test *);
/* JSON output routines. */
int iperf_json_start(struct iperf_test *);
@@ -280,6 +282,7 @@ enum {
IEAFFINITY = 132, // Unable to set CPU affinity (check perror)
IEDAEMON = 133, // Unable to become a daemon process
IESETCONGESTION = 134, // Unable to set TCP_CONGESTION
+ IEPIDFILE = 135, // Unable to write PID file
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
diff --git a/src/iperf_error.c b/src/iperf_error.c
index 04afed0..645df48 100644
--- a/src/iperf_error.c
+++ b/src/iperf_error.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2013, The Regents of the University of California,
+ * Copyright (c) 2009-2014, The Regents of the University of California,
* through Lawrence Berkeley National Laboratory (subject to receipt of any
* required approvals from the U.S. Dept. of Energy). All rights reserved.
*
@@ -47,6 +47,7 @@ iperf_errexit(struct iperf_test *test, const char *format, ...)
} else
fprintf(stderr, "iperf3: %s\n", str);
va_end(argp);
+ iperf_delete_pidfile(test);
exit(1);
}
@@ -294,6 +295,10 @@ iperf_strerror(int i_errno)
snprintf(errstr, len, "unable to set TCP_CONGESTION: "
"Supplied congestion control algorithm not supported on this host");
break;
+ case IEPIDFILE:
+ snprintf(errstr, len, "unable to write PID file");
+ perr = 1;
+ break;
}
if (herr || perr)
diff --git a/src/locale.c b/src/locale.c
index 4471e6c..84c1953 100644
--- a/src/locale.c
+++ b/src/locale.c
@@ -84,6 +84,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
"Server specific:\n"
" -s, --server run in server mode\n"
" -D, --daemon run the server as a daemon\n"
+ " -I, --pidfile file write PID file\n"
"Client specific:\n"
" -c, --client <host> run in client mode, connecting to <host>\n"
" -u, --udp use UDP rather than TCP\n"
diff --git a/src/main.c b/src/main.c
index 66efd6a..6b49fb2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -112,6 +112,10 @@ run(struct iperf_test *test)
}
}
consecutive_errors = 0;
+ if (iperf_create_pidfile(test) < 0) {
+ i_errno = IEPIDFILE;
+ iperf_errexit(test, "error - %s", iperf_strerror(i_errno));
+ }
for (;;) {
if (iperf_run_server(test) < 0) {
iperf_err(test, "error - %s", iperf_strerror(i_errno));
@@ -125,6 +129,7 @@ run(struct iperf_test *test)
consecutive_errors = 0;
iperf_reset_test(test);
}
+ iperf_delete_pidfile(test);
break;
case 'c':
if (iperf_run_client(test) < 0)