2 * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 #endif /* HAVE_CONFIG_H */
47 #include <infiniband/common.h>
48 #include <infiniband/umad.h>
49 #include <infiniband/mad.h>
51 #include "ibdiag_common.h"
54 #define DEBUG if (verbose) IBWARN
56 static int dest_type = IB_DEST_LID;
58 static char host_and_domain[IB_VENDOR_RANGE2_DATA_SIZE];
59 static char last_host[IB_VENDOR_RANGE2_DATA_SIZE];
61 char *argv0 = "ibping";
64 get_host_and_domain(char *data, int sz)
69 if (gethostname(s, sz) < 0)
70 snprintf(s, sz, "?hostname?");
73 if ((n = strlen(s)) >= sz)
79 if (getdomainname(s, sz) < 0)
80 snprintf(s, sz, "?domainname?");
82 s[-1] = 0; /* no domain */
92 DEBUG("starting to serve...");
94 while ((umad = mad_receive(0, -1))) {
96 mad = umad_get_mad(umad);
97 data = (char *)mad + IB_VENDOR_RANGE2_DATA_OFFS;
99 memcpy(data, host_and_domain, IB_VENDOR_RANGE2_DATA_SIZE);
101 DEBUG("Pong: %s", data);
103 if (mad_respond(umad, 0, 0) < 0)
104 DEBUG("respond failed");
114 ibping(ib_portid_t *portid, int quiet)
116 char data[IB_VENDOR_RANGE2_DATA_SIZE] = {0};
117 ib_vendor_call_t call;
122 start = getcurrenttime();
124 call.method = IB_MAD_METHOD_GET;
125 call.mgmt_class = IB_VENDOR_OPENIB_PING_CLASS;
128 call.oui = IB_OPENIB_OUI;
130 memset(&call.rmpp, 0, sizeof call.rmpp);
132 if (!ib_vendor_call(data, portid, &call))
135 rtt = getcurrenttime() - start;
138 memcpy(last_host, data, sizeof last_host);
141 printf("Pong from %s (%s): time %" PRIu64 ".%03" PRIu64 " ms\n",
142 data, portid2str(portid), rtt/1000, rtt%1000);
152 if (!(basename = strrchr(argv0, '/')))
157 fprintf(stderr, "Usage: %s [-d(ebug) -e(rr_show) -v(erbose) -G(uid) -s smlid -V(ersion) -C ca_name -P ca_port "
158 "-t(imeout) timeout_ms -c ping_count -f(lood) -o oui -S(erver)] <dest lid|guid>\n",
163 static uint64_t minrtt = ~0ull, maxrtt, total_rtt;
164 static uint64_t start, total_time, replied, lost, ntrans;
165 static ib_portid_t portid = {0};
170 total_time = getcurrenttime() - start;
172 DEBUG("out due signal %d", sig);
174 printf("\n--- %s (%s) ibping statistics ---\n", last_host, portid2str(&portid));
175 printf("%" PRIu64 " packets transmitted, %" PRIu64 " received, %" PRIu64 "%% packet loss, time %" PRIu64 " ms\n",
177 (lost != 0) ? lost * 100 / ntrans : 0, total_time / 1000);
178 printf("rtt min/avg/max = %" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 " ms\n",
179 minrtt == ~0ull ? 0 : minrtt/1000,
180 minrtt == ~0ull ? 0 : minrtt%1000,
181 replied ? total_rtt/replied/1000 : 0,
182 replied ? (total_rtt/replied)%1000 : 0,
183 maxrtt/1000, maxrtt%1000);
189 main(int argc, char **argv)
191 int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
192 int ping_class = IB_VENDOR_OPENIB_PING_CLASS;
193 ib_portid_t *sm_id = 0, sm_portid = {0};
194 int timeout = 0, udebug = 0, server = 0, flood = 0;
195 int oui = IB_OPENIB_OUI;
203 static char const str_opts[] = "C:P:t:s:c:o:devGfSVhu";
204 static const struct option long_opts[] = {
207 { "debug", 0, 0, 'd'},
208 { "err_show", 0, 0, 'e'},
209 { "verbose", 0, 0, 'v'},
210 { "Guid", 0, 0, 'G'},
212 { "timeout", 1, 0, 't'},
214 { "flood", 0, 0, 'f'},
216 { "Server", 0, 0, 'S'},
217 { "Version", 0, 0, 'V'},
218 { "help", 0, 0, 'h'},
219 { "usage", 0, 0, 'u'},
226 int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
234 ca_port = strtoul(optarg, 0, 0);
237 count = strtoul(optarg, 0, 0);
241 madrpc_show_errors(1);
246 madrpc_show_errors(1);
252 dest_type = IB_DEST_GUID;
255 oui = strtoul(optarg, 0, 0);
258 if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)
259 IBERROR("can't resolve SM destination port %s", optarg);
266 timeout = strtoul(optarg, 0, 0);
267 madrpc_set_timeout(timeout);
273 fprintf(stderr, "%s %s\n", argv0, get_build_version() );
283 if (!argc && !server)
286 madrpc_init(ca, ca_port, mgmt_classes, 3);
289 if (mad_register_server(ping_class, 0, 0, oui) < 0)
290 IBERROR("can't serve class %d on this port", ping_class);
292 get_host_and_domain(host_and_domain, sizeof host_and_domain);
294 if ((err = ibping_serv()))
295 IBERROR("ibping to %s: %s", portid2str(&portid), err);
299 if (mad_register_client(ping_class, 0) < 0)
300 IBERROR("can't register ping class %d on this port", ping_class);
302 if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)
303 IBERROR("can't resolve destination port %s", argv[0]);
305 signal(SIGINT, report);
306 signal(SIGTERM, report);
308 start = getcurrenttime();
310 while (count-- > 0) {
312 if ((rtt = ibping(&portid, flood)) == ~0ull) {
313 DEBUG("ibping to %s failed", portid2str(&portid));