| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #ifdef WANT_OMNI |
| char nettest_omni_id[]="\ |
| @(#)nettest_omni.c (c) Copyright 2008 Hewlett-Packard Co. Version 2.5.0pre"; |
| |
| #include <stdio.h> |
| #if HAVE_SYS_TYPES_H |
| # include <sys/types.h> |
| #endif |
| #if HAVE_SYS_STAT_H |
| # include <sys/stat.h> |
| #endif |
| #if STDC_HEADERS |
| # include <stdlib.h> |
| # include <stddef.h> |
| #else |
| # if HAVE_STDLIB_H |
| # include <stdlib.h> |
| # endif |
| #endif |
| #if HAVE_STRING_H |
| # if !STDC_HEADERS && HAVE_MEMORY_H |
| # include <memory.h> |
| # endif |
| # include <string.h> |
| #endif |
| #if HAVE_STRINGS_H |
| # include <strings.h> |
| #endif |
| #if HAVE_INTTYPES_H |
| # include <inttypes.h> |
| #else |
| # if HAVE_STDINT_H |
| # include <stdint.h> |
| # endif |
| #endif |
| #if HAVE_UNISTD_H |
| # include <unistd.h> |
| #endif |
| |
| #include <fcntl.h> |
| #ifndef WIN32 |
| #include <errno.h> |
| #include <signal.h> |
| #endif |
| |
| #if TIME_WITH_SYS_TIME |
| # include <sys/time.h> |
| # include <time.h> |
| #else |
| # if HAVE_SYS_TIME_H |
| # include <sys/time.h> |
| # else |
| # include <time.h> |
| # endif |
| #endif |
| |
| #include <ctype.h> |
| |
| #ifdef NOSTDLIBH |
| #include <malloc.h> |
| #endif /* NOSTDLIBH */ |
| |
| #ifdef WANT_SCTP |
| #include <netinet/sctp.h> |
| #endif |
| |
| #ifndef WIN32 |
| #if !defined(__VMS) |
| #include <sys/ipc.h> |
| #endif /* !defined(__VMS) */ |
| #include <sys/socket.h> |
| #include <netinet/in.h> |
| #include <netinet/tcp.h> |
| #include <arpa/inet.h> |
| #include <netdb.h> |
| #else /* WIN32 */ |
| #include <process.h> |
| #define netperf_socklen_t socklen_t |
| #include <winsock2.h> |
| |
| /* while it is unlikely that anyone running Windows 2000 or NT 4 is |
| going to be trying to compile this, if they are they will want to |
| define DONT_IPV6 in the sources file */ |
| #ifndef DONT_IPV6 |
| #include <ws2tcpip.h> |
| #endif |
| #include <windows.h> |
| |
| #define sleep(x) Sleep((x)*1000) |
| |
| #define __func__ __FUNCTION__ |
| #endif /* WIN32 */ |
| |
| /* We don't want to use bare constants in the shutdown() call. In the |
| extremely unlikely event that SHUT_WR isn't defined, we will define |
| it to the value we used to be passing to shutdown() anyway. raj |
| 2007-02-08 */ |
| #if !defined(SHUT_WR) |
| #define SHUT_WR 1 |
| #endif |
| |
| #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) |
| # include "missing/getaddrinfo.h" |
| #endif |
| |
| #include "netlib.h" |
| #include "netsh.h" |
| #include "nettest_bsd.h" |
| |
| #if defined(WANT_HISTOGRAM) || defined(WANT_DEMO) |
| #include "hist.h" |
| #endif /* WANT_HISTOGRAM */ |
| |
| #ifdef WANT_HISTOGRAM |
| #ifdef HAVE_GETHRTIME |
| static hrtime_t time_one; |
| static hrtime_t time_two; |
| #elif HAVE_GET_HRT |
| #include "hrt.h" |
| static hrt_t time_one; |
| static hrt_t time_two; |
| #elif defined(WIN32) |
| static LARGE_INTEGER time_one; |
| static LARGE_INTEGER time_two; |
| #else |
| static struct timeval time_one; |
| static struct timeval time_two; |
| #endif /* HAVE_GETHRTIME */ |
| static HIST time_hist; |
| #endif /* WANT_HISTOGRAM */ |
| |
| #ifdef WANT_DEMO |
| #ifdef HAVE_GETHRTIME |
| static hrtime_t demo_one; |
| static hrtime_t demo_two; |
| static hrtime_t *demo_one_ptr = &demo_one; |
| static hrtime_t *demo_two_ptr = &demo_two; |
| static hrtime_t *temp_demo_ptr = &demo_one; |
| #elif defined(WIN32) |
| static LARGE_INTEGER demo_one; |
| static LARGE_INTEGER demo_two; |
| static LARGE_INTEGER *demo_one_ptr = &demo_one; |
| static LARGE_INTEGER *demo_two_ptr = &demo_two; |
| static LARGE_INTEGER *temp_demo_ptr = &demo_one; |
| #else |
| static struct timeval demo_one; |
| static struct timeval demo_two; |
| static struct timeval *demo_one_ptr = &demo_one; |
| static struct timeval *demo_two_ptr = &demo_two; |
| static struct timeval *temp_demo_ptr = &demo_one; |
| #endif |
| |
| /* for a _STREAM test, "a" should be lss_size and "b" should be |
| rsr_size. for a _MAERTS test, "a" should be lsr_size and "b" should |
| be rss_size. raj 2005-04-06 */ |
| #define DEMO_STREAM_SETUP(a,b) \ |
| if ((demo_mode) && (demo_units == 0)) { \ |
| /* take our default value of demo_units to be the larger of \ |
| twice the remote's SO_RCVBUF or twice our SO_SNDBUF */ \ |
| if (a > b) { \ |
| demo_units = 2*a; \ |
| } \ |
| else { \ |
| demo_units = 2*b; \ |
| } \ |
| } |
| |
| #define DEMO_INTERVAL(units) \ |
| if (demo_mode) { \ |
| double actual_interval; \ |
| units_this_tick += units; \ |
| if (units_this_tick >= demo_units) { \ |
| /* time to possibly update demo_units and maybe output an \ |
| interim result */ \ |
| HIST_timestamp(demo_two_ptr); \ |
| actual_interval = delta_micro(demo_one_ptr,demo_two_ptr); \ |
| /* we always want to fine-tune demo_units here whether we \ |
| emit an interim result or not. if we are short, this \ |
| will lengthen demo_units. if we are long, this will \ |
| shorten it */ \ |
| demo_units = demo_units * (demo_interval / actual_interval); \ |
| if (actual_interval >= demo_interval) { \ |
| /* time to emit an interim result */ \ |
| fprintf(where, \ |
| "Interim result: %7.2f %s/s over %.2f seconds\n", \ |
| calc_thruput_interval(units_this_tick, \ |
| actual_interval/1000000.0), \ |
| format_units(), \ |
| actual_interval/1000000.0); \ |
| units_this_tick = 0.0; \ |
| /* now get a new starting timestamp. we could be clever \ |
| and swap pointers - the math we do probably does not \ |
| take all that long, but for now this will suffice */ \ |
| temp_demo_ptr = demo_one_ptr; \ |
| demo_one_ptr = demo_two_ptr; \ |
| demo_two_ptr = temp_demo_ptr; \ |
| } \ |
| } \ |
| } |
| |
| #define DEMO_STREAM_INTERVAL(units) DEMO_INTERVAL(units) |
| |
| #define DEMO_RR_SETUP(a) \ |
| if ((demo_mode) && (demo_units == 0)) { \ |
| /* take whatever we are given */ \ |
| demo_units = a; \ |
| } |
| |
| #define DEMO_RR_INTERVAL(units) DEMO_INTERVAL(units) |
| |
| #endif |
| |
| #ifdef WANT_INTERVALS |
| int interval_count; |
| #ifndef WANT_SPIN |
| sigset_t signal_set; |
| #define INTERVALS_INIT() \ |
| if (interval_burst) { \ |
| /* zero means that we never pause, so we never should need the \ |
| interval timer. we used to use it for demo mode, but we deal \ |
| with that with a variant on watching the clock rather than \ |
| waiting for a timer. raj 2006-02-06 */ \ |
| start_itimer(interval_wate); \ |
| } \ |
| interval_count = interval_burst; \ |
| /* get the signal set for the call to sigsuspend */ \ |
| if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &signal_set) != 0) { \ |
| fprintf(where, \ |
| "%s: unable to get sigmask errno %d\n", \ |
| __func__, \ |
| errno); \ |
| fflush(where); \ |
| exit(1); \ |
| } |
| |
| #define INTERVALS_WAIT() \ |
| /* in this case, the interval count is the count-down couter \ |
| to decide to sleep for a little bit */ \ |
| if ((interval_burst) && (--interval_count == 0)) { \ |
| /* call sigsuspend and wait for the interval timer to get us \ |
| out */ \ |
| if (debug > 1) { \ |
| fprintf(where,"about to suspend\n"); \ |
| fflush(where); \ |
| } \ |
| if (sigsuspend(&signal_set) == EFAULT) { \ |
| fprintf(where, \ |
| "%s: fault with sigsuspend.\n", \ |
| __func__); \ |
| fflush(where); \ |
| exit(1); \ |
| } \ |
| interval_count = interval_burst; \ |
| } |
| #else |
| /* first out timestamp */ |
| #ifdef HAVE_GETHRTIME |
| static hrtime_t intvl_one; |
| static hrtime_t intvl_two; |
| static hrtime_t *intvl_one_ptr = &intvl_one; |
| static hrtime_t *intvl_two_ptr = &intvl_two; |
| static hrtime_t *temp_intvl_ptr = &intvl_one; |
| #elif defined(WIN32) |
| static LARGE_INTEGER intvl_one; |
| static LARGE_INTEGER intvl_two; |
| static LARGE_INTEGER *intvl_one_ptr = &intvl_one; |
| static LARGE_INTEGER *intvl_two_ptr = &intvl_two; |
| static LARGE_INTEGER *temp_intvl_ptr = &intvl_one; |
| #else |
| static struct timeval intvl_one; |
| static struct timeval intvl_two; |
| static struct timeval *intvl_one_ptr = &intvl_one; |
| static struct timeval *intvl_two_ptr = &intvl_two; |
| static struct timeval *temp_intvl_ptr = &intvl_one; |
| #endif |
| |
| #define INTERVALS_INIT() \ |
| if (interval_burst) { \ |
| HIST_timestamp(intvl_one_ptr); \ |
| } \ |
| interval_count = interval_burst; \ |
| |
| #define INTERVALS_WAIT() \ |
| /* in this case, the interval count is the count-down couter \ |
| to decide to sleep for a little bit */ \ |
| if ((interval_burst) && (--interval_count == 0)) { \ |
| /* call sigsuspend and wait for the interval timer to get us \ |
| out */ \ |
| if (debug > 1) { \ |
| fprintf(where,"about to spin suspend\n"); \ |
| fflush(where); \ |
| } \ |
| HIST_timestamp(intvl_two_ptr); \ |
| while(delta_micro(intvl_one_ptr,intvl_two_ptr) < interval_usecs) { \ |
| HIST_timestamp(intvl_two_ptr); \ |
| } \ |
| temp_intvl_ptr = intvl_one_ptr; \ |
| intvl_one_ptr = intvl_two_ptr; \ |
| intvl_two_ptr = temp_intvl_ptr; \ |
| interval_count = interval_burst; \ |
| } |
| #endif |
| #endif |
| |
| #define NETPERF_WAITALL 0x1 |
| #define NETPERF_XMIT 0x2 |
| #define NETPERF_RECV 0x4 |
| |
| #define NETPERF_IS_RR(x) (((x & NETPERF_XMIT) && (x & NETPERF_RECV)) || \ |
| (!((x & NETPERF_XMIT) || (x & NETPERF_RECV)))) |
| |
| #define NETPERF_RECV_ONLY(x) ((x & NETPERF_RECV) && !(x & NETPERF_XMIT)) |
| |
| #define NETPERF_XMIT_ONLY(x) ((x & NETPERF_XMIT) && !(x & NETPERF_RECV)) |
| |
| #define NETPERF_CC(x) (!(x & NETPERF_XMIT) && !(x & NETPERF_RECV)) |
| |
| extern void get_uuid_string(char *string, size_t size); |
| |
| /* a boatload of globals while I settle things out */ |
| char *csv_selection_file = NULL; |
| char *human_selection_file = NULL; |
| char *keyword_selection_file = NULL; |
| |
| char test_uuid[38]; |
| |
| double result_confid_pct = -1.0; |
| double loc_cpu_confid_pct = -1.0; |
| double rem_cpu_confid_pct = -1.0; |
| double interval_pct = -1.0; |
| |
| int protocol; |
| int direction; |
| int remote_send_size = -1; |
| int remote_recv_size = -1; |
| int remote_send_size_req = -1; |
| int remote_recv_size_req = -1; |
| int remote_use_sendfile; |
| #if 0 |
| int remote_send_dirty_count; |
| int remote_recv_dirty_count; |
| int remote_recv_clean_count; |
| #endif |
| extern int loc_dirty_count; |
| extern int loc_clean_count; |
| extern int rem_dirty_count; |
| extern int rem_clean_count; |
| int remote_checksum_off; |
| int connection_test; |
| int need_to_connect; |
| int need_connection; |
| int bytes_to_send; |
| double bytes_per_send; |
| int failed_sends; |
| int bytes_to_recv; |
| double bytes_per_recv; |
| int null_message_ok = 0; |
| int csv = 0; |
| int keyword = 0; |
| uint64_t trans_completed = 0; |
| uint64_t units_remaining; |
| uint64_t bytes_sent = 0; |
| uint64_t bytes_received = 0; |
| uint64_t local_send_calls = 0; |
| uint64_t local_receive_calls = 0; |
| uint64_t remote_bytes_sent; |
| uint64_t remote_bytes_received; |
| uint64_t remote_send_calls; |
| uint64_t remote_receive_calls; |
| double bytes_xferd; |
| double remote_bytes_xferd; |
| double remote_bytes_per_recv; |
| double remote_bytes_per_send; |
| float elapsed_time; |
| float local_cpu_utilization; |
| float local_service_demand; |
| float remote_cpu_utilization; |
| float remote_service_demand; |
| double thruput; |
| double local_send_thruput; |
| double local_recv_thruput; |
| double remote_send_thruput; |
| double remote_recv_thruput; |
| |
| /* kludges for omni output */ |
| double elapsed_time_double; |
| double local_cpu_utilization_double; |
| double local_service_demand_double; |
| double remote_cpu_utilization_double; |
| double remote_service_demand_double; |
| double transaction_rate = 1.0; |
| double rtt_latency = -1.0; |
| int32_t transport_mss = -2; |
| char *local_interface_name=NULL; |
| char *remote_interface_name=NULL; |
| char local_driver_name[32]=""; |
| char local_driver_version[32]=""; |
| char local_driver_firmware[32]=""; |
| char local_driver_bus[32]=""; |
| char remote_driver_name[32]=""; |
| char remote_driver_version[32]=""; |
| char remote_driver_firmware[32]=""; |
| char remote_driver_bus[32]=""; |
| char *local_interface_slot=NULL; |
| char *remote_interface_slot=NULL; |
| int remote_interface_vendor; |
| int remote_interface_device; |
| int remote_interface_subvendor; |
| int remote_interface_subdevice; |
| int local_interface_vendor; |
| int local_interface_device; |
| int local_interface_subvendor; |
| int local_interface_subdevice; |
| char *local_system_model; |
| char *local_cpu_model; |
| int local_cpu_frequency; |
| char *remote_system_model; |
| char *remote_cpu_model; |
| int remote_cpu_frequency; |
| |
| int local_security_type_id; |
| int local_security_enabled_num; |
| char *local_security_type; |
| char *local_security_enabled; |
| char *local_security_specific; |
| int remote_security_type_id; |
| int remote_security_enabled_num; |
| char *remote_security_enabled; |
| char *remote_security_type; |
| char *remote_security_specific; |
| |
| int printing_initialized = 0; |
| |
| char *sd_str; |
| char *thruput_format_str; |
| |
| char *socket_type_str; |
| char *protocol_str; |
| char *direction_str; |
| |
| extern int first_burst_size; |
| |
| #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun)) |
| #include <sys/sendfile.h> |
| #endif /* HAVE_SENDFILE && (__linux || __sun) */ |
| |
| static int confidence_iteration; |
| |
| static int local_cpu_method; |
| static int remote_cpu_method; |
| |
| /* these will control the width of port numbers we try to use in the */ |
| /* TCP_CRR and/or TCP_TRR tests. raj 3/95 */ |
| static int client_port_min = 5000; |
| static int client_port_max = 65535; |
| |
| /* different options for the sockets */ |
| |
| int |
| loc_nodelay, /* don't/do use NODELAY locally */ |
| rem_nodelay, /* don't/do use NODELAY remotely */ |
| loc_sndavoid, /* avoid send copies locally */ |
| loc_rcvavoid, /* avoid recv copies locally */ |
| rem_sndavoid, /* avoid send copies remotely */ |
| rem_rcvavoid; /* avoid recv_copies remotely */ |
| |
| extern int |
| loc_tcpcork, |
| rem_tcpcork, |
| local_connected, |
| remote_connected; |
| |
| /* you should add to this in the order in which they should appear in |
| the default csv (everything) output */ |
| |
| enum netperf_output_name { |
| OUTPUT_NONE, |
| SOCKET_TYPE, |
| PROTOCOL, |
| DIRECTION, |
| ELAPSED_TIME, |
| THROUGHPUT, |
| THROUGHPUT_UNITS, |
| LSS_SIZE_REQ, |
| LSS_SIZE, |
| LSS_SIZE_END, |
| LSR_SIZE_REQ, |
| LSR_SIZE, |
| LSR_SIZE_END, |
| RSS_SIZE_REQ, |
| RSS_SIZE, |
| RSS_SIZE_END, |
| RSR_SIZE_REQ, |
| RSR_SIZE, |
| RSR_SIZE_END, |
| LOCAL_SEND_SIZE, |
| LOCAL_RECV_SIZE, |
| REMOTE_SEND_SIZE, |
| REMOTE_RECV_SIZE, |
| REQUEST_SIZE, |
| RESPONSE_SIZE, |
| LOCAL_CPU_UTIL, |
| LOCAL_CPU_METHOD, |
| LOCAL_SD, |
| REMOTE_CPU_UTIL, |
| REMOTE_CPU_METHOD, |
| REMOTE_SD, |
| SD_UNITS, |
| CONFIDENCE_LEVEL, |
| CONFIDENCE_INTERVAL, |
| CONFIDENCE_ITERATION, |
| THROUGHPUT_CONFID, |
| LOCAL_CPU_CONFID, |
| REMOTE_CPU_CONFID, |
| TRANSACTION_RATE, |
| RT_LATENCY, |
| BURST_SIZE, |
| TRANSPORT_MSS, |
| LOCAL_SEND_THROUGHPUT, |
| LOCAL_RECV_THROUGHPUT, |
| REMOTE_SEND_THROUGHPUT, |
| REMOTE_RECV_THROUGHPUT, |
| LOCAL_CPU_BIND, |
| LOCAL_CPU_COUNT, |
| LOCAL_CPU_PEAK_UTIL, |
| LOCAL_CPU_PEAK_ID, |
| LOCAL_CPU_MODEL, |
| LOCAL_CPU_FREQUENCY, |
| REMOTE_CPU_BIND, |
| REMOTE_CPU_COUNT, |
| REMOTE_CPU_PEAK_UTIL, |
| REMOTE_CPU_PEAK_ID, |
| REMOTE_CPU_MODEL, |
| REMOTE_CPU_FREQUENCY, |
| SOURCE_PORT, |
| SOURCE_ADDR, |
| SOURCE_FAMILY, |
| DEST_PORT, |
| DEST_ADDR, |
| DEST_FAMILY, |
| LOCAL_SEND_CALLS, |
| LOCAL_RECV_CALLS, |
| LOCAL_BYTES_PER_RECV, |
| LOCAL_BYTES_PER_SEND, |
| LOCAL_BYTES_SENT, |
| LOCAL_BYTES_RECVD, |
| LOCAL_BYTES_XFERD, |
| LOCAL_SEND_OFFSET, |
| LOCAL_RECV_OFFSET, |
| LOCAL_SEND_ALIGN, |
| LOCAL_RECV_ALIGN, |
| LOCAL_SEND_WIDTH, |
| LOCAL_RECV_WIDTH, |
| LOCAL_SEND_DIRTY_COUNT, |
| LOCAL_RECV_DIRTY_COUNT, |
| LOCAL_RECV_CLEAN_COUNT, |
| LOCAL_NODELAY, |
| LOCAL_CORK, |
| REMOTE_SEND_CALLS, |
| REMOTE_RECV_CALLS, |
| REMOTE_BYTES_PER_RECV, |
| REMOTE_BYTES_PER_SEND, |
| REMOTE_BYTES_SENT, |
| REMOTE_BYTES_RECVD, |
| REMOTE_BYTES_XFERD, |
| REMOTE_SEND_OFFSET, |
| REMOTE_RECV_OFFSET, |
| REMOTE_SEND_ALIGN, |
| REMOTE_RECV_ALIGN, |
| REMOTE_SEND_WIDTH, |
| REMOTE_RECV_WIDTH, |
| REMOTE_SEND_DIRTY_COUNT, |
| REMOTE_RECV_DIRTY_COUNT, |
| REMOTE_RECV_CLEAN_COUNT, |
| REMOTE_NODELAY, |
| REMOTE_CORK, |
| LOCAL_SYSNAME, |
| LOCAL_SYSTEM_MODEL, |
| LOCAL_RELEASE, |
| LOCAL_VERSION, |
| LOCAL_MACHINE, |
| REMOTE_SYSNAME, |
| REMOTE_SYSTEM_MODEL, |
| REMOTE_RELEASE, |
| REMOTE_VERSION, |
| REMOTE_MACHINE, |
| LOCAL_INTERFACE_NAME, |
| LOCAL_INTERFACE_VENDOR, |
| LOCAL_INTERFACE_DEVICE, |
| LOCAL_INTERFACE_SUBVENDOR, |
| LOCAL_INTERFACE_SUBDEVICE, |
| LOCAL_DRIVER_NAME, |
| LOCAL_DRIVER_VERSION, |
| LOCAL_DRIVER_FIRMWARE, |
| LOCAL_DRIVER_BUS, |
| LOCAL_INTERFACE_SLOT, |
| REMOTE_INTERFACE_NAME, |
| REMOTE_INTERFACE_VENDOR, |
| REMOTE_INTERFACE_DEVICE, |
| REMOTE_INTERFACE_SUBVENDOR, |
| REMOTE_INTERFACE_SUBDEVICE, |
| REMOTE_DRIVER_NAME, |
| REMOTE_DRIVER_VERSION, |
| REMOTE_DRIVER_FIRMWARE, |
| REMOTE_DRIVER_BUS, |
| REMOTE_INTERFACE_SLOT, |
| LOCAL_INTERVAL_USECS, |
| LOCAL_INTERVAL_BURST, |
| REMOTE_INTERVAL_USECS, |
| REMOTE_INTERVAL_BURST, |
| LOCAL_SECURITY_TYPE_ID, |
| LOCAL_SECURITY_TYPE, |
| LOCAL_SECURITY_ENABLED_NUM, |
| LOCAL_SECURITY_ENABLED, |
| LOCAL_SECURITY_SPECIFIC, |
| REMOTE_SECURITY_TYPE_ID, |
| REMOTE_SECURITY_TYPE, |
| REMOTE_SECURITY_ENABLED_NUM, |
| REMOTE_SECURITY_ENABLED, |
| REMOTE_SECURITY_SPECIFIC, |
| RESULT_BRAND, |
| UUID, |
| COMMAND_LINE, |
| OUTPUT_END, |
| NETPERF_OUTPUT_MAX |
| }; |
| |
| typedef struct netperf_output_elt { |
| enum netperf_output_name output_name; /* belt and suspenders */ |
| int max_line_len; /* length of the longest of the "lines" */ |
| int tot_line_len; /* total length of all lines, including spaces */ |
| char *line[4]; |
| char *brief; /* the brief name of the value */ |
| char *format; /* format to apply to value */ |
| void *display_value; /* where to find the value */ |
| } netperf_output_elt_t; |
| |
| netperf_output_elt_t netperf_output_source[NETPERF_OUTPUT_MAX]; |
| |
| /* the list of things we will emit for CSV output. I suppose we could |
| at some point try to make this a special case of output_human_list, |
| or at least use some of that space... but for now we won't worry |
| about it. that can come after things are actually working :) raj |
| 2008-01-23 */ |
| enum netperf_output_name output_csv_list[NETPERF_OUTPUT_MAX]; |
| |
| /* the list of things we will emit for "human" output. up to |
| NETPERF_MAX_BLOCKS of output (groups of lines) each out to |
| NETPERF_OUTPUT_MAX entries. that should more than cover it */ |
| |
| #define NETPERF_MAX_BLOCKS 4 |
| enum netperf_output_name output_human_list[NETPERF_MAX_BLOCKS][NETPERF_OUTPUT_MAX]; |
| |
| char *direction_to_str(int direction) { |
| if (NETPERF_RECV_ONLY(direction)) return "Receive"; |
| if (NETPERF_XMIT_ONLY(direction)) return "Send"; |
| if (NETPERF_CC(direction)) return "Connection"; |
| else return "Send|Recv"; |
| } |
| |
| static unsigned short |
| get_port_number(struct addrinfo *res) |
| { |
| switch(res->ai_family) { |
| case AF_INET: { |
| struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; |
| return(ntohs(foo->sin_port)); |
| break; |
| } |
| #if defined(AF_INET6) |
| case AF_INET6: { |
| struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; |
| return(ntohs(foo->sin6_port)); |
| break; |
| } |
| #endif |
| default: |
| fprintf(where, |
| "Unexpected Address Family %u\n",res->ai_family); |
| fflush(where); |
| exit(-1); |
| } |
| } |
| |
| static void |
| extract_inet_address_and_port(struct addrinfo *res, void *addr, int len, int *port) |
| { |
| switch(res->ai_family) { |
| case AF_INET: { |
| struct sockaddr_in *foo = (struct sockaddr_in *)res->ai_addr; |
| *port = foo->sin_port; |
| memcpy(addr,&(foo->sin_addr),min(len,sizeof(foo->sin_addr))); |
| break; |
| } |
| #if defined(AF_INET6) |
| case AF_INET6: { |
| struct sockaddr_in6 *foo = (struct sockaddr_in6 *)res->ai_addr; |
| *port = foo->sin6_port; |
| memcpy(addr,&(foo->sin6_addr),min(len,sizeof(foo->sin6_addr))); |
| break; |
| } |
| #endif |
| default: |
| *port = 0xDEADBEEF; |
| strncpy(addr,"UNKN FAMILY",len); |
| } |
| } |
| |
| void |
| pick_next_port_number(struct addrinfo *local_res, struct addrinfo *remote_res) { |
| |
| static int myport_init = 0; |
| static unsigned short myport = 0; |
| |
| if (0 == myport_init) { |
| /* pick a nice random spot between client_port_min and |
| client_port_max for our initial port number, but only for a |
| connection oriented test. otherwise, we will want to set myport |
| to a specific port provided by the user if they have so provided |
| a specific port :) raj 2008-01-08 */ |
| srand(getpid()); |
| if (client_port_max - client_port_min) { |
| myport = client_port_min + |
| (rand() % (client_port_max - client_port_min)); |
| } |
| else { |
| myport = client_port_min; |
| } |
| /* there will be a ++ before the first call to bind, so subtract one */ |
| myport--; |
| myport_init = 1; |
| } |
| |
| newport: |
| /* pick a new port number */ |
| myport++; |
| |
| /* check to see if we are using the port number on which the |
| server is sitting _before_ we check against the boundaries lest |
| the server sits at the upper boundary. if this happens to be a |
| loopback test, trying to use the same portnumber would lead to |
| unsatisfying results and should be avoided. if this isn't a |
| loopback test, avoiding using the same port number doesn't |
| seriously affect anything anyway */ |
| |
| if (myport == get_port_number(remote_res)) myport++; |
| |
| /* wrap the port number when we reach the upper bound. for |
| students of networking history, some ancient stacks (1980's and |
| early 1990's perhaps) mistakenly treated these port numbers as |
| signed 16 bit quantities. we make no effort here to support |
| such stacks. raj 2008-01-08 */ |
| if (myport >= client_port_max) { |
| myport = client_port_min; |
| } |
| |
| /* set up the data socket */ |
| set_port_number(local_res, (unsigned short)myport); |
| } |
| |
| char * |
| netperf_output_enum_to_str(enum netperf_output_name output_name) |
| { |
| switch (output_name) { |
| case OUTPUT_NONE: |
| return "OUTPUT_NONE"; |
| case COMMAND_LINE: |
| return "COMMAND_LINE"; |
| case UUID: |
| return "UUID"; |
| case RESULT_BRAND: |
| return "RESULT_BRAND"; |
| case SOCKET_TYPE: |
| return "SOCKET_TYPE"; |
| case DIRECTION: |
| return "DIRECTION"; |
| case PROTOCOL: |
| return "PROTOCOL"; |
| case ELAPSED_TIME: |
| return "ELAPSED_TIME"; |
| case SOURCE_PORT: |
| return "SOURCE_PORT"; |
| case SOURCE_ADDR: |
| return "SOURCE_ADDR"; |
| case SOURCE_FAMILY: |
| return "SOURCE_FAMILY"; |
| case DEST_PORT: |
| return "DEST_PORT"; |
| case DEST_ADDR: |
| return "DEST_ADDR"; |
| case DEST_FAMILY: |
| return "DEST_FAMILY"; |
| case THROUGHPUT: |
| return "THROUGHPUT"; |
| case LOCAL_SEND_THROUGHPUT: |
| return "LOCAL_SEND_THROUGHPUT"; |
| case LOCAL_RECV_THROUGHPUT: |
| return "LOCAL_RECV_THROUGHPUT"; |
| case REMOTE_SEND_THROUGHPUT: |
| return "REMOTE_SEND_THROUGHPUT"; |
| case REMOTE_RECV_THROUGHPUT: |
| return "REMOTE_RECV_THROUGHPUT"; |
| case THROUGHPUT_UNITS: |
| return "THROUGHPUT_UNITS"; |
| case CONFIDENCE_LEVEL: |
| return "CONFIDENCE_LEVEL"; |
| case CONFIDENCE_INTERVAL: |
| return "CONFIDENCE_INTERVAL"; |
| case CONFIDENCE_ITERATION: |
| return "CONFIDENCE_ITERATION"; |
| case THROUGHPUT_CONFID: |
| return "THROUGHPUT_CONFID"; |
| case LOCAL_CPU_CONFID: |
| return "LOCAL_CPU_CONFID"; |
| case REMOTE_CPU_CONFID: |
| return "REMOTE_CPU_CONFID"; |
| case RT_LATENCY: |
| return "RT_LATENCY"; |
| case TRANSACTION_RATE: |
| return "TRANSACTION_RATE"; |
| case BURST_SIZE: |
| return "BURST_SIZE"; |
| case TRANSPORT_MSS: |
| return "TRANSPORT_MSS"; |
| case REQUEST_SIZE: |
| return "REQUEST_SIZE"; |
| case RESPONSE_SIZE: |
| return "RESPONSE_SIZE"; |
| case LSS_SIZE_REQ: |
| return "LSS_SIZE_REQ"; |
| case LSS_SIZE: |
| return "LSS_SIZE"; |
| case LSS_SIZE_END: |
| return "LSS_SIZE_END"; |
| case LSR_SIZE_REQ: |
| return "LSR_SIZE_REQ"; |
| case LSR_SIZE: |
| return "LSR_SIZE"; |
| case LSR_SIZE_END: |
| return "LSR_SIZE_END"; |
| case LOCAL_SEND_SIZE: |
| return "LOCAL_SEND_SIZE"; |
| case LOCAL_RECV_SIZE: |
| return "LOCAL_RECV_SIZE"; |
| case LOCAL_SEND_CALLS: |
| return "LOCAL_SEND_CALLS"; |
| case LOCAL_RECV_CALLS: |
| return "LOCAL_RECV_CALLS"; |
| case LOCAL_BYTES_PER_RECV: |
| return "LOCAL_BYTES_PER_RECV"; |
| case LOCAL_BYTES_PER_SEND: |
| return "LOCAL_BYTES_PER_SEND"; |
| case LOCAL_BYTES_SENT: |
| return "LOCAL_BYTES_SENT"; |
| case LOCAL_BYTES_RECVD: |
| return "LOCAL_BYTES_RECVD"; |
| case LOCAL_BYTES_XFERD: |
| return "LOCAL_BYTES_XFERD"; |
| case LOCAL_SEND_OFFSET: |
| return "LOCAL_SEND_OFFSET"; |
| case LOCAL_RECV_OFFSET: |
| return "LOCAL_RECV_OFFSET"; |
| case LOCAL_RECV_ALIGN: |
| return "LOCAL_RECV_ALIGN"; |
| case LOCAL_SEND_ALIGN: |
| return "LOCAL_SEND_ALIGN"; |
| case LOCAL_SEND_WIDTH: |
| return "LOCAL_SEND_WIDTH"; |
| case LOCAL_RECV_WIDTH: |
| return "LOCAL_RECV_WIDTH"; |
| case LOCAL_SEND_DIRTY_COUNT: |
| return "LOCAL_SEND_DIRTY_COUNT"; |
| case LOCAL_RECV_DIRTY_COUNT: |
| return "LOCAL_RECV_DIRTY_COUNT"; |
| case LOCAL_RECV_CLEAN_COUNT: |
| return "LOCAL_RECV_CLEAN_COUNT"; |
| case LOCAL_CPU_UTIL: |
| return "LOCAL_CPU_UTIL"; |
| case LOCAL_CPU_BIND: |
| return "LOCAL_CPU_BIND"; |
| case LOCAL_SD: |
| return "LOCAL_SD"; |
| case SD_UNITS: |
| return "SD_UNITS"; |
| case LOCAL_CPU_METHOD: |
| return "LOCAL_CPU_METHOD"; |
| case LOCAL_CPU_COUNT: |
| return "LOCAL_CPU_COUNT"; |
| case LOCAL_CPU_PEAK_UTIL: |
| return "LOCAL_CPU_PEAK_UTIL"; |
| case LOCAL_CPU_PEAK_ID: |
| return "LOCAL_CPU_PEAK_ID"; |
| case LOCAL_NODELAY: |
| return "LOCAL_NODELAY"; |
| case LOCAL_CORK: |
| return "LOCAL_CORK"; |
| case RSS_SIZE_REQ: |
| return "RSS_SIZE_REQ"; |
| case RSS_SIZE: |
| return "RSS_SIZE"; |
| case RSS_SIZE_END: |
| return "RSS_SIZE_END"; |
| case RSR_SIZE_REQ: |
| return "RSR_SIZE_REQ"; |
| case RSR_SIZE: |
| return "RSR_SIZE"; |
| case RSR_SIZE_END: |
| return "RSR_SIZE_END"; |
| case REMOTE_SEND_SIZE: |
| return "REMOTE_SEND_SIZE"; |
| case REMOTE_RECV_SIZE: |
| return "REMOTE_RECV_SIZE"; |
| case REMOTE_SEND_CALLS: |
| return "REMOTE_SEND_CALLS"; |
| case REMOTE_RECV_CALLS: |
| return "REMOTE_RECV_CALLS"; |
| case REMOTE_BYTES_PER_RECV: |
| return "REMOTE_BYTES_PER_RECV"; |
| case REMOTE_BYTES_PER_SEND: |
| return "REMOTE_BYTES_PER_SEND"; |
| case REMOTE_BYTES_SENT: |
| return "REMOTE_BYTES_SENT"; |
| case REMOTE_BYTES_RECVD: |
| return "REMOTE_BYTES_RECVD"; |
| case REMOTE_BYTES_XFERD: |
| return "REMOTE_BYTES_XFERD"; |
| case REMOTE_SEND_OFFSET: |
| return "REMOTE_SEND_OFFSET"; |
| case REMOTE_RECV_OFFSET: |
| return "REMOTE_RECV_OFFSET"; |
| case REMOTE_RECV_ALIGN: |
| return "REMOTE_RECV_ALIGN"; |
| case REMOTE_SEND_ALIGN: |
| return "REMOTE_SEND_ALIGN"; |
| case REMOTE_SEND_WIDTH: |
| return "REMOTE_SEND_WIDTH"; |
| case REMOTE_RECV_WIDTH: |
| return "REMOTE_RECV_WIDTH"; |
| case REMOTE_SEND_DIRTY_COUNT: |
| return "REMOTE_SEND_DIRTY_COUNT"; |
| case REMOTE_RECV_DIRTY_COUNT: |
| return "REMOTE_RECV_DIRTY_COUNT"; |
| case REMOTE_RECV_CLEAN_COUNT: |
| return "REMOTE_RECV_CLEAN_COUNT"; |
| case REMOTE_CPU_UTIL: |
| return "REMOTE_CPU_UTIL"; |
| case REMOTE_CPU_BIND: |
| return "REMOTE_CPU_BIND"; |
| case REMOTE_SD: |
| return "REMOTE_SD"; |
| case REMOTE_CPU_METHOD: |
| return "REMOTE_CPU_METHOD"; |
| case REMOTE_CPU_COUNT: |
| return "REMOTE_CPU_COUNT"; |
| case REMOTE_CPU_PEAK_UTIL: |
| return "REMOTE_CPU_PEAK_UTIL"; |
| case REMOTE_CPU_PEAK_ID: |
| return "REMOTE_CPU_PEAK_ID"; |
| case REMOTE_NODELAY: |
| return "REMOTE_NODELAY"; |
| case REMOTE_CORK: |
| return "REMOTE_CORK"; |
| case LOCAL_INTERFACE_SLOT: |
| return "LOCAL_INTERFACE_SLOT"; |
| case REMOTE_INTERFACE_SLOT: |
| return "REMOTE_INTERFACE_SLOT"; |
| case REMOTE_INTERFACE_SUBDEVICE: |
| return "REMOTE_INTERFACE_SUBDEVICE"; |
| case REMOTE_INTERFACE_SUBVENDOR: |
| return "REMOTE_INTERFACE_SUBVENDOR"; |
| case REMOTE_INTERFACE_DEVICE: |
| return "REMOTE_INTERFACE_DEVICE"; |
| case REMOTE_INTERFACE_VENDOR: |
| return "REMOTE_INTERFACE_VENDOR"; |
| case LOCAL_INTERFACE_SUBDEVICE: |
| return "LOCAL_INTERFACE_SUBDEVICE"; |
| case LOCAL_INTERFACE_SUBVENDOR: |
| return "LOCAL_INTERFACE_SUBVENDOR"; |
| case LOCAL_INTERFACE_DEVICE: |
| return "LOCAL_INTERFACE_DEVICE"; |
| case LOCAL_INTERFACE_VENDOR: |
| return "LOCAL_INTERFACE_VENDOR"; |
| case LOCAL_INTERFACE_NAME: |
| return "LOCAL_INTERFACE_NAME"; |
| case REMOTE_INTERFACE_NAME: |
| return "REMOTE_INTERFACE_NAME"; |
| case REMOTE_DRIVER_NAME: |
| return "REMOTE_DRIVER_NAME"; |
| case REMOTE_DRIVER_VERSION: |
| return "REMOTE_DRIVER_VERSION"; |
| case REMOTE_DRIVER_FIRMWARE: |
| return "REMOTE_DRIVER_FIRMWARE"; |
| case REMOTE_DRIVER_BUS: |
| return "REMOTE_DRIVER_BUS"; |
| case LOCAL_DRIVER_NAME: |
| return "LOCAL_DRIVER_NAME"; |
| case LOCAL_DRIVER_VERSION: |
| return "LOCAL_DRIVER_VERSION"; |
| case LOCAL_DRIVER_FIRMWARE: |
| return "LOCAL_DRIVER_FIRMWARE"; |
| case LOCAL_INTERVAL_USECS: |
| return "LOCAL_INTERVAL_USECS"; |
| case LOCAL_INTERVAL_BURST: |
| return "LOCAL_INTERVAL_BURST"; |
| case REMOTE_INTERVAL_USECS: |
| return "REMOTE_INTERVAL_USECS"; |
| case REMOTE_INTERVAL_BURST: |
| return "REMOTE_INTERVAL_BURST"; |
| case LOCAL_SECURITY_TYPE_ID: |
| return "LOCAL_SECURITY_TYPE_ID"; |
| case LOCAL_SECURITY_ENABLED_NUM: |
| return "LOCAL_SECURITY_ENABLED_NUM"; |
| case LOCAL_SECURITY_TYPE: |
| return "LOCAL_SECURITY_TYPE"; |
| case LOCAL_SECURITY_ENABLED: |
| return "LOCAL_SECURITY_ENABLED"; |
| case LOCAL_SECURITY_SPECIFIC: |
| return "LOCAL_SECURITY_SPECIFIC"; |
| case REMOTE_SECURITY_TYPE_ID: |
| return "REMOTE_SECURITY_TYPE_ID"; |
| case REMOTE_SECURITY_ENABLED_NUM: |
| return "REMOTE_SECURITY_ENABLED_NUM"; |
| case REMOTE_SECURITY_TYPE: |
| return "REMOTE_SECURITY_TYPE"; |
| case REMOTE_SECURITY_ENABLED: |
| return "REMOTE_SECURITY_ENABLED"; |
| case REMOTE_SECURITY_SPECIFIC: |
| return "REMOTE_SECURITY_SPECIFIC"; |
| case LOCAL_DRIVER_BUS: |
| return "LOCAL_DRIVER_BUS"; |
| case REMOTE_SYSNAME: |
| return "REMOTE_SYSNAME"; |
| case REMOTE_MACHINE: |
| return "REMOTE_MACHINE"; |
| case REMOTE_VERSION: |
| return "REMOTE_VERSION"; |
| case REMOTE_RELEASE: |
| return "REMOTE_RELEASE"; |
| case LOCAL_SYSNAME: |
| return "LOCAL_SYSNAME"; |
| case LOCAL_MACHINE: |
| return "LOCAL_MACHINE"; |
| case LOCAL_VERSION: |
| return "LOCAL_VERSION"; |
| case LOCAL_RELEASE: |
| return "LOCAL_RELEASE"; |
| case REMOTE_CPU_MODEL: |
| return "REMOTE_CPU_MODEL"; |
| case REMOTE_CPU_FREQUENCY: |
| return "REMOTE_CPU_FREQUENCY"; |
| case REMOTE_SYSTEM_MODEL: |
| return "REMOTE_SYSTEM_MODEL"; |
| case LOCAL_CPU_MODEL: |
| return "LOCAL_CPU_MODEL"; |
| case LOCAL_CPU_FREQUENCY: |
| return "LOCAL_CPU_FREQUENCY"; |
| case LOCAL_SYSTEM_MODEL: |
| return "LOCAL_SYSTEM_MODEL"; |
| case OUTPUT_END: |
| return "OUTPUT_END"; |
| default: |
| return "!UNKNOWN OUTPUT SELECTOR!"; |
| } |
| } |
| |
| void |
| print_netperf_output_entry(FILE *where, enum netperf_output_name what) |
| { |
| } |
| |
| void print_omni_init_list(); |
| |
| void |
| dump_netperf_output_list(FILE *where, int csv) { |
| int i; |
| |
| print_omni_init_list(); |
| |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++){ |
| if (OUTPUT_NONE != i) { |
| fprintf(where,"%c",(csv) ? ',' : '\n'); |
| } |
| fprintf(where, |
| "%s", |
| netperf_output_enum_to_str(netperf_output_source[i].output_name)); |
| } |
| fprintf(where,"\n"); |
| fflush(where); |
| } |
| |
| void |
| dump_netperf_output_source(FILE *where) |
| { |
| int i; |
| |
| /* belts and suspenders everyone... */ |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { |
| fprintf(where, |
| "Output Name: %s\n", |
| netperf_output_enum_to_str(netperf_output_source[i].output_name)); |
| fprintf(where, |
| "\tmax_line_len %d tot_line_len %d display_value %p\n", |
| netperf_output_source[i].max_line_len, |
| netperf_output_source[i].tot_line_len, |
| netperf_output_source[i].display_value); |
| fprintf(where, |
| "\tline[0]: |%s|\n", |
| (netperf_output_source[i].line[0] == NULL) ? "" : |
| netperf_output_source[i].line[0]); |
| fprintf(where, |
| "\tline[1]: |%s|\n", |
| (netperf_output_source[i].line[1] == NULL) ? "" : |
| netperf_output_source[i].line[1]); |
| fprintf(where, |
| "\tline[2]: |%s|\n", |
| (netperf_output_source[i].line[2] == NULL) ? "" : |
| netperf_output_source[i].line[2]); |
| fprintf(where, |
| "\tline[3]: |%s|\n", |
| (netperf_output_source[i].line[3] == NULL) ? "" : |
| netperf_output_source[i].line[3]); |
| fprintf(where, |
| "\tbrief: |%s|\n", |
| (netperf_output_source[i].brief == NULL) ? "" : |
| netperf_output_source[i].brief); |
| fprintf(where, |
| "\tformat: |%s|\n", |
| (netperf_output_source[i].format == NULL) ? "" : |
| netperf_output_source[i].format); |
| } |
| fflush(where); |
| } |
| |
| #define MY_MAX(a,b) ((a > b) ? a : b) |
| |
| #define NETPERF_LINE_MAX(x) \ |
| MY_MAX(MY_MAX(MY_MAX(strlen(netperf_output_source[x].line[0]),\ |
| strlen(netperf_output_source[x].line[1])),\ |
| strlen(netperf_output_source[x].line[2])),\ |
| strlen(netperf_output_source[x].line[3])) |
| |
| #define NETPERF_LINE_TOT(x) \ |
| strlen(netperf_output_source[x].line[0]) +\ |
| strlen(netperf_output_source[x].line[1]) +\ |
| strlen(netperf_output_source[x].line[2]) +\ |
| strlen(netperf_output_source[x].line[3]) + 4 |
| |
| enum netperf_output_name |
| match_string_to_output(char *candidate) |
| { |
| char *h1,*temp; |
| enum netperf_output_name name; |
| int k,len; |
| |
| /* at some point we may need/want to worry about leading and |
| trailing spaces, but for now we will leave that onus on the |
| user. */ |
| |
| for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) { |
| /* try for a match based on the nmemonic/enum */ |
| if (!strcasecmp(candidate,netperf_output_enum_to_str(name))) |
| return name; |
| |
| /* try for a match on the actual header text */ |
| temp = malloc(NETPERF_LINE_TOT(name)); |
| h1 = temp; |
| if (h1 != NULL) { |
| for (k = 0; ((k < 4) && |
| (NULL != netperf_output_source[name].line[k]) && |
| (strcmp("",netperf_output_source[name].line[k]))); k++) { |
| len = sprintf(h1, |
| "%s", |
| netperf_output_source[name].line[k]); |
| *(h1 + len) = ' '; |
| /* now move to the next starting column. for csv we aren't worried |
| about alignment between the header and the value lines */ |
| h1 += len + 1; |
| } |
| /* this time we want null termination please */ |
| *(h1 - 1) = 0; |
| if (!strcasecmp(candidate,temp)) { |
| free(temp); |
| return name; |
| } |
| else |
| free(temp); |
| } |
| } |
| /* if we get here it means there was no match */ |
| return OUTPUT_NONE; |
| } |
| |
| void |
| parse_output_csv_selection_file(char *selection_file) { |
| FILE *selections; |
| char name[81]; /* best be more than enough */ |
| int namepos; |
| int c; |
| int j; |
| enum netperf_output_name match; |
| int line,column; |
| |
| selections = fopen(selection_file,"r"); |
| if (!selections) { |
| perror("Could Not Open output selection file"); |
| exit(-1); |
| } |
| |
| /* should this really be necessary? */ |
| rewind(selections); |
| |
| line = 0; |
| column = 1; |
| namepos = 0; |
| name[0] = 0; |
| name[80] = 0; |
| j = 0; |
| /* let's allow the csv to turn the four lines of a human readable |
| output file to be used to create a single line csv output file by |
| not worrying about the line count. raj 2008--02-04 */ |
| while ((c = fgetc(selections)) != EOF) { |
| if (namepos == 80) { |
| /* too long */ |
| |
| fprintf(where, |
| "Output selection starting column %d on line %d is too long\n", |
| line + 1, |
| column); |
| fflush(where); |
| exit(-1); |
| } |
| if (c == ',') { |
| /* time to check for a match, but only if we won't overflow the |
| current row of the array */ |
| if (j == NETPERF_OUTPUT_MAX) { |
| fprintf(where,"Too many output selectors on line %d\n",line); |
| fflush(where); |
| exit(-1); |
| } |
| name[namepos] = 0; |
| output_csv_list[j++] = match_string_to_output(name); |
| namepos = 0; |
| } |
| else if (c == '\n') { |
| /* move to the next line after checking for a match */ |
| name[namepos] = 0; |
| output_csv_list[j++] = match_string_to_output(name); |
| line++; |
| namepos = 0; |
| } |
| else if (isprint(c)) { |
| name[namepos++] = c; |
| } |
| column++; |
| } |
| |
| /* ok, do we need/want to do anything here? at present we will |
| silently ignore the rest of the file if we exit the loop on line |
| count */ |
| if ((c == EOF) && (namepos > 0)) { |
| name[namepos] = 0; |
| output_csv_list[j] = match_string_to_output(name); |
| } |
| } |
| void |
| parse_output_human_selection_file(char *selection_file) { |
| FILE *selections; |
| char name[81]; /* best be more than enough */ |
| int namepos; |
| char c; |
| int j; |
| enum netperf_output_name match; |
| int line,column; |
| |
| selections = fopen(selection_file,"r"); |
| if (!selections) { |
| perror("Could Not Open output selection file"); |
| exit(-1); |
| } |
| |
| line = 0; |
| column = 1; |
| namepos = 0; |
| name[0] = 0; |
| name[80] = 0; |
| j = 0; |
| while (((c = fgetc(selections)) != EOF) && (line < 4)) { |
| if (namepos == 80) { |
| /* too long */ |
| |
| fprintf(where, |
| "Output selection starting column %d on line %d is too long\n", |
| line + 1, |
| column); |
| fflush(where); |
| exit(-1); |
| } |
| if (c == ',') { |
| /* time to check for a match, but only if we won't overflow the |
| current row of the array */ |
| if (j == NETPERF_OUTPUT_MAX) { |
| fprintf(where,"Too many output selectors on line %d\n",line); |
| fflush(where); |
| exit(-1); |
| } |
| name[namepos] = 0; |
| output_human_list[line][j++] = match_string_to_output(name); |
| namepos = 0; |
| } |
| else if (c == '\n') { |
| /* move to the next line after checking for a match */ |
| name[namepos] = 0; |
| output_human_list[line++][j++] = match_string_to_output(name); |
| namepos = 0; |
| j = 0; |
| } |
| else if (isprint(c)) { |
| name[namepos++] = c; |
| } |
| column++; |
| } |
| |
| /* ok, do we need/want to do anything here? at present we will |
| silently ignore the rest of the file if we exit the loop on line |
| count */ |
| if ((c == EOF) && (namepos > 0)) { |
| name[namepos] = 0; |
| output_human_list[line][j] = match_string_to_output(name); |
| } |
| |
| } |
| |
| void |
| set_output_csv_list_default() { |
| |
| int i = 0; |
| enum netperf_output_name j; |
| |
| /* this should cause us to catch everything unless someone botches |
| adding an output name to the enum. raj 2008-02-22 */ |
| for (j = SOCKET_TYPE; j < OUTPUT_END; j++) { |
| output_csv_list[i++] = j; |
| } |
| |
| } |
| |
| void |
| set_output_human_list_default() { |
| |
| int i, j; /* line, column */ |
| enum netperf_output_name k; |
| |
| /* Line One SOCKET_TYPE to RESPONSE_SIZE */ |
| i = 0; |
| j = 0; |
| for (k = SOCKET_TYPE; k <= RESPONSE_SIZE; k++) |
| output_human_list[i][j++] = k; |
| |
| /* Line Two LOCAL_CPU_UTIL to TRANSPORT_MSS */ |
| i = 1; |
| j = 0; |
| for (k = LOCAL_CPU_UTIL; k <= TRANSPORT_MSS; k++) |
| output_human_list[i][j++] = k; |
| |
| /* Line Three LOCAL_SEND_THROUGHPUT throught REMOTE_CORK */ |
| i = 2; |
| j = 0; |
| for (k = LOCAL_SEND_THROUGHPUT; k <= REMOTE_CORK; k++) |
| output_human_list[i][j++] = k; |
| |
| /* Line Four LOCAL_SYSNAME through COMMAND_LINE */ |
| i = 3; |
| j = 0; |
| for (k = LOCAL_SYSNAME; k <= COMMAND_LINE; k++) |
| output_human_list[i][j++] = k; |
| |
| } |
| |
| void |
| print_omni_init_list() { |
| |
| int i; |
| |
| /* belts and suspenders everyone... */ |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { |
| netperf_output_source[i].output_name = i; |
| netperf_output_source[i].max_line_len = 0; |
| netperf_output_source[i].tot_line_len = 0; |
| netperf_output_source[i].line[0] = ""; |
| netperf_output_source[i].line[1] = ""; |
| netperf_output_source[i].line[2] = ""; |
| netperf_output_source[i].line[3] = ""; |
| netperf_output_source[i].brief = ""; |
| netperf_output_source[i].format = ""; |
| netperf_output_source[i].display_value = NULL; |
| } |
| |
| netperf_output_source[OUTPUT_NONE].output_name = OUTPUT_NONE; |
| netperf_output_source[OUTPUT_NONE].line[0] = " "; |
| netperf_output_source[OUTPUT_NONE].format = "%s"; |
| netperf_output_source[OUTPUT_NONE].display_value = &" "; |
| netperf_output_source[OUTPUT_NONE].max_line_len = |
| NETPERF_LINE_MAX(OUTPUT_NONE); |
| netperf_output_source[OUTPUT_NONE].tot_line_len = |
| NETPERF_LINE_TOT(OUTPUT_NONE); |
| |
| netperf_output_source[COMMAND_LINE].output_name = COMMAND_LINE; |
| netperf_output_source[COMMAND_LINE].line[0] = "Command"; |
| netperf_output_source[COMMAND_LINE].line[1] = "Line"; |
| netperf_output_source[COMMAND_LINE].format = "\"%s\""; |
| netperf_output_source[COMMAND_LINE].display_value = command_line; |
| netperf_output_source[COMMAND_LINE].max_line_len = |
| NETPERF_LINE_MAX(COMMAND_LINE); |
| netperf_output_source[COMMAND_LINE].tot_line_len = |
| NETPERF_LINE_TOT(COMMAND_LINE); |
| |
| netperf_output_source[UUID].output_name = UUID; |
| netperf_output_source[UUID].line[0] = "Test"; |
| netperf_output_source[UUID].line[1] = "UUID"; |
| netperf_output_source[UUID].format = "%s"; |
| netperf_output_source[UUID].display_value = test_uuid; |
| netperf_output_source[UUID].max_line_len = |
| NETPERF_LINE_MAX(UUID); |
| netperf_output_source[UUID].tot_line_len = |
| NETPERF_LINE_TOT(UUID); |
| |
| netperf_output_source[RESULT_BRAND].output_name = RESULT_BRAND; |
| netperf_output_source[RESULT_BRAND].line[0] = "Result"; |
| netperf_output_source[RESULT_BRAND].line[1] = "Tag"; |
| netperf_output_source[RESULT_BRAND].format = "\"%s\""; |
| netperf_output_source[RESULT_BRAND].display_value = result_brand; |
| netperf_output_source[RESULT_BRAND].max_line_len = |
| NETPERF_LINE_MAX(RESULT_BRAND); |
| netperf_output_source[RESULT_BRAND].tot_line_len = |
| NETPERF_LINE_TOT(RESULT_BRAND); |
| |
| netperf_output_source[SOCKET_TYPE].output_name = SOCKET_TYPE; |
| netperf_output_source[SOCKET_TYPE].line[0] = "Socket"; |
| netperf_output_source[SOCKET_TYPE].line[1] = "Type"; |
| netperf_output_source[SOCKET_TYPE].format = "%s"; |
| netperf_output_source[SOCKET_TYPE].display_value = socket_type_str; |
| netperf_output_source[SOCKET_TYPE].max_line_len = |
| NETPERF_LINE_MAX(SOCKET_TYPE); |
| netperf_output_source[SOCKET_TYPE].tot_line_len = |
| NETPERF_LINE_TOT(SOCKET_TYPE); |
| |
| netperf_output_source[DIRECTION].output_name = DIRECTION; |
| netperf_output_source[DIRECTION].line[0] = "Direction"; |
| netperf_output_source[DIRECTION].line[1] = ""; |
| netperf_output_source[DIRECTION].format = "%s"; |
| netperf_output_source[DIRECTION].display_value = direction_str; |
| netperf_output_source[DIRECTION].max_line_len = |
| NETPERF_LINE_MAX(DIRECTION); |
| netperf_output_source[DIRECTION].tot_line_len = |
| NETPERF_LINE_TOT(DIRECTION); |
| |
| netperf_output_source[PROTOCOL].output_name = PROTOCOL; |
| netperf_output_source[PROTOCOL].line[0] = "Protocol"; |
| netperf_output_source[PROTOCOL].format = "%s"; |
| netperf_output_source[PROTOCOL].display_value = protocol_str; |
| netperf_output_source[PROTOCOL].max_line_len = |
| NETPERF_LINE_MAX(PROTOCOL); |
| netperf_output_source[PROTOCOL].tot_line_len = |
| NETPERF_LINE_TOT(PROTOCOL); |
| |
| netperf_output_source[ELAPSED_TIME].output_name = ELAPSED_TIME; |
| netperf_output_source[ELAPSED_TIME].line[0] = "Elapsed"; |
| netperf_output_source[ELAPSED_TIME].line[1] = "Time"; |
| netperf_output_source[ELAPSED_TIME].line[2] = "(sec)"; |
| netperf_output_source[ELAPSED_TIME].format = "%.2f"; |
| netperf_output_source[ELAPSED_TIME].display_value = &elapsed_time_double; |
| netperf_output_source[ELAPSED_TIME].max_line_len = |
| NETPERF_LINE_MAX(ELAPSED_TIME); |
| netperf_output_source[ELAPSED_TIME].tot_line_len = |
| NETPERF_LINE_TOT(ELAPSED_TIME); |
| |
| netperf_output_source[SOURCE_PORT].output_name = SOURCE_PORT; |
| netperf_output_source[SOURCE_PORT].line[0] = "Source"; |
| netperf_output_source[SOURCE_PORT].line[1] = "Port"; |
| netperf_output_source[SOURCE_PORT].format = "%s"; |
| netperf_output_source[SOURCE_PORT].display_value = local_data_port; |
| netperf_output_source[SOURCE_PORT].max_line_len = |
| NETPERF_LINE_MAX(SOURCE_PORT); |
| netperf_output_source[SOURCE_PORT].tot_line_len = |
| NETPERF_LINE_TOT(SOURCE_PORT); |
| |
| netperf_output_source[SOURCE_ADDR].output_name = SOURCE_ADDR; |
| netperf_output_source[SOURCE_ADDR].line[0] = "Source"; |
| netperf_output_source[SOURCE_ADDR].line[1] = "Address"; |
| netperf_output_source[SOURCE_ADDR].format = "%s"; |
| netperf_output_source[SOURCE_ADDR].display_value = local_data_address; |
| netperf_output_source[SOURCE_ADDR].max_line_len = |
| NETPERF_LINE_MAX(SOURCE_ADDR); |
| netperf_output_source[SOURCE_ADDR].tot_line_len = |
| NETPERF_LINE_TOT(SOURCE_ADDR); |
| |
| netperf_output_source[SOURCE_FAMILY].output_name = SOURCE_FAMILY; |
| netperf_output_source[SOURCE_FAMILY].line[0] = "Source"; |
| netperf_output_source[SOURCE_FAMILY].line[1] = "Family"; |
| netperf_output_source[SOURCE_FAMILY].format = "%d"; |
| netperf_output_source[SOURCE_FAMILY].display_value = &local_data_family; |
| netperf_output_source[SOURCE_FAMILY].max_line_len = |
| NETPERF_LINE_MAX(SOURCE_FAMILY); |
| netperf_output_source[SOURCE_FAMILY].tot_line_len = |
| NETPERF_LINE_TOT(SOURCE_FAMILY); |
| |
| netperf_output_source[DEST_PORT].output_name = DEST_PORT; |
| netperf_output_source[DEST_PORT].line[0] = "Destination"; |
| netperf_output_source[DEST_PORT].line[1] = "Port"; |
| netperf_output_source[DEST_PORT].format = "%s"; |
| netperf_output_source[DEST_PORT].display_value = remote_data_port; |
| netperf_output_source[DEST_PORT].max_line_len = |
| NETPERF_LINE_MAX(DEST_PORT); |
| netperf_output_source[DEST_PORT].tot_line_len = |
| NETPERF_LINE_TOT(DEST_PORT); |
| |
| netperf_output_source[DEST_ADDR].output_name = DEST_ADDR; |
| netperf_output_source[DEST_ADDR].line[0] = "Destination"; |
| netperf_output_source[DEST_ADDR].line[1] = "Address"; |
| netperf_output_source[DEST_ADDR].format = "%s"; |
| netperf_output_source[DEST_ADDR].display_value = remote_data_address; |
| netperf_output_source[DEST_ADDR].max_line_len = |
| NETPERF_LINE_MAX(DEST_ADDR); |
| netperf_output_source[DEST_ADDR].tot_line_len = |
| NETPERF_LINE_TOT(DEST_ADDR); |
| |
| netperf_output_source[DEST_FAMILY].output_name = DEST_FAMILY; |
| netperf_output_source[DEST_FAMILY].line[0] = "Destination"; |
| netperf_output_source[DEST_FAMILY].line[1] = "Family"; |
| netperf_output_source[DEST_FAMILY].format = "%d"; |
| netperf_output_source[DEST_FAMILY].display_value = &remote_data_family; |
| netperf_output_source[DEST_FAMILY].max_line_len = |
| NETPERF_LINE_MAX(DEST_FAMILY); |
| netperf_output_source[DEST_FAMILY].tot_line_len = |
| NETPERF_LINE_TOT(DEST_FAMILY); |
| |
| netperf_output_source[THROUGHPUT].output_name = THROUGHPUT; |
| netperf_output_source[THROUGHPUT].line[0] = "Throughput"; |
| netperf_output_source[THROUGHPUT].line[1] = ""; |
| netperf_output_source[THROUGHPUT].format = "%.2f"; |
| netperf_output_source[THROUGHPUT].display_value = &thruput; |
| netperf_output_source[THROUGHPUT].max_line_len = |
| NETPERF_LINE_MAX(THROUGHPUT); |
| netperf_output_source[THROUGHPUT].tot_line_len = |
| NETPERF_LINE_TOT(THROUGHPUT); |
| |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].output_name = LOCAL_SEND_THROUGHPUT; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].line[2] = "Throughput"; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].format = "%.2f"; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].display_value = &local_send_thruput; |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_THROUGHPUT); |
| netperf_output_source[LOCAL_SEND_THROUGHPUT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_THROUGHPUT); |
| |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].output_name = LOCAL_RECV_THROUGHPUT; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].line[2] = "Throughput"; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].format = "%.2f"; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].display_value = &local_recv_thruput; |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_THROUGHPUT); |
| netperf_output_source[LOCAL_RECV_THROUGHPUT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_THROUGHPUT); |
| |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].output_name = REMOTE_SEND_THROUGHPUT; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].line[2] = "Throughput"; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].format = "%.2f"; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].display_value = &remote_send_thruput; |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_THROUGHPUT); |
| netperf_output_source[REMOTE_SEND_THROUGHPUT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_THROUGHPUT); |
| |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].output_name = REMOTE_RECV_THROUGHPUT; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].line[2] = "Throughput"; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].format = "%.2f"; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].display_value = &remote_recv_thruput; |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_THROUGHPUT); |
| netperf_output_source[REMOTE_RECV_THROUGHPUT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_THROUGHPUT); |
| |
| netperf_output_source[THROUGHPUT_UNITS].output_name = THROUGHPUT_UNITS; |
| netperf_output_source[THROUGHPUT_UNITS].line[0] = "Throughput"; |
| netperf_output_source[THROUGHPUT_UNITS].line[1] = "Units"; |
| netperf_output_source[THROUGHPUT_UNITS].format = "%s/s"; |
| netperf_output_source[THROUGHPUT_UNITS].display_value = thruput_format_str; |
| netperf_output_source[THROUGHPUT_UNITS].max_line_len = |
| NETPERF_LINE_MAX(THROUGHPUT_UNITS); |
| netperf_output_source[THROUGHPUT_UNITS].tot_line_len = |
| NETPERF_LINE_TOT(THROUGHPUT_UNITS); |
| |
| netperf_output_source[CONFIDENCE_LEVEL].output_name = CONFIDENCE_LEVEL; |
| netperf_output_source[CONFIDENCE_LEVEL].line[0] = "Confidence"; |
| netperf_output_source[CONFIDENCE_LEVEL].line[1] = "Level"; |
| netperf_output_source[CONFIDENCE_LEVEL].line[2] = "Percent"; |
| netperf_output_source[CONFIDENCE_LEVEL].format = "%d"; |
| netperf_output_source[CONFIDENCE_LEVEL].display_value = &confidence_level; |
| netperf_output_source[CONFIDENCE_LEVEL].max_line_len = |
| NETPERF_LINE_MAX(CONFIDENCE_LEVEL); |
| netperf_output_source[CONFIDENCE_LEVEL].tot_line_len = |
| NETPERF_LINE_TOT(CONFIDENCE_LEVEL); |
| |
| netperf_output_source[CONFIDENCE_INTERVAL].output_name = CONFIDENCE_INTERVAL; |
| netperf_output_source[CONFIDENCE_INTERVAL].line[0] = "Confidence"; |
| netperf_output_source[CONFIDENCE_INTERVAL].line[1] = "Width"; |
| netperf_output_source[CONFIDENCE_INTERVAL].line[2] = "Target"; |
| netperf_output_source[CONFIDENCE_INTERVAL].format = "%f"; |
| netperf_output_source[CONFIDENCE_INTERVAL].display_value = &interval_pct; |
| netperf_output_source[CONFIDENCE_INTERVAL].max_line_len = |
| NETPERF_LINE_MAX(CONFIDENCE_INTERVAL); |
| netperf_output_source[CONFIDENCE_INTERVAL].tot_line_len = |
| NETPERF_LINE_TOT(CONFIDENCE_INTERVAL); |
| |
| netperf_output_source[CONFIDENCE_ITERATION].output_name = CONFIDENCE_ITERATION; |
| netperf_output_source[CONFIDENCE_ITERATION].line[0] = "Confidence"; |
| netperf_output_source[CONFIDENCE_ITERATION].line[1] = "Iterations"; |
| netperf_output_source[CONFIDENCE_ITERATION].line[2] = "Run"; |
| netperf_output_source[CONFIDENCE_ITERATION].format = "%d"; |
| netperf_output_source[CONFIDENCE_ITERATION].display_value = &confidence_iteration; |
| netperf_output_source[CONFIDENCE_ITERATION].max_line_len = |
| NETPERF_LINE_MAX(CONFIDENCE_ITERATION); |
| netperf_output_source[CONFIDENCE_ITERATION].tot_line_len = |
| NETPERF_LINE_TOT(CONFIDENCE_ITERATION); |
| |
| netperf_output_source[THROUGHPUT_CONFID].output_name = THROUGHPUT_CONFID; |
| netperf_output_source[THROUGHPUT_CONFID].line[0] = "Throughput"; |
| netperf_output_source[THROUGHPUT_CONFID].line[1] = "Confidence"; |
| netperf_output_source[THROUGHPUT_CONFID].line[2] = "Width (%)"; |
| netperf_output_source[THROUGHPUT_CONFID].format = "%.3f"; |
| netperf_output_source[THROUGHPUT_CONFID].display_value = &result_confid_pct; |
| netperf_output_source[THROUGHPUT_CONFID].max_line_len = |
| NETPERF_LINE_MAX(THROUGHPUT_CONFID); |
| netperf_output_source[THROUGHPUT_CONFID].tot_line_len = |
| NETPERF_LINE_TOT(THROUGHPUT_CONFID); |
| |
| netperf_output_source[LOCAL_CPU_CONFID].output_name = LOCAL_CPU_CONFID; |
| netperf_output_source[LOCAL_CPU_CONFID].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_CONFID].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_CONFID].line[2] = "Confidence"; |
| netperf_output_source[LOCAL_CPU_CONFID].line[3] = "Width (%)"; |
| netperf_output_source[LOCAL_CPU_CONFID].format = "%.3f"; |
| netperf_output_source[LOCAL_CPU_CONFID].display_value = &loc_cpu_confid_pct; |
| netperf_output_source[LOCAL_CPU_CONFID].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_CONFID); |
| netperf_output_source[LOCAL_CPU_CONFID].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_CONFID); |
| |
| netperf_output_source[REMOTE_CPU_CONFID].output_name = REMOTE_CPU_CONFID; |
| netperf_output_source[REMOTE_CPU_CONFID].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_CONFID].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_CONFID].line[2] = "Confidence"; |
| netperf_output_source[REMOTE_CPU_CONFID].line[3] = "Width (%)"; |
| netperf_output_source[REMOTE_CPU_CONFID].format = "%.3f"; |
| netperf_output_source[REMOTE_CPU_CONFID].display_value = &rem_cpu_confid_pct; |
| netperf_output_source[REMOTE_CPU_CONFID].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_CONFID); |
| netperf_output_source[REMOTE_CPU_CONFID].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_CONFID); |
| |
| netperf_output_source[RT_LATENCY].output_name = RT_LATENCY; |
| netperf_output_source[RT_LATENCY].line[0] = "Round"; |
| netperf_output_source[RT_LATENCY].line[1] = "Trip"; |
| netperf_output_source[RT_LATENCY].line[2] = "Latency"; |
| netperf_output_source[RT_LATENCY].line[3] = "usec/tran"; |
| netperf_output_source[RT_LATENCY].format = "%.3f"; |
| netperf_output_source[RT_LATENCY].display_value = &rtt_latency; |
| netperf_output_source[RT_LATENCY].max_line_len = |
| NETPERF_LINE_MAX(RT_LATENCY); |
| netperf_output_source[RT_LATENCY].tot_line_len = |
| NETPERF_LINE_TOT(RT_LATENCY); |
| |
| netperf_output_source[TRANSACTION_RATE].output_name = TRANSACTION_RATE; |
| netperf_output_source[TRANSACTION_RATE].line[0] = "Transaction"; |
| netperf_output_source[TRANSACTION_RATE].line[1] = "Rate"; |
| netperf_output_source[TRANSACTION_RATE].line[2] = "Tran/s"; |
| netperf_output_source[TRANSACTION_RATE].format = "%.3f"; |
| netperf_output_source[TRANSACTION_RATE].display_value = &transaction_rate; |
| netperf_output_source[TRANSACTION_RATE].max_line_len = |
| NETPERF_LINE_MAX(TRANSACTION_RATE); |
| netperf_output_source[TRANSACTION_RATE].tot_line_len = |
| NETPERF_LINE_TOT(TRANSACTION_RATE); |
| |
| netperf_output_source[TRANSPORT_MSS].output_name = TRANSPORT_MSS; |
| netperf_output_source[TRANSPORT_MSS].line[0] = "Transport"; |
| netperf_output_source[TRANSPORT_MSS].line[1] = "MSS"; |
| netperf_output_source[TRANSPORT_MSS].line[2] = "bytes"; |
| netperf_output_source[TRANSPORT_MSS].format = "%d"; |
| netperf_output_source[TRANSPORT_MSS].display_value = &transport_mss; |
| netperf_output_source[TRANSPORT_MSS].max_line_len = |
| NETPERF_LINE_MAX(TRANSPORT_MSS); |
| netperf_output_source[TRANSPORT_MSS].tot_line_len = |
| NETPERF_LINE_TOT(TRANSPORT_MSS); |
| |
| netperf_output_source[REQUEST_SIZE].output_name = REQUEST_SIZE; |
| netperf_output_source[REQUEST_SIZE].line[0] = "Request"; |
| netperf_output_source[REQUEST_SIZE].line[1] = "Size"; |
| netperf_output_source[REQUEST_SIZE].line[2] = "Bytes"; |
| netperf_output_source[REQUEST_SIZE].format = "%d"; |
| netperf_output_source[REQUEST_SIZE].display_value = &req_size; |
| netperf_output_source[REQUEST_SIZE].max_line_len = |
| NETPERF_LINE_MAX(REQUEST_SIZE); |
| netperf_output_source[REQUEST_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(REQUEST_SIZE); |
| |
| netperf_output_source[RESPONSE_SIZE].output_name = RESPONSE_SIZE; |
| netperf_output_source[RESPONSE_SIZE].line[0] = "Response"; |
| netperf_output_source[RESPONSE_SIZE].line[1] = "Size"; |
| netperf_output_source[RESPONSE_SIZE].line[2] = "Bytes"; |
| netperf_output_source[RESPONSE_SIZE].format = "%d"; |
| netperf_output_source[RESPONSE_SIZE].display_value = &rsp_size; |
| netperf_output_source[RESPONSE_SIZE].max_line_len = |
| NETPERF_LINE_MAX(RESPONSE_SIZE); |
| netperf_output_source[RESPONSE_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(RESPONSE_SIZE); |
| |
| netperf_output_source[BURST_SIZE].output_name = BURST_SIZE; |
| netperf_output_source[BURST_SIZE].line[0] = "Initial"; |
| netperf_output_source[BURST_SIZE].line[1] = "Burst"; |
| netperf_output_source[BURST_SIZE].line[2] = "Requests"; |
| netperf_output_source[BURST_SIZE].format = "%d"; |
| netperf_output_source[BURST_SIZE].display_value = &first_burst_size; |
| netperf_output_source[BURST_SIZE].max_line_len = |
| NETPERF_LINE_MAX(BURST_SIZE); |
| netperf_output_source[BURST_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(BURST_SIZE); |
| |
| netperf_output_source[LSS_SIZE_REQ].output_name = LSS_SIZE_REQ; |
| netperf_output_source[LSS_SIZE_REQ].line[0] = "Local"; |
| netperf_output_source[LSS_SIZE_REQ].line[1] = "Send Socket"; |
| netperf_output_source[LSS_SIZE_REQ].line[2] = "Size"; |
| netperf_output_source[LSS_SIZE_REQ].line[3] = "Requested"; |
| netperf_output_source[LSS_SIZE_REQ].format = "%d"; |
| netperf_output_source[LSS_SIZE_REQ].display_value = &lss_size_req; |
| netperf_output_source[LSS_SIZE_REQ].max_line_len = |
| NETPERF_LINE_MAX(LSS_SIZE_REQ); |
| netperf_output_source[LSS_SIZE_REQ].tot_line_len = |
| NETPERF_LINE_TOT(LSS_SIZE_REQ); |
| |
| netperf_output_source[LSS_SIZE].output_name = LSS_SIZE; |
| netperf_output_source[LSS_SIZE].line[0] = "Local"; |
| netperf_output_source[LSS_SIZE].line[1] = "Send Socket"; |
| netperf_output_source[LSS_SIZE].line[2] = "Size"; |
| netperf_output_source[LSS_SIZE].line[3] = "Initial"; |
| netperf_output_source[LSS_SIZE].format = "%d"; |
| netperf_output_source[LSS_SIZE].display_value = &lss_size; |
| netperf_output_source[LSS_SIZE].max_line_len = |
| NETPERF_LINE_MAX(LSS_SIZE); |
| netperf_output_source[LSS_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(LSS_SIZE); |
| |
| netperf_output_source[LSS_SIZE_END].output_name = LSS_SIZE_END; |
| netperf_output_source[LSS_SIZE_END].line[0] = "Local"; |
| netperf_output_source[LSS_SIZE_END].line[1] = "Send Socket"; |
| netperf_output_source[LSS_SIZE_END].line[2] = "Size"; |
| netperf_output_source[LSS_SIZE_END].line[3] = "Final"; |
| netperf_output_source[LSS_SIZE_END].format = "%d"; |
| netperf_output_source[LSS_SIZE_END].display_value = &lss_size_end; |
| netperf_output_source[LSS_SIZE_END].max_line_len = |
| NETPERF_LINE_MAX(LSS_SIZE_END); |
| netperf_output_source[LSS_SIZE_END].tot_line_len = |
| NETPERF_LINE_TOT(LSS_SIZE_END); |
| |
| netperf_output_source[LSR_SIZE_REQ].output_name = LSR_SIZE_REQ; |
| netperf_output_source[LSR_SIZE_REQ].line[0] = "Local"; |
| netperf_output_source[LSR_SIZE_REQ].line[1] = "Recv Socket"; |
| netperf_output_source[LSR_SIZE_REQ].line[2] = "Size"; |
| netperf_output_source[LSR_SIZE_REQ].line[3] = "Requested"; |
| netperf_output_source[LSR_SIZE_REQ].format = "%d"; |
| netperf_output_source[LSR_SIZE_REQ].display_value = &lsr_size_req; |
| netperf_output_source[LSR_SIZE_REQ].max_line_len = |
| NETPERF_LINE_MAX(LSR_SIZE_REQ); |
| netperf_output_source[LSR_SIZE_REQ].tot_line_len = |
| NETPERF_LINE_TOT(LSR_SIZE_REQ); |
| |
| netperf_output_source[LSR_SIZE].output_name = LSR_SIZE; |
| netperf_output_source[LSR_SIZE].line[0] = "Local"; |
| netperf_output_source[LSR_SIZE].line[1] = "Recv Socket"; |
| netperf_output_source[LSR_SIZE].line[2] = "Size"; |
| netperf_output_source[LSR_SIZE].line[3] = "Initial"; |
| netperf_output_source[LSR_SIZE].format = "%d"; |
| netperf_output_source[LSR_SIZE].display_value = &lsr_size; |
| netperf_output_source[LSR_SIZE].max_line_len = |
| NETPERF_LINE_MAX(LSR_SIZE); |
| netperf_output_source[LSR_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(LSR_SIZE); |
| |
| netperf_output_source[LSR_SIZE_END].output_name = LSR_SIZE_END; |
| netperf_output_source[LSR_SIZE_END].line[0] = "Local"; |
| netperf_output_source[LSR_SIZE_END].line[1] = "Recv Socket"; |
| netperf_output_source[LSR_SIZE_END].line[2] = "Size"; |
| netperf_output_source[LSR_SIZE_END].line[3] = "Final"; |
| netperf_output_source[LSR_SIZE_END].format = "%d"; |
| netperf_output_source[LSR_SIZE_END].display_value = &lsr_size_end; |
| netperf_output_source[LSR_SIZE_END].max_line_len = |
| NETPERF_LINE_MAX(LSR_SIZE_END); |
| netperf_output_source[LSR_SIZE_END].tot_line_len = |
| NETPERF_LINE_TOT(LSR_SIZE_END); |
| |
| netperf_output_source[LOCAL_SEND_SIZE].output_name = LOCAL_SEND_SIZE; |
| netperf_output_source[LOCAL_SEND_SIZE].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_SIZE].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_SIZE].line[2] = "Size"; |
| netperf_output_source[LOCAL_SEND_SIZE].line[3] = ""; |
| netperf_output_source[LOCAL_SEND_SIZE].format = "%d"; |
| netperf_output_source[LOCAL_SEND_SIZE].display_value = &send_size; |
| netperf_output_source[LOCAL_SEND_SIZE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_SIZE); |
| netperf_output_source[LOCAL_SEND_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_SIZE); |
| |
| netperf_output_source[LOCAL_RECV_SIZE].output_name = LOCAL_RECV_SIZE; |
| netperf_output_source[LOCAL_RECV_SIZE].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_SIZE].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_SIZE].line[2] = "Size"; |
| netperf_output_source[LOCAL_RECV_SIZE].line[3] = ""; |
| netperf_output_source[LOCAL_RECV_SIZE].format = "%d"; |
| netperf_output_source[LOCAL_RECV_SIZE].display_value = &recv_size; |
| netperf_output_source[LOCAL_RECV_SIZE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_SIZE); |
| netperf_output_source[LOCAL_RECV_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_SIZE); |
| |
| netperf_output_source[LOCAL_SEND_CALLS].output_name = LOCAL_SEND_CALLS; |
| netperf_output_source[LOCAL_SEND_CALLS].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_CALLS].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_CALLS].line[2] = "Calls"; |
| netperf_output_source[LOCAL_SEND_CALLS].line[3] = ""; |
| netperf_output_source[LOCAL_SEND_CALLS].format = "%d"; |
| netperf_output_source[LOCAL_SEND_CALLS].display_value = &local_send_calls; |
| netperf_output_source[LOCAL_SEND_CALLS].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_CALLS); |
| netperf_output_source[LOCAL_SEND_CALLS].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_CALLS); |
| |
| netperf_output_source[LOCAL_RECV_CALLS].output_name = LOCAL_RECV_CALLS; |
| netperf_output_source[LOCAL_RECV_CALLS].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_CALLS].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_CALLS].line[2] = "Calls"; |
| netperf_output_source[LOCAL_RECV_CALLS].line[3] = ""; |
| netperf_output_source[LOCAL_RECV_CALLS].format = "%d"; |
| netperf_output_source[LOCAL_RECV_CALLS].display_value = &local_receive_calls; |
| netperf_output_source[LOCAL_RECV_CALLS].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_CALLS); |
| netperf_output_source[LOCAL_RECV_CALLS].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_CALLS); |
| |
| netperf_output_source[LOCAL_BYTES_PER_RECV].output_name = LOCAL_BYTES_PER_RECV; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].line[0] = "Local"; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].line[1] = "Bytes"; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].line[2] = "Per"; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].line[3] = "Recv"; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].format = "%.2f"; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].display_value = &bytes_per_recv; |
| netperf_output_source[LOCAL_BYTES_PER_RECV].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_BYTES_PER_RECV); |
| netperf_output_source[LOCAL_BYTES_PER_RECV].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_BYTES_PER_RECV); |
| |
| netperf_output_source[LOCAL_BYTES_PER_SEND].output_name = LOCAL_BYTES_PER_SEND; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].line[0] = "Local"; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].line[1] = "Bytes"; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].line[2] = "Per"; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].line[3] = "Send"; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].format = "%.2f"; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].display_value = &bytes_per_send; |
| netperf_output_source[LOCAL_BYTES_PER_SEND].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_BYTES_PER_SEND); |
| netperf_output_source[LOCAL_BYTES_PER_SEND].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_BYTES_PER_SEND); |
| |
| netperf_output_source[LOCAL_BYTES_RECVD].output_name = LOCAL_BYTES_RECVD; |
| netperf_output_source[LOCAL_BYTES_RECVD].line[0] = "Local"; |
| netperf_output_source[LOCAL_BYTES_RECVD].line[1] = "Bytes"; |
| netperf_output_source[LOCAL_BYTES_RECVD].line[2] = "Received"; |
| netperf_output_source[LOCAL_BYTES_RECVD].line[3] = ""; |
| netperf_output_source[LOCAL_BYTES_RECVD].format = "%lld"; |
| netperf_output_source[LOCAL_BYTES_RECVD].display_value = &bytes_received; |
| netperf_output_source[LOCAL_BYTES_RECVD].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_BYTES_RECVD); |
| netperf_output_source[LOCAL_BYTES_RECVD].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_BYTES_RECVD); |
| |
| netperf_output_source[LOCAL_BYTES_SENT].output_name = LOCAL_BYTES_SENT; |
| netperf_output_source[LOCAL_BYTES_SENT].line[0] = "Local"; |
| netperf_output_source[LOCAL_BYTES_SENT].line[1] = "Bytes"; |
| netperf_output_source[LOCAL_BYTES_SENT].line[2] = "Sent"; |
| netperf_output_source[LOCAL_BYTES_SENT].line[3] = ""; |
| netperf_output_source[LOCAL_BYTES_SENT].format = "%lld"; |
| netperf_output_source[LOCAL_BYTES_SENT].display_value = &bytes_sent; |
| netperf_output_source[LOCAL_BYTES_SENT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_BYTES_SENT); |
| netperf_output_source[LOCAL_BYTES_SENT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_BYTES_SENT); |
| |
| netperf_output_source[LOCAL_BYTES_XFERD].output_name = LOCAL_BYTES_XFERD; |
| netperf_output_source[LOCAL_BYTES_XFERD].line[0] = "Local"; |
| netperf_output_source[LOCAL_BYTES_XFERD].line[1] = "Bytes"; |
| netperf_output_source[LOCAL_BYTES_XFERD].line[2] = "Xferred"; |
| netperf_output_source[LOCAL_BYTES_XFERD].line[3] = ""; |
| netperf_output_source[LOCAL_BYTES_XFERD].format = "%.0f"; |
| netperf_output_source[LOCAL_BYTES_XFERD].display_value = &bytes_xferd; |
| netperf_output_source[LOCAL_BYTES_XFERD].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_BYTES_XFERD); |
| netperf_output_source[LOCAL_BYTES_XFERD].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_BYTES_XFERD); |
| |
| netperf_output_source[LOCAL_SEND_WIDTH].output_name = LOCAL_SEND_WIDTH; |
| netperf_output_source[LOCAL_SEND_WIDTH].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_WIDTH].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_WIDTH].line[2] = "Width"; |
| netperf_output_source[LOCAL_SEND_WIDTH].format = "%d"; |
| netperf_output_source[LOCAL_SEND_WIDTH].display_value = &send_width; |
| netperf_output_source[LOCAL_SEND_WIDTH].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_WIDTH); |
| netperf_output_source[LOCAL_SEND_WIDTH].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_WIDTH); |
| |
| netperf_output_source[LOCAL_RECV_WIDTH].output_name = LOCAL_RECV_WIDTH; |
| netperf_output_source[LOCAL_RECV_WIDTH].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_WIDTH].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_WIDTH].line[2] = "Width"; |
| netperf_output_source[LOCAL_RECV_WIDTH].format = "%d"; |
| netperf_output_source[LOCAL_RECV_WIDTH].display_value = &recv_width; |
| netperf_output_source[LOCAL_RECV_WIDTH].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_WIDTH); |
| netperf_output_source[LOCAL_RECV_WIDTH].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_WIDTH); |
| |
| netperf_output_source[LOCAL_SEND_OFFSET].output_name = LOCAL_SEND_OFFSET; |
| netperf_output_source[LOCAL_SEND_OFFSET].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_OFFSET].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_OFFSET].line[2] = "Offset"; |
| netperf_output_source[LOCAL_SEND_OFFSET].format = "%d"; |
| netperf_output_source[LOCAL_SEND_OFFSET].display_value = &local_send_offset; |
| netperf_output_source[LOCAL_SEND_OFFSET].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_OFFSET); |
| netperf_output_source[LOCAL_SEND_OFFSET].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_OFFSET); |
| |
| netperf_output_source[LOCAL_RECV_OFFSET].output_name = LOCAL_RECV_OFFSET; |
| netperf_output_source[LOCAL_RECV_OFFSET].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_OFFSET].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_OFFSET].line[2] = "Offset"; |
| netperf_output_source[LOCAL_RECV_OFFSET].format = "%d"; |
| netperf_output_source[LOCAL_RECV_OFFSET].display_value = &local_recv_offset; |
| netperf_output_source[LOCAL_RECV_OFFSET].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_OFFSET); |
| netperf_output_source[LOCAL_RECV_OFFSET].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_OFFSET); |
| |
| netperf_output_source[LOCAL_RECV_ALIGN].output_name = LOCAL_RECV_ALIGN; |
| netperf_output_source[LOCAL_RECV_ALIGN].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_ALIGN].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_ALIGN].line[2] = "Alignment"; |
| netperf_output_source[LOCAL_RECV_ALIGN].format = "%d"; |
| netperf_output_source[LOCAL_RECV_ALIGN].display_value = &local_recv_align; |
| netperf_output_source[LOCAL_RECV_ALIGN].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_ALIGN); |
| netperf_output_source[LOCAL_RECV_ALIGN].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_ALIGN); |
| |
| netperf_output_source[LOCAL_SEND_ALIGN].output_name = LOCAL_SEND_ALIGN; |
| netperf_output_source[LOCAL_SEND_ALIGN].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_ALIGN].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_ALIGN].line[2] = "Alignment"; |
| netperf_output_source[LOCAL_SEND_ALIGN].format = "%d"; |
| netperf_output_source[LOCAL_SEND_ALIGN].display_value = &local_send_align; |
| netperf_output_source[LOCAL_SEND_ALIGN].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_ALIGN); |
| netperf_output_source[LOCAL_SEND_ALIGN].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_ALIGN); |
| |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].output_name = LOCAL_SEND_DIRTY_COUNT; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[0] = "Local"; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[1] = "Send"; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[2] = "Dirty"; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].line[3] = "Count"; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].format = "%d"; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].display_value = &loc_dirty_count; |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SEND_DIRTY_COUNT); |
| netperf_output_source[LOCAL_SEND_DIRTY_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SEND_DIRTY_COUNT); |
| |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].output_name = LOCAL_RECV_DIRTY_COUNT; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[2] = "Dirty"; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].line[3] = "Count"; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].format = "%d"; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].display_value = &loc_dirty_count; |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_DIRTY_COUNT); |
| netperf_output_source[LOCAL_RECV_DIRTY_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_DIRTY_COUNT); |
| |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].output_name = LOCAL_RECV_CLEAN_COUNT; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[0] = "Local"; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[1] = "Recv"; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[2] = "Clean"; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].line[3] = "Count"; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].format = "%d"; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].display_value = &loc_clean_count; |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RECV_CLEAN_COUNT); |
| netperf_output_source[LOCAL_RECV_CLEAN_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RECV_CLEAN_COUNT); |
| |
| netperf_output_source[LOCAL_CPU_UTIL].output_name = LOCAL_CPU_UTIL; |
| netperf_output_source[LOCAL_CPU_UTIL].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_UTIL].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_UTIL].line[2] = "Util"; |
| netperf_output_source[LOCAL_CPU_UTIL].line[3] = "%"; |
| netperf_output_source[LOCAL_CPU_UTIL].format = "%.2f"; |
| netperf_output_source[LOCAL_CPU_UTIL].display_value = &local_cpu_utilization_double; |
| netperf_output_source[LOCAL_CPU_UTIL].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_UTIL); |
| netperf_output_source[LOCAL_CPU_UTIL].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_UTIL); |
| |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].output_name = LOCAL_CPU_PEAK_UTIL; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[1] = "Peak"; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[2] = "Per CPU"; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].line[3] = "Util %"; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].format = "%.2f"; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].display_value = &lib_local_peak_cpu_util; |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_PEAK_UTIL); |
| netperf_output_source[LOCAL_CPU_PEAK_UTIL].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_PEAK_UTIL); |
| |
| netperf_output_source[LOCAL_CPU_PEAK_ID].output_name = LOCAL_CPU_PEAK_ID; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].line[1] = "Peak"; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].line[2] = "Per CPU"; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].line[3] = "ID"; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].format = "%d"; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].display_value = &lib_local_peak_cpu_id; |
| netperf_output_source[LOCAL_CPU_PEAK_ID].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_PEAK_ID); |
| netperf_output_source[LOCAL_CPU_PEAK_ID].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_PEAK_ID); |
| |
| netperf_output_source[LOCAL_CPU_BIND].output_name = LOCAL_CPU_BIND; |
| netperf_output_source[LOCAL_CPU_BIND].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_BIND].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_BIND].line[2] = "Bind"; |
| netperf_output_source[LOCAL_CPU_BIND].line[3] = ""; |
| netperf_output_source[LOCAL_CPU_BIND].format = "%d"; |
| netperf_output_source[LOCAL_CPU_BIND].display_value = &local_proc_affinity; |
| netperf_output_source[LOCAL_CPU_BIND].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_BIND); |
| netperf_output_source[LOCAL_CPU_BIND].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_BIND); |
| |
| netperf_output_source[LOCAL_SD].output_name = LOCAL_SD; |
| netperf_output_source[LOCAL_SD].line[0] = "Local"; |
| netperf_output_source[LOCAL_SD].line[1] = "Service"; |
| netperf_output_source[LOCAL_SD].line[2] = "Demand"; |
| netperf_output_source[LOCAL_SD].line[3] = ""; |
| netperf_output_source[LOCAL_SD].format = "%.3f"; |
| netperf_output_source[LOCAL_SD].display_value = &local_service_demand_double; |
| netperf_output_source[LOCAL_SD].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SD); |
| netperf_output_source[LOCAL_SD].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SD); |
| |
| netperf_output_source[SD_UNITS].output_name = SD_UNITS; |
| netperf_output_source[SD_UNITS].line[0] = "Service"; |
| netperf_output_source[SD_UNITS].line[1] = "Demand"; |
| netperf_output_source[SD_UNITS].line[2] = "Units"; |
| netperf_output_source[SD_UNITS].format = "%s"; |
| netperf_output_source[SD_UNITS].display_value = sd_str; |
| netperf_output_source[SD_UNITS].max_line_len = |
| NETPERF_LINE_MAX(SD_UNITS); |
| netperf_output_source[SD_UNITS].tot_line_len = |
| NETPERF_LINE_TOT(SD_UNITS); |
| |
| netperf_output_source[LOCAL_CPU_METHOD].output_name = LOCAL_CPU_METHOD; |
| netperf_output_source[LOCAL_CPU_METHOD].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_METHOD].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_METHOD].line[2] = "Util"; |
| netperf_output_source[LOCAL_CPU_METHOD].line[3] = "Method"; |
| netperf_output_source[LOCAL_CPU_METHOD].format = "%c"; |
| netperf_output_source[LOCAL_CPU_METHOD].display_value = &local_cpu_method; |
| netperf_output_source[LOCAL_CPU_METHOD].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_METHOD); |
| netperf_output_source[LOCAL_CPU_METHOD].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_METHOD); |
| |
| netperf_output_source[LOCAL_CPU_COUNT].output_name = LOCAL_CPU_COUNT; |
| netperf_output_source[LOCAL_CPU_COUNT].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_COUNT].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_COUNT].line[2] = "Count"; |
| netperf_output_source[LOCAL_CPU_COUNT].format = "%d"; |
| netperf_output_source[LOCAL_CPU_COUNT].display_value = &lib_num_loc_cpus; |
| netperf_output_source[LOCAL_CPU_COUNT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_COUNT); |
| netperf_output_source[LOCAL_CPU_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_COUNT); |
| |
| netperf_output_source[LOCAL_NODELAY].output_name = LOCAL_NODELAY; |
| netperf_output_source[LOCAL_NODELAY].line[0] = "Local"; |
| netperf_output_source[LOCAL_NODELAY].line[1] = "NODELAY"; |
| netperf_output_source[LOCAL_NODELAY].line[2] = ""; |
| netperf_output_source[LOCAL_NODELAY].line[3] = ""; |
| netperf_output_source[LOCAL_NODELAY].format = "%d"; |
| netperf_output_source[LOCAL_NODELAY].display_value = &loc_nodelay; |
| netperf_output_source[LOCAL_NODELAY].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_NODELAY); |
| netperf_output_source[LOCAL_NODELAY].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_NODELAY); |
| |
| netperf_output_source[LOCAL_CORK].output_name = LOCAL_CORK; |
| netperf_output_source[LOCAL_CORK].line[0] = "Local"; |
| netperf_output_source[LOCAL_CORK].line[1] = "Cork"; |
| netperf_output_source[LOCAL_CORK].line[2] = ""; |
| netperf_output_source[LOCAL_CORK].line[3] = ""; |
| netperf_output_source[LOCAL_CORK].format = "%d"; |
| netperf_output_source[LOCAL_CORK].display_value = &loc_tcpcork; |
| netperf_output_source[LOCAL_CORK].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CORK); |
| netperf_output_source[LOCAL_CORK].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CORK); |
| |
| netperf_output_source[RSS_SIZE_REQ].output_name = RSS_SIZE_REQ; |
| netperf_output_source[RSS_SIZE_REQ].line[0] = "Remote"; |
| netperf_output_source[RSS_SIZE_REQ].line[1] = "Send Socket"; |
| netperf_output_source[RSS_SIZE_REQ].line[2] = "Size"; |
| netperf_output_source[RSS_SIZE_REQ].line[3] = "Requested"; |
| netperf_output_source[RSS_SIZE_REQ].format = "%d"; |
| netperf_output_source[RSS_SIZE_REQ].display_value = &rss_size_req; |
| netperf_output_source[RSS_SIZE_REQ].max_line_len = |
| NETPERF_LINE_MAX(RSS_SIZE_REQ); |
| netperf_output_source[RSS_SIZE_REQ].tot_line_len = |
| NETPERF_LINE_TOT(RSS_SIZE_REQ); |
| |
| netperf_output_source[RSS_SIZE].output_name = RSS_SIZE; |
| netperf_output_source[RSS_SIZE].line[0] = "Remote"; |
| netperf_output_source[RSS_SIZE].line[1] = "Send Socket"; |
| netperf_output_source[RSS_SIZE].line[2] = "Size"; |
| netperf_output_source[RSS_SIZE].line[3] = "Initial"; |
| netperf_output_source[RSS_SIZE].format = "%d"; |
| netperf_output_source[RSS_SIZE].display_value = &rss_size; |
| netperf_output_source[RSS_SIZE].max_line_len = |
| NETPERF_LINE_MAX(RSS_SIZE); |
| netperf_output_source[RSS_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(RSS_SIZE); |
| |
| netperf_output_source[RSS_SIZE_END].output_name = RSS_SIZE_END; |
| netperf_output_source[RSS_SIZE_END].line[0] = "Remote"; |
| netperf_output_source[RSS_SIZE_END].line[1] = "Send Socket"; |
| netperf_output_source[RSS_SIZE_END].line[2] = "Size"; |
| netperf_output_source[RSS_SIZE_END].line[3] = "Final"; |
| netperf_output_source[RSS_SIZE_END].format = "%d"; |
| netperf_output_source[RSS_SIZE_END].display_value = &rss_size_end; |
| netperf_output_source[RSS_SIZE_END].max_line_len = |
| NETPERF_LINE_MAX(RSS_SIZE_END); |
| netperf_output_source[RSS_SIZE_END].tot_line_len = |
| NETPERF_LINE_TOT(RSS_SIZE_END); |
| |
| netperf_output_source[RSR_SIZE_REQ].output_name = RSR_SIZE_REQ; |
| netperf_output_source[RSR_SIZE_REQ].line[0] = "Remote"; |
| netperf_output_source[RSR_SIZE_REQ].line[1] = "Recv Socket"; |
| netperf_output_source[RSR_SIZE_REQ].line[2] = "Size"; |
| netperf_output_source[RSR_SIZE_REQ].line[3] = "Requested"; |
| netperf_output_source[RSR_SIZE_REQ].format = "%d"; |
| netperf_output_source[RSR_SIZE_REQ].display_value = &rsr_size_req; |
| netperf_output_source[RSR_SIZE_REQ].max_line_len = |
| NETPERF_LINE_MAX(RSR_SIZE_REQ); |
| netperf_output_source[RSR_SIZE_REQ].tot_line_len = |
| NETPERF_LINE_TOT(RSR_SIZE_REQ); |
| |
| netperf_output_source[RSR_SIZE].output_name = RSR_SIZE; |
| netperf_output_source[RSR_SIZE].line[0] = "Remote"; |
| netperf_output_source[RSR_SIZE].line[1] = "Recv Socket"; |
| netperf_output_source[RSR_SIZE].line[2] = "Size"; |
| netperf_output_source[RSR_SIZE].line[3] = "Initial"; |
| netperf_output_source[RSR_SIZE].format = "%d"; |
| netperf_output_source[RSR_SIZE].display_value = &rsr_size; |
| netperf_output_source[RSR_SIZE].max_line_len = |
| NETPERF_LINE_MAX(RSR_SIZE); |
| netperf_output_source[RSR_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(RSR_SIZE); |
| |
| netperf_output_source[RSR_SIZE_END].output_name = RSR_SIZE_END; |
| netperf_output_source[RSR_SIZE_END].line[0] = "Remote"; |
| netperf_output_source[RSR_SIZE_END].line[1] = "Recv Socket"; |
| netperf_output_source[RSR_SIZE_END].line[2] = "Size"; |
| netperf_output_source[RSR_SIZE_END].line[3] = "Final"; |
| netperf_output_source[RSR_SIZE_END].format = "%d"; |
| netperf_output_source[RSR_SIZE_END].display_value = &rsr_size_end; |
| netperf_output_source[RSR_SIZE_END].max_line_len = |
| NETPERF_LINE_MAX(RSR_SIZE_END); |
| netperf_output_source[RSR_SIZE_END].tot_line_len = |
| NETPERF_LINE_TOT(RSR_SIZE_END); |
| |
| netperf_output_source[REMOTE_SEND_SIZE].output_name = REMOTE_SEND_SIZE; |
| netperf_output_source[REMOTE_SEND_SIZE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_SIZE].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_SIZE].line[2] = "Size"; |
| netperf_output_source[REMOTE_SEND_SIZE].line[3] = ""; |
| netperf_output_source[REMOTE_SEND_SIZE].format = "%d"; |
| netperf_output_source[REMOTE_SEND_SIZE].display_value = &remote_send_size; |
| netperf_output_source[REMOTE_SEND_SIZE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_SIZE); |
| netperf_output_source[REMOTE_SEND_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_SIZE); |
| |
| netperf_output_source[REMOTE_RECV_SIZE].output_name = REMOTE_RECV_SIZE; |
| netperf_output_source[REMOTE_RECV_SIZE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_SIZE].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_SIZE].line[2] = "Size"; |
| netperf_output_source[REMOTE_RECV_SIZE].line[3] = ""; |
| netperf_output_source[REMOTE_RECV_SIZE].format = "%d"; |
| netperf_output_source[REMOTE_RECV_SIZE].display_value = &remote_recv_size; |
| netperf_output_source[REMOTE_RECV_SIZE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_SIZE); |
| netperf_output_source[REMOTE_RECV_SIZE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_SIZE); |
| |
| netperf_output_source[REMOTE_SEND_CALLS].output_name = REMOTE_SEND_CALLS; |
| netperf_output_source[REMOTE_SEND_CALLS].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_CALLS].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_CALLS].line[2] = "Calls"; |
| netperf_output_source[REMOTE_SEND_CALLS].line[3] = ""; |
| netperf_output_source[REMOTE_SEND_CALLS].format = "%lld"; |
| netperf_output_source[REMOTE_SEND_CALLS].display_value = &remote_send_calls; |
| netperf_output_source[REMOTE_SEND_CALLS].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_CALLS); |
| netperf_output_source[REMOTE_SEND_CALLS].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_CALLS); |
| |
| netperf_output_source[REMOTE_RECV_CALLS].output_name = REMOTE_RECV_CALLS; |
| netperf_output_source[REMOTE_RECV_CALLS].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_CALLS].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_CALLS].line[2] = "Calls"; |
| netperf_output_source[REMOTE_RECV_CALLS].line[3] = ""; |
| netperf_output_source[REMOTE_RECV_CALLS].format = "%lld"; |
| netperf_output_source[REMOTE_RECV_CALLS].display_value = &remote_receive_calls; |
| netperf_output_source[REMOTE_RECV_CALLS].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_CALLS); |
| netperf_output_source[REMOTE_RECV_CALLS].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_CALLS); |
| |
| netperf_output_source[REMOTE_BYTES_PER_RECV].output_name = REMOTE_BYTES_PER_RECV; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].line[0] = "Remote"; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].line[1] = "Bytes"; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].line[2] = "Per"; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].line[3] = "Recv"; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].format = "%.2f"; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].display_value = &remote_bytes_per_recv; |
| netperf_output_source[REMOTE_BYTES_PER_RECV].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_BYTES_PER_RECV); |
| netperf_output_source[REMOTE_BYTES_PER_RECV].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_BYTES_PER_RECV); |
| |
| netperf_output_source[REMOTE_BYTES_PER_SEND].output_name = REMOTE_BYTES_PER_SEND; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].line[0] = "Remote"; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].line[1] = "Bytes"; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].line[2] = "Per"; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].line[3] = "Send"; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].format = "%.2f"; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].display_value = &remote_bytes_per_send; |
| netperf_output_source[REMOTE_BYTES_PER_SEND].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_BYTES_PER_SEND); |
| netperf_output_source[REMOTE_BYTES_PER_SEND].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_BYTES_PER_SEND); |
| |
| netperf_output_source[REMOTE_BYTES_RECVD].output_name = REMOTE_BYTES_RECVD; |
| netperf_output_source[REMOTE_BYTES_RECVD].line[0] = "Remote"; |
| netperf_output_source[REMOTE_BYTES_RECVD].line[1] = "Bytes"; |
| netperf_output_source[REMOTE_BYTES_RECVD].line[2] = "Received"; |
| netperf_output_source[REMOTE_BYTES_RECVD].line[3] = ""; |
| netperf_output_source[REMOTE_BYTES_RECVD].format = "%lld"; |
| netperf_output_source[REMOTE_BYTES_RECVD].display_value = &remote_bytes_received; |
| netperf_output_source[REMOTE_BYTES_RECVD].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_BYTES_RECVD); |
| netperf_output_source[REMOTE_BYTES_RECVD].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_BYTES_RECVD); |
| |
| netperf_output_source[REMOTE_BYTES_SENT].output_name = REMOTE_BYTES_SENT; |
| netperf_output_source[REMOTE_BYTES_SENT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_BYTES_SENT].line[1] = "Bytes"; |
| netperf_output_source[REMOTE_BYTES_SENT].line[2] = "Sent"; |
| netperf_output_source[REMOTE_BYTES_SENT].line[3] = ""; |
| netperf_output_source[REMOTE_BYTES_SENT].format = "%lld"; |
| netperf_output_source[REMOTE_BYTES_SENT].display_value = &remote_bytes_sent; |
| netperf_output_source[REMOTE_BYTES_SENT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_BYTES_SENT); |
| netperf_output_source[REMOTE_BYTES_SENT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_BYTES_SENT); |
| |
| netperf_output_source[REMOTE_BYTES_XFERD].output_name = REMOTE_BYTES_XFERD; |
| netperf_output_source[REMOTE_BYTES_XFERD].line[0] = "Remote"; |
| netperf_output_source[REMOTE_BYTES_XFERD].line[1] = "Bytes"; |
| netperf_output_source[REMOTE_BYTES_XFERD].line[2] = "Xferred"; |
| netperf_output_source[REMOTE_BYTES_XFERD].line[3] = ""; |
| netperf_output_source[REMOTE_BYTES_XFERD].format = "%.0f"; |
| netperf_output_source[REMOTE_BYTES_XFERD].display_value = &remote_bytes_xferd; |
| netperf_output_source[REMOTE_BYTES_XFERD].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_BYTES_XFERD); |
| netperf_output_source[REMOTE_BYTES_XFERD].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_BYTES_XFERD); |
| |
| netperf_output_source[REMOTE_SEND_WIDTH].output_name = REMOTE_SEND_WIDTH; |
| netperf_output_source[REMOTE_SEND_WIDTH].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_WIDTH].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_WIDTH].line[2] = "Width"; |
| netperf_output_source[REMOTE_SEND_WIDTH].format = "%d"; |
| netperf_output_source[REMOTE_SEND_WIDTH].display_value = &remote_send_width; |
| netperf_output_source[REMOTE_SEND_WIDTH].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_WIDTH); |
| netperf_output_source[REMOTE_SEND_WIDTH].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_WIDTH); |
| |
| netperf_output_source[REMOTE_RECV_WIDTH].output_name = REMOTE_RECV_WIDTH; |
| netperf_output_source[REMOTE_RECV_WIDTH].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_WIDTH].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_WIDTH].line[2] = "Width"; |
| netperf_output_source[REMOTE_RECV_WIDTH].format = "%d"; |
| netperf_output_source[REMOTE_RECV_WIDTH].display_value = &remote_recv_width; |
| netperf_output_source[REMOTE_RECV_WIDTH].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_WIDTH); |
| netperf_output_source[REMOTE_RECV_WIDTH].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_WIDTH); |
| |
| netperf_output_source[REMOTE_SEND_OFFSET].output_name = REMOTE_SEND_OFFSET; |
| netperf_output_source[REMOTE_SEND_OFFSET].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_OFFSET].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_OFFSET].line[2] = "Offset"; |
| netperf_output_source[REMOTE_SEND_OFFSET].format = "%d"; |
| netperf_output_source[REMOTE_SEND_OFFSET].display_value = &remote_send_offset; |
| netperf_output_source[REMOTE_SEND_OFFSET].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_OFFSET); |
| netperf_output_source[REMOTE_SEND_OFFSET].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_OFFSET); |
| |
| netperf_output_source[REMOTE_RECV_OFFSET].output_name = REMOTE_RECV_OFFSET; |
| netperf_output_source[REMOTE_RECV_OFFSET].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_OFFSET].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_OFFSET].line[2] = "Offset"; |
| netperf_output_source[REMOTE_RECV_OFFSET].format = "%d"; |
| netperf_output_source[REMOTE_RECV_OFFSET].display_value = &remote_recv_offset; |
| netperf_output_source[REMOTE_RECV_OFFSET].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_OFFSET); |
| netperf_output_source[REMOTE_RECV_OFFSET].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_OFFSET); |
| |
| netperf_output_source[REMOTE_RECV_ALIGN].output_name = REMOTE_RECV_ALIGN; |
| netperf_output_source[REMOTE_RECV_ALIGN].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_ALIGN].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_ALIGN].line[2] = "Alignment"; |
| netperf_output_source[REMOTE_RECV_ALIGN].format = "%d"; |
| netperf_output_source[REMOTE_RECV_ALIGN].display_value = &remote_recv_align; |
| netperf_output_source[REMOTE_RECV_ALIGN].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_ALIGN); |
| netperf_output_source[REMOTE_RECV_ALIGN].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_ALIGN); |
| |
| netperf_output_source[REMOTE_SEND_ALIGN].output_name = REMOTE_SEND_ALIGN; |
| netperf_output_source[REMOTE_SEND_ALIGN].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_ALIGN].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_ALIGN].line[2] = "Alignment"; |
| netperf_output_source[REMOTE_SEND_ALIGN].format = "%d"; |
| netperf_output_source[REMOTE_SEND_ALIGN].display_value = &remote_send_align; |
| netperf_output_source[REMOTE_SEND_ALIGN].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_ALIGN); |
| netperf_output_source[REMOTE_SEND_ALIGN].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_ALIGN); |
| |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].output_name = REMOTE_SEND_DIRTY_COUNT; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[1] = "Send"; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[2] = "Dirty"; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].line[3] = "Count"; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].format = "%d"; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].display_value = &rem_dirty_count; |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SEND_DIRTY_COUNT); |
| netperf_output_source[REMOTE_SEND_DIRTY_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SEND_DIRTY_COUNT); |
| |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].output_name = REMOTE_RECV_DIRTY_COUNT; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[2] = "Dirty"; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].line[3] = "Count"; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].format = "%d"; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].display_value = &rem_dirty_count; |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_DIRTY_COUNT); |
| netperf_output_source[REMOTE_RECV_DIRTY_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_DIRTY_COUNT); |
| |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].output_name = REMOTE_RECV_CLEAN_COUNT; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[1] = "Recv"; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[2] = "Clean"; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].line[3] = "Count"; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].format = "%d"; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].display_value = &rem_clean_count; |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RECV_CLEAN_COUNT); |
| netperf_output_source[REMOTE_RECV_CLEAN_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RECV_CLEAN_COUNT); |
| |
| netperf_output_source[REMOTE_CPU_UTIL].output_name = REMOTE_CPU_UTIL; |
| netperf_output_source[REMOTE_CPU_UTIL].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_UTIL].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_UTIL].line[2] = "Util"; |
| netperf_output_source[REMOTE_CPU_UTIL].line[3] = "%"; |
| netperf_output_source[REMOTE_CPU_UTIL].format = "%.2f"; |
| netperf_output_source[REMOTE_CPU_UTIL].display_value = &remote_cpu_utilization_double; |
| netperf_output_source[REMOTE_CPU_UTIL].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_UTIL); |
| netperf_output_source[REMOTE_CPU_UTIL].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_UTIL); |
| |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].output_name = REMOTE_CPU_PEAK_UTIL; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[1] = "Peak"; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[2] = "Per CPU"; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].line[3] = "Util %"; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].format = "%.2f"; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].display_value = &lib_remote_peak_cpu_util; |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_PEAK_UTIL); |
| netperf_output_source[REMOTE_CPU_PEAK_UTIL].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_PEAK_UTIL); |
| |
| netperf_output_source[REMOTE_CPU_PEAK_ID].output_name = REMOTE_CPU_PEAK_ID; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].line[1] = "Peak"; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].line[2] = "Per CPU"; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].line[3] = "ID"; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].format = "%d"; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].display_value = &lib_remote_peak_cpu_id; |
| netperf_output_source[REMOTE_CPU_PEAK_ID].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_PEAK_ID); |
| netperf_output_source[REMOTE_CPU_PEAK_ID].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_PEAK_ID); |
| |
| netperf_output_source[REMOTE_CPU_BIND].output_name = REMOTE_CPU_BIND; |
| netperf_output_source[REMOTE_CPU_BIND].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_BIND].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_BIND].line[2] = "Bind"; |
| netperf_output_source[REMOTE_CPU_BIND].line[3] = ""; |
| netperf_output_source[REMOTE_CPU_BIND].format = "%d"; |
| netperf_output_source[REMOTE_CPU_BIND].display_value = &remote_proc_affinity; |
| netperf_output_source[REMOTE_CPU_BIND].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_BIND); |
| netperf_output_source[REMOTE_CPU_BIND].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_BIND); |
| |
| netperf_output_source[REMOTE_SD].output_name = REMOTE_SD; |
| netperf_output_source[REMOTE_SD].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SD].line[1] = "Service"; |
| netperf_output_source[REMOTE_SD].line[2] = "Demand"; |
| netperf_output_source[REMOTE_SD].line[3] = ""; |
| netperf_output_source[REMOTE_SD].format = "%.3f"; |
| netperf_output_source[REMOTE_SD].display_value = &remote_service_demand_double; |
| netperf_output_source[REMOTE_SD].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SD); |
| netperf_output_source[REMOTE_SD].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SD); |
| |
| netperf_output_source[REMOTE_CPU_METHOD].output_name = REMOTE_CPU_METHOD; |
| netperf_output_source[REMOTE_CPU_METHOD].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_METHOD].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_METHOD].line[2] = "Util"; |
| netperf_output_source[REMOTE_CPU_METHOD].line[3] = "Method"; |
| netperf_output_source[REMOTE_CPU_METHOD].format = "%c"; |
| netperf_output_source[REMOTE_CPU_METHOD].display_value = &remote_cpu_method; |
| netperf_output_source[REMOTE_CPU_METHOD].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_METHOD); |
| netperf_output_source[REMOTE_CPU_METHOD].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_METHOD); |
| |
| netperf_output_source[REMOTE_CPU_COUNT].output_name = REMOTE_CPU_COUNT; |
| netperf_output_source[REMOTE_CPU_COUNT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_COUNT].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_COUNT].line[2] = "Count"; |
| netperf_output_source[REMOTE_CPU_COUNT].format = "%d"; |
| netperf_output_source[REMOTE_CPU_COUNT].display_value = &lib_num_rem_cpus; |
| netperf_output_source[REMOTE_CPU_COUNT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_COUNT); |
| netperf_output_source[REMOTE_CPU_COUNT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_COUNT); |
| |
| netperf_output_source[REMOTE_NODELAY].output_name = REMOTE_NODELAY; |
| netperf_output_source[REMOTE_NODELAY].line[0] = "Remote"; |
| netperf_output_source[REMOTE_NODELAY].line[1] = "NODELAY"; |
| netperf_output_source[REMOTE_NODELAY].line[2] = ""; |
| netperf_output_source[REMOTE_NODELAY].line[3] = ""; |
| netperf_output_source[REMOTE_NODELAY].format = "%d"; |
| netperf_output_source[REMOTE_NODELAY].display_value = &rem_nodelay; |
| netperf_output_source[REMOTE_NODELAY].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_NODELAY); |
| netperf_output_source[REMOTE_NODELAY].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_NODELAY); |
| |
| netperf_output_source[REMOTE_CORK].output_name = REMOTE_CORK; |
| netperf_output_source[REMOTE_CORK].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CORK].line[1] = "Cork"; |
| netperf_output_source[REMOTE_CORK].line[2] = ""; |
| netperf_output_source[REMOTE_CORK].line[3] = ""; |
| netperf_output_source[REMOTE_CORK].format = "%d"; |
| netperf_output_source[REMOTE_CORK].display_value = &rem_tcpcork; |
| netperf_output_source[REMOTE_CORK].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CORK); |
| netperf_output_source[REMOTE_CORK].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CORK); |
| |
| netperf_output_source[LOCAL_DRIVER_NAME].output_name = LOCAL_DRIVER_NAME; |
| netperf_output_source[LOCAL_DRIVER_NAME].line[0] = "Local"; |
| netperf_output_source[LOCAL_DRIVER_NAME].line[1] = "Driver"; |
| netperf_output_source[LOCAL_DRIVER_NAME].line[2] = "Name"; |
| netperf_output_source[LOCAL_DRIVER_NAME].line[3] = ""; |
| netperf_output_source[LOCAL_DRIVER_NAME].format = "%s"; |
| netperf_output_source[LOCAL_DRIVER_NAME].display_value = local_driver_name; |
| netperf_output_source[LOCAL_DRIVER_NAME].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_DRIVER_NAME); |
| netperf_output_source[LOCAL_DRIVER_NAME].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_DRIVER_NAME); |
| |
| netperf_output_source[LOCAL_DRIVER_VERSION].output_name = LOCAL_DRIVER_VERSION; |
| netperf_output_source[LOCAL_DRIVER_VERSION].line[0] = "Local"; |
| netperf_output_source[LOCAL_DRIVER_VERSION].line[1] = "Driver"; |
| netperf_output_source[LOCAL_DRIVER_VERSION].line[2] = "Version"; |
| netperf_output_source[LOCAL_DRIVER_VERSION].line[3] = ""; |
| netperf_output_source[LOCAL_DRIVER_VERSION].format = "%s"; |
| netperf_output_source[LOCAL_DRIVER_VERSION].display_value = local_driver_version; |
| netperf_output_source[LOCAL_DRIVER_VERSION].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_DRIVER_VERSION); |
| netperf_output_source[LOCAL_DRIVER_VERSION].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_DRIVER_VERSION); |
| |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].output_name = LOCAL_DRIVER_FIRMWARE; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[0] = "Local"; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[1] = "Driver"; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[2] = "Firmware"; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].line[3] = ""; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].format = "%s"; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].display_value = local_driver_firmware; |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_DRIVER_FIRMWARE); |
| netperf_output_source[LOCAL_DRIVER_FIRMWARE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_DRIVER_FIRMWARE); |
| |
| netperf_output_source[LOCAL_DRIVER_BUS].output_name = LOCAL_DRIVER_BUS; |
| netperf_output_source[LOCAL_DRIVER_BUS].line[0] = "Local"; |
| netperf_output_source[LOCAL_DRIVER_BUS].line[1] = "Driver"; |
| netperf_output_source[LOCAL_DRIVER_BUS].line[2] = "Bus"; |
| netperf_output_source[LOCAL_DRIVER_BUS].line[3] = ""; |
| netperf_output_source[LOCAL_DRIVER_BUS].format = "%s"; |
| netperf_output_source[LOCAL_DRIVER_BUS].display_value = local_driver_bus; |
| netperf_output_source[LOCAL_DRIVER_BUS].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_DRIVER_BUS); |
| netperf_output_source[LOCAL_DRIVER_BUS].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_DRIVER_BUS); |
| |
| netperf_output_source[REMOTE_DRIVER_NAME].output_name = REMOTE_DRIVER_NAME; |
| netperf_output_source[REMOTE_DRIVER_NAME].line[0] = "Remote"; |
| netperf_output_source[REMOTE_DRIVER_NAME].line[1] = "Driver"; |
| netperf_output_source[REMOTE_DRIVER_NAME].line[2] = "Name"; |
| netperf_output_source[REMOTE_DRIVER_NAME].line[3] = ""; |
| netperf_output_source[REMOTE_DRIVER_NAME].format = "%s"; |
| netperf_output_source[REMOTE_DRIVER_NAME].display_value = remote_driver_name; |
| netperf_output_source[REMOTE_DRIVER_NAME].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_DRIVER_NAME); |
| netperf_output_source[REMOTE_DRIVER_NAME].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_DRIVER_NAME); |
| |
| netperf_output_source[REMOTE_DRIVER_VERSION].output_name = REMOTE_DRIVER_VERSION; |
| netperf_output_source[REMOTE_DRIVER_VERSION].line[0] = "Remote"; |
| netperf_output_source[REMOTE_DRIVER_VERSION].line[1] = "Driver"; |
| netperf_output_source[REMOTE_DRIVER_VERSION].line[2] = "Version"; |
| netperf_output_source[REMOTE_DRIVER_VERSION].line[3] = ""; |
| netperf_output_source[REMOTE_DRIVER_VERSION].format = "%s"; |
| netperf_output_source[REMOTE_DRIVER_VERSION].display_value = remote_driver_version; |
| netperf_output_source[REMOTE_DRIVER_VERSION].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_DRIVER_VERSION); |
| netperf_output_source[REMOTE_DRIVER_VERSION].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_DRIVER_VERSION); |
| |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].output_name = REMOTE_DRIVER_FIRMWARE; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[1] = "Driver"; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[2] = "Firmware"; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].line[3] = ""; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].format = "%s"; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].display_value = remote_driver_firmware; |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_DRIVER_FIRMWARE); |
| netperf_output_source[REMOTE_DRIVER_FIRMWARE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_DRIVER_FIRMWARE); |
| |
| netperf_output_source[REMOTE_DRIVER_BUS].output_name = REMOTE_DRIVER_BUS; |
| netperf_output_source[REMOTE_DRIVER_BUS].line[0] = "Remote"; |
| netperf_output_source[REMOTE_DRIVER_BUS].line[1] = "Driver"; |
| netperf_output_source[REMOTE_DRIVER_BUS].line[2] = "Bus"; |
| netperf_output_source[REMOTE_DRIVER_BUS].line[3] = ""; |
| netperf_output_source[REMOTE_DRIVER_BUS].format = "%s"; |
| netperf_output_source[REMOTE_DRIVER_BUS].display_value = remote_driver_bus; |
| netperf_output_source[REMOTE_DRIVER_BUS].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_DRIVER_BUS); |
| netperf_output_source[REMOTE_DRIVER_BUS].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_DRIVER_BUS); |
| |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].output_name = LOCAL_INTERFACE_SUBDEVICE; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[2] = "Subdevice"; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].format = "0x%.4x"; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].display_value = &local_interface_subdevice; |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_SUBDEVICE); |
| netperf_output_source[LOCAL_INTERFACE_SUBDEVICE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_SUBDEVICE); |
| |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].output_name = LOCAL_INTERFACE_DEVICE; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].line[2] = "Device"; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].format = "0x%.4x"; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].display_value = &local_interface_device; |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_DEVICE); |
| netperf_output_source[LOCAL_INTERFACE_DEVICE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_DEVICE); |
| |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].output_name = LOCAL_INTERFACE_SUBVENDOR; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[2] = "Subvendor"; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].format = "0x%.4x"; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].display_value = &local_interface_subvendor; |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_SUBVENDOR); |
| netperf_output_source[LOCAL_INTERFACE_SUBVENDOR].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_SUBVENDOR); |
| |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].output_name = LOCAL_INTERFACE_VENDOR; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].line[2] = "Vendor"; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].format = "0x%.4x"; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].display_value = &local_interface_vendor; |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_VENDOR); |
| netperf_output_source[LOCAL_INTERFACE_VENDOR].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_VENDOR); |
| |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].output_name = REMOTE_INTERFACE_SUBDEVICE; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[2] = "Subdevice"; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].format = "0x%.4x"; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].display_value = &remote_interface_subdevice; |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_SUBDEVICE); |
| netperf_output_source[REMOTE_INTERFACE_SUBDEVICE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_SUBDEVICE); |
| |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].output_name = REMOTE_INTERFACE_DEVICE; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].line[2] = "Device"; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].format = "0x%.4x"; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].display_value = &remote_interface_device; |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_DEVICE); |
| netperf_output_source[REMOTE_INTERFACE_DEVICE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_DEVICE); |
| |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].output_name = REMOTE_INTERFACE_SUBVENDOR; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[2] = "Subvendor"; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].format = "0x%.4x"; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].display_value = &remote_interface_subvendor; |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_SUBVENDOR); |
| netperf_output_source[REMOTE_INTERFACE_SUBVENDOR].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_SUBVENDOR); |
| |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].output_name = REMOTE_INTERFACE_VENDOR; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].line[2] = "Vendor"; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].format = "0x%.4x"; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].display_value = &remote_interface_vendor; |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_VENDOR); |
| netperf_output_source[REMOTE_INTERFACE_VENDOR].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_VENDOR); |
| |
| netperf_output_source[LOCAL_INTERFACE_NAME].output_name = LOCAL_INTERFACE_NAME; |
| netperf_output_source[LOCAL_INTERFACE_NAME].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_NAME].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_NAME].line[2] = "Name"; |
| netperf_output_source[LOCAL_INTERFACE_NAME].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_NAME].format = "%s"; |
| netperf_output_source[LOCAL_INTERFACE_NAME].display_value = local_interface_name; |
| netperf_output_source[LOCAL_INTERFACE_NAME].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_NAME); |
| netperf_output_source[LOCAL_INTERFACE_NAME].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_NAME); |
| |
| netperf_output_source[REMOTE_INTERFACE_NAME].output_name = REMOTE_INTERFACE_NAME; |
| netperf_output_source[REMOTE_INTERFACE_NAME].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_NAME].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_NAME].line[2] = "Name"; |
| netperf_output_source[REMOTE_INTERFACE_NAME].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_NAME].format = "%s"; |
| netperf_output_source[REMOTE_INTERFACE_NAME].display_value = remote_interface_name; |
| netperf_output_source[REMOTE_INTERFACE_NAME].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_NAME); |
| netperf_output_source[REMOTE_INTERFACE_NAME].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_NAME); |
| |
| netperf_output_source[LOCAL_INTERFACE_SLOT].output_name = LOCAL_INTERFACE_SLOT; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].line[1] = "Interface"; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].line[2] = "Slot"; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].line[3] = ""; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].format = "%s"; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].display_value = local_interface_slot; |
| netperf_output_source[LOCAL_INTERFACE_SLOT].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERFACE_SLOT); |
| netperf_output_source[LOCAL_INTERFACE_SLOT].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERFACE_SLOT); |
| |
| netperf_output_source[REMOTE_INTERFACE_SLOT].output_name = REMOTE_INTERFACE_SLOT; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].line[1] = "Interface"; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].line[2] = "Slot"; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].line[3] = ""; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].format = "%s"; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].display_value = remote_interface_slot; |
| netperf_output_source[REMOTE_INTERFACE_SLOT].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERFACE_SLOT); |
| netperf_output_source[REMOTE_INTERFACE_SLOT].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERFACE_SLOT); |
| |
| netperf_output_source[REMOTE_MACHINE].output_name = REMOTE_MACHINE; |
| netperf_output_source[REMOTE_MACHINE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_MACHINE].line[1] = "Machine"; |
| netperf_output_source[REMOTE_MACHINE].line[2] = ""; |
| netperf_output_source[REMOTE_MACHINE].line[3] = ""; |
| netperf_output_source[REMOTE_MACHINE].format = "%s"; |
| netperf_output_source[REMOTE_MACHINE].display_value = remote_machine; |
| netperf_output_source[REMOTE_MACHINE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_MACHINE); |
| netperf_output_source[REMOTE_MACHINE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_MACHINE); |
| |
| netperf_output_source[REMOTE_VERSION].output_name = REMOTE_VERSION; |
| netperf_output_source[REMOTE_VERSION].line[0] = "Remote"; |
| netperf_output_source[REMOTE_VERSION].line[1] = "Version"; |
| netperf_output_source[REMOTE_VERSION].line[2] = ""; |
| netperf_output_source[REMOTE_VERSION].line[3] = ""; |
| netperf_output_source[REMOTE_VERSION].format = "%s"; |
| netperf_output_source[REMOTE_VERSION].display_value = remote_version; |
| netperf_output_source[REMOTE_VERSION].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_VERSION); |
| netperf_output_source[REMOTE_VERSION].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_VERSION); |
| |
| netperf_output_source[REMOTE_RELEASE].output_name = REMOTE_RELEASE; |
| netperf_output_source[REMOTE_RELEASE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_RELEASE].line[1] = "Release"; |
| netperf_output_source[REMOTE_RELEASE].line[2] = ""; |
| netperf_output_source[REMOTE_RELEASE].line[3] = ""; |
| netperf_output_source[REMOTE_RELEASE].format = "%s"; |
| netperf_output_source[REMOTE_RELEASE].display_value = remote_release; |
| netperf_output_source[REMOTE_RELEASE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_RELEASE); |
| netperf_output_source[REMOTE_RELEASE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_RELEASE); |
| |
| netperf_output_source[REMOTE_SYSNAME].output_name = REMOTE_SYSNAME; |
| netperf_output_source[REMOTE_SYSNAME].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SYSNAME].line[1] = "Sysname"; |
| netperf_output_source[REMOTE_SYSNAME].line[2] = ""; |
| netperf_output_source[REMOTE_SYSNAME].line[3] = ""; |
| netperf_output_source[REMOTE_SYSNAME].format = "%s"; |
| netperf_output_source[REMOTE_SYSNAME].display_value = remote_sysname; |
| netperf_output_source[REMOTE_SYSNAME].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SYSNAME); |
| netperf_output_source[REMOTE_SYSNAME].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SYSNAME); |
| |
| netperf_output_source[LOCAL_MACHINE].output_name = LOCAL_MACHINE; |
| netperf_output_source[LOCAL_MACHINE].line[0] = "Local"; |
| netperf_output_source[LOCAL_MACHINE].line[1] = "Machine"; |
| netperf_output_source[LOCAL_MACHINE].line[2] = ""; |
| netperf_output_source[LOCAL_MACHINE].line[3] = ""; |
| netperf_output_source[LOCAL_MACHINE].format = "%s"; |
| netperf_output_source[LOCAL_MACHINE].display_value = local_machine; |
| netperf_output_source[LOCAL_MACHINE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_MACHINE); |
| netperf_output_source[LOCAL_MACHINE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_MACHINE); |
| |
| netperf_output_source[LOCAL_VERSION].output_name = LOCAL_VERSION; |
| netperf_output_source[LOCAL_VERSION].line[0] = "Local"; |
| netperf_output_source[LOCAL_VERSION].line[1] = "Version"; |
| netperf_output_source[LOCAL_VERSION].line[2] = ""; |
| netperf_output_source[LOCAL_VERSION].line[3] = ""; |
| netperf_output_source[LOCAL_VERSION].format = "%s"; |
| netperf_output_source[LOCAL_VERSION].display_value = local_version; |
| netperf_output_source[LOCAL_VERSION].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_VERSION); |
| netperf_output_source[LOCAL_VERSION].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_VERSION); |
| |
| netperf_output_source[LOCAL_RELEASE].output_name = LOCAL_RELEASE; |
| netperf_output_source[LOCAL_RELEASE].line[0] = "Local"; |
| netperf_output_source[LOCAL_RELEASE].line[1] = "Release"; |
| netperf_output_source[LOCAL_RELEASE].line[2] = ""; |
| netperf_output_source[LOCAL_RELEASE].line[3] = ""; |
| netperf_output_source[LOCAL_RELEASE].format = "%s"; |
| netperf_output_source[LOCAL_RELEASE].display_value = local_release; |
| netperf_output_source[LOCAL_RELEASE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_RELEASE); |
| netperf_output_source[LOCAL_RELEASE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_RELEASE); |
| |
| netperf_output_source[LOCAL_SYSNAME].output_name = LOCAL_SYSNAME; |
| netperf_output_source[LOCAL_SYSNAME].line[0] = "Local"; |
| netperf_output_source[LOCAL_SYSNAME].line[1] = "Sysname"; |
| netperf_output_source[LOCAL_SYSNAME].line[2] = ""; |
| netperf_output_source[LOCAL_SYSNAME].line[3] = ""; |
| netperf_output_source[LOCAL_SYSNAME].format = "%s"; |
| netperf_output_source[LOCAL_SYSNAME].display_value = local_sysname; |
| netperf_output_source[LOCAL_SYSNAME].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SYSNAME); |
| netperf_output_source[LOCAL_SYSNAME].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SYSNAME); |
| |
| netperf_output_source[REMOTE_INTERVAL_USECS].output_name = REMOTE_INTERVAL_USECS; |
| netperf_output_source[REMOTE_INTERVAL_USECS].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERVAL_USECS].line[1] = "Interval"; |
| netperf_output_source[REMOTE_INTERVAL_USECS].line[2] = "Usecs"; |
| netperf_output_source[REMOTE_INTERVAL_USECS].line[3] = ""; |
| netperf_output_source[REMOTE_INTERVAL_USECS].format = "%d"; |
| netperf_output_source[REMOTE_INTERVAL_USECS].display_value = &remote_interval_usecs; |
| netperf_output_source[REMOTE_INTERVAL_USECS].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERVAL_USECS); |
| netperf_output_source[REMOTE_INTERVAL_USECS].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERVAL_USECS); |
| |
| netperf_output_source[REMOTE_INTERVAL_BURST].output_name = REMOTE_INTERVAL_BURST; |
| netperf_output_source[REMOTE_INTERVAL_BURST].line[0] = "Remote"; |
| netperf_output_source[REMOTE_INTERVAL_BURST].line[1] = "Interval"; |
| netperf_output_source[REMOTE_INTERVAL_BURST].line[2] = "Burst"; |
| netperf_output_source[REMOTE_INTERVAL_BURST].line[3] = ""; |
| netperf_output_source[REMOTE_INTERVAL_BURST].format = "%d"; |
| netperf_output_source[REMOTE_INTERVAL_BURST].display_value = &remote_interval_burst; |
| netperf_output_source[REMOTE_INTERVAL_BURST].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_INTERVAL_BURST); |
| netperf_output_source[REMOTE_INTERVAL_BURST].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_INTERVAL_BURST); |
| |
| netperf_output_source[LOCAL_SECURITY_ENABLED].output_name = LOCAL_SECURITY_ENABLED; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].line[0] = "Local"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].line[1] = "OS"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].line[2] = "Security"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].line[3] = "Enabled"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].format = "%s"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].display_value = local_security_enabled; |
| netperf_output_source[LOCAL_SECURITY_ENABLED].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SECURITY_ENABLED); |
| netperf_output_source[LOCAL_SECURITY_ENABLED].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SECURITY_ENABLED); |
| |
| netperf_output_source[LOCAL_SECURITY_TYPE].output_name = LOCAL_SECURITY_TYPE; |
| netperf_output_source[LOCAL_SECURITY_TYPE].line[0] = "Local"; |
| netperf_output_source[LOCAL_SECURITY_TYPE].line[1] = "OS"; |
| netperf_output_source[LOCAL_SECURITY_TYPE].line[2] = "Security"; |
| netperf_output_source[LOCAL_SECURITY_TYPE].line[3] = "Type"; |
| netperf_output_source[LOCAL_SECURITY_TYPE].format = "%s"; |
| netperf_output_source[LOCAL_SECURITY_TYPE].display_value = local_security_type; |
| netperf_output_source[LOCAL_SECURITY_TYPE].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SECURITY_TYPE); |
| netperf_output_source[LOCAL_SECURITY_TYPE].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SECURITY_TYPE); |
| |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].output_name = LOCAL_SECURITY_SPECIFIC; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[0] = "Local"; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[1] = "OS"; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[2] = "Security"; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].line[3] = "Specific"; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].format = "%s"; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].display_value = local_security_specific; |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SECURITY_SPECIFIC); |
| netperf_output_source[LOCAL_SECURITY_SPECIFIC].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SECURITY_SPECIFIC); |
| |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].output_name = LOCAL_SECURITY_ENABLED_NUM; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[0] = "Local"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[1] = "OS"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[2] = "Security"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].line[3] = "Enabled Num"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].format = "%d"; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].display_value = &local_security_enabled_num; |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SECURITY_ENABLED_NUM); |
| netperf_output_source[LOCAL_SECURITY_ENABLED_NUM].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SECURITY_ENABLED_NUM); |
| |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].output_name = LOCAL_SECURITY_TYPE_ID; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[0] = "Local"; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[1] = "OS"; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[2] = "Security"; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].line[3] = "Type ID"; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].format = "%d"; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].display_value = &local_security_type_id; |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SECURITY_TYPE_ID); |
| netperf_output_source[LOCAL_SECURITY_TYPE_ID].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SECURITY_TYPE_ID); |
| |
| netperf_output_source[REMOTE_SECURITY_ENABLED].output_name = REMOTE_SECURITY_ENABLED; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].line[1] = "OS"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].line[2] = "Security"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].line[3] = "Enabled"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].format = "%s"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].display_value = remote_security_enabled; |
| netperf_output_source[REMOTE_SECURITY_ENABLED].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SECURITY_ENABLED); |
| netperf_output_source[REMOTE_SECURITY_ENABLED].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SECURITY_ENABLED); |
| |
| netperf_output_source[REMOTE_SECURITY_TYPE].output_name = REMOTE_SECURITY_TYPE; |
| netperf_output_source[REMOTE_SECURITY_TYPE].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SECURITY_TYPE].line[1] = "OS"; |
| netperf_output_source[REMOTE_SECURITY_TYPE].line[2] = "Security"; |
| netperf_output_source[REMOTE_SECURITY_TYPE].line[3] = "Type"; |
| netperf_output_source[REMOTE_SECURITY_TYPE].format = "%s"; |
| netperf_output_source[REMOTE_SECURITY_TYPE].display_value = remote_security_type; |
| netperf_output_source[REMOTE_SECURITY_TYPE].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SECURITY_TYPE); |
| netperf_output_source[REMOTE_SECURITY_TYPE].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SECURITY_TYPE); |
| |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].output_name = REMOTE_SECURITY_SPECIFIC; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[1] = "OS"; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[2] = "Security"; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].line[3] = "Specific"; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].format = "%s"; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].display_value = remote_security_specific; |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SECURITY_SPECIFIC); |
| netperf_output_source[REMOTE_SECURITY_SPECIFIC].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SECURITY_SPECIFIC); |
| |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].output_name = REMOTE_SECURITY_ENABLED_NUM; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[1] = "OS"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[2] = "Security"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].line[3] = "Enabled"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].format = "%d"; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].display_value = &remote_security_enabled_num; |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SECURITY_ENABLED_NUM); |
| netperf_output_source[REMOTE_SECURITY_ENABLED_NUM].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SECURITY_ENABLED_NUM); |
| |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].output_name = REMOTE_SECURITY_TYPE_ID; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[1] = "OS"; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[2] = "Security"; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].line[3] = "Type"; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].format = "%d"; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].display_value = &remote_security_type_id; |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SECURITY_TYPE_ID); |
| netperf_output_source[REMOTE_SECURITY_TYPE_ID].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SECURITY_TYPE_ID); |
| |
| netperf_output_source[LOCAL_INTERVAL_USECS].output_name = LOCAL_INTERVAL_USECS; |
| netperf_output_source[LOCAL_INTERVAL_USECS].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERVAL_USECS].line[1] = "Interval"; |
| netperf_output_source[LOCAL_INTERVAL_USECS].line[2] = "Usecs"; |
| netperf_output_source[LOCAL_INTERVAL_USECS].line[3] = ""; |
| netperf_output_source[LOCAL_INTERVAL_USECS].format = "%d"; |
| netperf_output_source[LOCAL_INTERVAL_USECS].display_value = &interval_usecs; |
| netperf_output_source[LOCAL_INTERVAL_USECS].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERVAL_USECS); |
| netperf_output_source[LOCAL_INTERVAL_USECS].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERVAL_USECS); |
| |
| netperf_output_source[LOCAL_INTERVAL_BURST].output_name = LOCAL_INTERVAL_BURST; |
| netperf_output_source[LOCAL_INTERVAL_BURST].line[0] = "Local"; |
| netperf_output_source[LOCAL_INTERVAL_BURST].line[1] = "Interval"; |
| netperf_output_source[LOCAL_INTERVAL_BURST].line[2] = "Burst"; |
| netperf_output_source[LOCAL_INTERVAL_BURST].line[3] = ""; |
| netperf_output_source[LOCAL_INTERVAL_BURST].format = "%d"; |
| netperf_output_source[LOCAL_INTERVAL_BURST].display_value = &interval_burst; |
| netperf_output_source[LOCAL_INTERVAL_BURST].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_INTERVAL_BURST); |
| netperf_output_source[LOCAL_INTERVAL_BURST].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_INTERVAL_BURST); |
| |
| netperf_output_source[REMOTE_SYSTEM_MODEL].output_name = REMOTE_SYSTEM_MODEL; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].line[0] = "Remote"; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].line[1] = "System"; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].line[2] = "Model"; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].line[3] = ""; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].format = "%s"; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].display_value = remote_system_model; |
| netperf_output_source[REMOTE_SYSTEM_MODEL].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_SYSTEM_MODEL); |
| netperf_output_source[REMOTE_SYSTEM_MODEL].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_SYSTEM_MODEL); |
| |
| netperf_output_source[REMOTE_CPU_MODEL].output_name = REMOTE_CPU_MODEL; |
| netperf_output_source[REMOTE_CPU_MODEL].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_MODEL].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_MODEL].line[2] = "Model"; |
| netperf_output_source[REMOTE_CPU_MODEL].line[3] = ""; |
| netperf_output_source[REMOTE_CPU_MODEL].format = "%s"; |
| netperf_output_source[REMOTE_CPU_MODEL].display_value = remote_cpu_model; |
| netperf_output_source[REMOTE_CPU_MODEL].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_MODEL); |
| netperf_output_source[REMOTE_CPU_MODEL].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_MODEL); |
| |
| netperf_output_source[REMOTE_CPU_FREQUENCY].output_name = REMOTE_CPU_FREQUENCY; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].line[0] = "Remote"; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].line[1] = "CPU"; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].line[2] = "Frequency"; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].line[3] = "MHz"; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].format = "%d"; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].display_value = &remote_cpu_frequency; |
| netperf_output_source[REMOTE_CPU_FREQUENCY].max_line_len = |
| NETPERF_LINE_MAX(REMOTE_CPU_FREQUENCY); |
| netperf_output_source[REMOTE_CPU_FREQUENCY].tot_line_len = |
| NETPERF_LINE_TOT(REMOTE_CPU_FREQUENCY); |
| |
| netperf_output_source[LOCAL_SYSTEM_MODEL].output_name = LOCAL_SYSTEM_MODEL; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].line[0] = "Local"; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].line[1] = "System"; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].line[2] = "Model"; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].line[3] = ""; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].format = "%s"; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].display_value = local_system_model; |
| netperf_output_source[LOCAL_SYSTEM_MODEL].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_SYSTEM_MODEL); |
| netperf_output_source[LOCAL_SYSTEM_MODEL].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_SYSTEM_MODEL); |
| |
| netperf_output_source[LOCAL_CPU_MODEL].output_name = LOCAL_CPU_MODEL; |
| netperf_output_source[LOCAL_CPU_MODEL].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_MODEL].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_MODEL].line[2] = "Model"; |
| netperf_output_source[LOCAL_CPU_MODEL].line[3] = ""; |
| netperf_output_source[LOCAL_CPU_MODEL].format = "%s"; |
| netperf_output_source[LOCAL_CPU_MODEL].display_value = local_cpu_model; |
| netperf_output_source[LOCAL_CPU_MODEL].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_MODEL); |
| netperf_output_source[LOCAL_CPU_MODEL].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_MODEL); |
| |
| netperf_output_source[LOCAL_CPU_FREQUENCY].output_name = LOCAL_CPU_FREQUENCY; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].line[0] = "Local"; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].line[1] = "CPU"; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].line[2] = "Frequency"; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].line[3] = "MHz"; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].format = "%d"; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].display_value = &local_cpu_frequency; |
| netperf_output_source[LOCAL_CPU_FREQUENCY].max_line_len = |
| NETPERF_LINE_MAX(LOCAL_CPU_FREQUENCY); |
| netperf_output_source[LOCAL_CPU_FREQUENCY].tot_line_len = |
| NETPERF_LINE_TOT(LOCAL_CPU_FREQUENCY); |
| |
| netperf_output_source[OUTPUT_END].output_name = OUTPUT_END; |
| netperf_output_source[OUTPUT_END].line[0] = "This"; |
| netperf_output_source[OUTPUT_END].line[1] = "Is"; |
| netperf_output_source[OUTPUT_END].line[2] = "The"; |
| netperf_output_source[OUTPUT_END].line[3] = "End"; |
| netperf_output_source[OUTPUT_END].format = "%s"; |
| netperf_output_source[OUTPUT_END].display_value = NULL; |
| netperf_output_source[OUTPUT_END].max_line_len = |
| NETPERF_LINE_MAX(OUTPUT_END); |
| netperf_output_source[OUTPUT_END].tot_line_len = |
| NETPERF_LINE_TOT(OUTPUT_END); |
| |
| } |
| /* lots of boring, repetitive code */ |
| void |
| print_omni_init() { |
| |
| int i,j; |
| |
| if (printing_initialized) return; |
| |
| printing_initialized = 1; |
| |
| print_omni_init_list(); |
| |
| /* belts and suspenders */ |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) |
| output_csv_list[i] = OUTPUT_END; |
| |
| for (j = 0; j < NETPERF_MAX_BLOCKS; j++) |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) |
| output_human_list[j][i] = OUTPUT_END; |
| |
| |
| /* the default for csv is the kitchen-sink. ultimately it will be |
| possible to override by providing one's own list in a file */ |
| |
| if ((csv) || (keyword)) { |
| if (csv_selection_file) |
| /* name of file, list to fill, number of rows/lines */ |
| parse_output_csv_selection_file(csv_selection_file); |
| else |
| set_output_csv_list_default(output_csv_list); |
| } |
| else { |
| if (human_selection_file) |
| parse_output_human_selection_file(human_selection_file); |
| else |
| set_output_human_list_default(output_human_list); |
| } |
| |
| |
| } |
| |
| /* why? because one cannot simply pass a pointer to snprintf :) for |
| our nefarious porpoises, we only expect to handle single-value |
| format statements, not a full-blown format */ |
| int |
| my_long_long_snprintf(char *buffer, size_t size, const char *format, void *value) |
| { |
| const char *fmt = format; |
| while (*fmt) |
| switch (*fmt++) { |
| case 'd': |
| case 'i': |
| return snprintf(buffer, size, format, *(long long *)value); |
| case 'u': |
| case 'o': |
| case 'x': |
| case 'X': |
| return snprintf(buffer, size, format, *(unsigned long long *)value); |
| } |
| return -1; |
| } |
| |
| int |
| my_long_snprintf(char *buffer, size_t size, const char *format, void *value) |
| { |
| const char *fmt = format; |
| while (*fmt) |
| switch (*fmt++) { |
| case 'd': |
| case 'i': |
| return snprintf(buffer, size, format, *(long *)value); |
| case 'u': |
| case 'o': |
| case 'x': |
| case 'X': |
| return snprintf(buffer, size, format, *(unsigned long *)value); |
| case 'l': |
| return my_long_long_snprintf(buffer, size, format, value); |
| } |
| return -1; |
| } |
| |
| int |
| my_snprintf(char *buffer, size_t size, const char *format, void *value) |
| { |
| const char *fmt = format; |
| |
| while (*fmt) |
| switch (*fmt++) { |
| case 'c': |
| return snprintf(buffer, size, format, *(int *)value); |
| case 'f': |
| case 'e': |
| case 'E': |
| case 'g': |
| case 'G': |
| return snprintf(buffer, size, format, *(double *)value); |
| case 's': |
| return snprintf(buffer, size, format, (char *)value); |
| case 'd': |
| case 'i': |
| return snprintf(buffer, size, format, *(int *)value); |
| case 'u': |
| case 'o': |
| case 'x': |
| case 'X': |
| return snprintf(buffer, size, format, *(unsigned int *)value); |
| case 'l': |
| return my_long_snprintf(buffer, size, format, value); |
| } |
| return -1; |
| } |
| |
| void |
| print_omni_csv() |
| { |
| |
| int j,k,buflen,vallen; |
| |
| char *hdr1 = NULL; |
| char *val1 = NULL; |
| char tmpval[1024]; |
| |
| buflen = 0; |
| for (j = 0; |
| ((j < NETPERF_OUTPUT_MAX) && |
| (output_csv_list[j] != OUTPUT_END)); |
| j++) { |
| if ((netperf_output_source[output_csv_list[j]].format != NULL) && |
| (netperf_output_source[output_csv_list[j]].display_value != NULL)) { |
| vallen = |
| my_snprintf(tmpval, |
| 1024, |
| netperf_output_source[output_csv_list[j]].format, |
| (netperf_output_source[output_csv_list[j]].display_value)); |
| if (vallen == -1) { |
| fprintf(where,"my_snprintf failed on %s with format %s\n", |
| netperf_output_enum_to_str(j), |
| netperf_output_source[output_csv_list[j]].format); |
| fflush(where); |
| } |
| vallen += 1; /* forget not the terminator */ |
| } |
| else |
| vallen = 0; |
| |
| if (vallen > |
| netperf_output_source[output_csv_list[j]].tot_line_len) |
| netperf_output_source[output_csv_list[j]].tot_line_len = vallen; |
| |
| buflen += |
| netperf_output_source[output_csv_list[j]].tot_line_len; |
| } |
| |
| if (print_headers) hdr1 = malloc(buflen + 1); |
| val1 = malloc(buflen + 1); |
| |
| if (((hdr1 == NULL) && (print_headers)) || |
| (val1 == NULL)) { |
| fprintf(where,"unable to allocate output buffers\n"); |
| fflush(where); |
| exit(-1); |
| } |
| |
| if (print_headers) memset(hdr1,' ',buflen + 1); |
| memset(val1,' ',buflen + 1); |
| |
| /* ostensibly, we now "know" that we have enough space in all our |
| strings, and we have spaces where we want them etc */ |
| char *h1 = hdr1; |
| char *v1 = val1; |
| for (j = 0; |
| ((j < NETPERF_OUTPUT_MAX) && |
| (output_csv_list[j] != OUTPUT_END)); |
| j++) { |
| int len; |
| len = 0; |
| if (print_headers) { |
| for (k = 0; ((k < 4) && |
| (NULL != |
| netperf_output_source[output_csv_list[j]].line[k]) && |
| (strcmp("",netperf_output_source[output_csv_list[j]].line[k]))); k++) { |
| |
| len = sprintf(h1, |
| "%s", |
| netperf_output_source[output_csv_list[j]].line[k]); |
| *(h1 + len) = ' '; |
| /* now move to the next starting column. for csv we aren't worried |
| about alignment between the header and the value lines */ |
| h1 += len + 1; |
| } |
| *(h1 - 1) = ','; |
| } |
| if ((netperf_output_source[output_csv_list[j]].format != NULL) && |
| (netperf_output_source[output_csv_list[j]].display_value != NULL)) { |
| /* tot_line_len is bogus here, but should be "OK" ? */ |
| len = my_snprintf(v1, |
| netperf_output_source[output_csv_list[j]].tot_line_len, |
| netperf_output_source[output_csv_list[j]].format, |
| netperf_output_source[output_csv_list[j]].display_value); |
| |
| /* nuke the trailing \n" from the string routine. */ |
| *(v1 + len) = ','; |
| v1 += len + 1; |
| } |
| else { |
| /* we need a ',' even if there is no value */ |
| *v1 = ','; |
| v1 += 2; |
| } |
| } |
| |
| /* ok, _now_ null terminate each line by nuking the last comma. do |
| we have an OBOB here? */ |
| if (print_headers) *(h1-1) = 0; |
| *(v1-1) = 0; |
| /* and now spit it out, but only if it is going to have something |
| in it. we don't want a bunch of blank lines or nulls... */ |
| if (output_csv_list[0] != OUTPUT_END) { |
| if (print_headers) printf("%s\n",hdr1); |
| printf("%s\n",val1); |
| } |
| |
| if (hdr1 != NULL) free(hdr1); |
| if (val1 != NULL) free(val1); |
| |
| } |
| |
| void |
| print_omni_keyword() |
| { |
| /* this one should be the simplest of all - no buffers to allocate, |
| just spit it all out. raj 20080805 */ |
| |
| int j; |
| char tmpval[1024]; |
| int vallen; |
| |
| for (j = 0; |
| ((j < NETPERF_OUTPUT_MAX) && |
| (output_csv_list[j] != OUTPUT_END)); |
| j++) { |
| if ((netperf_output_source[output_csv_list[j]].format != NULL) && |
| (netperf_output_source[output_csv_list[j]].display_value != NULL)) { |
| vallen = |
| my_snprintf(tmpval, |
| 1024, |
| netperf_output_source[output_csv_list[j]].format, |
| (netperf_output_source[output_csv_list[j]].display_value)); |
| if (vallen == -1) { |
| snprintf(tmpval, |
| 1024, |
| "my_snprintf failed with format %s\n", |
| netperf_output_source[output_csv_list[j]].format); |
| } |
| fprintf(where, |
| "%s=%s\n",netperf_output_enum_to_str(output_csv_list[j]), |
| tmpval); |
| } |
| } |
| fflush(where); |
| } |
| |
| void |
| print_omni_human() |
| { |
| |
| int i,j,k,buflen,buflen_max; |
| |
| char *hdr[4]; |
| char *val1 = NULL; |
| char tmpval[1024]; /* excessive, but we may have the command line */ |
| int vallen; |
| |
| for (k = 0; k < 4; k ++) { |
| hdr[k] = NULL; |
| } |
| |
| /* decisions, decisions... walk the list twice to only need to |
| allocate the charcter buffers once, or walk it once and possibly |
| reallocate them as I go... oh, lets walk it twice just for fun to |
| start. since only now do we know that the values are around to be |
| printed, we should try the snprintf for the value and see how |
| much space it wants and update max_line_len accordingly */ |
| buflen_max = 0; |
| for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { |
| buflen = 0; |
| for (j = 0; |
| ((j < NETPERF_OUTPUT_MAX) && |
| (output_human_list[i][j] != OUTPUT_END)); |
| j++) { |
| if ((netperf_output_source[output_human_list[i][j]].format != NULL) && |
| (netperf_output_source[output_human_list[i][j]].display_value != NULL)) |
| vallen = my_snprintf(tmpval, |
| 1024, |
| netperf_output_source[output_human_list[i][j]].format, |
| (netperf_output_source[output_human_list[i][j]].display_value)) + 1; /* need to count the \n */ |
| else |
| vallen = 0; |
| |
| if (vallen > |
| netperf_output_source[output_human_list[i][j]].max_line_len) |
| netperf_output_source[output_human_list[i][j]].max_line_len = vallen; |
| |
| buflen += |
| netperf_output_source[output_human_list[i][j]].max_line_len + 1; |
| } |
| |
| if (buflen > buflen_max) |
| buflen_max = buflen; |
| } |
| |
| /* more belts and suspenders */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| hdr[k] = malloc(buflen_max+1); |
| } |
| val1 = malloc(buflen_max+1); |
| |
| /* we could probably be more succinct here but perhaps the compiler |
| can figure that out for us :) */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| if (hdr[k] == NULL) { |
| fprintf(where,"Unable to allocate output buffers\n"); |
| fflush(where); |
| exit(-1); |
| } |
| } |
| |
| /* ostensibly, we now "know" that we have enough space in all our |
| strings, and we have spaces where we want them etc */ |
| for (i = 0; i < NETPERF_MAX_BLOCKS; i++) { |
| char *h[4]; |
| char *v1 = val1; |
| |
| for (k = 0; k < 4; k++) h[k] = hdr[k]; |
| |
| /* we want to blank things out each time since we skip around a lot */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| memset(hdr[k],' ',buflen_max+1); |
| } |
| memset(val1,' ',buflen_max+1); |
| |
| |
| for (j = 0; |
| ((j < NETPERF_OUTPUT_MAX) && |
| (output_human_list[i][j] != OUTPUT_END)); |
| j++) { |
| if (print_headers) { |
| for (k = 0; k < 4; k++) { |
| memcpy(h[k], |
| netperf_output_source[output_human_list[i][j]].line[k], |
| strlen(netperf_output_source[output_human_list[i][j]].line[k])); |
| } |
| } |
| if ((netperf_output_source[output_human_list[i][j]].format != NULL) && |
| (netperf_output_source[output_human_list[i][j]].display_value != NULL)) { |
| int len; |
| len = my_snprintf(v1, |
| netperf_output_source[output_human_list[i][j]].max_line_len, |
| netperf_output_source[output_human_list[i][j]].format, |
| netperf_output_source[output_human_list[i][j]].display_value); |
| /* nuke the trailing \n" from the string routine. */ |
| *(v1 + len) = ' '; |
| } |
| /* now move to the next starting column */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| h[k] += |
| netperf_output_source[output_human_list[i][j]].max_line_len + 1; |
| } |
| v1 += netperf_output_source[output_human_list[i][j]].max_line_len + 1; |
| } |
| /* ok, _now_ null terminate each line. do we have an OBOB here? */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| *h[k] = 0; |
| } |
| *v1 = 0; |
| /* and now spit it out, but only if it is going to have something |
| in it. we don't want a bunch of blank lines or nulls... at some |
| point we might want to work backwards collapsine whitespace from |
| the right but for now, we won't bother */ |
| if (output_human_list[i][0] != OUTPUT_END) { |
| if (i > 0) printf("\n"); /* we want a blank line between blocks ? */ |
| for (k = 0; (k < 4) && (print_headers); k++) { |
| printf("%s\n",hdr[k]); |
| } |
| printf("%s\n",val1); |
| } |
| }; |
| for (k = 0; k < 4; k++) { |
| if (hdr[k] != NULL) free(hdr[k]); |
| } |
| } |
| |
| void |
| print_omni() |
| { |
| |
| print_omni_init(); |
| |
| if (debug > 2) |
| dump_netperf_output_source(where); |
| |
| if (csv) |
| print_omni_csv(); |
| else if (keyword) |
| print_omni_keyword(); |
| else |
| print_omni_human(); |
| |
| } |
| /* for the next few routines (connect, accept, send, recv, |
| disconnect/close) we will use a return of -1 to mean times up, -2 |
| to mean a transient error (eg ENOBUFS on a UDP send call) and -3 to |
| mean hard error. this means it is ok for the connect routine to |
| return a 0 (zero) if that happens to be the fd/SOCKET we get and in |
| theory we will be able to support zero-length messages on those |
| protocols which support it. all in theory of course. raj |
| 2008-01-09 */ |
| |
| int |
| connect_data_socket(SOCKET send_socket, struct addrinfo *remote_res) |
| { |
| int ret; |
| |
| /* Connect up to the remote port on the data socket */ |
| if ((ret = connect(send_socket, |
| remote_res->ai_addr, |
| remote_res->ai_addrlen)) == INVALID_SOCKET) { |
| if (SOCKET_EINTR(ret)) { |
| /* we interpret this to mean that the test is supposed to be |
| over, so return a value of -1 to the caller */ |
| return -1; |
| } |
| if ((SOCKET_EADDRINUSE(ret)) || SOCKET_EADDRNOTAVAIL(ret)) { |
| /* likely something our explicit bind() would have caught in |
| the past, so go get another port, via create_data_socket. |
| yes, this is a bit more overhead than before, but the |
| condition should be rather rare. we only get a new port if |
| this was a connection-including test like TCP_CRR or |
| TCP_CC. Otherwise we need to return an error. raj |
| 2008-01-08 */ |
| return -2; |
| } |
| else |
| /* -3 means there was an error */ |
| return -3; |
| } |
| return 0; |
| } |
| |
| int |
| send_data(SOCKET data_socket, struct ring_elt *send_ring, uint32_t bytes_to_send, struct sockaddr *destination, int destlen) { |
| |
| int len; |
| |
| /* if the user has supplied a destination, we use sendto, otherwise |
| we use send. we ass-u-me blocking operations always, so no need |
| to check for eagain or the like. */ |
| |
| if (debug > 1) { |
| fprintf(where, |
| "send_data sock %d ring %p bytes %d dest %p len %d\n", |
| data_socket, |
| send_ring, |
| bytes_to_send, |
| destination, |
| destlen); |
| fflush(where); |
| } |
| |
| if (destination) { |
| len = sendto(data_socket, |
| send_ring->buffer_ptr, |
| bytes_to_send, |
| 0, |
| destination, |
| destlen); |
| } |
| else { |
| len = send(data_socket, |
| send_ring->buffer_ptr, |
| bytes_to_send, |
| 0); |
| } |
| if(len != bytes_to_send) { |
| /* don't forget that some platforms may do a partial send upon |
| receipt of the interrupt and not return an EINTR... */ |
| if (SOCKET_EINTR(len) || (len >= 0)) |
| { |
| /* we hit the end of a timed test. */ |
| return -1; |
| } |
| /* if this is UDP it is possible to receive an ENOBUFS on the send |
| call and it would not be a fatal error. of course if we were |
| to return 0 then it would make the test think it was over when |
| it really wasn't. the question becomes what to do. for the |
| time being, the answer will likely be to return something like |
| -2 to indicate a non-fatal error happened on the send and let |
| the caller figure it out :) we won't actually check to see if |
| this is UDP - it is the author's experience in many, Many, MANY |
| years that the only time an ENOBUFS has been returned in a |
| netperf test has been with UDP. famous last words :) */ |
| if (errno == ENOBUFS) |
| return -2; |
| else { |
| fprintf(where,"send_data: data send error: errno %d",errno); |
| return -3; |
| } |
| } |
| return len; |
| } |
| |
| int |
| recv_data(SOCKET data_socket, struct ring_elt *recv_ring, uint32_t bytes_to_recv, struct sockaddr *source, int *sourcelen, uint32_t flags, uint32_t *num_receives) { |
| |
| char *temp_message_ptr; |
| int bytes_left; |
| int bytes_recvd; |
| int my_recvs; |
| |
| /* receive data off the data_socket, ass-u-me-ing a blocking socket |
| all the way!-) 2008-01-08 */ |
| my_recvs = 0; |
| bytes_left = bytes_to_recv; |
| temp_message_ptr = recv_ring->buffer_ptr; |
| |
| if (debug > 1) { |
| fprintf(where, |
| "recv_data sock %d, elt %p, bytes %d source %p srclen %d, flags %x num_recv %p\n", |
| data_socket, |
| recv_ring, |
| bytes_to_recv, |
| source, |
| (source != NULL) ? *sourcelen : -1, |
| flags, |
| num_receives); |
| fflush(where); |
| } |
| do { |
| if (source) { |
| /* call recvfrom it does look a little silly here inside the do |
| while, but I think it is ok - a UDP or other DGRAM or |
| SEQPACKET (?) socket, which should be the only time we |
| pass-in a source pointer will have a semantic that should get |
| us out of the dowhile on the first call anyway. if it |
| turns-out not to be the case, then we can hoist the if above |
| the do and put the dowhile in the else. */ |
| bytes_recvd = recvfrom(data_socket, |
| temp_message_ptr, |
| bytes_left, |
| 0, |
| source, |
| sourcelen); |
| } |
| else { |
| /* just call recv */ |
| bytes_recvd = recv(data_socket, |
| temp_message_ptr, |
| bytes_left, |
| 0); |
| } |
| if (bytes_recvd > 0) { |
| bytes_left -= bytes_recvd; |
| temp_message_ptr += bytes_recvd; |
| } |
| else { |
| break; |
| } |
| my_recvs++; |
| } while ((bytes_left > 0) && (flags & NETPERF_WAITALL)); |
| |
| *num_receives = my_recvs; |
| |
| /* OK, we are out of the loop - now what? */ |
| if (bytes_recvd < 0) { |
| /* did the timer hit, or was there an error? */ |
| if (SOCKET_EINTR(bytes_recvd)) |
| { |
| /* We hit the end of a timed test. */ |
| return -1; |
| } |
| /* it was a hard error */ |
| return -3; |
| } |
| |
| |
| /* this looks a little funny, but should be correct. if we had |
| NETPERF_WAITALL set and we got here, it means we got all the |
| bytes of the request/response. otherwise we would have hit the |
| error or end of test cases. if NETPERF_WAITALL isn't set, this |
| is a STREAM test, and we will have only made one call to recv, so |
| bytes_recvd will be accurate. */ |
| if (bytes_left) |
| return bytes_recvd; |
| else |
| return bytes_to_recv; |
| |
| } |
| |
| |
| int |
| close_data_socket(SOCKET data_socket, struct sockaddr *peer, int peerlen) |
| { |
| |
| int ret; |
| char buffer[4]; |
| |
| if (protocol == IPPROTO_UDP) { |
| int i; |
| for (i = 0; i < 3; i++) { |
| if (peer) |
| ret = sendto(data_socket, |
| buffer, |
| 0, |
| 0, |
| peer, |
| peerlen); |
| else |
| ret = send(data_socket, |
| buffer, |
| 0, |
| 0); |
| if (SOCKET_EINTR(ret)) { |
| close(data_socket); |
| return -1; |
| } |
| } |
| } |
| ret = close(data_socket); |
| |
| if (SOCKET_EINTR(ret)) { |
| /* end of test */ |
| return -1; |
| } |
| else if (ret == 0) { |
| return ret; |
| } |
| else |
| return -3; |
| |
| } |
| |
| int |
| disconnect_data_socket(SOCKET data_socket, int initiate, int do_close, struct sockaddr *peer, int peerlen) |
| { |
| |
| char buffer[4]; |
| int bytes_recvd; |
| |
| if (debug) { |
| fprintf(where, |
| "disconnect_d_s sock %d init %d do_close %d protocol %d\n", |
| data_socket, |
| initiate, |
| do_close, |
| protocol); |
| fflush(where); |
| } |
| |
| /* at some point we'll need to abstract this a little. for now, if |
| the protocol is UDP, we try to send some number of zero-length |
| datagrams to allow the remote to get out of its loop without |
| having to wait for the padded timer to expire. if it isn't UDP, |
| we assume a reliable connection and can do the usual graceful |
| shutdown thing */ |
| |
| if (protocol != IPPROTO_UDP) { |
| if (initiate) |
| shutdown(data_socket, SHUT_WR); |
| |
| /* we are expecting to get either a return of zero indicating |
| connection close, or an error. */ |
| bytes_recvd = recv(data_socket, |
| buffer, |
| 1, |
| 0); |
| |
| if (bytes_recvd != 0) { |
| /* connection close, call close. we assume that the requisite */ |
| /* number of bytes have been received */ |
| if (SOCKET_EINTR(bytes_recvd)) |
| { |
| /* We hit the end of a timed test. */ |
| return -1; |
| } |
| return -3; |
| } |
| } |
| else { |
| int i; |
| for (i = 0; i < 3; i++) { |
| if (peer) |
| bytes_recvd = sendto(data_socket, |
| buffer, |
| 0, |
| 0, |
| peer, |
| peerlen); |
| else |
| bytes_recvd = send(data_socket, |
| buffer, |
| 0, |
| 0); |
| /* we only really care if the timer expired on us */ |
| if (SOCKET_EINTR(bytes_recvd)) { |
| if (do_close) close(data_socket); |
| return -1; |
| } |
| } |
| } |
| |
| if (do_close) |
| close(data_socket); |
| |
| return 0; |
| } |
| |
| static void |
| get_transport_info(SOCKET socket, int *mss, int protocol) |
| { |
| |
| netperf_socklen_t sock_opt_len; |
| int option; |
| sock_opt_len = sizeof(netperf_socklen_t); |
| |
| switch (protocol) { |
| #if defined(IPPROTO_TCP) && defined(TCP_MAXSEG) |
| case IPPROTO_TCP: |
| option = TCP_MAXSEG; |
| break; |
| #endif |
| |
| #if defined(IPPROTO_SCTP) && defined(SCTP_MAXSEG) |
| case IPPROTO_SCTP: |
| option = SCTP_MAXSEG; |
| break; |
| #endif |
| default: |
| *mss = -1; |
| return; |
| } |
| |
| if (getsockopt(socket, |
| protocol, |
| option, |
| (char *)mss, |
| &sock_opt_len) == SOCKET_ERROR) { |
| fprintf(where, |
| "netperf: get_transport_info: getsockopt: errno %d\n", |
| errno); |
| fflush(where); |
| *mss = -1; |
| } |
| } |
| |
| /* brain dead simple way to get netperf to emit a uuid. sadly, by this |
| point we will have already established the control connection but |
| those are the breaks. we do _NOT_ include a trailing newline |
| because we want to be able to use this in a script */ |
| |
| void |
| print_uuid(char remote_host[]) |
| { |
| printf("%s",test_uuid); |
| } |
| |
| /* this code is intended to be "the two routines to run them all" for |
| BSDish sockets. it comes about as part of a desire to shrink the |
| code footprint of netperf and to avoid having so many blessed |
| routines to alter as time goes by. the downside is there will be |
| more "ifs" than there were before. there may be some other |
| "complications" for things like demo mode or perhaps histograms if |
| we ever want to track individual RTTs when burst mode is in use |
| etc etc... raj 2008-01-07 */ |
| |
| void |
| send_omni(char remote_host[]) |
| { |
| |
| |
| int len; |
| int ret,rret; |
| int connected = 0; |
| int timed_out = 0; |
| int pad_time = 0; |
| |
| struct ring_elt *send_ring; |
| struct ring_elt *recv_ring; |
| |
| struct sockaddr_storage remote_addr; |
| struct sockaddr_storage my_addr; |
| int remote_addr_len = sizeof(remote_addr); |
| int my_addr_len = sizeof(my_addr); |
| |
| SOCKET data_socket; |
| int need_socket; |
| |
| int temp_recvs; |
| |
| struct addrinfo *local_res; |
| struct addrinfo *remote_res; |
| |
| struct omni_request_struct *omni_request; |
| struct omni_response_struct *omni_response; |
| struct omni_results_struct *omni_result; |
| |
| #ifdef WANT_FIRST_BURST |
| #define REQUEST_CWND_INITIAL 2 |
| /* "in the beginning..." the WANT_FIRST_BURST stuff was like both |
| Unix and the state of New Jersey - both were simple an unspoiled. |
| then it was realized that some stacks are quite picky about |
| initial congestion windows and a non-trivial initial burst of |
| requests would not be individual segments even with TCP_NODELAY |
| set. so, we have to start tracking a poor-man's congestion window |
| up here in window space because we want to try to make something |
| happen that frankly, we cannot guarantee with the specification |
| of TCP. ain't that grand?-) raj 2006-01-30 */ |
| int requests_outstanding = 0; |
| int request_cwnd = REQUEST_CWND_INITIAL; /* we ass-u-me that having |
| three requests |
| outstanding at the |
| beginning of the test |
| is ok with TCP stacks |
| of interest. the first |
| two will come from our |
| first_burst loop, and |
| the third from our |
| regularly scheduled |
| send */ |
| #endif |
| |
| omni_request = |
| (struct omni_request_struct *)netperf_request.content.test_specific_data; |
| omni_response = |
| (struct omni_response_struct *)netperf_response.content.test_specific_data; |
| omni_result = |
| (struct omni_results_struct *)netperf_response.content.test_specific_data; |
| |
| |
| /* before we start doing things with our own requests and responses |
| lets go ahead and find-out about the remote system. at some point |
| we probably need to put this somewhere else... */ |
| get_remote_system_info(); |
| |
| #ifdef WANT_HISTOGRAM |
| if (verbosity > 1) { |
| time_hist = HIST_new(); |
| } |
| #endif /* WANT_HISTOGRAM */ |
| |
| /* since we are now disconnected from the code that established the |
| control socket, and since we want to be able to use different |
| protocols and such, we are passed the name of the remote host and |
| must turn that into the test specific addressing information. */ |
| |
| complete_addrinfos(&remote_res, |
| &local_res, |
| remote_host, |
| socket_type, |
| protocol, |
| 0); |
| |
| if ( print_headers ) { |
| print_top_test_header("OMNI TEST",local_res,remote_res); |
| } |
| |
| /* initialize a few counters */ |
| |
| need_socket = 1; |
| |
| if (connection_test) |
| pick_next_port_number(local_res,remote_res); |
| |
| |
| /* If the user has requested cpu utilization measurements, we must */ |
| /* calibrate the cpu(s). We will perform this task within the tests */ |
| /* themselves. If the user has specified the cpu rate, then */ |
| /* calibrate_local_cpu will return rather quickly as it will have */ |
| /* nothing to do. If local_cpu_rate is zero, then we will go through */ |
| /* all the "normal" calibration stuff and return the rate back.*/ |
| |
| if (local_cpu_usage) { |
| local_cpu_rate = calibrate_local_cpu(local_cpu_rate); |
| } |
| |
| confidence_iteration = 1; |
| init_stat(); |
| |
| send_ring = NULL; |
| recv_ring = NULL; |
| |
| /* you will keep running the test until you get it right! :) */ |
| while (((confidence < 0) && (confidence_iteration <= iteration_max)) || |
| (confidence_iteration <= iteration_min)) { |
| |
| trans_completed = 0; |
| bytes_xferd = 0.0; |
| remote_bytes_xferd = 0.0; |
| times_up = 0; |
| bytes_sent = 0; |
| bytes_received = 0; |
| local_send_calls = 0; |
| local_receive_calls = 0; |
| |
| #ifdef WANT_FIRST_BURST |
| /* we have to remember to reset the number of transactions |
| outstanding and the "congestion window for each new |
| iteration. raj 2006-01-31 */ |
| requests_outstanding = 0; |
| request_cwnd = REQUEST_CWND_INITIAL; |
| #endif |
| |
| |
| data_socket = create_data_socket(local_res); |
| |
| if (data_socket == INVALID_SOCKET) { |
| perror("netperf: send_omni: unable to create data socket"); |
| exit(1); |
| } |
| need_socket = 0; |
| |
| /* we need to consider if this is a request/response test, if we |
| are receiving, if we are sending, etc, when setting-up our recv |
| and send buffer rings. we should only need to do this once, and |
| that would be when the relevant _ring variable is NULL. raj |
| 2008-01-18 */ |
| if ((direction & NETPERF_XMIT) && (NULL == send_ring)) { |
| if (req_size > 0) { |
| /* request/response test */ |
| if (send_width == 0) send_width = 1; |
| bytes_to_send = req_size; |
| } |
| else { |
| /* stream test */ |
| if (send_size == 0) { |
| if (lss_size > 0) { |
| send_size = lss_size; |
| } |
| else { |
| send_size = 4096; |
| } |
| } |
| if (send_width == 0) |
| send_width = (lss_size/send_size) + 1; |
| if (send_width == 1) send_width++; |
| bytes_to_send = send_size; |
| } |
| |
| send_ring = allocate_buffer_ring(send_width, |
| bytes_to_send, |
| local_send_align, |
| local_send_offset); |
| if (debug) { |
| fprintf(where, |
| "send_omni: %d entry send_ring obtained...\n", |
| send_width); |
| } |
| } |
| |
| if ((direction & NETPERF_RECV) && (NULL == recv_ring)) { |
| if (rsp_size > 0) { |
| if (recv_width == 0) recv_width = 1; |
| bytes_to_recv = rsp_size; |
| } |
| else { |
| /* stream test */ |
| if (recv_size == 0) { |
| if (lsr_size > 0) { |
| recv_size = lsr_size; |
| } |
| else { |
| recv_size = 4096; |
| } |
| } |
| if (recv_width == 0) { |
| recv_width = (lsr_size/recv_size) + 1; |
| if (recv_width == 1) recv_width++; |
| } |
| bytes_to_recv = recv_size; |
| } |
| |
| recv_ring = allocate_buffer_ring(recv_width, |
| bytes_to_recv, |
| local_recv_align, |
| local_recv_offset); |
| if (debug) { |
| fprintf(where, |
| "send_omni: %d entry recv_ring obtained...\n", |
| recv_width); |
| } |
| } |
| |
| if (!no_control) { /* foo */ |
| |
| /* Tell the remote end to do a listen or otherwise prepare for |
| what is to come. The server alters the socket paramters on the |
| other side at this point, hence the reason for all the values |
| being passed in the setup message. If the user did not specify |
| any of the parameters, they will be passed as values which will |
| indicate to the remote that no changes beyond the system's |
| default should be used. Alignment is the exception, it will |
| default to 8, which will probably be no alignment |
| alterations. */ |
| |
| netperf_request.content.request_type = DO_OMNI; |
| omni_request->send_buf_size = rss_size_req; |
| omni_request->send_size = remote_send_size_req; |
| omni_request->send_alignment = remote_send_align; |
| omni_request->send_offset = remote_send_offset; |
| omni_request->send_width = 1; /* FIX THIS */ |
| omni_request->request_size = req_size; |
| |
| omni_request->recv_buf_size = rsr_size_req; |
| omni_request->receive_size = remote_recv_size_req; |
| omni_request->recv_alignment = remote_recv_align; |
| omni_request->recv_offset = remote_recv_offset; |
| omni_request->recv_width = 1; /* FIX THIS */ |
| omni_request->response_size = rsp_size; |
| |
| omni_request->no_delay = rem_nodelay; |
| omni_request->use_sendfile = remote_use_sendfile; |
| omni_request->connect_test = connection_test; |
| |
| omni_request->measure_cpu = remote_cpu_usage; |
| omni_request->cpu_rate = remote_cpu_rate; |
| if (test_time) |
| omni_request->test_length = test_time; |
| else |
| omni_request->test_length = test_trans * -1; |
| omni_request->so_rcvavoid = rem_rcvavoid; |
| omni_request->so_sndavoid = rem_sndavoid; |
| omni_request->send_dirty_count = rem_dirty_count; |
| omni_request->recv_dirty_count = rem_dirty_count; |
| omni_request->recv_clean_count = rem_clean_count; |
| |
| omni_request->checksum_off = remote_checksum_off; |
| omni_request->data_port = atoi(remote_data_port); |
| omni_request->ipfamily = af_to_nf(remote_res->ai_family); |
| omni_request->socket_type = hst_to_nst(socket_type); |
| omni_request->protocol = protocol; |
| |
| omni_request->interval_burst = remote_interval_burst; |
| omni_request->interval_usecs = remote_interval_usecs; |
| |
| omni_request->direction = 0; |
| /* yes, the sense here is correct - if we are transmitting, they |
| receive, if we are receiving, they are transmitting... */ |
| if (direction & NETPERF_XMIT) |
| omni_request->direction |= NETPERF_RECV; |
| if (direction & NETPERF_RECV) |
| omni_request->direction |= NETPERF_XMIT; |
| |
| /* some tests may require knowledge of our local addressing. such |
| tests will for the time being require that the user specify a |
| local IP/name so we can extract them from the data_socket. */ |
| getsockname(data_socket, (struct sockaddr *)&my_addr, &my_addr_len); |
| ret = get_sockaddr_family_addr_port(&my_addr, |
| nf_to_af(omni_request->ipfamily), |
| omni_request->ipaddr, |
| &(omni_request->netperf_port)); |
| |
| if (debug > 1) { |
| fprintf(where,"netperf: send_omni: requesting OMNI test\n"); |
| } |
| |
| |
| send_request(); |
| |
| |
| /* the response from the remote should contain all the relevant |
| socket and other parameters we need to know for this test. |
| so, we can shove them back into the relevant variables here |
| and be on our way. */ |
| |
| recv_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */ |
| |
| if (!netperf_response.content.serv_errno) { |
| rsr_size = omni_response->recv_buf_size; |
| remote_recv_size = omni_response->receive_size; |
| rss_size = omni_response->send_buf_size; |
| remote_send_size = omni_response->send_size; |
| rem_nodelay = omni_response->no_delay; |
| remote_use_sendfile = omni_response->use_sendfile; |
| remote_cpu_usage = omni_response->measure_cpu; |
| remote_cpu_rate = omni_response->cpu_rate; |
| remote_send_width = omni_response->send_width; |
| remote_recv_width = omni_response->recv_width; |
| /* make sure that port numbers are in network order because |
| recv_response will have put everything into host order */ |
| set_port_number(remote_res, |
| (unsigned short)omni_response->data_port); |
| |
| if (debug) { |
| fprintf(where,"remote listen done.\n"); |
| fprintf(where,"remote port is %u\n",get_port_number(remote_res)); |
| fflush(where); |
| } |
| /* just in case the remote didn't null terminate */ |
| if (NULL == remote_system_model) { |
| omni_response->system_model[sizeof(omni_response->system_model)-1] = 0; |
| remote_system_model = strdup(omni_response->system_model); |
| } |
| if (NULL == remote_cpu_model) { |
| omni_response->cpu_model[sizeof(omni_response->cpu_model) -1 ] = 0; |
| remote_cpu_model = strdup(omni_response->cpu_model); |
| } |
| remote_cpu_frequency = omni_response->cpu_frequency; |
| |
| if (NULL == remote_security_specific) { |
| omni_response->security_string[sizeof(omni_response->security_string) - 1] = 0; |
| remote_security_specific = strdup(omni_response->security_string); |
| } |
| /* top bits type, bottom bits enabled */ |
| remote_security_type_id = (int) omni_response->security_info >> 16; |
| remote_security_enabled_num = (short)omni_response->security_info; |
| remote_security_type = nsec_type_to_str(remote_security_type_id); |
| remote_security_enabled = |
| nsec_enabled_to_str(remote_security_enabled_num); |
| } |
| else { |
| Set_errno(netperf_response.content.serv_errno); |
| fprintf(where, |
| "netperf: remote error %d", |
| netperf_response.content.serv_errno); |
| perror(""); |
| fflush(where); |
| exit(1); |
| } |
| |
| } |
| else { |
| if (NULL == remote_system_model) |
| remote_system_model = strdup("Unknown System Model"); |
| if (NULL == remote_cpu_model) |
| remote_cpu_model = strdup("Unknown CPU Model"); |
| remote_cpu_frequency = -1; |
| } |
| |
| #ifdef WANT_DEMO |
| /* at some point we will have to be more clever about this, but |
| for now we won't */ |
| |
| DEMO_RR_SETUP(100); |
| #endif |
| |
| /* if we are not a connectionless protocol, we need to connect. at |
| some point even if we are a connectionless protocol, we may |
| still want to "connect" for convenience raj 2008-01-14 */ |
| need_to_connect = (protocol != IPPROTO_UDP); |
| |
| /* Set-up the test end conditions. For tests over a |
| "reliable/connection-oriented" transport (eg TCP, SCTP, etc) this |
| can be either time or byte/transaction count based. for |
| unreliable transport or connection tests it can only be time |
| based. having said that, we rely entirely on other code to |
| enforce this before we even get here. raj 2008-01-08 */ |
| |
| if (test_time) { |
| /* The user wanted to end the test after a period of time. if |
| we are a recv-only test, we need to protect ourself against |
| the remote going poof, but we want to make sure we don't |
| give-up before they finish, so we will add a PAD_TIME to the |
| timer. if we are RR or XMIT, there should be no need for |
| padding */ |
| times_up = 0; |
| units_remaining = 0; |
| if ((!no_control) && (NETPERF_RECV_ONLY(direction))) |
| pad_time = PAD_TIME; |
| start_timer(test_time + pad_time); |
| } |
| else { |
| /* The tester wanted to send a number of bytes or exchange a |
| number of transactions. */ |
| if (NETPERF_IS_RR(direction)) |
| units_remaining = test_trans; |
| else |
| units_remaining = test_bytes; |
| times_up = 1; |
| } |
| |
| /* grab the current time, and if necessary any starting information |
| for the gathering of CPU utilization at this end. */ |
| cpu_start(local_cpu_usage); |
| |
| #if defined(WANT_INTERVALS) |
| INTERVALS_INIT(); |
| #endif /* WANT_INTERVALS */ |
| |
| #ifdef WANT_DEMO |
| if (demo_mode) { |
| HIST_timestamp(demo_one_ptr); |
| } |
| #endif |
| |
| /* the "OR" here allows us to control test length by either |
| byte/transaction count or by timer. when the test is |
| byte/transaction count based the time test will always evaluate |
| false. when the test is controlled by time, the byte/transaction |
| count will always evaluate to false. when the test is finished |
| the whole expression will go false and we will stop sending |
| data. at least that is the plan :) raj 2008-01-08 */ |
| |
| while ((!times_up) || (units_remaining > 0)) { |
| |
| #ifdef WANT_HISTOGRAM |
| /* only pull the timestamp if we are actually going to use the |
| results of the work. we put the call here so it can work for |
| any sort of test - connection, request/response, or stream. |
| no, it isn't "perfect" for all of them - for some it will |
| include a few more "if's" than a purpose-written routine, but |
| it _should_ be the case that the time spent up here is |
| epsilon compared to time spent elsewhere in the stack so it |
| should not be a big deal. famous last words of raj |
| 2008-01-08 */ |
| if (verbosity > 1) { |
| HIST_timestamp(&time_one); |
| } |
| #endif /* WANT_HISTOGRAM */ |
| |
| again: |
| |
| if (need_socket) { |
| if (connection_test) |
| pick_next_port_number(local_res,remote_res); |
| |
| data_socket = create_data_socket(local_res); |
| |
| if (data_socket == INVALID_SOCKET) { |
| perror("netperf: send_omni: unable to create data socket"); |
| exit(1); |
| } |
| need_socket = 0; |
| } |
| |
| /* only connect if and when we need to */ |
| if (need_to_connect) { |
| /* assign to data_socket since connect_data_socket returns |
| SOCKET and not int thanks to Windows. */ |
| ret = connect_data_socket(data_socket,remote_res); |
| if (ret == 0) { |
| connected = 1; |
| need_to_connect = 0; |
| } |
| else if (ret == -1) { |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else if ((ret == -2) && connection_test) { |
| /* transient error on a connection test means go around and |
| try again with another local port number */ |
| fprintf(where,"transient! transient! torpedo in the water!\n"); |
| fflush(where); |
| close(data_socket); |
| connected = 0; /* probably redundant but what the heck... */ |
| need_socket = 1; |
| need_to_connect = 1; |
| /* this will stuff the next local port number within bounds |
| into our local res, and then when the goto has us |
| allocating a new socket it will do the right thing with the |
| bind() call */ |
| pick_next_port_number(local_res,remote_res); |
| goto again; |
| } |
| else { |
| /* either this was a hard failure (-3) or a soft failure on |
| something other than a connection test */ |
| perror("netperf: send_omni: connect_data_socket failed"); |
| exit(1); |
| } |
| } |
| |
| #ifdef WANT_FIRST_BURST |
| /* we can inject no more than request_cwnd, which will grow with |
| time, and no more than first_burst_size. we don't use <= to |
| account for the "regularly scheduled" send call. of course |
| that makes it more a "max_outstanding_ than a |
| "first_burst_size" but for now we won't fix the names. also, |
| I suspect the extra check against < first_burst_size is |
| redundant since later I expect to make sure that request_cwnd |
| can never get larger than first_burst_size, but just at the |
| moment I'm feeling like a belt and suspenders kind of |
| programmer. raj 2006-01-30 */ |
| /* we only want to inject the burst if this is a full-on |
| request/response test. otherwise it doesn't make any sense |
| anyway. raj 2008-01-25 */ |
| while ((first_burst_size > 0) && |
| (requests_outstanding < request_cwnd) && |
| (requests_outstanding < first_burst_size) && |
| (NETPERF_IS_RR(direction)) && |
| (!connection_test)) { |
| if (debug) { |
| fprintf(where, |
| "injecting, req_outstanding %d req_cwnd %d burst %d\n", |
| requests_outstanding, |
| request_cwnd, |
| first_burst_size); |
| } |
| if ((ret = send_data(data_socket, |
| send_ring, |
| bytes_to_send, |
| (connected) ? NULL : remote_res->ai_addr, |
| remote_res->ai_addrlen)) != bytes_to_send) { |
| /* in theory, we should never hit the end of the test in the |
| first burst */ |
| perror("send_omni: initial burst data send error"); |
| exit(-1); |
| } |
| local_send_calls += 1; |
| requests_outstanding += 1; |
| } |
| |
| #endif /* WANT_FIRST_BURST */ |
| |
| /* if we should try to send something, then by all means, let us |
| try to send something. */ |
| if (direction & NETPERF_XMIT) { |
| ret = send_data(data_socket, |
| send_ring, |
| bytes_to_send, |
| (connected) ? NULL : remote_res->ai_addr, |
| /* if the destination above is NULL, this is ignored */ |
| remote_res->ai_addrlen); |
| /* the order of these if's will seem a triffle strange, but they |
| are my best guess as to order of probabilty and/or importance |
| to the overhead raj 2008-01-09*/ |
| if (ret == bytes_to_send) { |
| /* if this is a send-only test controlled by byte count we |
| decrement units_remaining by the bytes sent */ |
| if (!(direction & NETPERF_RECV) && (units_remaining > 0)) { |
| units_remaining -= ret; |
| } |
| bytes_sent += ret; |
| send_ring = send_ring->next; |
| local_send_calls++; |
| } |
| else if (ret == -2) { |
| /* what to do here -2 means a non-fatal error - probably |
| ENOBUFS and so our send didn't happen. in the old code for |
| UDP_STREAM we would just continue in the while loop. it |
| isn't clear that is what to do here, so we will simply |
| increment the failed_sends stat and fall-through. If this |
| is a UDP_STREAM style of test, the net effect should be the |
| same. if this is a UDP_RR with a really-big burst count, I |
| don't think we were checking for ENOBUFS there anyway and |
| so would have failed. Here we can just let things |
| slide. */ |
| failed_sends++; |
| } |
| else if (ret == 0) { |
| /* was this a zero-byte send? if it was, then ostensibly we |
| would hit the ret == bytes_to_send case which means we'd |
| never get here as we are using blocking semantics */ |
| fprintf(where,"HOW DID I GET HERE?\n"); |
| fflush(where); |
| } |
| else if (ret == -1) { |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else { |
| perror("netperf: send_omni: send_data failed"); |
| exit(1); |
| } |
| |
| } |
| |
| #ifdef WANT_FIRST_BURST |
| /* it isn't clear we need to check the directions here. the |
| increment should be cheaper than the conditional, and it |
| shouldn't hurt the other directions because they'll never |
| look at them. famous last words of raj 2008-01-25 */ |
| requests_outstanding += 1; |
| #endif |
| |
| if (direction & NETPERF_RECV) { |
| rret = recv_data(data_socket, |
| recv_ring, |
| bytes_to_recv, |
| (connected) ? NULL : (struct sockaddr *)&remote_addr, |
| /* if remote_addr NULL this is ignored */ |
| &remote_addr_len, |
| /* if XMIT also set this is RR so waitall */ |
| (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0, |
| &temp_recvs); |
| if (rret > 0) { |
| /* if this is a recv-only test controlled by byte count we |
| decrement the units_remaining by the bytes received */ |
| if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) { |
| units_remaining -= rret; |
| } |
| bytes_received += rret; |
| local_receive_calls += temp_recvs; |
| } |
| else if (rret == 0) { |
| /* is this the end of a test, just a zero-byte recv, or |
| something else? that is an exceedingly good question and |
| one for which I don't presently have a good answer, but |
| that won't stop me from guessing :) raj 2008-01-09 */ |
| if (!((connection_test) || (null_message_ok))) { |
| /* if it is neither a connection_test nor null_message_ok it |
| must be the end of the test */ |
| times_up = 1; /* ostensibly the signal handler did this */ |
| break; |
| } |
| local_receive_calls += temp_recvs; |
| } |
| else if (rret == -1) { |
| /* test timed-out */ |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else { |
| /* presently at least, -2 and -3 are equally bad on recv */ |
| perror("netperf: send_omni: recv_data failed"); |
| exit(1); |
| } |
| recv_ring = recv_ring->next; |
| |
| #ifdef WANT_FIRST_BURST |
| /* so, since we've gotten a response back, update the |
| bookkeeping accordingly. there is one less request |
| outstanding and we can put one more out there than before. */ |
| requests_outstanding -= 1; |
| if ((request_cwnd < first_burst_size) && |
| (NETPERF_IS_RR(direction))) { |
| request_cwnd += 1; |
| if (debug) { |
| fprintf(where, |
| "incr req_cwnd to %d first_burst %d reqs_outstndng %d\n", |
| request_cwnd, |
| first_burst_size, |
| requests_outstanding); |
| } |
| } |
| #endif |
| |
| } |
| |
| /* if this is a connection test, we want to do some stuff about |
| connection close here in the test loop. raj 2008-01-08 */ |
| if (connection_test) { |
| |
| #ifdef __linux |
| /* so, "Linux" with autotuning likes to alter the socket buffer |
| sizes over the life of the connection, but only does so when |
| one takes the defaults at time of socket creation. if we |
| took those defaults, we should inquire as to what the values |
| ultimately became. raj 2008-01-15 */ |
| if (lsr_size_req < 0) |
| get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); |
| else |
| lsr_size_end = lsr_size; |
| if (lss_size_req < 0) |
| get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); |
| else |
| lss_size_end = lss_size; |
| #else |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| #endif |
| |
| /* we will only make this call the one time - after the first |
| call, the value will be real or -1. if this is a connection |
| test we want to do this here because later we won't be |
| connected and the data may no longer be available */ |
| if (transport_mss == -2) |
| get_transport_info(data_socket, |
| &transport_mss, |
| local_res->ai_protocol); |
| |
| |
| ret = disconnect_data_socket(data_socket, |
| (no_control) ? 1 : 0, |
| 1, |
| NULL, |
| 0); |
| if (ret == 0) { |
| /* we will need a new connection to be established next time |
| around the loop */ |
| need_to_connect = 1; |
| connected = 0; |
| need_socket = 1; |
| pick_next_port_number(local_res,remote_res); |
| } |
| else if (ret == -1) { |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else { |
| perror("netperf: send_omni: disconnect_data_socket failed"); |
| exit(1); |
| } |
| } |
| |
| |
| #ifdef WANT_HISTOGRAM |
| if (verbosity > 1) { |
| HIST_timestamp(&time_two); |
| HIST_add(time_hist,delta_micro(&time_one,&time_two)); |
| } |
| #endif /* WANT_HISTOGRAM */ |
| |
| #ifdef WANT_DEMO |
| if (NETPERF_IS_RR(direction)) { |
| DEMO_INTERVAL(1); |
| } |
| else if (NETPERF_XMIT_ONLY(direction)) { |
| DEMO_INTERVAL(bytes_to_send); |
| } |
| else { |
| DEMO_INTERVAL(rret); |
| } |
| #endif |
| |
| #if defined(WANT_INTERVALS) |
| INTERVALS_WAIT(); |
| #endif /* WANT_INTERVALS */ |
| |
| |
| /* was this a "transaction" test? */ |
| if (NETPERF_IS_RR(direction)) { |
| trans_completed++; |
| if (units_remaining) { |
| units_remaining--; |
| } |
| } |
| |
| |
| } |
| |
| /* we are now, ostensibly, at the end of this iteration */ |
| |
| if (transport_mss == -2) |
| get_transport_info(data_socket, |
| &transport_mss, |
| local_res->ai_protocol); |
| |
| |
| find_security_info(&local_security_enabled_num, |
| &local_security_type_id, |
| &local_security_specific); |
| local_security_enabled = nsec_enabled_to_str(local_security_enabled_num); |
| local_security_type = nsec_type_to_str(local_security_type_id); |
| |
| /* so, if we have/had a data connection, we will want to close it |
| now, and this will be independent of whether there is a control |
| connection. */ |
| |
| if (connected) { |
| |
| #ifdef __linux |
| /* so, "Linux" with autotuning likes to alter the socket buffer |
| sizes over the life of the connection, but only does so when |
| one takes the defaults at time of socket creation. if we took |
| those defaults, we should inquire as to what the values |
| ultimately became. raj 2008-01-15 */ |
| if (lsr_size_req < 0) |
| get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); |
| else |
| lsr_size_end = lsr_size; |
| if (lss_size_req < 0) |
| get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); |
| else |
| lss_size_end = lss_size; |
| #else |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| #endif |
| /* CHECK PARMS HERE; */ |
| ret = disconnect_data_socket(data_socket, |
| 1, |
| 1, |
| NULL, |
| 0); |
| connected = 0; |
| need_socket = 1; |
| |
| } |
| else { |
| /* this is the UDP case at present */ |
| ret = disconnect_data_socket(data_socket, |
| 1, |
| 1, |
| remote_res->ai_addr, |
| remote_res->ai_addrlen); |
| need_socket = 1; |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| } |
| |
| /* this call will always give us the elapsed time for the test, and |
| will also store-away the necessaries for cpu utilization */ |
| |
| cpu_stop(local_cpu_usage,&elapsed_time); |
| |
| find_system_info(&local_system_model, |
| &local_cpu_model, |
| &local_cpu_frequency); |
| |
| local_interface_name = |
| find_egress_interface(local_res->ai_addr,remote_res->ai_addr); |
| |
| find_driver_info(local_interface_name,local_driver_name,local_driver_version,local_driver_firmware,local_driver_bus,32); |
| |
| local_interface_slot = find_interface_slot(local_interface_name); |
| |
| find_interface_ids(local_interface_name, |
| &local_interface_vendor, |
| &local_interface_device, |
| &local_interface_subvendor, |
| &local_interface_subdevice); |
| |
| /* if we timed-out, and had padded the timer, we need to subtract |
| the pad_time from the elapsed time on the assumption that we |
| were essentially idle for pad_time and just waiting for a timer |
| to expire on something like a UDP test. if we have not padded |
| the timer, pad_time will be zero. if we have not timed out |
| then we want to make sure we stop the timer. */ |
| if (timed_out) { |
| if (debug) { |
| fprintf(where,"Adjusting elapsed_time by %d seconds\n",pad_time); |
| fflush(where); |
| } |
| elapsed_time -= (float)pad_time; |
| } |
| else { |
| stop_timer(); |
| } |
| |
| if (!no_control) { |
| /* Get the statistics from the remote end. The remote will have |
| calculated service demand and all those interesting things. If |
| it wasn't supposed to care, it will return obvious values. */ |
| |
| recv_response_n(OMNI_RESULTS_CONF_CUTOFF); |
| if (!netperf_response.content.serv_errno) { |
| if (debug) |
| fprintf(where,"remote results obtained\n"); |
| remote_cpu_method = format_cpu_method(omni_result->cpu_method); |
| /* why? because some stacks want to be clever and autotune their |
| socket buffer sizes, which means that if we accept the defaults, |
| the size we get from getsockopt() at the beginning of a |
| connection may not be what we would get at the end of the |
| connection... */ |
| lib_num_rem_cpus = omni_result->num_cpus; |
| lib_remote_peak_cpu_util = (double)omni_result->peak_cpu_util; |
| lib_remote_peak_cpu_id = omni_result->peak_cpu_id; |
| rsr_size_end = omni_result->recv_buf_size; |
| rss_size_end = omni_result->send_buf_size; |
| remote_bytes_sent = (uint64_t)omni_result->bytes_sent_hi << 32; |
| remote_bytes_sent += omni_result->bytes_sent_lo; |
| remote_send_calls = omni_result->send_calls; |
| remote_bytes_received = (uint64_t)omni_result->bytes_received_hi << 32; |
| remote_bytes_received += omni_result->bytes_received_lo; |
| remote_receive_calls = omni_result->recv_calls; |
| remote_bytes_xferd = remote_bytes_received + remote_bytes_sent; |
| if (omni_result->recv_calls > 0) |
| remote_bytes_per_recv = (double) remote_bytes_received / |
| (double) omni_result->recv_calls; |
| else |
| remote_bytes_per_recv = 0.0; |
| if (omni_result->send_calls > 0) |
| remote_bytes_per_send = (double) remote_bytes_sent / |
| (double) omni_result->send_calls; |
| else |
| remote_bytes_per_send = 0.0; |
| omni_result->ifname[15] = 0; /* belt and suspenders */ |
| remote_interface_name = strdup(omni_result->ifname); |
| remote_interface_slot = strdup(omni_result->ifslot); |
| strncpy(remote_driver_name,omni_result->driver,32); |
| strncpy(remote_driver_version,omni_result->version,32); |
| strncpy(remote_driver_firmware,omni_result->firmware,32); |
| strncpy(remote_driver_bus,omni_result->bus,32); |
| remote_driver_name[31] = 0; |
| remote_driver_version[31] = 0; |
| remote_driver_firmware[31] = 0; |
| remote_driver_bus[31] = 0; |
| remote_interface_vendor = omni_result->vendor; |
| remote_interface_device = omni_result->device; |
| remote_interface_subvendor = omni_result->subvendor; |
| remote_interface_subdevice = omni_result->subdevice; |
| } |
| else { |
| Set_errno(netperf_response.content.serv_errno); |
| fprintf(where, |
| "netperf: remote error %d", |
| netperf_response.content.serv_errno); |
| perror(""); |
| fflush(where); |
| |
| exit(1); |
| } |
| } |
| |
| /* so, what was the end result? */ |
| local_cpu_method = format_cpu_method(cpu_method); |
| |
| if (local_send_calls > 0) |
| bytes_per_send = (double) bytes_sent / (double) local_send_calls; |
| else bytes_per_send = 0.0; |
| |
| if (local_receive_calls > 0) |
| bytes_per_recv = (double) bytes_received / (double) local_receive_calls; |
| else |
| bytes_per_recv = 0.0; |
| |
| bytes_xferd = bytes_sent + bytes_received; |
| |
| /* if the output format is 'x' we know the test was |
| request/response. if the libfmt is something else, it could be |
| xmit, recv or bidirectional. if we were the receiver then we |
| can use our byte totals even if it is |
| UDP/unreliable. otherwise, we use the remote totals - they |
| should be the same if the protocol is reliable, and if it is |
| unreliable then we want what was actually received */ |
| if ('x' == libfmt) |
| /* it was a request/response test */ |
| thruput = calc_thruput(trans_completed); |
| else if (NETPERF_RECV_ONLY(direction)) |
| thruput = calc_thruput(bytes_xferd); |
| else |
| thruput = calc_thruput(remote_bytes_xferd); |
| |
| if (NETPERF_IS_RR(direction)) { |
| char tmpfmt; |
| if (!connection_test) { |
| /* calculate the round trip latency, using the transaction rate |
| whether or not the user was asking for thruput to be in 'x' |
| units please... however... a connection_test only ever has |
| one transaction in flight at one time */ |
| rtt_latency = |
| (((double)1.0/(trans_completed/elapsed_time)) * (double)1000000.0) * |
| (double) (1 + ((first_burst_size > 0) ? first_burst_size : 0)); |
| } |
| else |
| rtt_latency = |
| ((double)1.0/(trans_completed/elapsed_time)) * (double)1000000.0; |
| tmpfmt = libfmt; |
| libfmt = 'x'; |
| transaction_rate = calc_thruput(trans_completed); |
| libfmt = tmpfmt; |
| } |
| |
| /* ok, time to possibly calculate cpu util and/or service demand */ |
| if (local_cpu_usage) { |
| |
| local_cpu_utilization = calc_cpu_util(elapsed_time); |
| |
| /* we need to decide what to feed the service demand beast, |
| which will, ultimately, depend on what sort of test it is and |
| whether or not the user asked for something specific - as in |
| per KB even on a TCP_RR test if it is being (ab)used as a |
| bidirectional bulk-transfer test. raj 2008-01-14 */ |
| local_service_demand = |
| calc_service_demand_fmt(('x' == libfmt) ? (double)trans_completed: bytes_xferd, |
| 0.0, |
| 0.0, |
| 0); |
| } |
| else { |
| local_cpu_utilization = (float) -1.0; |
| local_service_demand = (float) -1.0; |
| } |
| |
| if (remote_cpu_usage) { |
| |
| remote_cpu_utilization = omni_result->cpu_util; |
| |
| /* since calc_service demand is doing ms/Kunit we will */ |
| /* multiply the number of transaction by 1024 to get */ |
| /* "good" numbers */ |
| remote_service_demand = |
| calc_service_demand_fmt(('x' == libfmt) ? (double) trans_completed: bytes_xferd, |
| 0.0, |
| remote_cpu_utilization, |
| omni_result->num_cpus); |
| } |
| else { |
| remote_cpu_utilization = (float) -1.0; |
| remote_service_demand = (float) -1.0; |
| } |
| |
| /* time to calculate our confidence */ |
| calculate_confidence(confidence_iteration, |
| elapsed_time, |
| thruput, |
| local_cpu_utilization, |
| remote_cpu_utilization, |
| local_service_demand, |
| remote_service_demand); |
| |
| /* this this is the end of the confidence while loop? */ |
| confidence_iteration++; |
| } |
| |
| /* we end with confidence_iteration one larger than the number of |
| iterations. if we weren't doing confidence intervals this will |
| still be reported as one */ |
| confidence_iteration--; |
| |
| /* at some point we may want to actually display some results :) */ |
| |
| retrieve_confident_values(&elapsed_time, |
| &thruput, |
| &local_cpu_utilization, |
| &remote_cpu_utilization, |
| &local_service_demand, |
| &remote_service_demand); |
| |
| /* a kludge for omni printing because I don't know how to tell that |
| something is a float vs a double in my_snprintf() given what it |
| is passed and I'm not ready to force all the netlib.c stuff to |
| use doubles rather than floats. help there would be |
| appreciated. raj 2008-01-28 */ |
| elapsed_time_double = (double) elapsed_time; |
| local_cpu_utilization_double = (double)local_cpu_utilization; |
| local_service_demand_double = (double)local_service_demand; |
| remote_cpu_utilization_double = (double)remote_cpu_utilization; |
| remote_service_demand_double = (double)remote_service_demand; |
| |
| if ('x' == libfmt) sd_str = "usec/Tran"; |
| else sd_str = "usec/KB"; |
| |
| if (iteration_max > 1) { |
| result_confid_pct = get_result_confid(); |
| loc_cpu_confid_pct = get_loc_cpu_confid(); |
| rem_cpu_confid_pct = get_rem_cpu_confid(); |
| interval_pct = interval * 100.0; |
| } |
| |
| /* at some point we need to average these during a confidence |
| interval run, and when we do do that, we need to make sure we |
| restore the value of libfmt correctly */ |
| if ('x' == libfmt) libfmt = 'm'; |
| local_send_thruput = calc_thruput(bytes_sent); |
| local_recv_thruput = calc_thruput(bytes_received); |
| remote_send_thruput = calc_thruput(remote_bytes_sent); |
| remote_recv_thruput = calc_thruput(remote_bytes_received); |
| |
| print_omni(); |
| |
| #if defined(DEBUG_OMNI_OUTPUT) |
| { |
| /* just something quick to sanity check the output selectors. this |
| should be gone for "production" :) */ |
| int i; |
| print_omni_init(); |
| output_csv_list[1] = OUTPUT_END; |
| for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++) { |
| output_csv_list[0] = i; |
| print_omni_csv(); |
| } |
| } |
| #endif |
| |
| /* likely as not we are going to do something slightly different here */ |
| if (verbosity > 1) { |
| |
| #ifdef WANT_HISTOGRAM |
| fprintf(where,"\nHistogram of "); |
| if (NETPERF_RECV_ONLY(direction)) |
| fprintf(where,"recv"); |
| if (NETPERF_XMIT_ONLY(direction)) |
| fprintf(where,"send"); |
| if (NETPERF_IS_RR(direction)) { |
| if (connection_test) { |
| if (NETPERF_CC(direction)) { |
| fprintf(where,"connect/close"); |
| } |
| else { |
| fprintf(where,"connect/request/response/close"); |
| } |
| } |
| else { |
| fprintf(where,"request/response"); |
| } |
| } |
| fprintf(where," times\n"); |
| fflush(where); |
| HIST_report(time_hist); |
| #endif /* WANT_HISTOGRAM */ |
| |
| } |
| |
| } |
| |
| |
| |
| /* the name is something of a misnomer since this test could send, or |
| receive, or both, but it matches the historical netperf routine |
| naming. */ |
| void |
| recv_omni() |
| { |
| |
| char *message; |
| struct addrinfo *local_res; |
| char local_name[BUFSIZ]; |
| char port_buffer[PORTBUFSIZE]; |
| |
| struct sockaddr_storage myaddr_in, peeraddr_in; |
| SOCKET s_listen, data_socket; |
| netperf_socklen_t addrlen; |
| |
| struct ring_elt *send_ring; |
| struct ring_elt *recv_ring; |
| |
| int timed_out = 0; |
| int pad_time = 0; |
| int need_to_connect; |
| int need_to_accept; |
| int connected; |
| int ret; |
| int temp_recvs; |
| |
| struct omni_request_struct *omni_request; |
| struct omni_response_struct *omni_response; |
| struct omni_results_struct *omni_results; |
| |
| omni_request = |
| (struct omni_request_struct *)netperf_request.content.test_specific_data; |
| omni_response = |
| (struct omni_response_struct *)netperf_response.content.test_specific_data; |
| omni_results = |
| (struct omni_results_struct *)netperf_response.content.test_specific_data; |
| |
| if (debug) { |
| fprintf(where,"netserver: recv_omni: entered...\n"); |
| fflush(where); |
| } |
| |
| /* based on what we have been told by the remote netperf, we want to |
| setup our endpoint for the "data connection" and let the remote |
| netperf know the situation. */ |
| |
| if (debug) { |
| fprintf(where,"recv_omni: setting the response type...\n"); |
| fflush(where); |
| } |
| |
| netperf_response.content.response_type = OMNI_RESPONSE; |
| |
| if (debug) { |
| fprintf(where,"recv_omni: the response type is set...\n"); |
| fflush(where); |
| } |
| |
| /* Grab a socket to listen on, and then listen on it. */ |
| |
| if (debug) { |
| fprintf(where,"recv_omni: grabbing a socket...\n"); |
| fflush(where); |
| } |
| |
| /* create_data_socket expects to find some things in the global |
| variables, so set the globals based on the values in the request. |
| once the socket has been created, we will set the response values |
| based on the updated value of those globals. raj 7/94 */ |
| lss_size_req = omni_request->send_buf_size; |
| lsr_size_req = omni_request->recv_buf_size; |
| loc_nodelay = omni_request->no_delay; |
| loc_rcvavoid = omni_request->so_rcvavoid; |
| loc_sndavoid = omni_request->so_sndavoid; |
| |
| #ifdef WANT_INTERVALS |
| interval_usecs = omni_request->interval_usecs; |
| interval_wate = interval_usecs / 1000; |
| interval_burst = omni_request->interval_burst; |
| #else |
| interval_usecs = 0; |
| interval_wate = 1; |
| interval_burst = 0; |
| #endif |
| |
| connection_test = omni_request->connect_test; |
| direction = omni_request->direction; |
| |
| set_hostname_and_port(local_name, |
| port_buffer, |
| nf_to_af(omni_request->ipfamily), |
| omni_request->data_port); |
| |
| local_res = complete_addrinfo(local_name, |
| local_name, |
| port_buffer, |
| nf_to_af(omni_request->ipfamily), |
| nst_to_hst(omni_request->socket_type), |
| omni_request->protocol, |
| 0); |
| |
| s_listen = create_data_socket(local_res); |
| |
| if (s_listen == INVALID_SOCKET) { |
| netperf_response.content.serv_errno = errno; |
| send_response(); |
| if (debug) { |
| fprintf(where,"could not create data socket\n"); |
| fflush(where); |
| } |
| exit(1); |
| } |
| |
| /* We now alter the message_ptr variables to be at the desired */ |
| /* alignments with the desired offsets. */ |
| |
| if (debug) { |
| fprintf(where, |
| "recv_omni: requested recv alignment of %d offset %d\n", |
| omni_request->recv_alignment, |
| omni_request->recv_offset); |
| fprintf(where, |
| "recv_omni: requested send alignment of %d offset %d\n", |
| omni_request->send_alignment, |
| omni_request->send_offset); |
| fflush(where); |
| } |
| |
| omni_response->send_size = omni_request->send_size; |
| omni_response->send_width = omni_request->send_width; |
| if (omni_request->direction & NETPERF_XMIT) { |
| if (omni_request->response_size > 0) { |
| /* request/response_test */ |
| bytes_to_send = omni_request->response_size; |
| if (omni_request->send_width == 0) send_width = 1; |
| else send_width = omni_request->send_width; |
| } |
| else { |
| if (omni_request->send_size == -1) { |
| if (lss_size > 0) bytes_to_send = lss_size; |
| else bytes_to_send = 4096; |
| } |
| else bytes_to_send = omni_request->send_size; |
| /* set the send_width */ |
| if (omni_request->send_width == 0) { |
| send_width = (lss_size/bytes_to_send) + 1; |
| if (send_width == 1) send_width++; |
| } |
| else |
| send_width = omni_request->send_width; |
| } |
| send_ring = allocate_buffer_ring(send_width, |
| bytes_to_send, |
| omni_request->send_alignment, |
| omni_request->send_offset); |
| |
| omni_response->send_width = send_width; |
| omni_response->send_size = bytes_to_send; |
| } |
| |
| omni_response->receive_size = omni_request->receive_size; |
| omni_response->recv_width = omni_response->recv_width; |
| if (omni_request->direction & NETPERF_RECV) { |
| if (omni_request->request_size > 0) { |
| /* request/response test */ |
| bytes_to_recv = omni_request->request_size; |
| if (omni_request->recv_width == 0) recv_width = 1; |
| else recv_width = omni_request->recv_width; |
| } |
| else { |
| if (omni_request->receive_size == -1) { |
| if (lsr_size > 0) bytes_to_recv = lsr_size; |
| else bytes_to_recv = 4096; |
| } |
| else { |
| bytes_to_recv = omni_request->receive_size; |
| } |
| /* set the recv_width */ |
| if (omni_request->recv_width == 0) { |
| recv_width = (lsr_size/bytes_to_recv) + 1; |
| if (recv_width == 1) recv_width++; |
| } |
| else |
| recv_width = omni_request->recv_width; |
| } |
| recv_ring = allocate_buffer_ring(recv_width, |
| bytes_to_recv, |
| omni_request->recv_alignment, |
| omni_request->recv_offset); |
| |
| omni_response->receive_size = bytes_to_recv; |
| omni_response->recv_width = recv_width; |
| } |
| |
| #ifdef WIN32 |
| /* The test timer can fire during operations on the listening socket, |
| so to make the start_timer below work we have to move |
| it to close s_listen while we are blocked on accept. */ |
| win_kludge_socket2 = s_listen; |
| #endif |
| |
| need_to_accept = (omni_request->protocol != IPPROTO_UDP); |
| |
| /* we need to hang a listen for everything that needs at least one |
| accept */ |
| if (need_to_accept) { |
| if (listen(s_listen, 5) == SOCKET_ERROR) { |
| netperf_response.content.serv_errno = errno; |
| close(s_listen); |
| send_response(); |
| if (debug) { |
| fprintf(where,"could not listen\n"); |
| fflush(where); |
| } |
| exit(1); |
| } |
| } |
| |
| /* now get the port number assigned by the system */ |
| addrlen = sizeof(myaddr_in); |
| if (getsockname(s_listen, |
| (struct sockaddr *)&myaddr_in, |
| &addrlen) == SOCKET_ERROR){ |
| netperf_response.content.serv_errno = errno; |
| close(s_listen); |
| send_response(); |
| if (debug) { |
| fprintf(where,"could not getsockname\n"); |
| fflush(where); |
| } |
| exit(1); |
| } |
| |
| /* Now myaddr_in contains the port and the internet address this is |
| returned to the sender also implicitly telling the sender that |
| the socket buffer sizing has been done. likely as not, the IP |
| address will be the wildcard - so we only really need to extract |
| the port number. since send_response is going to call htonl on |
| all the fields, we want to initially put the port number in there |
| in host order. */ |
| |
| omni_response->data_port = |
| (int) ntohs(((struct sockaddr_in *)&myaddr_in)->sin_port); |
| if (debug) { |
| fprintf(where,"telling the remote to call me at %d\n", |
| omni_response->data_port); |
| fflush(where); |
| } |
| netperf_response.content.serv_errno = 0; |
| |
| /* But wait, there's more. If the initiator wanted cpu measurements, */ |
| /* then we must call the calibrate routine, which will return the max */ |
| /* rate back to the initiator. If the CPU was not to be measured, or */ |
| /* something went wrong with the calibration, we will return a 0.0 to */ |
| /* the initiator. */ |
| |
| omni_response->cpu_rate = (float)0.0; /* assume no cpu */ |
| omni_response->measure_cpu = 0; |
| if (omni_request->measure_cpu) { |
| omni_response->measure_cpu = 1; |
| omni_response->cpu_rate = |
| calibrate_local_cpu(omni_request->cpu_rate); |
| } |
| |
| /* before we send the response back to the initiator, pull some of */ |
| /* the socket parms from the globals */ |
| omni_response->send_buf_size = lss_size; |
| omni_response->recv_buf_size = lsr_size; |
| omni_response->no_delay = loc_nodelay; |
| omni_response->so_rcvavoid = loc_rcvavoid; |
| omni_response->so_sndavoid = loc_sndavoid; |
| omni_response->interval_usecs = interval_usecs; |
| omni_response->interval_burst = interval_burst; |
| |
| find_system_info(&local_system_model,&local_cpu_model,&local_cpu_frequency); |
| strncpy(omni_response->system_model,local_system_model,sizeof(omni_response->system_model)); |
| omni_response->system_model[sizeof(omni_response->system_model)-1] = 0; |
| strncpy(omni_response->cpu_model,local_cpu_model,sizeof(omni_response->cpu_model)); |
| omni_response->cpu_model[sizeof(omni_response->cpu_model)-1] = 0; |
| omni_response->cpu_frequency = local_cpu_frequency; |
| |
| find_security_info(&local_security_enabled_num, |
| &local_security_type_id, |
| &local_security_specific); |
| /* top bits type, bottom bits enabled */ |
| omni_response->security_info = local_security_type_id << 16; |
| omni_response->security_info += local_security_enabled_num & 0xffff; |
| strncpy(omni_response->security_string, |
| local_security_specific, |
| sizeof(omni_response->security_string)); |
| omni_response->security_string[sizeof(omni_response->security_string)-1] = 0; |
| |
| send_response_n(OMNI_RESPONSE_CONV_CUTOFF); /* brittle, but functional */ |
| |
| local_send_calls = 0; |
| local_receive_calls = 0; |
| |
| addrlen = sizeof(peeraddr_in); |
| memset(&peeraddr_in,0,sizeof(peeraddr_in)); |
| |
| /* Now it's time to start receiving data on the connection. We will */ |
| /* first grab the apropriate counters and then start grabbing. */ |
| |
| cpu_start(omni_request->measure_cpu); |
| |
| /* if the test is timed, set a timer of suitable length. if the |
| test is by byte/transaction count, we don't need a timer - or |
| rather we rely on the netperf to only ask us to do transaction |
| counts over "reliable" protocols. perhaps at some point we |
| should add a check herebouts to verify that... */ |
| |
| if (omni_request->test_length > 0) { |
| times_up = 0; |
| units_remaining = 0; |
| /* if we are the sender and only sending, then we don't need/want |
| the padding, otherwise, we need the padding */ |
| if (!(NETPERF_XMIT_ONLY(omni_request->direction))) |
| pad_time = PAD_TIME; |
| start_timer(omni_request->test_length + pad_time); |
| } |
| else { |
| times_up = 1; |
| units_remaining = omni_request->test_length * -1; |
| } |
| |
| #if defined(WANT_INTERVALS) |
| INTERVALS_INIT(); |
| #endif /* WANT_INTERVALS */ |
| |
| |
| trans_completed = 0; |
| bytes_sent = 0; |
| bytes_received = 0; |
| connected = 0; |
| |
| while ((!times_up) || (units_remaining > 0)) { |
| |
| if (need_to_accept) { |
| /* accept a connection from the remote */ |
| #ifdef WIN32 |
| /* The test timer will probably fire during this accept, |
| so to make the start_timer above work we have to move |
| it to close s_listen while we are blocked on accept. */ |
| win_kludge_socket = s_listen; |
| #endif |
| if ((data_socket=accept(s_listen, |
| (struct sockaddr *)&peeraddr_in, |
| &addrlen)) == INVALID_SOCKET) { |
| if (errno == EINTR) { |
| /* the timer popped */ |
| times_up = 1; /* ostensibly the signal hander dealt with this?*/ |
| timed_out = 1; |
| break; |
| } |
| fprintf(where,"recv_omni: accept: errno = %d\n",errno); |
| fflush(where); |
| close(s_listen); |
| |
| exit(1); |
| } |
| |
| if (debug) { |
| fprintf(where,"recv_omni: accepted data connection.\n"); |
| fflush(where); |
| } |
| need_to_accept = 0; |
| connected = 1; |
| |
| #ifdef KLUDGE_SOCKET_OPTIONS |
| /* this is for those systems which *INCORRECTLY* fail to pass |
| attributes across an accept() call. Including this goes |
| against my better judgement :( raj 11/95 */ |
| |
| kludge_socket_options(data_socket); |
| |
| #endif /* KLUDGE_SOCKET_OPTIONS */ |
| |
| } |
| else { |
| /* I wonder if duping would be better here? we also need to set |
| peeraddr_in so we can send to netperf if this isn't a |
| request/response test or if we are going to connect() the |
| socket */ |
| if (omni_request->protocol == IPPROTO_UDP) { |
| data_socket = s_listen; |
| set_sockaddr_family_addr_port(&peeraddr_in, |
| nf_to_af(omni_request->ipfamily), |
| omni_request->ipaddr, |
| omni_request->netperf_port); |
| } |
| } |
| |
| if (need_to_connect) { |
| /* initially this will only be used for UDP tests as a TCP or |
| other connection-oriented test will always have us making an |
| accept() call raj 2008-01-11 */ |
| } |
| |
| #ifdef WIN32 |
| /* this is used so the timer thread can close the socket out from |
| under us, which to date is the easiest/cleanest/least |
| Windows-specific way I can find to force the winsock calls to |
| return WSAEINTR with the test is over. anything that will run on |
| 95 and NT and is closer to what netperf expects from Unix signals |
| and such would be appreciated raj 1/96 */ |
| win_kludge_socket = data_socket; |
| #endif /* WIN32 */ |
| |
| /* in recv_omni, we check recv first, and _then_ send, otherwise, |
| a request/response test will be all messed-up :) and that then |
| is why there are two routines to rule them all rather than just |
| one :) */ |
| if ((omni_request->direction & NETPERF_RECV) && |
| !times_up) { |
| ret = recv_data(data_socket, |
| recv_ring, |
| bytes_to_recv, |
| (connected) ? NULL : (struct sockaddr *)&peeraddr_in, |
| &addrlen, |
| /* if XMIT also, then this is RR test so waitall */ |
| (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0, |
| &temp_recvs); |
| if (ret > 0) { |
| /* if this is a recv-only test controlled by byte count we |
| decrement the units_remaining by the bytes received */ |
| if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) { |
| units_remaining -= ret; |
| } |
| bytes_received += ret; |
| local_receive_calls += temp_recvs; |
| } |
| else if (ret == 0) { |
| /* is this the end of a test, just a zero-byte recv, or |
| something else? that is an exceedingly good question and |
| one for which I don't presently have a good answer, but |
| that won't stop me from guessing :) raj 2008-01-09 */ |
| fprintf(where,"read zero conn_test %d null_message_ok %d\n", |
| connection_test,null_message_ok); |
| fflush(where); |
| if (!((connection_test) || (null_message_ok))) { |
| /* if it is neither a connection_test nor null_message_ok it |
| must be the end of the test */ |
| times_up = 1; |
| break; |
| } |
| local_receive_calls += temp_recvs; |
| } |
| else if (ret == -1) { |
| /* test timed-out */ |
| fprintf(where,"YO! TIMESUP!\n"); |
| fflush(where); |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else { |
| /* presently at least, -2 and -3 are equally bad on recv */ |
| /* we need a response message here for the control connection |
| before we exit! */ |
| exit(1); |
| } |
| recv_ring = recv_ring->next; |
| } |
| |
| /* if we should try to send something, then by all means, let us |
| try to send something. */ |
| if ((omni_request->direction & NETPERF_XMIT) && |
| !times_up) { |
| ret = send_data(data_socket, |
| send_ring, |
| bytes_to_send, |
| (connected) ? NULL : (struct sockaddr *)&peeraddr_in, |
| addrlen); |
| |
| /* the order of these if's will seem a triffle strange, but they |
| are my best guess as to order of probabilty and/or importance |
| to the overhead raj 2008-01-09*/ |
| if (ret == bytes_to_send) { |
| /* if this is a send-only test controlled by byte count we |
| decrement units_remaining by the bytes sent */ |
| if (!(direction & NETPERF_RECV) && (units_remaining > 0)) { |
| units_remaining -= ret; |
| } |
| bytes_sent += ret; |
| send_ring = send_ring->next; |
| local_send_calls++; |
| } |
| else if (ret == -2) { |
| /* what to do here -2 means a non-fatal error - probably |
| ENOBUFS and so our send didn't happen. in the old code for |
| UDP_STREAM we would just continue in the while loop. it |
| isn't clear that is what to do here, so we will simply |
| increment the failed_sends stat and fall-through. If this |
| is a UDP_STREAM style of test, the net effect should be the |
| same. if this is a UDP_RR with a really-big burst count, I |
| don't think we were checking for ENOBUFS there anyway and |
| so would have failed. Here we can just let things |
| slide. */ |
| failed_sends++; |
| } |
| else if (ret == 0) { |
| /* was this a zero-byte send? if it was, then ostensibly we |
| would hit the ret == bytes_to_send case which means we'd |
| never get here as we are using blocking semantics */ |
| } |
| else if (ret == -1) { |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else { |
| /* we need a response message back to netperf here before we |
| exit */ |
| /* NEED RESPONSE; */ |
| exit(1); |
| } |
| |
| } |
| |
| if (connection_test) { |
| #ifdef __linux |
| /* so, "Linux" with autotuning likes to alter the socket buffer |
| sizes over the life of the connection, but only does so when |
| one takes the defaults at time of socket creation. if we |
| took those defaults, we should inquire as to what the values |
| ultimately became. raj 2008-01-15 */ |
| if (lsr_size_req < 0) |
| get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); |
| else |
| lsr_size_end = lsr_size; |
| if (lss_size_req < 0) |
| get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); |
| else |
| lss_size_end = lss_size; |
| #else |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| #endif |
| ret = close_data_socket(data_socket,NULL,0); |
| if (ret == -1) { |
| times_up = 1; |
| timed_out = 1; |
| break; |
| } |
| else if (ret < 0) { |
| perror("netperf: recv_omni: close_data_socket failed"); |
| fflush(where); |
| exit(1); |
| } |
| /* we will need a new connection to be established */ |
| need_to_accept = 1; |
| connected = 0; |
| } |
| |
| #if defined(WANT_INTERVALS) |
| INTERVALS_WAIT(); |
| #endif /* WANT_INTERVALS */ |
| |
| /* was this a "transaction" test? don't for get that a TCP_CC |
| style test will have no xmit or recv :) so, we check for either |
| both XMIT and RECV set, or neither XMIT nor RECV set */ |
| if (NETPERF_IS_RR(omni_request->direction)) { |
| trans_completed++; |
| if (units_remaining) { |
| units_remaining--; |
| } |
| } |
| } |
| |
| /* The current iteration loop now exits due to timeout or unit count |
| being reached */ |
| |
| cpu_stop(omni_request->measure_cpu,&elapsed_time); |
| |
| if (timed_out) { |
| /* we ended the test by time, which may have been PAD_TIME seconds |
| longer than we wanted to run. so, we want to subtract pad_time |
| from the elapsed_time. if we didn't pad the timer pad_time will |
| be 0 so we can just subtract it anyway :) */ |
| if (debug) { |
| fprintf(where,"Adjusting elapsed time by %d seconds\n",pad_time); |
| fflush(where); |
| } |
| elapsed_time -= pad_time; |
| } |
| |
| if (connected) { |
| #ifdef __linux |
| /* so, "Linux" with autotuning likes to alter the socket buffer |
| sizes over the life of the connection, but only does so when |
| one takes the defaults at time of socket creation. if we took |
| those defaults, we should inquire as to what the values |
| ultimately became. raj 2008-01-15 */ |
| if (lsr_size_req < 0) |
| get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end); |
| else |
| lsr_size_end = lsr_size; |
| if (lss_size_req < 0) |
| get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end); |
| else |
| lss_size_end = lss_size; |
| #else |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| #endif |
| close_data_socket(data_socket,NULL,0); |
| } |
| else { |
| close_data_socket(data_socket,(struct sockaddr *)&peeraddr_in,addrlen); |
| lsr_size_end = lsr_size; |
| lss_size_end = lss_size; |
| } |
| |
| /* send the results to the sender */ |
| |
| omni_results->send_calls = local_send_calls; |
| omni_results->bytes_received_lo = bytes_received & 0x00000000FFFFFFFFULL; |
| omni_results->bytes_received_hi = (bytes_received & 0xFFFFFFFF00000000ULL) >> 32; |
| omni_results->recv_buf_size = lsr_size_end; |
| omni_results->recv_calls = local_receive_calls; |
| omni_results->bytes_sent_lo = bytes_sent & 0x00000000FFFFFFFFULL; |
| omni_results->bytes_sent_hi = (bytes_sent & 0xFFFFFFFF00000000ULL) >> 32; |
| omni_results->send_buf_size = lss_size_end; |
| omni_results->trans_received = trans_completed; |
| omni_results->elapsed_time = elapsed_time; |
| omni_results->cpu_method = cpu_method; |
| omni_results->num_cpus = lib_num_loc_cpus; |
| if (omni_request->measure_cpu) { |
| omni_results->cpu_util = calc_cpu_util(elapsed_time); |
| } |
| omni_results->peak_cpu_util = (float)lib_local_peak_cpu_util; |
| omni_results->peak_cpu_id = lib_local_peak_cpu_id; |
| local_interface_name = |
| find_egress_interface(local_res->ai_addr,(struct sockaddr *)&peeraddr_in); |
| strncpy(omni_results->ifname,local_interface_name,16); |
| omni_results->ifname[15] = 0; |
| local_interface_slot = find_interface_slot(local_interface_name); |
| strncpy(omni_results->ifslot,local_interface_slot,16); |
| omni_results->ifslot[15] = 0; |
| find_interface_ids(local_interface_name, |
| &omni_results->vendor, |
| &omni_results->device, |
| &omni_results->subvendor, |
| &omni_results->subdevice); |
| find_driver_info(local_interface_name, |
| omni_results->driver, |
| omni_results->version, |
| omni_results->firmware, |
| omni_results->bus, |
| 32); |
| if (debug) { |
| fprintf(where, |
| "recv_omni: test complete, sending results.\n"); |
| fflush(where); |
| } |
| |
| send_response_n(OMNI_RESULTS_CONF_CUTOFF); |
| |
| /* when we implement this, it will look a little strange, but we do |
| it to avoid certain overheads when running aggregates and using |
| confidence intervals. we will post a recv_request() call to get |
| the next message or EOF on the control connection. either the |
| netperf will close the control connection, which will tell us we |
| are done, or the netperf will send us another "DO_OMNI" message, |
| which by definition should be identical to the first DO_OMNI |
| message we received. |
| |
| in this way we can avoid overheads like allocating the buffer |
| rings and the listen socket and the like */ |
| |
| } |
| |
| void |
| scan_omni_args(int argc, char *argv[]) |
| |
| { |
| |
| #define OMNI_ARGS "b:cCd:DnNhH:kL:m:M:oOp:P:r:s:S:t:T:u:Vw:W:46" |
| |
| extern char *optarg; /* pointer to option string */ |
| |
| int c; |
| int have_uuid = 0; |
| |
| char |
| arg1[BUFSIZ], /* argument holders */ |
| arg2[BUFSIZ]; |
| |
| if (debug) { |
| int i; |
| printf("%s called with the following argument vector\n", |
| __func__); |
| for (i = 0; i< argc; i++) { |
| printf("%s ",argv[i]); |
| } |
| printf("\n"); |
| } |
| |
| strncpy(local_data_port,"0",sizeof(local_data_port)); |
| strncpy(remote_data_port,"0",sizeof(remote_data_port)); |
| |
| /* default to a STREAM socket type. i wonder if this should be part |
| of send_omni or here... */ |
| socket_type = nst_to_hst(NST_STREAM); |
| socket_type_str = hst_to_str(socket_type); |
| |
| /* default to TCP. i wonder if this should be here or in |
| send_omni? */ |
| #ifdef IPPROTO_TCP |
| protocol = IPPROTO_TCP; |
| #endif |
| |
| /* we will check to see if this needs to remain 0 or set to |
| something else when we get finished scanning all the argument |
| values */ |
| direction = 0; |
| |
| /* default is to be a stream test, so req_size and rsp_size should |
| be < 0) */ |
| |
| req_size = rsp_size = -1; |
| |
| /* Go through all the command line arguments and break them */ |
| /* out. For those options that take two parms, specifying only */ |
| /* the first will set both to that value. Specifying only the */ |
| /* second will leave the first untouched. To change only the */ |
| /* first, use the form "first," (see the routine break_args.. */ |
| |
| while ((c= getopt(argc, argv, OMNI_ARGS)) != EOF) { |
| switch (c) { |
| case '?': |
| case '4': |
| remote_data_family = AF_INET; |
| local_data_family = AF_INET; |
| break; |
| case '6': |
| #if defined(AF_INET6) |
| remote_data_family = AF_INET6; |
| local_data_family = AF_INET6; |
| #else |
| fprintf(stderr, |
| "This netperf was not compiled on an IPv6 capable host!\n"); |
| fflush(stderr); |
| exit(-1); |
| #endif |
| break; |
| case 'h': |
| print_sockets_usage(); |
| exit(1); |
| case 'b': |
| #ifdef WANT_FIRST_BURST |
| first_burst_size = atoi(optarg); |
| #else /* WANT_FIRST_BURST */ |
| printf("Initial request burst functionality not compiled-in!\n"); |
| #endif /* WANT_FIRST_BURST */ |
| break; |
| case 'c': |
| /* this is a connection test */ |
| connection_test = 1; |
| break; |
| case 'C': |
| #ifdef TCP_CORK |
| /* set TCP_CORK */ |
| loc_tcpcork = 1; |
| rem_tcpcork = 1; /* however, at first, we ony have cork affect loc */ |
| #else |
| printf("WARNING: TCP_CORK not available on this platform!\n"); |
| #endif /* TCP_CORK */ |
| break; |
| case 'd': |
| /* arbitrarily set the direction variable */ |
| direction = strtol(optarg,NULL,0); |
| break; |
| case 'D': |
| /* set the TCP nodelay flag */ |
| loc_nodelay = 1; |
| rem_nodelay = 1; |
| break; |
| case 'H': |
| break_args_explicit(optarg,arg1,arg2); |
| if (arg1[0]) { |
| /* make sure we leave room for the NULL termination boys and |
| girls. raj 2005-02-82 */ |
| remote_data_address = malloc(strlen(arg1)+1); |
| strcpy(remote_data_address,arg1); |
| } |
| if (arg2[0]) |
| remote_data_family = parse_address_family(arg2); |
| break; |
| case 'k': |
| csv = 0; |
| keyword = 1; |
| /* obliterate any previous file name */ |
| if (human_selection_file) { |
| free(human_selection_file); |
| human_selection_file = NULL; |
| } |
| if (csv_selection_file) { |
| free(csv_selection_file); |
| csv_selection_file = NULL; |
| } |
| if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { |
| /* we assume that what follows is the name of a file with the |
| list of desired output values. */ |
| csv_selection_file = strdup(argv[optind]); |
| optind++; |
| /* special case - if the file name is "?" then we will emit a |
| list of the available outputs */ |
| if (strcmp(csv_selection_file,"?") == 0) { |
| dump_netperf_output_list(stdout,1); |
| exit(1); |
| } |
| } |
| break; |
| case 'L': |
| break_args_explicit(optarg,arg1,arg2); |
| if (arg1[0]) { |
| /* make sure we leave room for the NULL termination boys and |
| girls. raj 2005-02-82 */ |
| local_data_address = malloc(strlen(arg1)+1); |
| strcpy(local_data_address,arg1); |
| } |
| if (arg2[0]) |
| local_data_family = parse_address_family(arg2); |
| break; |
| case 'm': |
| /* set the send size. if we set the local send size it will add |
| XMIT to direction. if we set the remote send size it will |
| add RECV to the direction. likely as not this will need some |
| additional throught */ |
| break_args_explicit(optarg,arg1,arg2); |
| if (arg1[0]) { |
| send_size = convert(arg1); |
| direction |= NETPERF_XMIT; |
| } |
| if (arg2[0]) { |
| remote_send_size_req = convert(arg2); |
| direction |= NETPERF_RECV; |
| } |
| break; |
| case 'M': |
| /* set the recv sizes. if we set the local recv size it will |
| add RECV to direction. if we set the remote recv size it |
| will add XMIT to direction */ |
| break_args_explicit(optarg,arg1,arg2); |
| if (arg1[0]) { |
| remote_recv_size_req = convert(arg1); |
| direction |= NETPERF_XMIT; |
| } |
| if (arg2[0]) { |
| recv_size = convert(arg2); |
| direction |= NETPERF_RECV; |
| } |
| break; |
| case 'n': |
| /* set the local socket type */ |
| local_connected = 1; |
| break; |
| case 'N': |
| /* set the remote socket type */ |
| remote_connected = 1; |
| break; |
| case 'o': |
| csv = 1; |
| keyword = 0; |
| /* obliterate any previous file name */ |
| if (human_selection_file) { |
| free(human_selection_file); |
| human_selection_file = NULL; |
| } |
| if (csv_selection_file) { |
| free(csv_selection_file); |
| csv_selection_file = NULL; |
| } |
| if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { |
| /* we assume that what follows is the name of a file with the |
| list of desired output values. */ |
| csv_selection_file = strdup(argv[optind]); |
| optind++; |
| /* special case - if the file name is "?" then we will emit a |
| list of the available outputs */ |
| if (strcmp(csv_selection_file,"?") == 0) { |
| dump_netperf_output_list(stdout,1); |
| exit(1); |
| } |
| } |
| break; |
| case 'O': |
| csv = 0; |
| keyword = 0; |
| /* obliterate any previous file name */ |
| if (human_selection_file) { |
| free(human_selection_file); |
| human_selection_file = NULL; |
| } |
| if (csv_selection_file) { |
| free(csv_selection_file); |
| csv_selection_file = NULL; |
| } |
| if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) { |
| /* we assume that what follows is the name of a file with the |
| list of desired output values */ |
| human_selection_file = strdup(argv[optind]); |
| optind++; |
| if (strcmp(human_selection_file,"?") == 0) { |
| dump_netperf_output_list(stdout,0); |
| exit(1); |
| } |
| } |
| break; |
| case 'p': |
| /* set the min and max port numbers for the TCP_CRR and TCP_TRR */ |
| /* tests. */ |
| break_args(optarg,arg1,arg2); |
| if (arg1[0]) |
| client_port_min = atoi(arg1); |
| if (arg2[0]) |
| client_port_max = atoi(arg2); |
| break; |
| case 'P': |
| /* set the local and remote data port numbers for the tests to |
| allow them to run through those blankety blank end-to-end |
| breaking firewalls. raj 2004-06-15 */ |
| break_args(optarg,arg1,arg2); |
| if (arg1[0]) |
| strncpy(local_data_port,arg1,sizeof(local_data_port)); |
| if (arg2[0]) |
| strncpy(remote_data_port,arg2,sizeof(remote_data_port)); |
| break; |
| case 'r': |
| /* set the request/response sizes. setting request/response |
| sizes implicitly sets direction to XMIT and RECV */ |
| direction |= NETPERF_XMIT; |
| direction |= NETPERF_RECV; |
| break_args(optarg,arg1,arg2); |
| if (arg1[0]) |
| req_size = convert(arg1); |
| if (arg2[0]) |
| rsp_size = convert(arg2); |
| break; |
| case 's': |
| /* set local socket sizes */ |
| break_args(optarg,arg1,arg2); |
| if (arg1[0]) |
| lss_size_req = convert(arg1); |
| if (arg2[0]) |
| lsr_size_req = convert(arg2); |
| break; |
| case 'S': |
| /* set remote socket sizes */ |
| break_args(optarg,arg1,arg2); |
| if (arg1[0]) |
| rss_size_req = convert(arg1); |
| if (arg2[0]) |
| rsr_size_req = convert(arg2); |
| break; |
| case 't': |
| /* set the socket type */ |
| socket_type = parse_socket_type(optarg); |
| break; |
| case 'T': |
| /* set the protocol - aka "Transport" */ |
| protocol = parse_protocol(optarg); |
| break; |
| case 'u': |
| /* use the supplied string as the UUID for this test. at some |
| point we may want to sanity check the string we are given but |
| for now we won't worry about it */ |
| strncpy(test_uuid,optarg,sizeof(test_uuid)); |
| /* strncpy may leave us with a string without a null at the end */ |
| test_uuid[sizeof(test_uuid) - 1] = 0; |
| have_uuid = 1; |
| break; |
| case 'W': |
| /* set the "width" of the user space data */ |
| /* buffer. This will be the number of */ |
| /* send_size buffers malloc'd in the */ |
| /* *_STREAM test. It may be enhanced to set */ |
| /* both send and receive "widths" but for now */ |
| /* it is just the sending *_STREAM. */ |
| send_width = convert(optarg); |
| break; |
| case 'V' : |
| /* we want to do copy avoidance and will set */ |
| /* it for everything, everywhere, if we really */ |
| /* can. of course, we don't know anything */ |
| /* about the remote... */ |
| #ifdef SO_SND_COPYAVOID |
| loc_sndavoid = 1; |
| #else |
| loc_sndavoid = 0; |
| printf("Local send copy avoidance not available.\n"); |
| #endif |
| #ifdef SO_RCV_COPYAVOID |
| loc_rcvavoid = 1; |
| #else |
| loc_rcvavoid = 0; |
| printf("Local recv copy avoidance not available.\n"); |
| #endif |
| rem_sndavoid = 1; |
| rem_rcvavoid = 1; |
| break; |
| }; |
| } |
| |
| /* generate the UUID for this test if the user has not supplied it */ |
| if (!have_uuid) |
| get_uuid_string(test_uuid,sizeof(test_uuid)); |
| |
| |
| protocol_str = protocol_to_str(protocol); |
| /* ok, if we have gone through all that, and direction is still |
| zero, let us see if it needs to be set to something else. */ |
| if ((0 == direction) && (!connection_test)) direction = NETPERF_XMIT; |
| direction_str = direction_to_str(direction); |
| /* some other sanity checks we need to make would include stuff when |
| the user has set -m and -M such that both XMIT and RECV are set |
| and has not set -r. initially we will not allow that. at some |
| point we might allow that if the user has also set -r, but until |
| then the code will simply ignore the values from -m and -M when |
| -r is set. */ |
| |
| #if defined(WANT_FIRST_BURST) |
| #if defined(WANT_HISTOGRAM) |
| /* if WANT_FIRST_BURST and WANT_HISTOGRAM are defined and the user |
| indeed wants a non-zero first burst size, and we would emit a |
| histogram, then we should emit a warning that the two are not |
| compatible. raj 2006-01-31 */ |
| if ((first_burst_size > 0) && (verbosity >= 2)) { |
| fprintf(stderr, |
| "WARNING! Histograms and first bursts are incompatible!\n"); |
| fflush(stderr); |
| } |
| #endif |
| #endif |
| |
| /* ok, time to sanity check the output units */ |
| if ('?' == libfmt) { |
| /* if this is a RR test then set it to 'x' for transactions */ |
| if (NETPERF_IS_RR(direction)) { |
| libfmt = 'x'; |
| } |
| else { |
| libfmt = 'm'; |
| } |
| } |
| else if ('x' == libfmt) { |
| /* now, a format of 'x' makes no sense for anything other than |
| an RR test. if someone has been silly enough to try to set |
| that, we will reset it silently to default - namely 'm' */ |
| if (!NETPERF_IS_RR(direction)) { |
| libfmt = 'm'; |
| } |
| } |
| |
| /* this needs to be strdup :) */ |
| thruput_format_str = strdup(format_units()); |
| |
| /* so, if there is to be no control connection, we want to have some |
| different settings for a few things */ |
| |
| if (no_control) { |
| |
| fprintf(where,"I don't know about no control connection tests yet\n"); |
| exit(1); |
| |
| if (strcmp(remote_data_port,"0") == 0) { |
| /* we need to select either the discard port, echo port or |
| chargen port dedepending on the test name. raj 2007-02-08 */ |
| if (strstr(test_name,"STREAM") || |
| strstr(test_name,"SENDFILE")) { |
| strncpy(remote_data_port,"discard",sizeof(remote_data_port)); |
| } |
| else if (strstr(test_name,"RR")) { |
| strncpy(remote_data_port,"echo",sizeof(remote_data_port)); |
| } |
| else if (strstr(test_name,"MAERTS")) { |
| strncpy(remote_data_port,"chargen",sizeof(remote_data_port)); |
| } |
| else { |
| printf("No default port known for the %s test, please set one yourself\n",test_name); |
| exit(-1); |
| } |
| } |
| remote_data_port[sizeof(remote_data_port) - 1] = '\0'; |
| |
| /* I go back and forth on whether these should become -1 or if |
| they should become 0 for a no_control test. what do you think? |
| raj 2006-02-08 */ |
| |
| rem_rcvavoid = -1; |
| rem_sndavoid = -1; |
| rss_size_req = -1; |
| rsr_size_req = -1; |
| rem_nodelay = -1; |
| |
| if (strstr(test_name,"STREAM") || |
| strstr(test_name,"SENDFILE")) { |
| recv_size = -1; |
| } |
| else if (strstr(test_name,"RR")) { |
| /* I am however _certain_ that for a no control RR test the |
| response size must equal the request size since 99 times out |
| of ten we will be speaking to the echo service somewhere */ |
| rsp_size = req_size; |
| } |
| else if (strstr(test_name,"MAERTS")) { |
| send_size = -1; |
| } |
| else { |
| printf("No default port known for the %s test, please set one yourself\n",test_name); |
| exit(-1); |
| } |
| } |
| } |
| |
| #endif /* WANT_OMNI */ |