[LTP] [PATCH v2] netstress.c: change default setup of sysctl parameters

Alexey Kodanev alexey.kodanev@oracle.com
Mon Dec 19 14:30:55 CET 2016


* Allow 'netstress' to use whatever is set in tcp_fastopen sysctl
  parameter. There are several advantages to do this:
  a. It allows to test default configuration in kernel;
  b. We can control this parameter externally and avoid races
     when server/client runs on the same machine;
  c. Simplifies code.

* Introduce new parameter '-t x' (instead of '-O') where x is the new
  value for tcp_fastopen sysctl parameter.

* Enable fastopen API only if '-f' option set, remove '-o'.

* Remove 'run_force' parameter '-F'. It didn't do anything useful,
  instead, invoke tst_require_root() only if we're going to update
  sysctl parameter.

* Update tcp_fastopen test with new options ('-t' & '-f').

Additional fixes:

* Set SO_REUSEADDR option before bind in server.

* Remove linger option and consolidate setting busy_poll socket option
  into one function: init_socket_opts().

* Move setting tcp_tw_reuse to client side code.

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
v2: * set tcp_tw_reuse in client only
    * add -f option, remove '-o'
    * remove setting linger socket option

 testcases/network/netstress/netstress.c            |  151 +++++++++++---------
 testcases/network/tcp_fastopen/tcp_fastopen_run.sh |   17 +--
 2 files changed, 87 insertions(+), 81 deletions(-)

diff --git a/testcases/network/netstress/netstress.c b/testcases/network/netstress/netstress.c
index 26fd217..95be098 100644
--- a/testcases/network/netstress/netstress.c
+++ b/testcases/network/netstress/netstress.c
@@ -59,17 +59,16 @@ enum {
 static int net_mode;
 
 enum {
-	TFO_ENABLED = 0,
-	TFO_DISABLED,
+	TFO_DISABLED = 0,
+	TFO_ENABLED,
 };
-static int tfo_support;
+static int tfo_value = -1;
 static int fastopen_api;
 
 static const char tfo_cfg[]		= "/proc/sys/net/ipv4/tcp_fastopen";
 static const char tcp_tw_reuse[]	= "/proc/sys/net/ipv4/tcp_tw_reuse";
 static int tw_reuse_changed;
 static int tfo_cfg_value;
-static int tfo_bit_num;
 static int tfo_cfg_changed;
 static int tfo_queue_size	= 100;
 static int max_queue_len	= 100;
@@ -103,10 +102,9 @@ static long wait_timeout = 60000000;
 /* in the end test will save time result in this file */
 static char *rpath		= "./tfo_result";
 
-static int force_run;
 static int verbose;
 
-static char *narg, *Narg, *qarg, *rarg, *Rarg, *aarg, *Targ, *barg;
+static char *narg, *Narg, *qarg, *rarg, *Rarg, *aarg, *Targ, *barg, *targ;
 
 static const option_t options[] = {
 	/* server params */
@@ -126,20 +124,18 @@ static const option_t options[] = {
 	{"g:", NULL, &tcp_port},
 	{"b:", NULL, &barg},
 	{"U", &use_udp, NULL},
-	{"F", &force_run, NULL},
 	{"l", &net_mode, NULL},
-	{"o", &fastopen_api, NULL},
-	{"O", &tfo_support, NULL},
+	{"f", &fastopen_api, NULL},
+	{"t:", NULL, &targ},
 	{"v", &verbose, NULL},
 	{NULL, NULL, NULL}
 };
 
 static void help(void)
 {
-	printf("\n  -F      Force to run\n");
-	printf("  -v      Verbose\n");
-	printf("  -o      Use old TCP API, default is new TCP API\n");
-	printf("  -O      TFO support is off, default is on\n");
+	printf("\n  -v      Verbose\n");
+	printf("  -f      Use new TCP API, default is old TCP API\n");
+	printf("  -t x    Set tcp_fastopen value\n");
 	printf("  -l      Become TCP Client, default is TCP server\n");
 	printf("  -g x    x - server port, default is %s\n", tcp_port);
 	printf("  -b x    x - low latency busy poll timeout\n");
@@ -180,7 +176,13 @@ static struct addrinfo *local_addrinfo;
 static struct sockaddr_storage remote_addr;
 static socklen_t remote_addr_len;
 
-static const struct linger clo = { 1, 3 };
+static void init_socket_opts(int sd)
+{
+	if (busy_poll >= 0) {
+		setsockopt(sd, SOL_SOCKET, SO_BUSY_POLL,
+			&busy_poll, sizeof(busy_poll));
+	}
+}
 
 static void do_cleanup(void)
 {
@@ -191,9 +193,6 @@ static void do_cleanup(void)
 		net.cleanup();
 
 	if (tfo_cfg_changed) {
-		SAFE_FILE_SCANF(NULL, tfo_cfg, "%d", &tfo_cfg_value);
-		tfo_cfg_value &= ~tfo_bit_num;
-		tfo_cfg_value |= !tfo_support << (tfo_bit_num - 1);
 		tst_resm(TINFO, "unset '%s' back to '%d'",
 			tfo_cfg, tfo_cfg_value);
 		SAFE_FILE_PRINTF(NULL, tfo_cfg, "%d", tfo_cfg_value);
@@ -284,16 +283,11 @@ static int client_connect_send(const char *msg, int size)
 {
 	int cfd = socket(remote_addrinfo->ai_family,
 			 remote_addrinfo->ai_socktype, 0);
-	const int flag = 1;
 
 	if (cfd == -1)
 		return cfd;
 
-	setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
-	if (busy_poll >= 0) {
-		setsockopt(cfd, SOL_SOCKET, SO_BUSY_POLL,
-			   &busy_poll, sizeof(busy_poll));
-	}
+	init_socket_opts(cfd);
 
 	if (fastopen_api == TFO_ENABLED) {
 		/* Replaces connect() + send()/write() */
@@ -520,21 +514,14 @@ void *server_fn(void *cfd)
 {
 	int client_fd = (intptr_t) cfd;
 	int num_requests = 0, offset = 0;
-
 	/* Reply will be constructed from first client request */
 	char *send_msg = NULL;
 	int send_msg_size = 0;
-
 	char recv_msg[max_msg_len];
-
-	setsockopt(client_fd, SOL_SOCKET, SO_LINGER, &clo, sizeof(clo));
-	if (busy_poll >= 0) {
-		setsockopt(client_fd, SOL_SOCKET, SO_BUSY_POLL,
-			   &busy_poll, sizeof(busy_poll));
-	}
-
 	ssize_t recv_len;
 
+	init_socket_opts(client_fd);
+
 	while (1) {
 		recv_len = sock_recv_poll(client_fd, recv_msg,
 			max_msg_len, offset);
@@ -636,6 +623,8 @@ static void server_init(void)
 
 	/* IPv6 socket is also able to access IPv4 protocol stack */
 	sfd = SAFE_SOCKET(cleanup, AF_INET6, local_addrinfo->ai_socktype, 0);
+	const int flag = 1;
+	setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
 
 	tst_resm(TINFO, "assigning a name to the server socket...");
 	SAFE_BIND(cleanup, sfd, local_addrinfo->ai_addr,
@@ -646,8 +635,7 @@ static void server_init(void)
 	if (use_udp)
 		return;
 
-	const int flag = 1;
-	setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
+	init_socket_opts(sfd);
 
 	if (fastopen_api == TFO_ENABLED) {
 		if (setsockopt(sfd, IPPROTO_TCP, TCP_FASTOPEN, &tfo_queue_size,
@@ -729,6 +717,59 @@ static void check_opt_l(const char *name, char *arg, long *val, long lim)
 	}
 }
 
+static void check_tfo_value(void)
+{
+	/* Check if we can write to tcp_fastopen knob. We might be
+	 * inside netns and either have read-only permission or
+	 * doesn't have the knob at all.
+	 */
+	if (access(tfo_cfg, W_OK) < 0) {
+		/* TODO check /proc/self/ns/ or TST_USE_NETNS env var */
+		tst_resm(TINFO, "can't read %s, assume server runs in netns",
+			tfo_cfg);
+		return;
+	}
+
+	SAFE_FILE_SCANF(NULL, tfo_cfg, "%d", &tfo_cfg_value);
+	tst_resm(TINFO, "'%s' is %d", tfo_cfg, tfo_cfg_value);
+
+	/* The check can be the first in this function but set here
+	 * to allow to print information about the currently set config
+	 */
+	if (tfo_value < 0)
+		return;
+
+	if (tfo_cfg_value == tfo_value)
+		return;
+
+	tst_require_root();
+
+	tst_resm(TINFO, "set '%s' to '%d'", tfo_cfg, tfo_value);
+
+	SAFE_FILE_PRINTF(cleanup, tfo_cfg, "%d", tfo_value);
+	tfo_cfg_changed = 1;
+}
+
+static void check_tw_reuse(void)
+{
+	if (access(tcp_tw_reuse, W_OK) < 0)
+		return;
+
+	int reuse_value = 0;
+
+	SAFE_FILE_SCANF(cleanup, tcp_tw_reuse, "%d", &reuse_value);
+	if (reuse_value) {
+		tst_resm(TINFO, "tcp_tw_reuse is already set");
+		return;
+	}
+
+	tst_require_root();
+
+	SAFE_FILE_PRINTF(cleanup, tcp_tw_reuse, "1");
+	tw_reuse_changed = 1;
+	tst_resm(TINFO, "set '%s' to '1'", tcp_tw_reuse);
+}
+
 static void setup(int argc, char *argv[])
 {
 	tst_parse_opts(argc, argv, options, help);
@@ -744,29 +785,18 @@ static void setup(int argc, char *argv[])
 	check_opt("q", qarg, &tfo_queue_size, 1);
 	check_opt_l("T", Targ, &wait_timeout, 0L);
 	check_opt("b", barg, &busy_poll, 0);
+	check_opt("t", targ, &tfo_value, 0);
 
-	if (!force_run)
-		tst_require_root();
-
-	if (!force_run && tst_kvercmp(3, 7, 0) < 0) {
+	if (tfo_value > 0 && tst_kvercmp(3, 7, 0) < 0) {
 		tst_brkm(TCONF, NULL,
 			"Test must be run with kernel 3.7 or newer");
 	}
 
-	if (!force_run && busy_poll >= 0 && tst_kvercmp(3, 11, 0) < 0) {
+	if (busy_poll >= 0 && tst_kvercmp(3, 11, 0) < 0) {
 		tst_brkm(TCONF, NULL,
 			"Test must be run with kernel 3.11 or newer");
 	}
 
-	/* check tcp fast open knob */
-	if (!force_run && access(tfo_cfg, F_OK) == -1)
-		tst_brkm(TCONF, NULL, "Failed to find '%s'", tfo_cfg);
-
-	if (!force_run) {
-		SAFE_FILE_SCANF(NULL, tfo_cfg, "%d", &tfo_cfg_value);
-		tst_resm(TINFO, "'%s' is %d", tfo_cfg, tfo_cfg_value);
-	}
-
 	tst_sig(FORK, DEF_HANDLER, cleanup);
 
 	switch (net_mode) {
@@ -776,7 +806,6 @@ static void setup(int argc, char *argv[])
 		net.init	= server_init;
 		net.run		= (use_udp) ? server_run_udp : server_run;
 		net.cleanup	= (use_udp) ? NULL : server_cleanup;
-		tfo_bit_num = 2;
 	break;
 	case CLIENT_HOST:
 		tst_resm(TINFO, "connection: addr '%s', port '%s'",
@@ -789,7 +818,8 @@ static void setup(int argc, char *argv[])
 		net.init	= client_init;
 		net.run		= client_run;
 		net.cleanup	= client_cleanup;
-		tfo_bit_num = 1;
+
+		check_tw_reuse();
 	break;
 	}
 
@@ -803,26 +833,7 @@ static void setup(int argc, char *argv[])
 			(net_mode == SERVER_HOST) ? "server" : "client",
 			(fastopen_api == TFO_ENABLED) ? "Fastopen" : "old");
 
-		tfo_support = TFO_ENABLED == tfo_support;
-		if (((tfo_cfg_value & tfo_bit_num) == tfo_bit_num)
-		      != tfo_support) {
-			int value = (tfo_cfg_value & ~tfo_bit_num)
-				| (tfo_support << (tfo_bit_num - 1));
-			tst_resm(TINFO, "set '%s' to '%d'", tfo_cfg, value);
-			SAFE_FILE_PRINTF(cleanup, tfo_cfg, "%d", value);
-			tfo_cfg_changed = 1;
-		}
-
-		int reuse_value = 0;
-		SAFE_FILE_SCANF(cleanup, tcp_tw_reuse, "%d", &reuse_value);
-		if (!reuse_value) {
-			SAFE_FILE_PRINTF(cleanup, tcp_tw_reuse, "1");
-			tw_reuse_changed = 1;
-			tst_resm(TINFO, "set '%s' to '1'", tcp_tw_reuse);
-		}
-
-		tst_resm(TINFO, "TFO support %s",
-			(tfo_support) ? "enabled" : "disabled");
+		check_tfo_value();
 	}
 
 	net.init();
diff --git a/testcases/network/tcp_fastopen/tcp_fastopen_run.sh b/testcases/network/tcp_fastopen/tcp_fastopen_run.sh
index e506b87..9d0ce35 100755
--- a/testcases/network/tcp_fastopen/tcp_fastopen_run.sh
+++ b/testcases/network/tcp_fastopen/tcp_fastopen_run.sh
@@ -65,15 +65,8 @@ cleanup()
 
 read_result_file()
 {
-	if [ -f $tfo_result ]; then
-		if [ -r $tfo_result ]; then
-			cat $tfo_result
-		else
-			tst_brkm TBROK "Failed to read result file"
-		fi
-	else
-		tst_brkm TBROK "Failed to find result file"
-	fi
+	[ ! -f $tfo_result ] && echo "-1"
+	[ -r $tfo_result ] && cat $tfo_result || echo "-1"
 }
 
 tst_require_root
@@ -91,12 +84,14 @@ TST_CLEANUP="cleanup"
 tst_tmpdir
 
 tst_resm TINFO "using old TCP API"
-tst_netload $(tst_ipaddr rhost) $tfo_result TFO -o -O
+tst_netload $(tst_ipaddr rhost) $tfo_result TFO
 time_tfo_off=$(read_result_file)
+[ "$time_tfo_off" = "-1" ] && tst_brkm TFAIL "failed to find result file"
 
 tst_resm TINFO "using new TCP API"
-tst_netload $(tst_ipaddr rhost) $tfo_result TFO
+tst_netload $(tst_ipaddr rhost) $tfo_result TFO -f -t 3
 time_tfo_on=$(read_result_file)
+[ "$time_tfo_on" = "-1" ] && tst_brkm TFAIL "failed to find result file"
 
 tfo_cmp=$(( 100 - ($time_tfo_on * 100) / $time_tfo_off ))
 
-- 
1.7.1



More information about the ltp mailing list