From 4714e12e8feadcf62846323bffae2c5506ffd749 Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Sat, 30 Jan 2016 07:41:34 +0000 Subject: [PATCH 1/4] socket: Use alternatives if MSG_NOSIGNAL is unavailable Only Linux has MSG_NOSIGNAL as a socket flag (see http://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly ) which makes compilation fail on other OSes. The BSDs and OS X have SO_NOSIGPIPE which implements the same thing but others like Solaris don't even have that (see http://stackoverflow.com/questions/2205455/detecting-broken-pipe-in-solaris-send-call )... Work around this by checking using MSG_NOSIGNAL or SO_NOSIGPIPE if available otherwise don't set anything at all so we at least continue to compile. --- lib/socket.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/socket.c b/lib/socket.c index c308b4c..fb64261 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -643,6 +643,13 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) size_t total; struct iscsi_pdu *pdu; static char padding_buf[3]; + int socket_flags = 0; + +#ifdef MSG_NOSIGNAL + socket_flags |= MSG_NOSIGNAL; +#elif SO_NOSIGPIPE + socket_flags |= SO_NOSIGPIPE; +#endif if (iscsi->fd == -1) { iscsi_set_error(iscsi, "trying to write but not connected"); @@ -697,7 +704,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) count = send(iscsi->fd, pdu->outdata.data + pdu->outdata_written, pdu->outdata.size - pdu->outdata_written, - MSG_NOSIGNAL); + socket_flags); if (count == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return 0; @@ -746,7 +753,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) /* Write padding */ if (pdu->payload_written < total) { - count = send(iscsi->fd, padding_buf, total - pdu->payload_written, MSG_NOSIGNAL); + count = send(iscsi->fd, padding_buf, total - pdu->payload_written, socket_flags); if (count == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return 0; From 6ea30f9fb2bd9780dd67413283a2cbfef1c4f558 Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Sat, 30 Jan 2016 08:12:28 +0000 Subject: [PATCH 2/4] socket: Simplify SOL_TCP check Rather than checking for the names of OSes that don't implement it just check whether the define is available directly. --- lib/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/socket.c b/lib/socket.c index fb64261..7b93fec 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -140,7 +140,7 @@ static int set_tcp_sockopt(int sockfd, int optname, int value) { int level; - #if defined(__FreeBSD__) || defined(__sun) || (defined(__APPLE__) && defined(__MACH__)) + #ifndef SOL_TCP struct protoent *buf; if ((buf = getprotobyname("tcp")) != NULL) From 831b222917fd6cabdedf7aa40c0b928db0d6673e Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Sat, 30 Jan 2016 08:21:21 +0000 Subject: [PATCH 3/4] iscsi-perf: Allow a better clock to be used 7c6a3e4a0b86582bc68a6df0446592f156e86240 wound up always forcing the usage of gettimeofday (even when the more accurate CLOCK_MONOTONIC was available) because the define to indicate its availability is in config.h which wasn't included. Fix this by including config.h, correct the misnamed variable in the CLOCK_MONOTONIC branch and rename VERSION to PERF_VERSION to avoid the naming conflict. --- utils/iscsi-perf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/utils/iscsi-perf.c b/utils/iscsi-perf.c index a27d50a..f09802c 100644 --- a/utils/iscsi-perf.c +++ b/utils/iscsi-perf.c @@ -14,6 +14,9 @@ You should have received a copy of the GNU General Public License along with this program; if not, see . */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include @@ -32,7 +35,7 @@ #include #endif -#define VERSION "0.1" +#define PERF_VERSION "0.1" #define NOP_INTERVAL 5 #define MAX_NOP_FAILURES 3 @@ -77,8 +80,8 @@ uint64_t get_clock_ns(void) { #ifdef HAVE_CLOCK_GETTIME struct timespec ts; - res = clock_gettime (CLOCK_MONOTONIC, &tp); ns = ts.tv_sec * 1000000000 + ts.tv_nsec; + res = clock_gettime (CLOCK_MONOTONIC, &ts); #else struct timeval tv; res = gettimeofday(&tv, NULL); @@ -260,7 +263,7 @@ int main(int argc, char *argv[]) srand(time(NULL)); - printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven \n\n", VERSION); + printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven \n\n", PERF_VERSION); while ((c = getopt_long(argc, argv, "i:m:b:t:nrRx:", long_options, &option_index)) != -1) { From 403ec4493a7923a9c6a36426e73119b812299588 Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Sat, 30 Jan 2016 08:29:01 +0000 Subject: [PATCH 4/4] iscsi-perf: Add ULL suffix to large integer literals Add ULL to all the large integer literals. Without this they can be treated as being signed by the compiler (at least on 32 bit machines) leading to underflow problems and strange output when calculating the elapsed time. --- utils/iscsi-perf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/iscsi-perf.c b/utils/iscsi-perf.c index f09802c..0fccfa9 100644 --- a/utils/iscsi-perf.c +++ b/utils/iscsi-perf.c @@ -80,12 +80,12 @@ uint64_t get_clock_ns(void) { #ifdef HAVE_CLOCK_GETTIME struct timespec ts; - ns = ts.tv_sec * 1000000000 + ts.tv_nsec; res = clock_gettime (CLOCK_MONOTONIC, &ts); + ns = ts.tv_sec * 1000000000ULL + ts.tv_nsec; #else struct timeval tv; res = gettimeofday(&tv, NULL); - ns = tv.tv_sec * 1000000000 + tv.tv_usec * 1000; + ns = tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000; #endif if (res == -1) { fprintf(stderr,"could not get requested clock\n"); @@ -98,9 +98,9 @@ void fill_read_queue(struct client *client); void progress(struct client *client) { uint64_t now = get_clock_ns(); - if (now - client->last_ns < 1000000000) return; + if (now - client->last_ns < 1000000000ULL) return; - uint64_t _runtime = (now - client->first_ns) / 1000000000UL; + uint64_t _runtime = (now - client->first_ns) / 1000000000ULL; if (runtime) _runtime = runtime - _runtime; printf ("\r"); @@ -110,8 +110,8 @@ void progress(struct client *client) { finished = 1; printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s) ", aiops, (aiops * blocks_per_io * client->blocksize) >> 20); } else { - uint64_t iops = 1000000000UL * (client->iops - client->last_iops) / (now - client->last_ns); - uint64_t mbps = 1000000000UL * (client->bytes - client->last_bytes) / (now - client->last_ns); + uint64_t iops = 1000000000ULL * (client->iops - client->last_iops) / (now - client->last_ns); + uint64_t mbps = 1000000000ULL * (client->bytes - client->last_bytes) / (now - client->last_ns); printf ("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 " - ", _runtime / 3600, (_runtime % 3600) / 60, _runtime % 60); printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, mbps >> 20); printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, ambps >> 20, client->in_flight, client->busy_cnt);