Skip to content

Commit

Permalink
Attempt to fix some brokenness in -F from #301.
Browse files Browse the repository at this point in the history
In some work related to #125, we introduced a bug in which
chunks of a file being read for the -F option were not
completely sent, particularly with TCP sockets.  We attempt
to fix this by detecting cases in which not all data passed
to a socket could be actually sent (for example due to full
socket buffers) and preserving that data for future send
iterations.

The ending statistics in the "diskfile" JSON structure were
wrong, and did not properly distinguish between sender-side
and receiver-side statistics.  This has been fixed (at least
for the client side).

Specifically mention in the manpage that "iperf -F" is not
a file transfer tool.
  • Loading branch information
bmah888 committed May 30, 2017
1 parent 39de1e0 commit bd972dc
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ struct iperf_stream
int buffer_fd; /* data to send, file descriptor */
char *buffer; /* data to send, mmapped */
int diskfile_fd; /* file to send, file descriptor */
int diskfile_left; /* remaining file data on disk */

/*
* for udp measurements - This can be a structure outside stream, and
Expand Down
11 changes: 7 additions & 4 deletions src/iperf3.1
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ pause \fIn\fR seconds between periodic throughput reports;
default is 1, use 0 to disable
.TP
.BR -F ", " --file " \fIname\fR"
client-side: read from the file and write to the network, instead
of using random data;
server-side: read from the network and write to the file, instead
of throwing the data away
Use a file as the source (on the sender) or sink (on the receiver) of
data, rather than just generating random data or throwing it away.
This feature is used for finding whether or not the storage subsystem
is the bottleneck for file transfers.
It does not turn iperf3 into a file transfer tool.
The length, attributes, and in some cases contents of the received
file may not match those of the original file.
.TP
.BR -A ", " --affinity " \fIn/n,m\fR"
Set the CPU affinity, if possible (Linux and FreeBSD only).
Expand Down
57 changes: 48 additions & 9 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2743,15 +2743,22 @@ iperf_print_results(struct iperf_test *test)
if (sp->diskfile_fd >= 0) {
if (fstat(sp->diskfile_fd, &sb) == 0) {
/* In the odd case that it's a zero-sized file, say it was all transferred. */
int percent = 100;
int percent_sent = 100, percent_received = 100;
if (sb.st_size > 0) {
percent = (int) ( ( (double) bytes_sent / (double) sb.st_size ) * 100.0 );
percent_sent = (int) ( ( (double) bytes_sent / (double) sb.st_size ) * 100.0 );
percent_received = (int) ( ( (double) bytes_received / (double) sb.st_size ) * 100.0 );
}
unit_snprintf(sbuf, UNIT_LEN, (double) sb.st_size, 'A');
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "diskfile", iperf_json_printf("sent: %d size: %d percent: %d filename: %s", (int64_t) bytes_sent, (int64_t) sb.st_size, (int64_t) percent, test->diskfile_name));
cJSON_AddItemToObject(json_summary_stream, "diskfile", iperf_json_printf("sent: %d received: %d size: %d percent_sent: %d percent_received: %d filename: %s", (int64_t) bytes_sent, (int64_t) bytes_received, (int64_t) sb.st_size, (int64_t) percent_sent, (int64_t) percent_received, test->diskfile_name));
else
iperf_printf(test, report_diskfile, ubuf, sbuf, percent, test->diskfile_name);
if (test->sender) {
iperf_printf(test, report_diskfile, ubuf, sbuf, percent_sent, test->diskfile_name);
}
else {
unit_snprintf(ubuf, UNIT_LEN, (double) bytes_received, 'A');
iperf_printf(test, report_diskfile, ubuf, sbuf, percent_received, test->diskfile_name);
}
}
}

Expand Down Expand Up @@ -3281,12 +3288,44 @@ static int
diskfile_send(struct iperf_stream *sp)
{
int r;
static int rtot;

/* if needed, read enough data from the disk to fill up the buffer */
if (sp->diskfile_left < sp->test->settings->blksize && !sp->test->done) {
r = read(sp->diskfile_fd, sp->buffer, sp->test->settings->blksize -
sp->diskfile_left);
rtot += r;
if (sp->test->debug) {
printf("read %d bytes from file, %d total\n", r, rtot);
if (r != sp->test->settings->blksize - sp->diskfile_left)
printf("possible eof\n");
}
/* If there's no data left in the file or in the buffer, we're done */
if (r == 0 && sp->diskfile_left) {
sp->test->done = 1;
if (sp->test->debug)
printf("done\n");
}
}

r = read(sp->diskfile_fd, sp->buffer, sp->test->settings->blksize);
if (r == 0)
sp->test->done = 1;
else
r = sp->snd2(sp);
r = sp->snd2(sp);
if (r < 0) {
return r;
}
/*
* Compute how much data is in the buffer but didn't get sent.
* If there are bytes that got left behind, slide them to the
* front of the buffer so they can hopefully go out on the next
* pass.
*/
sp->diskfile_left = sp->test->settings->blksize - r;
if (sp->diskfile_left && sp->diskfile_left < sp->test->settings->blksize) {
memcpy(sp->buffer,
sp->buffer + (sp->test->settings->blksize - sp->diskfile_left),
sp->diskfile_left);
if (sp->test->debug)
printf("Shifting %d bytes by %d\n", sp->diskfile_left, (sp->test->settings->blksize - sp->diskfile_left));
}
return r;
}

Expand Down
3 changes: 3 additions & 0 deletions src/iperf_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ iperf_tcp_send(struct iperf_stream *sp)
sp->result->bytes_sent += r;
sp->result->bytes_sent_this_interval += r;

if (sp->test->debug)
printf("sent %d bytes of %d, total %lu\n", r, sp->settings->blksize, sp->result->bytes_sent);

return r;
}

Expand Down
3 changes: 3 additions & 0 deletions src/iperf_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ iperf_udp_send(struct iperf_stream *sp)
sp->result->bytes_sent += r;
sp->result->bytes_sent_this_interval += r;

if (sp->test->debug)
printf("sent %d bytes of %d, total %lu\n", r, sp->settings->blksize, sp->result->bytes_sent);

return r;
}

Expand Down

0 comments on commit bd972dc

Please sign in to comment.