Merge branch 'features/issue-125'

This commit is contained in:
Bruce A. Mah 2014-04-17 12:14:58 -07:00
commit 54f2264730
9 changed files with 33 additions and 104 deletions

View File

@ -126,15 +126,6 @@ as nuttcp in UDP mode. We are looking into this, but in the meantime,
if you want to get UDP above 5Gbps, we recommend using nuttcp instead
(http://www.nuttcp.net/).
* Interval reports on high-loss networks: The way iperf3 is currently
implemented, the sender write command will block until the entire
block has been written. This means that it might take several seconds
to send a full block if the network has high loss, and the interval
reports will have widely varying interval times. We are trying to
determine the best solution to this, but in the meantime, try using a
smaller block size if you get strange interval reports. For example,
try "-l 4K".
* The -Z flag sometimes hangs on OSX.
* On OpenBSD, the server seems to require a "-4" argument, implying

View File

@ -36,9 +36,6 @@ main( int argc, char** argv )
iperf_defaults( test );
iperf_set_verbose( test, 1 );
/* This main program doesn't use SIGALRM, so the iperf API may use it. */
iperf_set_test_may_use_sigalrm(test, 1);
iperf_set_test_role( test, 'c' );
iperf_set_test_server_hostname( test, host );
iperf_set_test_server_port( test, port );

View File

@ -193,7 +193,6 @@ struct iperf_test
int debug; /* -d option - enable debug */
int multisend;
int may_use_sigalrm;
char *json_output_string; /* rendered JSON output if json_output is set */
/* Select related parameters */

View File

@ -215,12 +215,6 @@ iperf_get_test_zerocopy(struct iperf_test *ipt)
return ipt->zerocopy;
}
int
iperf_get_test_may_use_sigalrm(struct iperf_test *ipt)
{
return ipt->may_use_sigalrm;
}
char
iperf_get_test_unit_format(struct iperf_test *ipt)
{
@ -362,12 +356,6 @@ iperf_set_test_zerocopy(struct iperf_test *ipt, int zerocopy)
ipt->zerocopy = zerocopy;
}
void
iperf_set_test_may_use_sigalrm(struct iperf_test *ipt, int may_use_sigalrm)
{
ipt->may_use_sigalrm = may_use_sigalrm;
}
void
iperf_set_test_unit_format(struct iperf_test *ipt, char unit_format)
{
@ -1604,7 +1592,6 @@ iperf_defaults(struct iperf_test *testp)
memset(testp->cookie, 0, COOKIE_SIZE);
testp->multisend = 10; /* arbitrary */
testp->may_use_sigalrm = 0;
/* Set up protocol list */
SLIST_INIT(&testp->streams);

View File

@ -70,7 +70,6 @@ int iperf_get_test_protocol_id( struct iperf_test* ipt );
int iperf_get_test_json_output( struct iperf_test* ipt );
char* iperf_get_test_json_output_string ( struct iperf_test* ipt );
int iperf_get_test_zerocopy( struct iperf_test* ipt );
int iperf_get_test_may_use_sigalrm( struct iperf_test* ipt );
/* Setter routines for some fields inside iperf_test. */
void iperf_set_verbose( struct iperf_test* ipt, int verbose );
@ -92,7 +91,6 @@ void iperf_set_test_reverse( struct iperf_test* ipt, int reverse );
void iperf_set_test_json_output( struct iperf_test* ipt, int json_output );
int iperf_has_zerocopy( void );
void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy );
void iperf_set_test_may_use_sigalrm( struct iperf_test* ipt, int may_use_sigalrm );
/**
* exchange_parameters - handles the param_Exchange part for client

View File

@ -315,26 +315,15 @@ sigend_handler(int sig)
}
typedef enum { cm_select, cm_itimer } cm_t;
static int sigalrm_triggered;
static void
sigalrm_handler(int sig)
{
sigalrm_triggered = 1;
}
int
iperf_run_client(struct iperf_test * test)
{
cm_t concurrency_model;
int startup;
int result = 0;
fd_set read_set, write_set;
struct timeval now;
struct timeval* timeout = NULL;
struct itimerval itv;
struct iperf_stream *sp;
/* Termination signals. */
iperf_catch_sigend(sigend_handler);
@ -367,26 +356,22 @@ iperf_run_client(struct iperf_test * test)
cpu_util(NULL);
startup = 1;
concurrency_model = cm_select; /* always start in select mode */
while (test->state != IPERF_DONE) {
if (concurrency_model == cm_select) {
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
(void) gettimeofday(&now, NULL);
timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
if (FD_ISSET(test->ctrl_sck, &read_set)) {
if (iperf_handle_message_client(test) < 0) {
return -1;
}
FD_CLR(test->ctrl_sck, &read_set);
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
(void) gettimeofday(&now, NULL);
timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
if (FD_ISSET(test->ctrl_sck, &read_set)) {
if (iperf_handle_message_client(test) < 0) {
return -1;
}
FD_CLR(test->ctrl_sck, &read_set);
}
}
@ -395,26 +380,10 @@ iperf_run_client(struct iperf_test * test)
/* Is this our first time really running? */
if (startup) {
startup = 0;
/* Decide which concurrency model to use for the real test.
** SIGALRM is less overhead but there are a bunch of cases
** where it either won't work or is ill-advised.
*/
if (test->may_use_sigalrm && test->settings->rate == 0 &&
(test->stats_interval == 0 || test->stats_interval > 0.2) &&
(test->reporter_interval == 0 || test->reporter_interval > 0.2) &&
(test->omit == 0 || test->omit > 0.2) &&
! test->reverse) {
concurrency_model = cm_itimer;
test->multisend = 1;
signal(SIGALRM, sigalrm_handler);
sigalrm_triggered = 0;
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 100000;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 100000;
(void) setitimer(ITIMER_REAL, &itv, NULL);
}
SLIST_FOREACH(sp, &test->streams, streams) {
setnonblocking(sp->socket, 1);
}
}
if (test->reverse) {
@ -423,41 +392,30 @@ iperf_run_client(struct iperf_test * test)
return -1;
} else {
// Regular mode. Client sends.
if (iperf_send(test, concurrency_model == cm_itimer ? NULL : &write_set) < 0)
if (iperf_send(test, &write_set) < 0)
return -1;
}
if ((concurrency_model == cm_select &&
(result == 0 ||
(timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0))) ||
(concurrency_model == cm_itimer && sigalrm_triggered)) {
/* Run the timers. */
(void) gettimeofday(&now, NULL);
tmr_run(&now);
if (concurrency_model == cm_itimer)
sigalrm_triggered = 0;
}
/* Run the timers. */
(void) gettimeofday(&now, NULL);
tmr_run(&now);
/* Is the test done yet? */
if ((!test->omitting) &&
((test->duration != 0 && test->done) ||
(test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes) ||
(test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks))) {
SLIST_FOREACH(sp, &test->streams, streams) {
setnonblocking(sp->socket, 0);
}
/* Yes, done! Send TEST_END. */
test->done = 1;
cpu_util(test->cpu_util);
test->stats_callback(test);
if (iperf_set_send_state(test, TEST_END) != 0)
return -1;
/* If we were doing setitimer(), go back to select() for the end. */
if (concurrency_model == cm_itimer) {
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
(void) setitimer(ITIMER_REAL, &itv, NULL);
concurrency_model = cm_select;
}
}
}
// If we're in reverse mode, continue draining the data

View File

@ -516,6 +516,8 @@ iperf_run_server(struct iperf_test *test)
FD_SET(s, &test->read_set);
if (s > test->max_fd) test->max_fd = s;
setnonblocking(s, 1);
streams_accepted++;
if (test->on_new_stream)
test->on_new_stream(sp);

View File

@ -79,9 +79,6 @@ main(int argc, char **argv)
iperf_errexit(NULL, "create new test error - %s", iperf_strerror(i_errno));
iperf_defaults(test); /* sets defaults */
/* This main program doesn't use SIGALRM, so the iperf API may use it. */
iperf_set_test_may_use_sigalrm(test, 1);
if (iperf_parse_arguments(test, argc, argv) < 0) {
iperf_err(test, "parameter error - %s", iperf_strerror(i_errno));
fprintf(stderr, "\n");

View File

@ -171,8 +171,8 @@ Nread(int fd, char *buf, size_t count, int prot)
while (nleft > 0) {
r = read(fd, buf, nleft);
if (r < 0) {
if (errno == EINTR)
r = 0;
if (errno == EINTR || errno == EAGAIN)
break;
else
return NET_HARDERROR;
} else if (r == 0)
@ -200,9 +200,9 @@ Nwrite(int fd, const char *buf, size_t count, int prot)
if (r < 0) {
switch (errno) {
case EINTR:
case EAGAIN:
return count - nleft;
case EAGAIN:
case ENOBUFS:
return NET_SOFTERROR;
@ -271,9 +271,9 @@ Nsendfile(int fromfd, int tofd, const char *buf, size_t count)
if (r < 0) {
switch (errno) {
case EINTR:
case EAGAIN:
return count - nleft;
case EAGAIN:
case ENOBUFS:
case ENOMEM:
return NET_SOFTERROR;