iperf: fix --daemon option

Support for -D got broken in the 2.0.11 release by the upstream commit
218d8c667944 ("first pass L2 mode w/UDP checks, v4 only"). After that
commit clients were still able to connect but no traffic was passed.
It was reported and is fixed now in the upstream git repository.

Backport two patches to fix this. The first one is just a requirement
for the later to apply. The second one is the real fix and it needed
only a small adjustment to apply without backporing the commit
10887b59c7e7 ("fix --txstart-time report messages").

Fixes: 457e6d5a27 ("iperf: bump to 2.0.12")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2018-10-07 14:17:50 +02:00
parent 5815bb2e41
commit 87cd118794
3 changed files with 205 additions and 1 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=iperf
PKG_VERSION:=2.0.12
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_HASH:=367f651fb1264b13f6518e41b8a7e08ce3e41b2a1c80e99ff0347561eed32646

View File

@ -0,0 +1,43 @@
From 7c0ac64ebea38d0d9ff4d160db4d33bc087a3490 Mon Sep 17 00:00:00 2001
From: Robert McMahon <rjmcmahon@rjmcmahon.com>
Date: Mon, 16 Jul 2018 17:51:29 -0700
Subject: [PATCH] fix latent bug in signal handling, per POSIX calling exit()
in signal handler is not safe. Use _exit() instead. Also, detect the user
signal SIGINT for the case of server needing two invocations to stop server
threads. Note: the server threads still need some work from graceful
termination with a single ctrl-c
---
--- a/compat/signal.c
+++ b/compat/signal.c
@@ -171,7 +171,7 @@ void sig_exit( int inSigno ) {
static int num = 0;
if ( num++ == 0 ) {
fflush( 0 );
- exit( 0 );
+ _exit(0);
}
} /* end sig_exit */
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -268,7 +268,7 @@ void Sig_Interupt( int inSigno ) {
// We try to not allow a single interrupt handled by multiple threads
// to completely kill the app so we save off the first thread ID
// then that is the only thread that can supply the next interrupt
- if ( thread_equalid( sThread, thread_zeroid() ) ) {
+ if ( (inSigno == SIGINT) && thread_equalid( sThread, thread_zeroid() ) ) {
sThread = thread_getid();
} else if ( thread_equalid( sThread, thread_getid() ) ) {
sig_exit( inSigno );
@@ -420,9 +420,3 @@ VOID ServiceStop() {
}
#endif
-
-
-
-
-
-

View File

@ -0,0 +1,161 @@
From 755be8bdb48d2536e39d2d7cf84e8a8f86b8776f Mon Sep 17 00:00:00 2001
From: Robert McMahon <rjmcmahon@rjmcmahon.com>
Date: Sat, 6 Oct 2018 13:36:52 -0700
Subject: [PATCH] cleanup main startup, fix daemon mode per redirecting stdin,
stderr and stdout to /dev/null
---
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -167,67 +167,7 @@ int main( int argc, char **argv ) {
Settings_ParseCommandLine( argc, argv, ext_gSettings );
// Check for either having specified client or server
- if ( ext_gSettings->mThreadMode == kMode_Client
- || ext_gSettings->mThreadMode == kMode_Listener ) {
-#ifdef WIN32
- // Start the server as a daemon
- if ( isDaemon( ext_gSettings )) {
- if (ext_gSettings->mThreadMode == kMode_Listener) {
- CmdInstallService(argc, argv);
- } else {
- fprintf(stderr, "Client cannot be run as a daemon\n");
- }
- return 0;
- }
-
- // Remove the Windows service if requested
- if ( isRemoveService( ext_gSettings ) ) {
- // remove the service
- if ( CmdRemoveService() ) {
- fprintf(stderr, "IPerf Service is removed.\n");
- return 0;
- }
- }
-#else
- if ( isDaemon( ext_gSettings ) ) {
- if (ext_gSettings->mThreadMode != kMode_Listener) {
- fprintf(stderr, "Iperf client cannot be run as a daemon\n");
- return 0;
- }
- if (daemon(1, 1) < 0) {
- perror("daemon");
- }
- fprintf( stderr, "Running Iperf Server as a daemon\n");
- fprintf( stderr, "The Iperf daemon process ID : %d\n",((int)getpid()));
- fclose(stdout);
- fclose(stderr);
- fclose(stdin);
- }
-#endif
- // initialize client(s)
- if ( ext_gSettings->mThreadMode == kMode_Client ) {
- client_init( ext_gSettings );
- }
-
-#ifdef HAVE_THREAD
- // start up the reporter and client(s) or listener
- {
- thread_Settings *into = NULL;
- // Create the settings structure for the reporter thread
- Settings_Copy( ext_gSettings, &into );
- into->mThreadMode = kMode_Reporter;
-
- // Have the reporter launch the client or listener
- into->runNow = ext_gSettings;
-
- // Start all the threads that are ready to go
- thread_start( into );
- }
-#else
- // No need to make a reporter thread because we don't have threads
- thread_start( ext_gSettings );
-#endif
- } else {
+ if ((ext_gSettings->mThreadMode != kMode_Client) && (ext_gSettings->mThreadMode != kMode_Listener)) {
// neither server nor client mode was specified
// print usage and exit
@@ -236,20 +176,75 @@ int main( int argc, char **argv ) {
// Starting in 2.0 to restart a previously defined service
// you must call iperf with "iperf -D" or using the environment variable
SERVICE_TABLE_ENTRY dispatchTable[] =
- {
- { (LPSTR)TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
- { NULL, NULL}
- };
+ {
+ { (LPSTR)TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
+ { NULL, NULL}
+ };
// starting the service by SCM, there is no arguments will be passed in.
// the arguments will pass into Service_Main entry.
if (!StartServiceCtrlDispatcher(dispatchTable) )
// If the service failed to start then print usage
#endif
- fprintf( stderr, usage_short, argv[0], argv[0] );
+ fprintf( stderr, usage_short, argv[0], argv[0] );
+ return 0;
+ }
+
+
+ switch (ext_gSettings->mThreadMode) {
+ case kMode_Client :
+ if ( isDaemon( ext_gSettings ) ) {
+ fprintf(stderr, "Iperf client cannot be run as a daemon\n");
+ return 0;
+ }
+ // initialize client(s)
+ client_init( ext_gSettings );
+ break;
+ case kMode_Listener :
+ if ( isDaemon( ext_gSettings ) ) {
+ fprintf( stderr, "Running Iperf Server as a daemon\n");
+ // Start the server as a daemon
+#ifdef WIN32
+ CmdInstallService(argc, argv);
+ // Remove the Windows service if requested
+ if ( isRemoveService( ext_gSettings ) ) {
+ // remove the service
+ if ( CmdRemoveService() ) {
+ fprintf(stderr, "IPerf Service is removed.\n");
+ return 0;
+ }
+ }
+#else
+ fflush(stderr);
+ // redirect stdin, stdout and sterr to /dev/null (see dameon and no close flag)
+ if (daemon(1, 0) < 0) {
+ perror("daemon");
+ }
+ }
+#endif
+ break;
+ default :
+ fprintf( stderr, "unknown mode");
+ break;
+ }
+#ifdef HAVE_THREAD
+ // start up the reporter and client(s) or listener
+ {
+ thread_Settings *into = NULL;
+ // Create the settings structure for the reporter thread
+ Settings_Copy( ext_gSettings, &into );
+ into->mThreadMode = kMode_Reporter;
+
+ // Have the reporter launch the client or listener
+ into->runNow = ext_gSettings;
- return 0;
+ // Start all the threads that are ready to go
+ thread_start( into );
}
+#else
+ // No need to make a reporter thread because we don't have threads
+ thread_start( ext_gSettings );
+#endif
// wait for other (client, server) threads to complete
thread_joinall();