RoCE/infiniband upgrade to Linux v4.9 for kernel and userspace.
This commit merges projects/bsd_rdma_4_9 to head. List of kernel sources used: ============================ 1) kernel sources were cloned from git://github.com/torvalds/linux.git Top commit 69973b830859bc6529a7a0468ba0d80ee5117826 - tag: v4.9, linux-4.9 2) krping was cloned from https://github.com/larrystevenwise/krping Top commit 292a2f1abf0348285e678a82264740d52e4dcfe4 List of userspace sources used: =============================== 1) rdma-core was cloned from https://github.com/linux-rdma/rdma-core.git Top commit d65138ef93af30b3ea249f3a84aa6a24ba7f8a75 2) OpenSM was cloned from git://git.openfabrics.org/~halr/opensm.git Top commit 85f841cf209f791c89a075048a907020e924528d 3) libibmad was cloned from git://git.openfabrics.org/~iraweiny/libibmad.git Tag 1.3.13 with some additional patches from Mellanox. 4) infiniband-diags was cloned from git://git.openfabrics.org/~iraweiny/infiniband-diags.git Tag 1.6.7 with some additional patches from Mellanox. NOTES: ====== 1) The mthca driver has been removed in kernel and in userspace. 2) All GPLv2 only sources have been removed and where applicable rewritten from scratch under a BSD license. 3) List of fully supported drivers in userspace and kernel: a) iw_cxgbe (Chelsio) b) mlx4ib (Mellanox) c) mlx5ib (Mellanox) 4) WITH_OFED=YES is still required by make in order to build OFED userspace and kernel code. 5) Full support has been added for routable RoCE, RoCE v2. Sponsored by: Mellanox Technologies
This commit is contained in:
+17
-9
@@ -2410,16 +2410,24 @@ _lib_libradius= lib/libradius
|
||||
.endif
|
||||
|
||||
.if ${MK_OFED} != "no"
|
||||
_ofed_lib= contrib/ofed/usr.lib
|
||||
_prebuild_libs+= contrib/ofed/usr.lib/libosmcomp
|
||||
_prebuild_libs+= contrib/ofed/usr.lib/libopensm
|
||||
_prebuild_libs+= contrib/ofed/usr.lib/libibcommon
|
||||
_prebuild_libs+= contrib/ofed/usr.lib/libibverbs
|
||||
_prebuild_libs+= contrib/ofed/usr.lib/libibumad
|
||||
#
|
||||
# The OFED libraries are built in four steps
|
||||
# as reflected below, due to interdependencies.
|
||||
#
|
||||
# NOTE: Depending on contrib/ofed/include is only needed for
|
||||
# the lib32 compat build.
|
||||
#
|
||||
_ofed_lib= \
|
||||
contrib/ofed/include \
|
||||
contrib/ofed/usr.lib/0 \
|
||||
contrib/ofed/usr.lib/1 \
|
||||
contrib/ofed/usr.lib/2 \
|
||||
contrib/ofed/usr.lib/3
|
||||
|
||||
contrib/ofed/usr.lib/libopensm__L: lib/libthr__L
|
||||
contrib/ofed/usr.lib/libosmcomp__L: lib/libthr__L
|
||||
contrib/ofed/usr.lib/libibumad__L: contrib/ofed/usr.lib/libibcommon__L
|
||||
contrib/ofed/usr.lib/0__L: contrib/ofed/include__L lib/libthr__L
|
||||
contrib/ofed/usr.lib/1__L: contrib/ofed/usr.lib/0__L
|
||||
contrib/ofed/usr.lib/2__L: contrib/ofed/usr.lib/1__L
|
||||
contrib/ofed/usr.lib/3__L: contrib/ofed/usr.lib/2__L
|
||||
.endif
|
||||
|
||||
.if ${MK_CASPER} != "no"
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
SUBDIR = include usr.lib usr.bin
|
||||
# $FreeBSD$
|
||||
|
||||
# NOTE: Make sure WITH_OFED=YES is set when building this top-level directory.
|
||||
|
||||
SUBDIR= \
|
||||
include \
|
||||
usr.lib \
|
||||
usr.bin
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -1,5 +1,191 @@
|
||||
.include <bsd.own.mk>
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR = infiniband rdma
|
||||
IBVERBS= ${.CURDIR}/../libibverbs
|
||||
IBMAD= ${.CURDIR}/../libibmad
|
||||
IBUMAD= ${.CURDIR}/../libibumad
|
||||
IBCM= ${.CURDIR}/../libibcm
|
||||
IBND= ${.CURDIR}/../libibnetdisc
|
||||
RDMACM= ${.CURDIR}/../librdmacm
|
||||
RDMA= ${.CURDIR}/../../../sys/ofed/include/uapi/rdma
|
||||
OSM= ${.CURDIR}/../opensm/include
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
IBINCS= \
|
||||
byteorder.h \
|
||||
byteswap.h \
|
||||
endian.h \
|
||||
types.h \
|
||||
udma_barrier.h \
|
||||
${IBVERBS}/arch.h \
|
||||
${IBVERBS}/driver.h \
|
||||
${IBVERBS}/kern-abi.h \
|
||||
${IBVERBS}/marshall.h \
|
||||
${IBVERBS}/opcode.h \
|
||||
${IBVERBS}/sa-kern-abi.h \
|
||||
${IBVERBS}/sa.h \
|
||||
${IBVERBS}/verbs.h \
|
||||
${IBUMAD}/umad.h \
|
||||
${IBUMAD}/umad_cm.h \
|
||||
${IBUMAD}/umad_sa.h \
|
||||
${IBUMAD}/umad_sm.h \
|
||||
${IBUMAD}/umad_str.h \
|
||||
${IBUMAD}/umad_types.h \
|
||||
${IBMAD}/mad.h \
|
||||
${IBMAD}/mad_osd.h \
|
||||
${IBCM}/cm.h \
|
||||
${IBCM}/cm_abi.h \
|
||||
${IBND}/ibnetdisc.h \
|
||||
${IBND}/ibnetdisc_osd.h \
|
||||
${RDMACM}/ib.h
|
||||
IBINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
RDMAINCS= \
|
||||
${RDMACM}/rdma_cma.h \
|
||||
${RDMACM}/rdma_cma_abi.h \
|
||||
${RDMACM}/rdma_verbs.h \
|
||||
${RDMACM}/rsocket.h \
|
||||
${RDMA}/ib_user_cm.h \
|
||||
${RDMA}/ib_user_sa.h \
|
||||
${RDMA}/ib_user_verbs.h \
|
||||
${RDMA}/rdma_user_cm.h \
|
||||
${RDMA}/mlx4-abi.h \
|
||||
${RDMA}/mlx5-abi.h
|
||||
RDMAINCSDIR= ${INCLUDEDIR}/rdma
|
||||
|
||||
COMPINCS= \
|
||||
${OSM}/complib/cl_atomic.h \
|
||||
${OSM}/complib/cl_atomic_osd.h \
|
||||
${OSM}/complib/cl_byteswap.h \
|
||||
${OSM}/complib/cl_byteswap_osd.h \
|
||||
${OSM}/complib/cl_comppool.h \
|
||||
${OSM}/complib/cl_debug.h \
|
||||
${OSM}/complib/cl_debug_osd.h \
|
||||
${OSM}/complib/cl_dispatcher.h \
|
||||
${OSM}/complib/cl_event.h \
|
||||
${OSM}/complib/cl_event_osd.h \
|
||||
${OSM}/complib/cl_event_wheel.h \
|
||||
${OSM}/complib/cl_fleximap.h \
|
||||
${OSM}/complib/cl_list.h \
|
||||
${OSM}/complib/cl_log.h \
|
||||
${OSM}/complib/cl_map.h \
|
||||
${OSM}/complib/cl_math.h \
|
||||
${OSM}/complib/cl_nodenamemap.h \
|
||||
${OSM}/complib/cl_packoff.h \
|
||||
${OSM}/complib/cl_packon.h \
|
||||
${OSM}/complib/cl_passivelock.h \
|
||||
${OSM}/complib/cl_pool.h \
|
||||
${OSM}/complib/cl_ptr_vector.h \
|
||||
${OSM}/complib/cl_qcomppool.h \
|
||||
${OSM}/complib/cl_qlist.h \
|
||||
${OSM}/complib/cl_qmap.h \
|
||||
${OSM}/complib/cl_qpool.h \
|
||||
${OSM}/complib/cl_spinlock.h \
|
||||
${OSM}/complib/cl_spinlock_osd.h \
|
||||
${OSM}/complib/cl_thread.h \
|
||||
${OSM}/complib/cl_thread_osd.h \
|
||||
${OSM}/complib/cl_threadpool.h \
|
||||
${OSM}/complib/cl_timer.h \
|
||||
${OSM}/complib/cl_timer_osd.h \
|
||||
${OSM}/complib/cl_types.h \
|
||||
${OSM}/complib/cl_types_osd.h \
|
||||
${OSM}/complib/cl_vector.h
|
||||
COMPINCSDIR= ${INCLUDEDIR}/infiniband/complib
|
||||
|
||||
OSMINCS= \
|
||||
${OSM}/opensm/osm_attrib_req.h \
|
||||
${OSM}/opensm/osm_base.h \
|
||||
${OSM}/opensm/osm_config.h \
|
||||
${OSM}/opensm/osm_congestion_control.h \
|
||||
${OSM}/opensm/osm_console.h \
|
||||
${OSM}/opensm/osm_console_io.h \
|
||||
${OSM}/opensm/osm_db.h \
|
||||
${OSM}/opensm/osm_db_pack.h \
|
||||
${OSM}/opensm/osm_errors.h \
|
||||
${OSM}/opensm/osm_event_plugin.h \
|
||||
${OSM}/opensm/osm_file_ids.h \
|
||||
${OSM}/opensm/osm_guid.h \
|
||||
${OSM}/opensm/osm_helper.h \
|
||||
${OSM}/opensm/osm_inform.h \
|
||||
${OSM}/opensm/osm_lid_mgr.h \
|
||||
${OSM}/opensm/osm_log.h \
|
||||
${OSM}/opensm/osm_mad_pool.h \
|
||||
${OSM}/opensm/osm_madw.h \
|
||||
${OSM}/opensm/osm_mcast_mgr.h \
|
||||
${OSM}/opensm/osm_mcast_tbl.h \
|
||||
${OSM}/opensm/osm_mcm_port.h \
|
||||
${OSM}/opensm/osm_mesh.h \
|
||||
${OSM}/opensm/osm_msgdef.h \
|
||||
${OSM}/opensm/osm_mtree.h \
|
||||
${OSM}/opensm/osm_multicast.h \
|
||||
${OSM}/opensm/osm_node.h \
|
||||
${OSM}/opensm/osm_opensm.h \
|
||||
${OSM}/opensm/osm_partition.h \
|
||||
${OSM}/opensm/osm_path.h \
|
||||
${OSM}/opensm/osm_perfmgr.h \
|
||||
${OSM}/opensm/osm_perfmgr_db.h \
|
||||
${OSM}/opensm/osm_pkey.h \
|
||||
${OSM}/opensm/osm_port.h \
|
||||
${OSM}/opensm/osm_port_profile.h \
|
||||
${OSM}/opensm/osm_prefix_route.h \
|
||||
${OSM}/opensm/osm_qos_policy.h \
|
||||
${OSM}/opensm/osm_remote_sm.h \
|
||||
${OSM}/opensm/osm_router.h \
|
||||
${OSM}/opensm/osm_sa.h \
|
||||
${OSM}/opensm/osm_sa_mad_ctrl.h \
|
||||
${OSM}/opensm/osm_service.h \
|
||||
${OSM}/opensm/osm_sm.h \
|
||||
${OSM}/opensm/osm_sm_mad_ctrl.h \
|
||||
${OSM}/opensm/osm_stats.h \
|
||||
${OSM}/opensm/osm_subnet.h \
|
||||
${OSM}/opensm/osm_switch.h \
|
||||
${OSM}/opensm/osm_ucast_cache.h \
|
||||
${OSM}/opensm/osm_ucast_lash.h \
|
||||
${OSM}/opensm/osm_ucast_mgr.h \
|
||||
${OSM}/opensm/osm_version.h \
|
||||
${OSM}/opensm/osm_vl15intf.h \
|
||||
${OSM}/opensm/st.h
|
||||
OSMINCSDIR= ${INCLUDEDIR}/infiniband/opensm
|
||||
|
||||
IBAINCS= \
|
||||
${OSM}/iba/ib_cm_types.h \
|
||||
${OSM}/iba/ib_types.h
|
||||
IBAINCSDIR= ${INCLUDEDIR}/infiniband/iba
|
||||
|
||||
VENDORINCS= \
|
||||
${OSM}/vendor/osm_mtl_bind.h \
|
||||
${OSM}/vendor/osm_pkt_randomizer.h \
|
||||
${OSM}/vendor/osm_ts_useraccess.h \
|
||||
${OSM}/vendor/osm_umadt.h \
|
||||
${OSM}/vendor/osm_vendor.h \
|
||||
${OSM}/vendor/osm_vendor_al.h \
|
||||
${OSM}/vendor/osm_vendor_api.h \
|
||||
${OSM}/vendor/osm_vendor_ibumad.h \
|
||||
${OSM}/vendor/osm_vendor_mlx.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_defs.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_dispatcher.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_hca.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_inout.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_rmpp_ctx.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_sar.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_sender.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_svc.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_transport.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_transport_anafa.h \
|
||||
${OSM}/vendor/osm_vendor_mlx_txn.h \
|
||||
${OSM}/vendor/osm_vendor_mtl.h \
|
||||
${OSM}/vendor/osm_vendor_mtl_hca_guid.h \
|
||||
${OSM}/vendor/osm_vendor_mtl_transaction_mgr.h \
|
||||
${OSM}/vendor/osm_vendor_sa_api.h \
|
||||
${OSM}/vendor/osm_vendor_test.h \
|
||||
${OSM}/vendor/osm_vendor_ts.h \
|
||||
${OSM}/vendor/osm_vendor_umadt.h
|
||||
VENDORINCSDIR= ${INCLUDEDIR}/infiniband/vendor
|
||||
|
||||
INCSGROUPS= \
|
||||
IBINCS \
|
||||
RDMAINCS \
|
||||
COMPINCS \
|
||||
OSMINCS \
|
||||
IBAINCS \
|
||||
VENDORINCS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
INCS=
|
||||
IBINCS= byteorder.h byteswap.h endian.h types.h
|
||||
IBINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
IBVERBS= ${.CURDIR}/../../libibverbs/include/infiniband
|
||||
VERBINCS= ${IBVERBS}/arch.h ${IBVERBS}/driver.h ${IBVERBS}/kern-abi.h
|
||||
VERBINCS+= ${IBVERBS}/marshall.h ${IBVERBS}/opcode.h
|
||||
VERBINCS+= ${IBVERBS}/sa-kern-abi.h ${IBVERBS}/sa.h ${IBVERBS}/verbs.h
|
||||
VERBINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
IBCOMMON= ${.CURDIR}/../../management/libibcommon/include/infiniband
|
||||
COMMONINCS= ${IBCOMMON}/common.h
|
||||
COMMONINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
IBMAD= ${.CURDIR}/../../management/libibmad/include/infiniband
|
||||
MADINCS= ${IBMAD}/mad.h
|
||||
MADINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
IBUMAD= ${.CURDIR}/../../management/libibumad/include/infiniband
|
||||
UMADINCS= ${IBUMAD}/umad.h
|
||||
UMADINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
COMPLIB= ${.CURDIR}/../../management/opensm/include/complib
|
||||
COMPLIBINCS= ${COMPLIB}/cl_atomic.h ${COMPLIB}/cl_atomic_osd.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_byteswap.h ${COMPLIB}/cl_byteswap_osd.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_comppool.h ${COMPLIB}/cl_debug.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_debug_osd.h ${COMPLIB}/cl_dispatcher.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_event.h ${COMPLIB}/cl_event_osd.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_event_wheel.h ${COMPLIB}/cl_fleximap.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_list.h ${COMPLIB}/cl_log.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_map.h ${COMPLIB}/cl_math.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_nodenamemap.h ${COMPLIB}/cl_packoff.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_packon.h ${COMPLIB}/cl_passivelock.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_pool.h ${COMPLIB}/cl_ptr_vector.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_qcomppool.h ${COMPLIB}/cl_qlist.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_qmap.h ${COMPLIB}/cl_qpool.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_spinlock.h ${COMPLIB}/cl_spinlock_osd.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_thread.h ${COMPLIB}/cl_thread_osd.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_threadpool.h ${COMPLIB}/cl_timer.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_timer_osd.h ${COMPLIB}/cl_types.h
|
||||
COMPLIBINCS+= ${COMPLIB}/cl_types_osd.h ${COMPLIB}/cl_vector.h
|
||||
COMPLIBINCSDIR= ${INCLUDEDIR}/infiniband/complib
|
||||
|
||||
IBADIR= ${.CURDIR}/../../management/opensm/include/iba
|
||||
IBAINCS= ${IBADIR}/ib_cm_types.h ${IBADIR}/ib_types.h
|
||||
IBAINCSDIR= ${INCLUDEDIR}/infiniband/iba
|
||||
|
||||
OPENSM= ${.CURDIR}/../../management/opensm/include/opensm
|
||||
|
||||
OPENSMINCS= ${OPENSM}/osm_attrib_req.h ${OPENSM}/osm_base.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_config.h ${OPENSM}/osm_console.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_console_io.h ${OPENSM}/osm_db.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_db_pack.h ${OPENSM}/osm_errors.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_event_plugin.h ${OPENSM}/osm_helper.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_inform.h ${OPENSM}/osm_lid_mgr.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_log.h ${OPENSM}/osm_mad_pool.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_madw.h ${OPENSM}/osm_mcast_tbl.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_mcm_info.h ${OPENSM}/osm_mcm_port.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_msgdef.h ${OPENSM}/osm_mtree.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_multicast.h ${OPENSM}/osm_node.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_opensm.h ${OPENSM}/osm_partition.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_path.h ${OPENSM}/osm_perfmgr.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_perfmgr_db.h ${OPENSM}/osm_pkey.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_pkey_mgr.h ${OPENSM}/osm_port.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_port_profile.h ${OPENSM}/osm_prefix_route.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_qos_policy.h ${OPENSM}/osm_remote_sm.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_router.h ${OPENSM}/osm_sa.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_sa_mad_ctrl.h ${OPENSM}/osm_service.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_sm.h ${OPENSM}/osm_sm_mad_ctrl.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_stats.h ${OPENSM}/osm_subnet.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_switch.h ${OPENSM}/osm_ucast_cache.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_ucast_mgr.h ${OPENSM}/osm_version.h
|
||||
OPENSMINCS+= ${OPENSM}/osm_vl15intf.h ${OPENSM}/st.h
|
||||
OPENSMINCSDIR= ${INCLUDEDIR}/infiniband/opensm
|
||||
|
||||
VENDOR= ${.CURDIR}/../../management/opensm/include/vendor
|
||||
VENDORINCS= ${VENDOR}/osm_mtl_bind.h ${VENDOR}/osm_pkt_randomizer.h
|
||||
VENDORINCS+= ${VENDOR}/osm_ts_useraccess.h ${VENDOR}/osm_umadt.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor.h ${VENDOR}/osm_vendor_al.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_api.h ${VENDOR}/osm_vendor_ibumad.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx.h ${VENDOR}/osm_vendor_mlx_defs.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_dispatcher.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_hca.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_inout.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_rmpp_ctx.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_sar.h ${VENDOR}/osm_vendor_mlx_sender.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_svc.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_transport.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_transport_anafa.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mlx_txn.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mtl.h ${VENDOR}/osm_vendor_mtl_hca_guid.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_mtl_transaction_mgr.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_sa_api.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_test.h ${VENDOR}/osm_vendor_ts.h
|
||||
VENDORINCS+= ${VENDOR}/osm_vendor_umadt.h
|
||||
VENDORINCSDIR= ${INCLUDEDIR}/infiniband/vendor
|
||||
|
||||
IBCM= ${.CURDIR}/../../libibcm/include/infiniband
|
||||
IBCMINCS= ${IBCM}/cm.h ${IBCM}/cm_abi.h
|
||||
IBCMINCSDIR= ${INCLUDEDIR}/infiniband
|
||||
|
||||
INCSGROUPS= INCS VERBINCS COMMONINCS MADINCS UMADINCS COMPLIBINCS IBAINCS
|
||||
INCSGROUPS+= OPENSMINCS VENDORINCS IBCMINCS IBINCS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,10 +0,0 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
INCS=
|
||||
RDMACM= ${.CURDIR}/../../librdmacm/include/rdma
|
||||
RDMACMINCS= ${RDMACM}/rdma_cma.h ${RDMACM}/rdma_cma_abi.h
|
||||
RDMACMINCSDIR= ${INCLUDEDIR}/rdma
|
||||
|
||||
INCSGROUPS= RDMACMINCS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -58,6 +58,4 @@ typedef uint32_t __be32;
|
||||
typedef uint64_t __le64;
|
||||
typedef uint64_t __be64;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#endif /* _INFINIBAND_TYPES_H_ */
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Topspin Communications. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_UDMA_BARRIER_H
|
||||
#define __UTIL_UDMA_BARRIER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/* Barriers for DMA.
|
||||
|
||||
These barriers are expliclty only for use with user DMA operations. If you
|
||||
are looking for barriers to use with cache-coherent multi-threaded
|
||||
consitency then look in stdatomic.h. If you need both kinds of synchronicity
|
||||
for the same address then use an atomic operation followed by one
|
||||
of these barriers.
|
||||
|
||||
When reasoning about these barriers there are two objects:
|
||||
- CPU attached address space (the CPU memory could be a range of things:
|
||||
cached/uncached/non-temporal CPU DRAM, uncached MMIO space in another
|
||||
device, pMEM). Generally speaking the ordering is only relative
|
||||
to the local CPU's view of the system. Eg if the local CPU
|
||||
is not guaranteed to see a write from another CPU then it is also
|
||||
OK for the DMA device to also not see the write after the barrier.
|
||||
- A DMA initiator on a bus. For instance a PCI-E device issuing
|
||||
MemRd/MemWr TLPs.
|
||||
|
||||
The ordering guarantee is always stated between those two streams. Eg what
|
||||
happens if a MemRd TLP is sent in via PCI-E relative to a CPU WRITE to the
|
||||
same memory location.
|
||||
|
||||
The providers have a very regular and predictable use of these barriers,
|
||||
to make things very clear each narrow use is given a name and the proper
|
||||
name should be used in the provider as a form of documentation.
|
||||
*/
|
||||
|
||||
/* Ensure that the device's view of memory matches the CPU's view of memory.
|
||||
This should be placed before any MMIO store that could trigger the device
|
||||
to begin doing DMA, such as a device doorbell ring.
|
||||
|
||||
eg
|
||||
*dma_buf = 1;
|
||||
udma_to_device_barrier();
|
||||
mmio_write(DO_DMA_REG, dma_buf);
|
||||
Must ensure that the device sees the '1'.
|
||||
|
||||
This is required to fence writes created by the libibverbs user. Those
|
||||
writes could be to any CPU mapped memory object with any cachability mode.
|
||||
|
||||
NOTE: x86 has historically used a weaker semantic for this barrier, and
|
||||
only fenced normal stores to normal memory. libibverbs users using other
|
||||
memory types or non-temporal stores are required to use SFENCE in their own
|
||||
code prior to calling verbs to start a DMA.
|
||||
*/
|
||||
#if defined(__i386__)
|
||||
#define udma_to_device_barrier() asm volatile("" ::: "memory")
|
||||
#elif defined(__x86_64__)
|
||||
#define udma_to_device_barrier() asm volatile("" ::: "memory")
|
||||
#elif defined(__PPC64__)
|
||||
#define udma_to_device_barrier() asm volatile("sync" ::: "memory")
|
||||
#elif defined(__PPC__)
|
||||
#define udma_to_device_barrier() asm volatile("sync" ::: "memory")
|
||||
#elif defined(__ia64__)
|
||||
#define udma_to_device_barrier() asm volatile("mf" ::: "memory")
|
||||
#elif defined(__sparc_v9__)
|
||||
#define udma_to_device_barrier() asm volatile("membar #StoreStore" ::: "memory")
|
||||
#elif defined(__aarch64__)
|
||||
#define udma_to_device_barrier() asm volatile("dsb st" ::: "memory");
|
||||
#elif defined(__sparc__) || defined(__s390x__)
|
||||
#define udma_to_device_barrier() asm volatile("" ::: "memory")
|
||||
#else
|
||||
#error No architecture specific memory barrier defines found!
|
||||
#endif
|
||||
|
||||
/* Ensure that all ordered stores from the device are observable from the
|
||||
CPU. This only makes sense after something that observes an ordered store
|
||||
from the device - eg by reading a MMIO register or seeing that CPU memory is
|
||||
updated.
|
||||
|
||||
This guarantees that all reads that follow the barrier see the ordered
|
||||
stores that preceded the observation.
|
||||
|
||||
For instance, this would be used after testing a valid bit in a memory
|
||||
that is a DMA target, to ensure that the following reads see the
|
||||
data written before the MemWr TLP that set the valid bit.
|
||||
*/
|
||||
#if defined(__i386__)
|
||||
#define udma_from_device_barrier() asm volatile("lock; addl $0,0(%%esp) " ::: "memory")
|
||||
#elif defined(__x86_64__)
|
||||
#define udma_from_device_barrier() asm volatile("lfence" ::: "memory")
|
||||
#elif defined(__PPC64__)
|
||||
#define udma_from_device_barrier() asm volatile("lwsync" ::: "memory")
|
||||
#elif defined(__PPC__)
|
||||
#define udma_from_device_barrier() asm volatile("sync" ::: "memory")
|
||||
#elif defined(__ia64__)
|
||||
#define udma_from_device_barrier() asm volatile("mf" ::: "memory")
|
||||
#elif defined(__sparc_v9__)
|
||||
#define udma_from_device_barrier() asm volatile("membar #LoadLoad" ::: "memory")
|
||||
#elif defined(__aarch64__)
|
||||
#define udma_from_device_barrier() asm volatile("dsb ld" ::: "memory");
|
||||
#elif defined(__sparc__) || defined(__s390x__)
|
||||
#define udma_from_device_barrier() asm volatile("" ::: "memory")
|
||||
#else
|
||||
#error No architecture specific memory barrier defines found!
|
||||
#endif
|
||||
|
||||
/* Order writes to CPU memory so that a DMA device cannot view writes after
|
||||
the barrier without also seeing all writes before the barrier. This does
|
||||
not guarantee any writes are visible to DMA.
|
||||
|
||||
This would be used in cases where a DMA buffer might have a valid bit and
|
||||
data, this barrier is placed after writing the data but before writing the
|
||||
valid bit to ensure the DMA device cannot observe a set valid bit with
|
||||
unwritten data.
|
||||
|
||||
Compared to udma_to_device_barrier() this barrier is not required to fence
|
||||
anything but normal stores to normal malloc memory. Usage should be:
|
||||
|
||||
write_wqe
|
||||
udma_to_device_barrier(); // Get user memory ready for DMA
|
||||
wqe->addr = ...;
|
||||
wqe->flags = ...;
|
||||
udma_ordering_write_barrier(); // Guarantee WQE written in order
|
||||
wqe->valid = 1;
|
||||
*/
|
||||
#define udma_ordering_write_barrier() udma_to_device_barrier()
|
||||
|
||||
/* Promptly flush writes to MMIO Write Cominbing memory.
|
||||
This should be used after a write to WC memory. This is both a barrier
|
||||
and a hint to the CPU to flush any buffers to reduce latency to TLP
|
||||
generation.
|
||||
|
||||
This is not required to have any effect on CPU memory.
|
||||
|
||||
If done while holding a lock then the ordering of MMIO writes across CPUs
|
||||
must be guaranteed to follow the natural ordering implied by the lock.
|
||||
|
||||
This must also act as a barrier that prevents write combining, eg
|
||||
*wc_mem = 1;
|
||||
mmio_flush_writes();
|
||||
*wc_mem = 2;
|
||||
Must always produce two MemWr TLPs, '1' and '2'. Without the barrier
|
||||
the CPU is allowed to produce a single TLP '2'.
|
||||
|
||||
Note that there is no order guarantee for writes to WC memory without
|
||||
barriers.
|
||||
|
||||
This is intended to be used in conjunction with WC memory to generate large
|
||||
PCI-E MemWr TLPs from the CPU.
|
||||
*/
|
||||
#if defined(__i386__)
|
||||
#define mmio_flush_writes() asm volatile("lock; addl $0,0(%%esp) " ::: "memory")
|
||||
#elif defined(__x86_64__)
|
||||
#define mmio_flush_writes() asm volatile("sfence" ::: "memory")
|
||||
#elif defined(__PPC64__)
|
||||
#define mmio_flush_writes() asm volatile("sync" ::: "memory")
|
||||
#elif defined(__PPC__)
|
||||
#define mmio_flush_writes() asm volatile("sync" ::: "memory")
|
||||
#elif defined(__ia64__)
|
||||
#define mmio_flush_writes() asm volatile("fwb" ::: "memory")
|
||||
#elif defined(__sparc_v9__)
|
||||
#define mmio_flush_writes() asm volatile("membar #StoreStore" ::: "memory")
|
||||
#elif defined(__aarch64__)
|
||||
#define mmio_flush_writes() asm volatile("dsb st" ::: "memory");
|
||||
#elif defined(__sparc__) || defined(__s390x__)
|
||||
#define mmio_flush_writes() asm volatile("" ::: "memory")
|
||||
#else
|
||||
#error No architecture specific memory barrier defines found!
|
||||
#endif
|
||||
|
||||
/* Prevent WC writes from being re-ordered relative to other MMIO
|
||||
writes. This should be used before a write to WC memory.
|
||||
|
||||
This must act as a barrier to prevent write re-ordering from different
|
||||
memory types:
|
||||
*mmio_mem = 1;
|
||||
mmio_flush_writes();
|
||||
*wc_mem = 2;
|
||||
Must always produce a TLP '1' followed by '2'.
|
||||
|
||||
This barrier implies udma_to_device_barrier()
|
||||
|
||||
This is intended to be used in conjunction with WC memory to generate large
|
||||
PCI-E MemWr TLPs from the CPU.
|
||||
*/
|
||||
#define mmio_wc_start() mmio_flush_writes()
|
||||
|
||||
/* Keep MMIO writes in order.
|
||||
Currently we lack writel macros that universally guarantee MMIO
|
||||
writes happen in order, like the kernel does. Even worse many
|
||||
providers haphazardly open code writes to MMIO memory omitting even
|
||||
volatile.
|
||||
|
||||
Until this can be fixed with a proper writel macro, this barrier
|
||||
is a stand in to indicate places where MMIO writes should be switched
|
||||
to some future writel.
|
||||
*/
|
||||
#define mmio_ordered_writes_hack() mmio_flush_writes()
|
||||
|
||||
/* Write Combining Spinlock primitive
|
||||
|
||||
Any access to a multi-value WC region must ensure that multiple cpus do not
|
||||
write to the same values concurrently, these macros make that
|
||||
straightforward and efficient if the choosen exclusion is a spinlock.
|
||||
|
||||
The spinlock guarantees that the WC writes issued within the critical
|
||||
section are made visible as TLP to the device. The TLP must be seen by the
|
||||
device strictly in the order that the spinlocks are acquired, and combining
|
||||
WC writes between different sections is not permitted.
|
||||
|
||||
Use of these macros allow the fencing inside the spinlock to be combined
|
||||
with the fencing required for DMA.
|
||||
*/
|
||||
static inline void mmio_wc_spinlock(pthread_spinlock_t *lock)
|
||||
{
|
||||
pthread_spin_lock(lock);
|
||||
#if !defined(__i386__) && !defined(__x86_64__)
|
||||
/* For x86 the serialization within the spin lock is enough to
|
||||
* strongly order WC and other memory types. */
|
||||
mmio_wc_start();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void mmio_wc_spinunlock(pthread_spinlock_t *lock)
|
||||
{
|
||||
/* It is possible that on x86 the atomic in the lock is strong enough
|
||||
* to force-flush the WC buffers quickly, and this SFENCE can be
|
||||
* omitted too. */
|
||||
mmio_flush_writes();
|
||||
pthread_spin_unlock(lock);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= \
|
||||
dump_fts \
|
||||
ibaddr \
|
||||
ibcacheedit \
|
||||
ibccconfig \
|
||||
ibccquery \
|
||||
iblinkinfo \
|
||||
ibmirror \
|
||||
ibnetdiscover \
|
||||
ibping \
|
||||
ibportstate \
|
||||
ibqueryerrors \
|
||||
ibroute \
|
||||
ibstat \
|
||||
ibsysstat \
|
||||
ibtracert \
|
||||
perfquery \
|
||||
saquery \
|
||||
sminfo \
|
||||
smpdump \
|
||||
smpquery \
|
||||
vendstat
|
||||
|
||||
SUBDIR_PARALLEL=
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../src ${.CURDIR}/../../man
|
||||
|
||||
BINDIR?= /usr/bin
|
||||
SRCS+= ibdiag_common.c ibdiag_sa.c
|
||||
CFLAGS+= -I${INCLUDEDIR}/infiniband
|
||||
CFLAGS+= -DHAVE_CONFIG_H=1
|
||||
CFLAGS+= -I${.CURDIR}/../../
|
||||
CFLAGS+= -I${.CURDIR}/../../src
|
||||
LIBADD+= osmcomp ibmad ibumad
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= dump_fts
|
||||
SRCS= dump_fts.c
|
||||
LIBADD= ibnetdisc
|
||||
MAN= dump_fts.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibaddr
|
||||
SRCS= ibaddr.c
|
||||
MAN= ibaddr.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibcacheedit
|
||||
SRCS= ibcacheedit.c
|
||||
LIBADD= ibnetdisc
|
||||
MAN= ibcacheedit.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibccconfig
|
||||
SRCS= ibccconfig.c
|
||||
MAN= ibccconfig.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibccquery
|
||||
SRCS= ibccquery.c
|
||||
MAN= ibccquery.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= iblinkinfo
|
||||
SRCS= iblinkinfo.c
|
||||
LIBADD= ibnetdisc
|
||||
MAN= iblinkinfo.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibmirror
|
||||
SRCS= ibmirror.c
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibnetdiscover
|
||||
SRCS= ibnetdiscover.c
|
||||
LIBADD= ibnetdisc
|
||||
MAN= ibnetdiscover.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibping
|
||||
SRCS= ibping.c
|
||||
MAN= ibping.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibportstate
|
||||
SRCS= ibportstate.c
|
||||
MAN= ibportstate.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibqueryerrors
|
||||
SRCS= ibqueryerrors.c
|
||||
LIBADD= ibnetdisc
|
||||
MAN= ibqueryerrors.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibroute
|
||||
SRCS= ibroute.c
|
||||
MAN= ibroute.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibstat
|
||||
SRCS= ibstat.c
|
||||
MAN= ibstat.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibsysstat
|
||||
SRCS= ibsysstat.c
|
||||
MAN= ibsysstat.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= ibtracert
|
||||
SRCS= ibtracert.c
|
||||
MAN= ibtracert.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= perfquery
|
||||
SRCS= perfquery.c
|
||||
MAN= perfquery.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= saquery
|
||||
SRCS= saquery.c
|
||||
MAN= saquery.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= sminfo
|
||||
SRCS= sminfo.c
|
||||
MAN= sminfo.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= smpdump
|
||||
SRCS= smpdump.c
|
||||
MAN= smpdump.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= smpquery
|
||||
SRCS= smpquery.c
|
||||
MAN= smpquery.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= vendstat
|
||||
SRCS= vendstat.c
|
||||
MAN= vendstat.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -0,0 +1,125 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 to indicate GLIB support */
|
||||
/* #undef HAVE_GLIB */
|
||||
|
||||
/* Define if IB_PC_QP1_DROP_F exists in mad.h enum MAD_FIELDS. */
|
||||
#define HAVE_IB_PC_QP1_DROP_F 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `ibmad' library (-libmad). */
|
||||
#define HAVE_LIBIBMAD 1
|
||||
|
||||
/* Define to 1 if you have the `ibumad' library (-libumad). */
|
||||
#define HAVE_LIBIBUMAD 1
|
||||
|
||||
/* Define to 1 if you have the `osmcomp' library (-losmcomp). */
|
||||
#define HAVE_LIBOSMCOMP 1
|
||||
|
||||
/* Define to 1 if you have the `udev' library (-ludev). */
|
||||
/* #undef HAVE_LIBUDEV */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#define HAVE_STRRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#define HAVE_STRTOULL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `udev_get_sys_path' function. */
|
||||
/* #undef HAVE_UDEV_GET_SYS_PATH */
|
||||
|
||||
/* Define to 1 if struct umad_port has link_layer member */
|
||||
#define HAVE_UMAD_PORT_LINK_LAYER 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define the path to configurations */
|
||||
#define IBDIAG_CONFIG_PATH "/etc/infiniband-diags"
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "infiniband-diags"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "linux-rdma@vger.kernel.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "infiniband-diags"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "infiniband-diags 1.6.7"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "infiniband-diags"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.6.7"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.6.7"
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
@@ -0,0 +1,68 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH CHECK_LFT_BALANCE 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
CHECK_LFT_BALANCE \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH CHECK INFINIBAND UNICAST FORWARDING TABLES BALANCE
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
check_lft_balance.sh [\-hRv]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
check_lft_balance.sh is a script which checks for balancing in Infiniband
|
||||
unicast forwarding tables. It analyzes the output of
|
||||
\fBdump_lfts(8)\fP and \fBiblinkinfo(8)\fP
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-h\fP
|
||||
show help
|
||||
.TP
|
||||
.B \fB\-R\fP
|
||||
Recalculate dump_lfts information, ie do not use the cached
|
||||
information. This option is slower but should be used if the diag
|
||||
tools have not been used for some time or if there are other reasons to
|
||||
believe that the fabric has changed.
|
||||
.TP
|
||||
.B \fB\-v\fP
|
||||
verbose output
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
\fBdump_lfts(8)\fP
|
||||
\fBiblinkinfo(8)\fP
|
||||
.SS AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Albert Chu
|
||||
< \fI\%chu11@llnl.gov\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,235 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH DUMP_FTS 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
DUMP_FTS \- dump InfiniBand forwarding tables
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
dump_fts [options] [<startlid> [<endlid>]]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
dump_fts is similar to ibroute but dumps tables for every switch found in an
|
||||
ibnetdiscover scan of the subnet.
|
||||
.sp
|
||||
The dump file format is compatible with loading into OpenSM using
|
||||
the \-R file \-U /path/to/dump\-file syntax.
|
||||
.SH OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-a, \-\-all\fP
|
||||
show all lids in range, even invalid entries
|
||||
.TP
|
||||
.B \fB\-n, \-\-no_dests\fP
|
||||
do not try to resolve destinations
|
||||
.TP
|
||||
.B \fB\-M, \-\-Multicast\fP
|
||||
show multicast forwarding tables
|
||||
In this case, the range parameters are specifying the mlid range.
|
||||
.UNINDENT
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBdump_lfts(8), dump_mfts(8), ibroute(8), ibswitches(8), opensm(8)\fP
|
||||
.SH AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,214 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBADDR 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBADDR \- query InfiniBand address(es)
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibaddr [options]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
Display the lid (and range) as well as the GID address of the
|
||||
port specified (by DR path, lid, or GUID) or the local port by default.
|
||||
.sp
|
||||
Note: this utility can be used as simple address resolver.
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
\fB\-\-gid_show, \-g\fP
|
||||
show gid address only
|
||||
.sp
|
||||
\fB\-\-lid_show, \-l\fP
|
||||
show lid range only
|
||||
.sp
|
||||
\fB\-\-Lid_show, \-L\fP
|
||||
show lid range (in decimal) only
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SH EXAMPLES
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # local port\e\(aqs address
|
||||
ibaddr 32 # show lid range and gid of lid 32
|
||||
ibaddr \-G 0x8f1040023 # same but using guid address
|
||||
ibaddr \-l 32 # show lid range only
|
||||
ibaddr \-L 32 # show decimal lid range only
|
||||
ibaddr \-g 32 # show gid address only
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fBibroute (8), ibtracert (8)\fP
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,80 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBCACHEEDIT 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBCACHEEDIT \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH EDIT AN IBNETDISCOVER CACHE
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibcacheedit [options] <orig.cache> <new.cache>
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibcacheedit allows users to edit an ibnetdiscover cache created through the
|
||||
\fB\-\-cache\fP option in \fBibnetdiscover(8)\fP .
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-switchguid BEFOREGUID:AFTERGUID\fP
|
||||
Specify a switchguid that should be changed. The before and after guid
|
||||
should be separated by a colon. On switches, port guids are identical
|
||||
to the switch guid, so port guids will be adjusted as well on switches.
|
||||
.TP
|
||||
.B \fB\-\-caguid BEFOREGUID:AFTERGUID\fP
|
||||
Specify a caguid that should be changed. The before and after guid
|
||||
should be separated by a colon.
|
||||
.TP
|
||||
.B \fB\-\-sysimgguid BEFOREGUID:AFTERGUID\fP
|
||||
Specify a sysimgguid that should be changed. The before and after guid
|
||||
should be spearated by a colon.
|
||||
.TP
|
||||
.B \fB\-\-portguid NODEGUID:BEFOREGUID:AFTERGUID\fP
|
||||
Specify a portguid that should be changed. The nodeguid of the port
|
||||
(e.g. switchguid or caguid) should be specified first, followed by a
|
||||
colon, the before port guid, another colon, then the after port guid.
|
||||
On switches, port guids are identical to the switch guid, so the switch
|
||||
guid will be adjusted as well on switches.
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Albert Chu
|
||||
< \fI\%chu11@llnl.gov\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,198 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBCCCONFIG 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBCCCONFIG \- configure congestion control settings
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibccconfig [common_options] [\-c cckey] [\-\-dgid gid] <op> <lid|guid> [port]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
\fBibccconfig\fP
|
||||
supports the configuration of congestion control settings on switches
|
||||
and HCAs.
|
||||
.sp
|
||||
\fBWARNING \-\- You should understand what you are doing before using this tool.
|
||||
Misuse of this tool could result in a broken fabric.\fP
|
||||
.SH OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Current supported operations and their parameters:
|
||||
CongestionKeyInfo (CK) <lid|guid> <cckey> <cckeyprotectbit> <cckeyleaseperiod> <cckeyviolations>
|
||||
SwitchCongestionSetting (SS) <lid|guid> <controlmap> <victimmask> <creditmask> <threshold> <packetsize> <csthreshold> <csreturndelay> <markingrate>
|
||||
SwitchPortCongestionSetting (SP) <lid|guid> <portnum> <valid> <control_type> <threshold> <packet_size> <cong_parm_marking_rate>
|
||||
CACongestionSetting (CS) <lid|guid> <port_control> <control_map> <ccti_timer> <ccti_increase> <trigger_threshold> <ccti_min>
|
||||
CongestionControlTable (CT) <lid|guid> <cctilimit> <index> <cctentry> <cctentry> ...
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-\-cckey, \-c, <cckey>\fP
|
||||
Specify a congestion control (CC) key. If none is specified, a key of 0 is used.
|
||||
.sp
|
||||
\fB\-\-dgid <dgid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH EXAMPLES
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibccconfig SwitchCongestionSetting 2 0x1F 0x1FFFFFFFFF 0x0 0xF 8 0 0:0 1 # Configure Switch Congestion Settings
|
||||
ibccconfig CACongestionSetting 1 0 0x3 150 1 0 0 # Configure CA Congestion Settings to SL 0 and SL 1
|
||||
ibccconfig CACongestionSetting 1 0 0x4 200 1 0 0 # Configure CA Congestion Settings to SL 2
|
||||
ibccconfig CongestionControlTable 1 63 0 0:0 0:1 ... # Configure first block of Congestion Control Table
|
||||
ibccconfig CongestionControlTable 1 127 0 0:64 0:65 ... # Configure second block of Congestion Control Table
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Albert Chu
|
||||
< \fI\%chu11@llnl.gov\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,194 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBCCQUERY 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBCCQUERY \- query congestion control settings/info
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibccquery [common_options] [\-c cckey] [\-\-dgid gid] <op> <lid|guid> [port]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibccquery support the querying of settings and other information related
|
||||
to congestion control.
|
||||
.SH OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Current supported operations and their parameters:
|
||||
CongestionInfo (CI) <addr>
|
||||
CongestionKeyInfo (CK) <addr>
|
||||
CongestionLog (CL) <addr>
|
||||
SwitchCongestionSetting (SS) <addr>
|
||||
SwitchPortCongestionSetting (SP) <addr> [<portnum>]
|
||||
CACongestionSetting (CS) <addr>
|
||||
CongestionControlTable (CT) <addr>
|
||||
Timestamp (TI) <addr>
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-\-cckey, \-c <cckey>\fP
|
||||
Specify a congestion control (CC) key. If none is specified, a key of 0 is used.
|
||||
\fB\-\-dgid <gid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SH EXAMPLES
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibccquery CongestionInfo 3 # Congestion Info by lid
|
||||
ibccquery SwitchPortCongestionSetting 3 # Query all Switch Port Congestion Settings
|
||||
ibccquery SwitchPortCongestionSetting 3 1 # Query Switch Port Congestion Setting for port 1
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Albert Chu
|
||||
< \fI\%chu11@llnl.gov\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,127 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBFINDNODESUSING 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBFINDNODESUSING \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH FIND A LIST OF END NODES WHICH ARE ROUTED THROUGH THE SPECIFIED SWITCH AND PORT
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibfindnodesusing.pl [options] <switch_guid|switch_name> <port>
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibfindnodesusing.pl uses ibroute and detects the current nodes which are routed
|
||||
through both directions of the link specified. The link is specified by one
|
||||
switch port end; the script finds the remote end automatically.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-h\fP
|
||||
show help
|
||||
.TP
|
||||
.B \fB\-R\fP
|
||||
Recalculate the ibnetdiscover information, ie do not use the cached
|
||||
information. This option is slower but should be used if the diag
|
||||
tools have not been used for some time or if there are other reasons to
|
||||
believe that the fabric has changed.
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-C <ca_name>\fP use the specified ca_name.
|
||||
.sp
|
||||
\fB\-P <ca_port>\fP use the specified ca_port.
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,184 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBHOSTS 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBHOSTS \- show InfiniBand host nodes in topology
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibhosts [options] [<topology\-file>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibhosts is a script which either walks the IB subnet topology or uses an
|
||||
already saved topology file and extracts the CA nodes.
|
||||
.SH OPTIONS
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
ibnetdiscover(8)
|
||||
.SH DEPENDENCIES
|
||||
.sp
|
||||
ibnetdiscover, ibnetdiscover format
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,80 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBIDSVERIFY 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBIDSVERIFY \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH VALIDATE IB IDENTIFIERS IN SUBNET AND REPORT ERRORS
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibidsverify.pl [\-h] [\-R]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibidsverify.pl is a perl script which uses a full topology file that was
|
||||
created by ibnetdiscover, scans the network to validate the LIDs and GUIDs
|
||||
in the subnet. The validation consists of checking that there are no zero
|
||||
or duplicate identifiers.
|
||||
.sp
|
||||
Finally, ibidsverify.pl will also reuse the cached ibnetdiscover output from
|
||||
some of the other diag tools which makes it a bit faster than running
|
||||
ibnetdiscover from scratch.
|
||||
.SS OPTIONS
|
||||
.sp
|
||||
\fB\-R\fP
|
||||
Recalculate the ibnetdiscover information, ie do not use the cached
|
||||
information. This option is slower but should be used if the diag tools have
|
||||
not been used for some time or if there are other reasons to believe the
|
||||
fabric has changed.
|
||||
.sp
|
||||
\fB\-C <ca_name>\fP use the specified ca_name.
|
||||
.sp
|
||||
\fB\-P <ca_port>\fP use the specified ca_port.
|
||||
.SS EXIT STATUS
|
||||
.sp
|
||||
Exit status is 1 if errors are found, 0 otherwise.
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
\fBibnetdiscover(8)\fP
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,319 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBLINKINFO 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBLINKINFO \- report link info for all links in the fabric
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
iblinkinfo <options>
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
iblinkinfo reports link info for each port in an IB fabric, node by node.
|
||||
Optionally, iblinkinfo can do partial scans and limit its output to parts of a
|
||||
fabric.
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
\fB\-\-down, \-d\fP
|
||||
Print only nodes which have a port in the "Down" state.
|
||||
.sp
|
||||
\fB\-\-line, \-l\fP
|
||||
Print all information for each link on one line. Default is to print a header
|
||||
with the node information and then a list for each port (useful for
|
||||
grep\(aqing output).
|
||||
.sp
|
||||
\fB\-\-additional, \-p\fP
|
||||
Print additional port settings (<LifeTime>,<HoqLife>,<VLStallCount>)
|
||||
.sp
|
||||
\fB\-\-switches\-only\fP
|
||||
Show only switches in output.
|
||||
.sp
|
||||
\fB\-\-cas\-only\fP
|
||||
Show only CAs in output.
|
||||
.SS Partial Scan flags
|
||||
.sp
|
||||
The node to start a partial scan can be specified with the following addresses.
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-\-port\-guid, \-G <port_guid>\fP Specify a port_guid
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct <dr_path>\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
\-D "0" # self port
|
||||
\-D "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNote:\fP For switches results are printed for all ports not just switch port 0.
|
||||
.sp
|
||||
\fB\-\-switch, \-S <port_guid>\fP same as "\-G". (provided only for backward compatibility)
|
||||
.sp
|
||||
How much of the scan to be printed can be controled with the following.
|
||||
.sp
|
||||
\fB\-\-all, \-a\fP
|
||||
Print all nodes found in a partial fabric scan. Normally a
|
||||
partial fabric scan will return only the node specified. This option will
|
||||
print the other nodes found as well.
|
||||
.sp
|
||||
\fB\-\-hops, \-n <hops>\fP
|
||||
Specify the number of hops away from a specified node to scan. This is useful
|
||||
to expand a partial fabric scan beyond the node specified.
|
||||
.SS Cache File flags
|
||||
.\" Define the common option load-cache
|
||||
.
|
||||
.sp
|
||||
\fB\-\-load\-cache <filename>\fP
|
||||
Load and use the cached ibnetdiscover data stored in the specified
|
||||
filename. May be useful for outputting and learning about other
|
||||
fabrics or a previous state of a fabric.
|
||||
.\" Define the common option diff
|
||||
.
|
||||
.sp
|
||||
\fB\-\-diff <filename>\fP
|
||||
Load cached ibnetdiscover data and do a diff comparison to the current
|
||||
network or another cache. A special diff output for ibnetdiscover
|
||||
output will be displayed showing differences between the old and current
|
||||
fabric. By default, the following are compared for differences: switches,
|
||||
channel adapters, routers, and port connections.
|
||||
.\" Define the common option diffcheck
|
||||
.
|
||||
.sp
|
||||
\fB\-\-diffcheck <key(s)>\fP
|
||||
Specify what diff checks should be done in the \fB\-\-diff\fP option above.
|
||||
Comma separate multiple diff check key(s). The available diff checks
|
||||
are: \fBsw = switches\fP, \fBca = channel adapters\fP, \fBrouter\fP = routers,
|
||||
\fBport\fP = port connections, \fBlid\fP = lids, \fBnodedesc\fP = node
|
||||
descriptions. Note that \fBport\fP, \fBlid\fP, and \fBnodedesc\fP are
|
||||
checked only for the node types that are specified (e.g. \fBsw\fP,
|
||||
\fBca\fP, \fBrouter\fP). If \fBport\fP is specified alongside \fBlid\fP
|
||||
or \fBnodedesc\fP, remote port lids and node descriptions will also be compared.
|
||||
.sp
|
||||
\fB\-\-filterdownports <filename>\fP
|
||||
Filter downports indicated in a ibnetdiscover cache. If a port was previously
|
||||
indicated as down in the specified cache, and is still down, do not output it in the
|
||||
resulting output. This option may be particularly useful for environments
|
||||
where switches are not fully populated, thus much of the default iblinkinfo
|
||||
info is considered unuseful. See \fBibnetdiscover\fP for information on caching
|
||||
ibnetdiscover output.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SH EXIT STATUS
|
||||
.sp
|
||||
0 on success, \-1 on failure to scan the fabric, 1 if check mode is used and
|
||||
inconsistencies are found.
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,399 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBNETDISCOVER 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBNETDISCOVER \- discover InfiniBand topology
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibnetdiscover [options] [<topology\-file>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibnetdiscover performs IB subnet discovery and outputs a human readable
|
||||
topology file. GUIDs, node types, and port numbers are displayed
|
||||
as well as port LIDs and NodeDescriptions. All nodes (and links) are displayed
|
||||
(full topology). Optionally, this utility can be used to list the current
|
||||
connected nodes by nodetype. The output is printed to standard output
|
||||
unless a topology file is specified.
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
\fB\-l, \-\-list\fP
|
||||
List of connected nodes
|
||||
.sp
|
||||
\fB\-g, \-\-grouping\fP
|
||||
Show grouping. Grouping correlates IB nodes by different vendor specific
|
||||
schemes. It may also show the switch external ports correspondence.
|
||||
.sp
|
||||
\fB\-H, \-\-Hca_list\fP
|
||||
List of connected CAs
|
||||
.sp
|
||||
\fB\-S, \-\-Switch_list\fP
|
||||
List of connected switches
|
||||
.sp
|
||||
\fB\-R, \-\-Router_list\fP
|
||||
List of connected routers
|
||||
.sp
|
||||
\fB\-s, \-\-show\fP
|
||||
Show progress information during discovery.
|
||||
.sp
|
||||
\fB\-f, \-\-full\fP
|
||||
Show full information (ports\(aq speed and width, vlcap)
|
||||
.sp
|
||||
\fB\-p, \-\-ports\fP
|
||||
Obtain a ports report which is a
|
||||
list of connected ports with relevant information (like LID, portnum,
|
||||
GUID, width, speed, and NodeDescription).
|
||||
.sp
|
||||
\fB\-m, \-\-max_hops\fP
|
||||
Report max hops discovered.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.SS Cache File flags
|
||||
.\" Define the common option cache
|
||||
.
|
||||
.sp
|
||||
\fB\-\-cache <filename>\fP
|
||||
Cache the ibnetdiscover network data in the specified filename. This
|
||||
cache may be used by other tools for later analysis.
|
||||
.\" Define the common option load-cache
|
||||
.
|
||||
.sp
|
||||
\fB\-\-load\-cache <filename>\fP
|
||||
Load and use the cached ibnetdiscover data stored in the specified
|
||||
filename. May be useful for outputting and learning about other
|
||||
fabrics or a previous state of a fabric.
|
||||
.\" Define the common option diff
|
||||
.
|
||||
.sp
|
||||
\fB\-\-diff <filename>\fP
|
||||
Load cached ibnetdiscover data and do a diff comparison to the current
|
||||
network or another cache. A special diff output for ibnetdiscover
|
||||
output will be displayed showing differences between the old and current
|
||||
fabric. By default, the following are compared for differences: switches,
|
||||
channel adapters, routers, and port connections.
|
||||
.\" Define the common option diffcheck
|
||||
.
|
||||
.sp
|
||||
\fB\-\-diffcheck <key(s)>\fP
|
||||
Specify what diff checks should be done in the \fB\-\-diff\fP option above.
|
||||
Comma separate multiple diff check key(s). The available diff checks
|
||||
are: \fBsw = switches\fP, \fBca = channel adapters\fP, \fBrouter\fP = routers,
|
||||
\fBport\fP = port connections, \fBlid\fP = lids, \fBnodedesc\fP = node
|
||||
descriptions. Note that \fBport\fP, \fBlid\fP, and \fBnodedesc\fP are
|
||||
checked only for the node types that are specified (e.g. \fBsw\fP,
|
||||
\fBca\fP, \fBrouter\fP). If \fBport\fP is specified alongside \fBlid\fP
|
||||
or \fBnodedesc\fP, remote port lids and node descriptions will also be compared.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Common text to describe the Topology file.
|
||||
.
|
||||
.SS TOPOLOGY FILE FORMAT
|
||||
.sp
|
||||
The topology file format is human readable and largely intuitive.
|
||||
Most identifiers are given textual names like vendor ID (vendid), device ID
|
||||
(device ID), GUIDs of various types (sysimgguid, caguid, switchguid, etc.).
|
||||
PortGUIDs are shown in parentheses (). For switches, this is shown on the
|
||||
switchguid line. For CA and router ports, it is shown on the connectivity
|
||||
lines. The IB node is identified followed by the number of ports and a quoted
|
||||
the node GUID. On the right of this line is a comment (#) followed by the
|
||||
NodeDescription in quotes. If the node is a switch, this line also contains
|
||||
whether switch port 0 is base or enhanced, and the LID and LMC of port 0.
|
||||
Subsequent lines pertaining to this node show the connectivity. On the
|
||||
left is the port number of the current node. On the right is the peer node
|
||||
(node at other end of link). It is identified in quotes with nodetype
|
||||
followed by \- followed by NodeGUID with the port number in square brackets.
|
||||
Further on the right is a comment (#). What follows the comment is
|
||||
dependent on the node type. If it it a switch node, it is followed by
|
||||
the NodeDescription in quotes and the LID of the peer node. If it is a
|
||||
CA or router node, it is followed by the local LID and LMC and then
|
||||
followed by the NodeDescription in quotes and the LID of the peer node.
|
||||
The active link width and speed are then appended to the end of this
|
||||
output line.
|
||||
.sp
|
||||
An example of this is:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
#
|
||||
# Topology file: generated on Tue Jun 5 14:15:10 2007
|
||||
#
|
||||
# Max of 3 hops discovered
|
||||
# Initiated from node 0008f10403960558 port 0008f10403960559
|
||||
|
||||
Non\-Chassis Nodes
|
||||
|
||||
vendid=0x8f1
|
||||
devid=0x5a06
|
||||
sysimgguid=0x5442ba00003000
|
||||
switchguid=0x5442ba00003080(5442ba00003080)
|
||||
Switch 24 "S\-005442ba00003080" # "ISR9024 Voltaire" base port 0 lid 6 lmc 0
|
||||
[22] "H\-0008f10403961354"[1](8f10403961355) # "MT23108 InfiniHost Mellanox Technologies" lid 4 4xSDR
|
||||
[10] "S\-0008f10400410015"[1] # "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
[8] "H\-0008f10403960558"[2](8f1040396055a) # "MT23108 InfiniHost Mellanox Technologies" lid 14 4xSDR
|
||||
[6] "S\-0008f10400410015"[3] # "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
[12] "H\-0008f10403960558"[1](8f10403960559) # "MT23108 InfiniHost Mellanox Technologies" lid 10 4xSDR
|
||||
|
||||
vendid=0x8f1
|
||||
devid=0x5a05
|
||||
switchguid=0x8f10400410015(8f10400410015)
|
||||
Switch 8 "S\-0008f10400410015" # "SW\-6IB4 Voltaire" base port 0 lid 3 lmc 0
|
||||
[6] "H\-0008f10403960984"[1](8f10403960985) # "MT23108 InfiniHost Mellanox Technologies" lid 16 4xSDR
|
||||
[4] "H\-005442b100004900"[1](5442b100004901) # "MT23108 InfiniHost Mellanox Technologies" lid 12 4xSDR
|
||||
[1] "S\-005442ba00003080"[10] # "ISR9024 Voltaire" lid 6 1xSDR
|
||||
[3] "S\-005442ba00003080"[6] # "ISR9024 Voltaire" lid 6 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403960984
|
||||
Ca 2 "H\-0008f10403960984" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](8f10403960985) "S\-0008f10400410015"[6] # lid 16 lmc 1 "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x5442b100004900
|
||||
Ca 2 "H\-005442b100004900" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](5442b100004901) "S\-0008f10400410015"[4] # lid 12 lmc 1 "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403961354
|
||||
Ca 2 "H\-0008f10403961354" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](8f10403961355) "S\-005442ba00003080"[22] # lid 4 lmc 1 "ISR9024 Voltaire" lid 6 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403960558
|
||||
Ca 2 "H\-0008f10403960558" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[2](8f1040396055a) "S\-005442ba00003080"[8] # lid 14 lmc 1 "ISR9024 Voltaire" lid 6 4xSDR
|
||||
[1](8f10403960559) "S\-005442ba00003080"[12] # lid 10 lmc 1 "ISR9024 Voltaire" lid 6 1xSDR
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
When grouping is used, IB nodes are organized into chassis which are
|
||||
numbered. Nodes which cannot be determined to be in a chassis are
|
||||
displayed as "Non\-Chassis Nodes". External ports are also shown on the
|
||||
connectivity lines.
|
||||
.SH AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,176 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBNODES 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBNODES \- show InfiniBand nodes in topology
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibnodes [options] [<topology\-file>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibnodes is a script which either walks the IB subnet topology or uses an
|
||||
already saved topology file and extracts the IB nodes (CAs and switches).
|
||||
.SH OPTIONS
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
ibnetdiscover(8)
|
||||
.SH DEPENDENCIES
|
||||
.sp
|
||||
ibnetdiscover, ibnetdiscover format
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,177 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBPING 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBPING \- ping an InfiniBand address
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibping [options] <dest lid | guid>
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibping uses vendor mads to validate connectivity between IB nodes.
|
||||
On exit, (IP) ping like output is show. ibping is run as client/server.
|
||||
Default is to run as client. Note also that a default ping server is
|
||||
implemented within the kernel.
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
\fB\-c, \-\-count\fP
|
||||
stop after count packets
|
||||
.sp
|
||||
\fB\-f, \-\-flood\fP
|
||||
flood destination: send packets back to back without delay
|
||||
.sp
|
||||
\fB\-o, \-\-oui\fP
|
||||
use specified OUI number to multiplex vendor mads
|
||||
.sp
|
||||
\fB\-S, \-\-Server\fP
|
||||
start in server mode (do not return)
|
||||
.sp
|
||||
\fB\-\-dgid <gid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,259 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBPORTSTATE 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBPORTSTATE \- handle port (physical) state and link speed of an InfiniBand port
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibportstate [options] <dest dr_path|lid|guid> <portnum> [<op>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibportstate allows the port state and port physical state of an IB port
|
||||
to be queried (in addition to link width and speed being validated
|
||||
relative to the peer port when the port queried is a switch port),
|
||||
or a switch port to be disabled, enabled, or reset. It
|
||||
also allows the link speed/width enabled on any IB port to be adjusted.
|
||||
.SH OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB<op>\fP
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B Supported ops: enable, disable, reset, speed, espeed, fdr10, width, query,
|
||||
on, off, down, arm, active, vls, mtu, lid, smlid, lmc,
|
||||
mkey, mkeylease, mkeyprot
|
||||
(Default is query)
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBenable, disable, and reset\fP are only allowed on switch ports (An
|
||||
error is indicated if attempted on CA or router ports)
|
||||
.sp
|
||||
\fBoff\fP change the port state to disable.
|
||||
.sp
|
||||
\fBon\fP change the port state to enable(only when the current state is disable).
|
||||
.sp
|
||||
\fBspeed and width\fP are allowed on any port
|
||||
.sp
|
||||
\fBspeed\fP values are the legal values for PortInfo:LinkSpeedEnabled (An
|
||||
error is indicated if PortInfo:LinkSpeedSupported does not support this
|
||||
setting)
|
||||
.sp
|
||||
\fBespeed\fP is allowed on any port supporting extended link speeds
|
||||
.sp
|
||||
\fBfdr10\fP is allowed on any port supporting fdr10 (An error is
|
||||
indicated if port\(aqs capability mask indicates extended link speeds are
|
||||
not supported or if PortInfo:LinkSpeedExtSupported does not support
|
||||
this setting)
|
||||
.sp
|
||||
\fBwidth\fP values are legal values for PortInfo:LinkWidthEnabled (An
|
||||
error is indicated if PortInfo:LinkWidthSupported does not support this
|
||||
setting) (NOTE: Speed and width changes are not effected until the port
|
||||
goes through link renegotiation)
|
||||
.sp
|
||||
\fBquery\fP also validates port characteristics (link width, speed,
|
||||
espeed, and fdr10) based on the peer port. This checking is done when
|
||||
the port queried is a switch port as it relies on combined routing (an
|
||||
initial LID route with directed routing to the peer) which can only be
|
||||
done on a switch. This peer port validation feature of query op
|
||||
requires LID routing to be functioning in the subnet.
|
||||
.sp
|
||||
\fBmkey, mkeylease, and mkeyprot\fP are only allowed on CAs, routers, or
|
||||
switch port 0 (An error is generated if attempted on external switch
|
||||
ports). Hexadecimal and octal mkeys may be specified by prepending the
|
||||
key with \(aq0x\(aq or \(aq0\(aq, respectively. If a non\-numeric value (like \(aqx\(aq)
|
||||
is specified for the mkey, then ibportstate will prompt for a value.
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -K
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-K, \-\-show_keys\fP
|
||||
show security keys (mkey, smkey, etc.) associated with the request.
|
||||
.UNINDENT
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SH EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibportstate 3 1 disable # by lid
|
||||
ibportstate \-G 0x2C9000100D051 1 enable # by guid
|
||||
ibportstate \-D 0 1 # (query) by direct route
|
||||
ibportstate 3 1 reset # by lid
|
||||
ibportstate 3 1 speed 1 # by lid
|
||||
ibportstate 3 1 width 1 # by lid
|
||||
ibportstate \-D 0 1 lid 0x1234 arm # by direct route
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%hal.rosenstock@gmail.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,339 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBQUERYERRORS 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBQUERYERRORS \- query and report IB port counters
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibqueryerrors [options]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
The default behavior is to report the port error counters which exceed a
|
||||
threshold for each port in the fabric. The default threshold is zero (0).
|
||||
Error fields can also be suppressed entirely.
|
||||
.sp
|
||||
In addition to reporting errors on every port. ibqueryerrors can report the
|
||||
port transmit and receive data as well as report full link information to the
|
||||
remote port if available.
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
\fB\-s, \-\-suppress <err1,err2,...>\fP
|
||||
Suppress the errors listed in the comma separated list provided.
|
||||
.sp
|
||||
\fB\-c, \-\-suppress\-common\fP
|
||||
Suppress some of the common "side effect" counters. These counters usually do
|
||||
not indicate an error condition and can be usually be safely ignored.
|
||||
.sp
|
||||
\fB\-r, \-\-report\-port\fP
|
||||
Report the port information. This includes LID, port, external port (if
|
||||
applicable), link speed setting, remote GUID, remote port, remote external port
|
||||
(if applicable), and remote node description information.
|
||||
.sp
|
||||
\fB\-\-data\fP
|
||||
Include the optional transmit and receive data counters.
|
||||
.sp
|
||||
\fB\-\-threshold\-file <filename>\fP
|
||||
Specify an alternate threshold file. The default is /etc/infiniband-diags/error_thresholds
|
||||
.sp
|
||||
\fB\-\-switch\fP print data for switch\(aqs only
|
||||
.sp
|
||||
\fB\-\-ca\fP print data for CA\(aqs only
|
||||
.sp
|
||||
\fB\-\-skip\-sl\fP Use the default sl for queries. This is not recommended when
|
||||
using a QoS aware routing engine as it can cause a credit deadlock.
|
||||
.sp
|
||||
\fB\-\-router\fP print data for routers only
|
||||
.sp
|
||||
\fB\-\-clear\-errors \-k\fP Clear error counters after read.
|
||||
.sp
|
||||
\fB\-\-clear\-counts \-K\fP Clear data counters after read.
|
||||
.sp
|
||||
\fBCAUTION\fP clearing data or error counters will occur regardless of if they
|
||||
are printed or not. See \fB\-\-counters\fP and \fB\-\-data\fP for details on
|
||||
controling which counters are printed.
|
||||
.sp
|
||||
\fB\-\-details\fP include receive error and transmit discard details
|
||||
.sp
|
||||
\fB\-\-counters\fP print data counters only
|
||||
.SS Partial Scan flags
|
||||
.sp
|
||||
The node to start a partial scan can be specified with the following addresses.
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-\-port\-guid, \-G <port_guid>\fP Specify a port_guid
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct <dr_path>\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
\-D "0" # self port
|
||||
\-D "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNote:\fP For switches results are printed for all ports not just switch port 0.
|
||||
.sp
|
||||
\fB\-S <port_guid>\fP same as "\-G". (provided only for backward compatibility)
|
||||
.SS Cache File flags
|
||||
.\" Define the common option load-cache
|
||||
.
|
||||
.sp
|
||||
\fB\-\-load\-cache <filename>\fP
|
||||
Load and use the cached ibnetdiscover data stored in the specified
|
||||
filename. May be useful for outputting and learning about other
|
||||
fabrics or a previous state of a fabric.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.sp
|
||||
\fB\-R\fP (This option is obsolete and does nothing)
|
||||
.SH EXIT STATUS
|
||||
.sp
|
||||
\fB\-1\fP if scan fails.
|
||||
.sp
|
||||
\fB0\fP if scan succeeds without errors beyond thresholds
|
||||
.sp
|
||||
\fB1\fP if errors are found beyond thresholds or inconsistencies are found in check mode.
|
||||
.SH FILES
|
||||
.SS ERROR THRESHOLD
|
||||
.sp
|
||||
/etc/infiniband-diags/error_thresholds
|
||||
.sp
|
||||
Define threshold values for errors. File format is simple "name=val".
|
||||
Comments begin with \(aq#\(aq
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# Define thresholds for error counters
|
||||
SymbolErrorCounter=10
|
||||
LinkErrorRecoveryCounter=10
|
||||
VL15Dropped=100
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,291 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBROUTE 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBROUTE \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND SWITCH FORWARDING TABLES
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibroute [options] [<dest dr_path|lid|guid> [<startlid> [<endlid>]]]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibroute uses SMPs to display the forwarding tables (unicast
|
||||
(LinearForwardingTable or LFT) or multicast (MulticastForwardingTable or MFT))
|
||||
for the specified switch LID and the optional lid (mlid) range.
|
||||
The default range is all valid entries in the range 1...FDBTop.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-a, \-\-all\fP
|
||||
show all lids in range, even invalid entries
|
||||
.TP
|
||||
.B \fB\-n, \-\-no_dests\fP
|
||||
do not try to resolve destinations
|
||||
.TP
|
||||
.B \fB\-M, \-\-Multicast\fP
|
||||
show multicast forwarding tables
|
||||
In this case, the range parameters are specifying the mlid range.
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS EXAMPLES
|
||||
.sp
|
||||
Unicast examples
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibroute 4 # dump all lids with valid out ports of switch with lid 4
|
||||
ibroute \-a 4 # same, but dump all lids, even with invalid out ports
|
||||
ibroute \-n 4 # simple dump format \- no destination resolution
|
||||
ibroute 4 10 # dump lids starting from 10 (up to FDBTop)
|
||||
ibroute 4 0x10 0x20 # dump lid range
|
||||
ibroute \-G 0x08f1040023 # resolve switch by GUID
|
||||
ibroute \-D 0,1 # resolve switch by direct path
|
||||
.UNINDENT
|
||||
.sp
|
||||
Multicast examples
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibroute \-M 4 # dump all non empty mlids of switch with lid 4
|
||||
ibroute \-M 4 0xc010 0xc020 # same, but with range
|
||||
ibroute \-M \-n 4 # simple dump format
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
ibtracert (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,184 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBROUTERS 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBROUTERS \- show InfiniBand router nodes in topology
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibrouters [options] [<topology\-file>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibrouters is a script which either walks the IB subnet topology or uses an
|
||||
already saved topology file and extracts the router nodes.
|
||||
.SH OPTIONS
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
ibnetdiscover(8)
|
||||
.SH DEPENDENCIES
|
||||
.sp
|
||||
ibnetdiscover, ibnetdiscover format
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,118 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBSTAT 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBSTAT \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY BASIC STATUS OF INFINIBAND DEVICE(S)
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibstat [options] <ca_name> [portnum]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibstat is a binary which displays basic information obtained from the local
|
||||
IB driver. Output includes LID, SMLID, port state, link width active, and port
|
||||
physical state.
|
||||
.sp
|
||||
It is similar to the ibstatus utility but implemented as a binary rather
|
||||
than a script. It has options to list CAs and/or ports and displays more
|
||||
information than ibstatus.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-l, \-\-list_of_cas\fP
|
||||
list all IB devices
|
||||
.TP
|
||||
.B \fB\-s, \-\-short\fP
|
||||
short output
|
||||
.TP
|
||||
.B \fB\-p, \-\-port_list\fP
|
||||
show port list
|
||||
.TP
|
||||
.B \fBca_name\fP
|
||||
InfiniBand device name
|
||||
.TP
|
||||
.B \fBportnum\fP
|
||||
port number of InfiniBand device
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibstat # display status of all ports on all IB devices
|
||||
ibstat \-l # list all IB devices
|
||||
ibstat \-p # show port guids
|
||||
ibstat mthca0 2 # show status of port 2 of \(aqmthca0\(aq
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
ibstatus (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,73 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBSTATUS 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBSTATUS \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY BASIC STATUS OF INFINIBAND DEVICE(S)
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibstatus [\-h] [devname[:port]]...
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibstatus is a script which displays basic information obtained from the local
|
||||
IB driver. Output includes LID, SMLID, port state, link width active, and port
|
||||
physical state.
|
||||
.SS OPTIONS
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fBdevname\fP
|
||||
InfiniBand device name
|
||||
.TP
|
||||
.B \fBportnum\fP
|
||||
port number of InfiniBand device
|
||||
.UNINDENT
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibstatus # display status of all IB ports
|
||||
ibstatus mthca1 # status of mthca1 ports
|
||||
ibstatus mthca1:1 mthca0:2 # show status of specified ports
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
\fBibstat (8)\fP
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,184 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBSWITCHES 8 "" "" "OpenIB Diagnostics"
|
||||
.SH NAME
|
||||
IBSWITCHES \- show InfiniBand switch nodes in topology
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
ibswitches [options] [<topology\-file>]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
ibswitches is a script which either walks the IB subnet topology or uses an
|
||||
already saved topology file and extracts the switch nodes.
|
||||
.SH OPTIONS
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
ibnetdiscover(8)
|
||||
.SH DEPENDENCIES
|
||||
.sp
|
||||
ibnetdiscover, ibnetdiscover format
|
||||
.SH AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,188 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBSYSSTAT 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBSYSSTAT \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH SYSTEM STATUS ON AN INFINIBAND ADDRESS
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibsysstat [options] <dest lid | guid> [<op>]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibsysstat uses vendor mads to validate connectivity between IB nodes
|
||||
and obtain other information about the IB node. ibsysstat is run as
|
||||
client/server. Default is to run as client.
|
||||
.SS OPTIONS
|
||||
.sp
|
||||
Current supported operations:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ping \e\- verify connectivity to server (default)
|
||||
host \e\- obtain host information from server
|
||||
cpu \e\- obtain cpu information from server
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-o, \-\-oui\fP
|
||||
use specified OUI number to multiplex vendor mads
|
||||
.TP
|
||||
.B \fB\-S, \-\-Server\fP
|
||||
start in server mode (do not return)
|
||||
.TP
|
||||
.B .sp
|
||||
\fB\-\-dgid <gid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,268 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH IBTRACERT 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
IBTRACERT \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH TRACE INFINIBAND PATH
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
ibtracert [options] [<lid|guid> [<startlid> [<endlid>]]]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
ibtracert uses SMPs to trace the path from a source GID/LID to a
|
||||
destination GID/LID. Each hop along the path is displayed until
|
||||
the destination is reached or a hop does not respond. By using
|
||||
the \-m option, multicast path tracing can be performed between source
|
||||
and destination nodes.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-n, \-\-no_info\fP
|
||||
simple format; don\(aqt show additional information
|
||||
.TP
|
||||
.B \fB\-m\fP
|
||||
show the multicast trace of the specified mlid
|
||||
.TP
|
||||
.B \fB\-f, \-\-force\fP
|
||||
force route to destination port
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS EXAMPLES
|
||||
.sp
|
||||
Unicast examples
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibtracert 4 16 # show path between lids 4 and 16
|
||||
ibtracert \-n 4 16 # same, but using simple output format
|
||||
ibtracert \-G 0x8f1040396522d 0x002c9000100d051 # use guid addresses
|
||||
.UNINDENT
|
||||
.sp
|
||||
Multicast example
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
ibtracert \-m 0xc000 4 16 # show multicast path of mlid 0xc000 between lids 4 and 16
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
ibroute (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
<\fI\%hal.rosenstock@gmail.com\fP>
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,452 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH INFINIBAND-DIAGS 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
INFINIBAND-DIAGS \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH DIAGNOSTICS FOR INFINIBAND FABRICS
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
infiniband\-diags is a set of utilities designed to help configure, debug, and
|
||||
maintain infiniband fabrics. Many tools and utilities are provided. Some with
|
||||
similar functionality.
|
||||
.sp
|
||||
The base utilities use directed route MAD\(aqs to perform their operations. They
|
||||
may therefore work even in unconfigured subnets. Other, higher level
|
||||
utilities, require LID routed MAD\(aqs and to some extent SA/SM access.
|
||||
.SS THE USE OF SMPs (QP0)
|
||||
.sp
|
||||
Many of the tools in this package rely on the use of SMPs via QP0 to acquire
|
||||
data directly from the SMA. While this mode of operation is not technically in
|
||||
compliance with the InfiniBand specification, practical experience has found
|
||||
that this level of diagnostics is valuable when working with a fabric which is
|
||||
broken or only partially configured. For this reason many of these tools may
|
||||
require the use of an MKey or operation from Virtual Machines may be restricted
|
||||
for security reasons.
|
||||
.SS COMMON OPTIONS
|
||||
.sp
|
||||
Most OpenIB diagnostics take some of the following common flags. The exact list
|
||||
of supported flags per utility can be found in the documentation for those
|
||||
commands.
|
||||
.SS Addressing Flags
|
||||
.sp
|
||||
The \-D and \-G option have two forms:
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct <dr_path>\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
\-D "0" # self port
|
||||
\-D "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-\-port\-guid, \-G <port_guid>\fP Specify a port_guid
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS COMMON FILES
|
||||
.sp
|
||||
The following config files are common amongst many of the utilities.
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Common text to describe the Topology file.
|
||||
.
|
||||
.SS TOPOLOGY FILE FORMAT
|
||||
.sp
|
||||
The topology file format is human readable and largely intuitive.
|
||||
Most identifiers are given textual names like vendor ID (vendid), device ID
|
||||
(device ID), GUIDs of various types (sysimgguid, caguid, switchguid, etc.).
|
||||
PortGUIDs are shown in parentheses (). For switches, this is shown on the
|
||||
switchguid line. For CA and router ports, it is shown on the connectivity
|
||||
lines. The IB node is identified followed by the number of ports and a quoted
|
||||
the node GUID. On the right of this line is a comment (#) followed by the
|
||||
NodeDescription in quotes. If the node is a switch, this line also contains
|
||||
whether switch port 0 is base or enhanced, and the LID and LMC of port 0.
|
||||
Subsequent lines pertaining to this node show the connectivity. On the
|
||||
left is the port number of the current node. On the right is the peer node
|
||||
(node at other end of link). It is identified in quotes with nodetype
|
||||
followed by \- followed by NodeGUID with the port number in square brackets.
|
||||
Further on the right is a comment (#). What follows the comment is
|
||||
dependent on the node type. If it it a switch node, it is followed by
|
||||
the NodeDescription in quotes and the LID of the peer node. If it is a
|
||||
CA or router node, it is followed by the local LID and LMC and then
|
||||
followed by the NodeDescription in quotes and the LID of the peer node.
|
||||
The active link width and speed are then appended to the end of this
|
||||
output line.
|
||||
.sp
|
||||
An example of this is:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
#
|
||||
# Topology file: generated on Tue Jun 5 14:15:10 2007
|
||||
#
|
||||
# Max of 3 hops discovered
|
||||
# Initiated from node 0008f10403960558 port 0008f10403960559
|
||||
|
||||
Non\-Chassis Nodes
|
||||
|
||||
vendid=0x8f1
|
||||
devid=0x5a06
|
||||
sysimgguid=0x5442ba00003000
|
||||
switchguid=0x5442ba00003080(5442ba00003080)
|
||||
Switch 24 "S\-005442ba00003080" # "ISR9024 Voltaire" base port 0 lid 6 lmc 0
|
||||
[22] "H\-0008f10403961354"[1](8f10403961355) # "MT23108 InfiniHost Mellanox Technologies" lid 4 4xSDR
|
||||
[10] "S\-0008f10400410015"[1] # "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
[8] "H\-0008f10403960558"[2](8f1040396055a) # "MT23108 InfiniHost Mellanox Technologies" lid 14 4xSDR
|
||||
[6] "S\-0008f10400410015"[3] # "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
[12] "H\-0008f10403960558"[1](8f10403960559) # "MT23108 InfiniHost Mellanox Technologies" lid 10 4xSDR
|
||||
|
||||
vendid=0x8f1
|
||||
devid=0x5a05
|
||||
switchguid=0x8f10400410015(8f10400410015)
|
||||
Switch 8 "S\-0008f10400410015" # "SW\-6IB4 Voltaire" base port 0 lid 3 lmc 0
|
||||
[6] "H\-0008f10403960984"[1](8f10403960985) # "MT23108 InfiniHost Mellanox Technologies" lid 16 4xSDR
|
||||
[4] "H\-005442b100004900"[1](5442b100004901) # "MT23108 InfiniHost Mellanox Technologies" lid 12 4xSDR
|
||||
[1] "S\-005442ba00003080"[10] # "ISR9024 Voltaire" lid 6 1xSDR
|
||||
[3] "S\-005442ba00003080"[6] # "ISR9024 Voltaire" lid 6 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403960984
|
||||
Ca 2 "H\-0008f10403960984" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](8f10403960985) "S\-0008f10400410015"[6] # lid 16 lmc 1 "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x5442b100004900
|
||||
Ca 2 "H\-005442b100004900" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](5442b100004901) "S\-0008f10400410015"[4] # lid 12 lmc 1 "SW\-6IB4 Voltaire" lid 3 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403961354
|
||||
Ca 2 "H\-0008f10403961354" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[1](8f10403961355) "S\-005442ba00003080"[22] # lid 4 lmc 1 "ISR9024 Voltaire" lid 6 4xSDR
|
||||
|
||||
vendid=0x2c9
|
||||
devid=0x5a44
|
||||
caguid=0x8f10403960558
|
||||
Ca 2 "H\-0008f10403960558" # "MT23108 InfiniHost Mellanox Technologies"
|
||||
[2](8f1040396055a) "S\-005442ba00003080"[8] # lid 14 lmc 1 "ISR9024 Voltaire" lid 6 4xSDR
|
||||
[1](8f10403960559) "S\-005442ba00003080"[12] # lid 10 lmc 1 "ISR9024 Voltaire" lid 6 1xSDR
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
When grouping is used, IB nodes are organized into chassis which are
|
||||
numbered. Nodes which cannot be determined to be in a chassis are
|
||||
displayed as "Non\-Chassis Nodes". External ports are also shown on the
|
||||
connectivity lines.
|
||||
.SS Utilities list
|
||||
.SS Basic fabric conectivity
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibnetdiscover, iblinkinfo
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Node information
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibnodes, ibswitches, ibhosts, ibrouters
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Port information
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibportstate, ibaddr
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Switch Forwarding Table info
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibtracert, ibroute, dump_lfts, dump_mfts, check_lft_balance, ibfindnodesusing
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Peformance counters
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibqueryerrors, perfquery
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Local HCA info
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibstat, ibstatus
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Connectivity check
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibping, ibsysstat
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Low level query tools
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: smpquery, smpdump, saquery, sminfo
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Fabric verification tools
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
See: ibidsverify
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Backwards compatibility scripts
|
||||
.sp
|
||||
The following scripts have been identified as redundant and/or lower performing
|
||||
as compared to the above scripts. They are provided as legacy scripts when
|
||||
\-\-enable\-compat\-utils is specified at build time.
|
||||
.sp
|
||||
ibcheckerrors, ibclearcounters, ibclearerrors, ibdatacounters
|
||||
ibchecknet, ibchecknode, ibcheckport, ibcheckportstate,
|
||||
ibcheckportwidth, ibcheckstate, ibcheckwidth, ibswportwatch,
|
||||
ibprintca, ibprintrt, ibprintswitch, set_nodedesc.sh
|
||||
.SS AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,291 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH PERFQUERY 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
PERFQUERY \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND PORT COUNTERS ON A SINGLE PORT
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
perfquery [options] [<lid|guid> [[port(s)] [reset_mask]]]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
perfquery uses PerfMgt GMPs to obtain the PortCounters (basic performance and
|
||||
error counters), PortExtendedCounters, PortXmitDataSL, PortRcvDataSL,
|
||||
PortRcvErrorDetails, PortXmitDiscardDetails, PortExtendedSpeedsCounters, or
|
||||
PortSamplesControl from the PMA at the node/port specified. Optionally shows
|
||||
aggregated counters for all ports of node. Finally it can, reset after read,
|
||||
or just reset the counters.
|
||||
.sp
|
||||
Note: In PortCounters, PortCountersExtended, PortXmitDataSL, and PortRcvDataSL,
|
||||
components that represent Data (e.g. PortXmitData and PortRcvData) indicate
|
||||
octets divided by 4 rather than just octets.
|
||||
.sp
|
||||
Note: Inputting a port of 255 indicates an operation be performed on all ports.
|
||||
.sp
|
||||
Note: For PortCounters, ExtendedCounters, and resets, multiple ports can be
|
||||
specified by either a comma separated list or a port range. See examples below.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-x, \-\-extended\fP
|
||||
show extended port counters rather than (basic) port counters.
|
||||
Note that extended port counters attribute is optional.
|
||||
.TP
|
||||
.B \fB\-X, \-\-xmtsl\fP
|
||||
show transmit data SL counter. This is an optional counter for QoS.
|
||||
.TP
|
||||
.B \fB\-S, \-\-rcvsl\fP
|
||||
show receive data SL counter. This is an optional counter for QoS.
|
||||
.TP
|
||||
.B \fB\-D, \-\-xmtdisc\fP
|
||||
show transmit discard details. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-E, \-\-rcverr\fP
|
||||
show receive error details. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-D, \-\-xmtdisc\fP
|
||||
show transmit discard details. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-T, \-\-extended_speeds\fP
|
||||
show extended speeds port counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-oprcvcounters\fP
|
||||
show Rcv Counters per Op code. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-flowctlcounters\fP
|
||||
show flow control counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-vloppackets\fP
|
||||
show packets received per Op code per VL. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-vlopdata\fP
|
||||
show data received per Op code per VL. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-vlxmitflowctlerrors\fP
|
||||
show flow control update errors per VL. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-vlxmitcounters\fP
|
||||
show ticks waiting to transmit counters per VL. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-swportvlcong\fP
|
||||
show sw port VL congestion. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-rcvcc\fP
|
||||
show Rcv congestion control counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-slrcvfecn\fP
|
||||
show SL Rcv FECN counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-slrcvbecn\fP
|
||||
show SL Rcv BECN counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-xmitcc\fP
|
||||
show Xmit congestion control counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-\-vlxmittimecc\fP
|
||||
show VL Xmit Time congestion control counters. This is an optional counter.
|
||||
.TP
|
||||
.B \fB\-c, \-\-smplctl\fP
|
||||
show port samples control.
|
||||
.TP
|
||||
.B \fB\-a, \-\-all_ports\fP
|
||||
show aggregated counters for all ports of the destination lid, reset
|
||||
all counters for all ports, or if multiple ports are specified, aggregate
|
||||
the counters of the specified ports. If the destination lid does not support
|
||||
the AllPortSelect flag, all ports will be iterated through to emulate
|
||||
AllPortSelect behavior.
|
||||
.TP
|
||||
.B \fB\-l, \-\-loop_ports\fP
|
||||
If all ports are selected by the user (either through the \fB\-a\fP option
|
||||
or port 255) or multiple ports are specified iterate through each port rather
|
||||
than doing than aggregate operation.
|
||||
.TP
|
||||
.B \fB\-r, \-\-reset_after_read\fP
|
||||
reset counters after read
|
||||
.TP
|
||||
.B \fB\-R, \-\-Reset_only\fP
|
||||
only reset counters
|
||||
.TP
|
||||
.B \fB\-\-dgid <gid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
perfquery # read local port performance counters
|
||||
perfquery 32 1 # read performance counters from lid 32, port 1
|
||||
perfquery \-x 32 1 # read extended performance counters from lid 32, port 1
|
||||
perfquery \-a 32 # read perf counters from lid 32, all ports
|
||||
perfquery \-r 32 1 # read performance counters and reset
|
||||
perfquery \-x \-r 32 1 # read extended performance counters and reset
|
||||
perfquery \-R 0x20 1 # reset performance counters of port 1 only
|
||||
perfquery \-x \-R 0x20 1 # reset extended performance counters of port 1 only
|
||||
perfquery \-R \-a 32 # reset performance counters of all ports
|
||||
perfquery \-R 32 2 0x0fff # reset only error counters of port 2
|
||||
perfquery \-R 32 2 0xf000 # reset only non\-error counters of port 2
|
||||
perfquery \-a 32 1\-10 # read performance counters from lid 32, port 1\-10, aggregate output
|
||||
perfquery \-l 32 1\-10 # read performance counters from lid 32, port 1\-10, output each port
|
||||
perfquery \-a 32 1,4,8 # read performance counters from lid 32, port 1, 4, and 8, aggregate output
|
||||
perfquery \-l 32 1,4,8 # read performance counters from lid 32, port 1, 4, and 8, output each port
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%hal.rosenstock@gmail.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,380 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH SAQUERY 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
SAQUERY \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND SUBNET ADMINISTRATION ATTRIBUTES
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
saquery [options] [<name> | <lid> | <guid>]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
saquery issues the selected SA query. Node records are queried by default.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-p\fP
|
||||
get PathRecord info
|
||||
.TP
|
||||
.B \fB\-N\fP
|
||||
get NodeRecord info
|
||||
.TP
|
||||
.B \fB\-D, \-\-list\fP
|
||||
get NodeDescriptions of CAs only
|
||||
.TP
|
||||
.B \fB\-S\fP
|
||||
get ServiceRecord info
|
||||
.TP
|
||||
.B \fB\-I\fP
|
||||
get InformInfoRecord (subscription) info
|
||||
.TP
|
||||
.B \fB\-L\fP
|
||||
return the Lids of the name specified
|
||||
.TP
|
||||
.B \fB\-l\fP
|
||||
return the unique Lid of the name specified
|
||||
.TP
|
||||
.B \fB\-G\fP
|
||||
return the Guids of the name specified
|
||||
.TP
|
||||
.B \fB\-O\fP
|
||||
return the name for the Lid specified
|
||||
.TP
|
||||
.B \fB\-U\fP
|
||||
return the name for the Guid specified
|
||||
.TP
|
||||
.B \fB\-c\fP
|
||||
get the SA\(aqs class port info
|
||||
.TP
|
||||
.B \fB\-s\fP
|
||||
return the PortInfoRecords with isSM or isSMdisabled capability mask bit on
|
||||
.TP
|
||||
.B \fB\-g\fP
|
||||
get multicast group info
|
||||
.TP
|
||||
.B \fB\-m\fP
|
||||
get multicast member info. If a group is specified, limit the output
|
||||
to the group specified and print one line containing only the GUID and
|
||||
node description for each entry. Example: saquery \-m 0xc000
|
||||
.TP
|
||||
.B \fB\-x\fP
|
||||
get LinkRecord info
|
||||
.TP
|
||||
.B \fB\-\-src\-to\-dst <src:dst>\fP
|
||||
get a PathRecord for <src:dst>
|
||||
where src and dst are either node names or LIDs
|
||||
.TP
|
||||
.B \fB\-\-sgid\-to\-dgid <sgid:dgid>\fP
|
||||
get a PathRecord for \fBsgid\fP to \fBdgid\fP
|
||||
where both GIDs are in an IPv6 format acceptable to \fBinet_pton (3)\fP
|
||||
.TP
|
||||
.B \fB\-\-smkey <val>\fP
|
||||
use SM_Key value for the query. Will be used only with "trusted"
|
||||
queries. If non\-numeric value (like \(aqx\(aq) is specified then saquery
|
||||
will prompt for a value.
|
||||
Default (when not specified here or in
|
||||
/etc/infiniband-diags/ibdiag.conf) is to use SM_Key == 0 (or
|
||||
"untrusted")
|
||||
.TP
|
||||
.B \fB\-\-sa-dgid <gid>\fP
|
||||
Set the destination GID (in IPv6 format) of the SA in the GRH of the request.
|
||||
Either the actual SM GID or the SA well known GID (0::2) can be used to include
|
||||
in the GRH of the SA queries.
|
||||
.UNINDENT
|
||||
.\" Define the common option -K
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-K, \-\-show_keys\fP
|
||||
show security keys (mkey, smkey, etc.) associated with the request.
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-\-slid <lid>\fP Source LID (PathRecord)
|
||||
.sp
|
||||
\fB\-\-dlid <lid>\fP Destination LID (PathRecord)
|
||||
.sp
|
||||
\fB\-\-mlid <lid>\fP Multicast LID (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-sgid <gid>\fP Source GID (IPv6 format) (PathRecord)
|
||||
.sp
|
||||
\fB\-\-dgid <gid>\fP Destination GID (IPv6 format) (PathRecord)
|
||||
.sp
|
||||
\fB\-\-gid <gid>\fP Port GID (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-mgid <gid>\fP Multicast GID (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-reversible\fP Reversible path (PathRecord)
|
||||
.sp
|
||||
\fB\-\-numb_path\fP Number of paths (PathRecord)
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-pkey\fP P_Key (PathRecord, MCMemberRecord). If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then saquery will prompt for a value
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-\-qos_class\fP QoS Class (PathRecord)
|
||||
.sp
|
||||
\fB\-\-sl\fP Service level (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-mtu\fP MTU and selector (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-rate\fP Rate and selector (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-pkt_lifetime\fP Packet lifetime and selector (PathRecord, MCMemberRecord)
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-qkey\fP Q_Key (MCMemberRecord). If non\-numeric value (like \(aqx\(aq) is specified
|
||||
then saquery will prompt for a value
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-\-tclass\fP Traffic Class (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-flow_label\fP Flow Label (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-hop_limit\fP Hop limit (PathRecord, MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-scope\fP Scope (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-join_state\fP Join state (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-proxy_join\fP Proxy join (MCMemberRecord)
|
||||
.sp
|
||||
\fB\-\-service_id\fP ServiceID (PathRecord)
|
||||
.sp
|
||||
Supported query names (and aliases):
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ClassPortInfo (CPI)
|
||||
NodeRecord (NR) [lid]
|
||||
PortInfoRecord (PIR) [[lid]/[port]/[options]]
|
||||
SL2VLTableRecord (SL2VL) [[lid]/[in_port]/[out_port]]
|
||||
PKeyTableRecord (PKTR) [[lid]/[port]/[block]]
|
||||
VLArbitrationTableRecord (VLAR) [[lid]/[port]/[block]]
|
||||
InformInfoRecord (IIR)
|
||||
LinkRecord (LR) [[from_lid]/[from_port]] [[to_lid]/[to_port]]
|
||||
ServiceRecord (SR)
|
||||
PathRecord (PR)
|
||||
MCMemberRecord (MCMR)
|
||||
LFTRecord (LFTR) [[lid]/[block]]
|
||||
MFTRecord (MFTR) [[mlid]/[position]/[block]]
|
||||
GUIDInfoRecord (GIR) [[lid]/[block]]
|
||||
SwitchInfoRecord (SWIR) [lid]
|
||||
SMInfoRecord (SMIR) [lid]
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-\-outstanding_smps, \-o <val>\fP
|
||||
Specify the number of outstanding SMP\(aqs which should be issued during the scan
|
||||
.sp
|
||||
Default: 2
|
||||
.UNINDENT
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS COMMON FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS DEPENDENCIES
|
||||
.sp
|
||||
OpenSM (or other running SM/SA), libosmcomp, libibumad, libibmad
|
||||
.SS AUTHORS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Ira Weiny
|
||||
< \fI\%ira.weiny@intel.com\fP >
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@mellanox.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,215 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH SMINFO 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
SMINFO \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND SMINFO ATTRIBUTE
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
sminfo [options] sm_lid | sm_dr_path [modifier]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
Optionally set and display the output of a sminfo query in human readable
|
||||
format. The target SM is the one listed in the local port info, or the SM
|
||||
specified by the optional SM lid or by the SM direct routed path.
|
||||
.sp
|
||||
Note: using sminfo for any purposes other then simple query may be very
|
||||
dangerous, and may result in a malfunction of the target SM.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-s, \-\-state <state>\fP set SM state
|
||||
0 not active
|
||||
.sp
|
||||
1 discovering
|
||||
.sp
|
||||
2 standby
|
||||
.sp
|
||||
3 master
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fB\-p, \-\-priority <priority>\fP set priority (0\-15)
|
||||
.sp
|
||||
\fB\-a, \-\-activity <val>\fP set activity count
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
sminfo # local port\(aqs sminfo
|
||||
sminfo 32 # show sminfo of lid 32
|
||||
sminfo \-G 0x8f1040023 # same but using guid address
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
smpdump (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,207 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH SMPDUMP 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
SMPDUMP \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH DUMP INFINIBAND SUBNET MANAGEMENT ATTRIBUTES
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
smpdump [options] <dlid|dr_path> <attribute> [attribute_modifier]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
smpdump is a general purpose SMP utility which gets SM attributes from a
|
||||
specified SMA. The result is dumped in hex by default.
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fBdlid|drpath\fP
|
||||
LID or DR path to SMA
|
||||
.TP
|
||||
.B \fBattribute\fP
|
||||
IBA attribute ID for SM attribute
|
||||
.TP
|
||||
.B \fBattribute_modifier\fP
|
||||
IBA modifier for SM attribute
|
||||
.TP
|
||||
.B \fB\-s, \-\-string\fP
|
||||
Print strings in packet if possible
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS EXAMPLES
|
||||
.sp
|
||||
Direct Routed Examples
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
smpdump \-D 0,1,2,3,5 16 # NODE DESC
|
||||
smpdump \-D 0,1,2 0x15 2 # PORT INFO, port 2
|
||||
.UNINDENT
|
||||
.sp
|
||||
LID Routed Examples
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
smpdump 3 0x15 2 # PORT INFO, lid 3 port 2
|
||||
smpdump 0xa0 0x11 # NODE INFO, lid 0xa0
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
smpquery (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%halr@voltaire.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,310 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH SMPQUERY 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
SMPQUERY \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND SUBNET MANAGEMENT ATTRIBUTES
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
smpquery [options] <op> <dest dr_path|lid|guid> [op params]
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
smpquery allows a basic subset of standard SMP queries including the following:
|
||||
node info, node description, switch info, port info. Fields are displayed in
|
||||
human readable format.
|
||||
.SS OPTIONS
|
||||
.sp
|
||||
Current supported operations (case insensitive) and their parameters:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Nodeinfo (NI) <addr>
|
||||
|
||||
Nodedesc (ND) <addr>
|
||||
|
||||
Portinfo (PI) <addr> [<portnum>] # default port is zero
|
||||
|
||||
PortInfoExtended (PIE) <addr> [<portnum>]
|
||||
|
||||
Switchinfo (SI) <addr>
|
||||
|
||||
PKeyTable (PKeys) <addr> [<portnum>]
|
||||
|
||||
SL2VLTable (SL2VL) <addr> [<portnum>]
|
||||
|
||||
VLArbitration (VLArb) <addr> [<portnum>]
|
||||
|
||||
GUIDInfo (GI) <addr>
|
||||
|
||||
MlnxExtPortInfo (MEPI) <addr> [<portnum>] # default port is zero
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-c, \-\-combined\fP
|
||||
Use Combined route address argument \fB<lid> <DR_Path>\fP
|
||||
.TP
|
||||
.B \fB\-x, \-\-extended\fP
|
||||
Set SMSupportsExtendedSpeeds bit 31 in AttributeModifier
|
||||
(only impacts PortInfo queries).
|
||||
.UNINDENT
|
||||
.\" Define the common option -K
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-K, \-\-show_keys\fP
|
||||
show security keys (mkey, smkey, etc.) associated with the request.
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -D for Directed routes
|
||||
.
|
||||
.sp
|
||||
\fB\-D, \-\-Direct\fP The address specified is a directed route
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
Examples:
|
||||
[options] \-D [options] "0" # self port
|
||||
[options] \-D [options] "0,1,2,1,4" # out via port 1, then 2, ...
|
||||
|
||||
(Note the second number in the path specified must match the port being
|
||||
used. This can be specified using the port selection flag \(aq\-P\(aq or the
|
||||
port found through the automatic selection process.)
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option --node-name-map
|
||||
.
|
||||
.sp
|
||||
\fB\-\-node\-name\-map <node\-name\-map>\fP Specify a node name map.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
This file maps GUIDs to more user friendly names. See FILES section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.\" Define the common option -y
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-y, \-\-m_key <key>\fP
|
||||
use the specified M_key for requests. If non\-numeric value (like \(aqx\(aq)
|
||||
is specified then a value will be prompted for.
|
||||
.UNINDENT
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.\" Common text to describe the node name map file.
|
||||
.
|
||||
.SS NODE NAME MAP FILE FORMAT
|
||||
.sp
|
||||
The node name map is used to specify user friendly names for nodes in the
|
||||
output. GUIDs are used to perform the lookup.
|
||||
.sp
|
||||
This functionality is provided by the opensm\-libs package. See \fBopensm(8)\fP
|
||||
for the file location for your installation.
|
||||
.sp
|
||||
\fBGenerically:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# comment
|
||||
<guid> "<name>"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBExample:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
# IB1
|
||||
# Line cards
|
||||
0x0008f104003f125c "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f125d "IB1 (Rack 11 slot 1 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d2 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10d3 "IB1 (Rack 11 slot 2 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
0x0008f104003f10bf "IB1 (Rack 11 slot 12 ) ISR9288/ISR9096 Voltaire sLB\-24D"
|
||||
|
||||
# Spines
|
||||
0x0008f10400400e2d "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2e "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e2f "IB1 (Rack 11 spine 1 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e31 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
0x0008f10400400e32 "IB1 (Rack 11 spine 2 ) ISR9288 Voltaire sFB\-12D"
|
||||
|
||||
# GUID Node Name
|
||||
0x0008f10400411a08 "SW1 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a28 "SW2 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f10400411a34 "SW3 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
0x0008f104004119d0 "SW4 (Rack 3) ISR9024 Voltaire 9024D"
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
smpquery portinfo 3 1 # portinfo by lid, with port modifier
|
||||
smpquery \-G switchinfo 0x2C9000100D051 1 # switchinfo by guid
|
||||
smpquery \-D nodeinfo 0 # nodeinfo by direct route
|
||||
smpquery \-c nodeinfo 6 0,12 # nodeinfo by combined route
|
||||
.UNINDENT
|
||||
.SS SEE ALSO
|
||||
.sp
|
||||
smpdump (8)
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%hal@mellanox.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,221 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH VENDSTAT 8 "" "" "Open IB Diagnostics"
|
||||
.SH NAME
|
||||
VENDSTAT \-
|
||||
.
|
||||
.nr rst2man-indent-level 0
|
||||
.
|
||||
.de1 rstReportMargin
|
||||
\\$1 \\n[an-margin]
|
||||
level \\n[rst2man-indent-level]
|
||||
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
-
|
||||
\\n[rst2man-indent0]
|
||||
\\n[rst2man-indent1]
|
||||
\\n[rst2man-indent2]
|
||||
..
|
||||
.de1 INDENT
|
||||
.\" .rstReportMargin pre:
|
||||
. RS \\$1
|
||||
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||||
. nr rst2man-indent-level +1
|
||||
.\" .rstReportMargin post:
|
||||
..
|
||||
.de UNINDENT
|
||||
. RE
|
||||
.\" indent \\n[an-margin]
|
||||
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.nr rst2man-indent-level -1
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.SH QUERY INFINIBAND VENDOR SPECIFIC FUNCTIONS
|
||||
.SS SYNOPSIS
|
||||
.sp
|
||||
vendstat [options] <lid|guid>
|
||||
.SS DESCRIPTION
|
||||
.sp
|
||||
vendstat uses vendor specific MADs to access beyond the IB spec
|
||||
vendor specific functionality. Currently, there is support for
|
||||
Mellanox InfiniSwitch\-III (IS3) and InfiniSwitch\-IV (IS4).
|
||||
.SS OPTIONS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-N\fP
|
||||
show IS3 or IS4 general information.
|
||||
.TP
|
||||
.B \fB\-w\fP
|
||||
show IS3 port xmit wait counters.
|
||||
.TP
|
||||
.B \fB\-i\fP
|
||||
show IS4 counter group info.
|
||||
.TP
|
||||
.B \fB\-c <num,num>\fP
|
||||
configure IS4 counter groups.
|
||||
.sp
|
||||
Configure IS4 counter groups 0 and 1. Such configuration is not
|
||||
persistent across IS4 reboot. First number is for counter group 0 and
|
||||
second is for counter group 1.
|
||||
.sp
|
||||
Group 0 counter config values:
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
0 \- PortXmitDataSL0\-7
|
||||
1 \- PortXmitDataSL8\-15
|
||||
2 \- PortRcvDataSL0\-7
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Group 1 counter config values:
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
1 \- PortXmitDataSL8\-15
|
||||
2 \- PortRcvDataSL0\-7
|
||||
8 \- PortRcvDataSL8\-15
|
||||
.TP
|
||||
.B \fB\-R, \-\-Read <addr,mask>\fP
|
||||
Read configuration space record at addr
|
||||
.TP
|
||||
.B \fB\-W, \-\-Write <addr,val,mask>\fP
|
||||
Write configuration space record at addr
|
||||
.TP
|
||||
.B \fB\-\-dgid <gid>\fP
|
||||
destination GID: use when GRH is required in packets (IPv6 format)
|
||||
.UNINDENT
|
||||
.SS Addressing Flags
|
||||
.\" Define the common option -G
|
||||
.
|
||||
.sp
|
||||
\fB\-G, \-\-Guid\fP The address specified is a Port GUID
|
||||
.\" Define the common option -L
|
||||
.
|
||||
.sp
|
||||
\fB\-L, \-\-Lid\fP The address specified is a LID
|
||||
.\" Define the common option -s
|
||||
.
|
||||
.sp
|
||||
\fB\-s, \-\-sm_port <smlid>\fP use \(aqsmlid\(aq as the target lid for SA queries.
|
||||
.SS Port Selection flags
|
||||
.\" Define the common option -C
|
||||
.
|
||||
.sp
|
||||
\fB\-C, \-\-Ca <ca_name>\fP use the specified ca_name.
|
||||
.\" Define the common option -P
|
||||
.
|
||||
.sp
|
||||
\fB\-P, \-\-Port <ca_port>\fP use the specified ca_port.
|
||||
.\" Explanation of local port selection
|
||||
.
|
||||
.SS Local port Selection
|
||||
.sp
|
||||
Multiple port/Multiple CA support: when no IB device or port is specified
|
||||
(see the "local umad parameters" below), the libibumad library
|
||||
selects the port to use by the following criteria:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.IP 1. 3
|
||||
the first port that is ACTIVE.
|
||||
.IP 2. 3
|
||||
if not found, the first port that is UP (physical link up).
|
||||
.UNINDENT
|
||||
.sp
|
||||
If a port and/or CA name is specified, the libibumad library attempts
|
||||
to fulfill the user request, and will fail if it is not possible.
|
||||
.sp
|
||||
For example:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
ibaddr # use the first port (criteria #1 above)
|
||||
ibaddr \-C mthca1 # pick the best port from "mthca1" only.
|
||||
ibaddr \-P 2 # use the second (active/up) port from the first available IB device.
|
||||
ibaddr \-C mthca0 \-P 2 # use the specified port only.
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS Debugging flags
|
||||
.\" Define the common option -d
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-d
|
||||
raise the IB debugging level.
|
||||
May be used several times (\-ddd or \-d \-d \-d).
|
||||
.UNINDENT
|
||||
.\" Define the common option -e
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-e
|
||||
show send and receive errors (timeouts and others)
|
||||
.UNINDENT
|
||||
.\" Define the common option -h
|
||||
.
|
||||
.sp
|
||||
\fB\-h, \-\-help\fP show the usage message
|
||||
.\" Define the common option -v
|
||||
.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fB\-v, \-\-verbose\fP
|
||||
increase the application verbosity level.
|
||||
May be used several times (\-vv or \-v \-v \-v)
|
||||
.UNINDENT
|
||||
.\" Define the common option -V
|
||||
.
|
||||
.sp
|
||||
\fB\-V, \-\-version\fP show the version info.
|
||||
.SS Configuration flags
|
||||
.\" Define the common option -t
|
||||
.
|
||||
.sp
|
||||
\fB\-t, \-\-timeout <timeout_ms>\fP override the default timeout for the solicited mads.
|
||||
.\" Define the common option -z
|
||||
.
|
||||
.sp
|
||||
\fB\-\-config, \-z <config_file>\fP Specify alternate config file.
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
Default: /etc/infiniband-diags/ibdiag.conf
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SS FILES
|
||||
.\" Common text for the config file
|
||||
.
|
||||
.SS CONFIG FILE
|
||||
.sp
|
||||
/etc/infiniband-diags/ibdiag.conf
|
||||
.sp
|
||||
A global config file is provided to set some of the common options for all
|
||||
tools. See supplied config file for details.
|
||||
.SS EXAMPLES
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B ::
|
||||
vendstat \-N 6 # read IS3 or IS4 general information
|
||||
vendstat \-w 6 # read IS3 port xmit wait counters
|
||||
vendstat \-i 6 12 # read IS4 port 12 counter group info
|
||||
vendstat \-c 0,1 6 12 # configure IS4 port 12 counter groups for PortXmitDataSL
|
||||
vendstat \-c 2,8 6 12 # configure IS4 port 12 counter groups for PortRcvDataSL
|
||||
.UNINDENT
|
||||
.SS AUTHOR
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B Hal Rosenstock
|
||||
< \fI\%hal.rosenstock@gmail.com\fP >
|
||||
.UNINDENT
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2011 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2013 Lawrence Livermore National Security. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <complib/cl_nodenamemap.h>
|
||||
|
||||
#include <infiniband/ibnetdisc.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
unsigned startlid = 0, endlid = 0;
|
||||
|
||||
static int brief, dump_all, multicast;
|
||||
|
||||
static char *node_name_map_file = NULL;
|
||||
static nn_map_t *node_name_map = NULL;
|
||||
|
||||
#define IB_MLIDS_IN_BLOCK (IB_SMP_DATA_SIZE/2)
|
||||
|
||||
int dump_mlid(char *str, int strlen, unsigned mlid, unsigned nports,
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK])
|
||||
{
|
||||
uint16_t mask;
|
||||
unsigned i, chunk, bit, nonzero = 0;
|
||||
|
||||
if (brief) {
|
||||
int n = 0;
|
||||
unsigned chunks = ALIGN(nports + 1, 16) / 16;
|
||||
for (i = 0; i < chunks; i++) {
|
||||
mask = ntohs(mft[i][mlid % IB_MLIDS_IN_BLOCK]);
|
||||
if (mask)
|
||||
nonzero++;
|
||||
n += snprintf(str + n, strlen - n, "%04hx", mask);
|
||||
if (n >= strlen) {
|
||||
n = strlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nonzero && !dump_all) {
|
||||
str[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
for (i = 0; i <= nports; i++) {
|
||||
chunk = i / 16;
|
||||
bit = i % 16;
|
||||
|
||||
mask = ntohs(mft[chunk][mlid % IB_MLIDS_IN_BLOCK]);
|
||||
if (mask)
|
||||
nonzero++;
|
||||
str[i * 2] = (mask & (1 << bit)) ? 'x' : ' ';
|
||||
str[i * 2 + 1] = ' ';
|
||||
}
|
||||
if (!nonzero && !dump_all) {
|
||||
str[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
str[i * 2] = 0;
|
||||
return i * 2;
|
||||
}
|
||||
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0}, { 0 }, { 0 } };
|
||||
|
||||
void dump_multicast_tables(ibnd_node_t * node, unsigned startlid,
|
||||
unsigned endlid, struct ibmad_port * mad_port)
|
||||
{
|
||||
ib_portid_t *portid = &node->path_portid;
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char str[512];
|
||||
char *s;
|
||||
uint64_t nodeguid;
|
||||
uint32_t mod;
|
||||
unsigned block, i, j, e, nports, cap, chunks, startblock, lastblock,
|
||||
top;
|
||||
char *mapnd = NULL;
|
||||
int n = 0;
|
||||
|
||||
memcpy(nd, node->nodedesc, strlen(node->nodedesc));
|
||||
nports = node->numports;
|
||||
nodeguid = node->guid;
|
||||
|
||||
mad_decode_field(node->switchinfo, IB_SW_MCAST_FDB_CAP_F, &cap);
|
||||
mad_decode_field(node->switchinfo, IB_SW_MCAST_FDB_TOP_F, &top);
|
||||
|
||||
if (!endlid || endlid > IB_MIN_MCAST_LID + cap - 1)
|
||||
endlid = IB_MIN_MCAST_LID + cap - 1;
|
||||
if (!dump_all && top && top < endlid) {
|
||||
if (top < IB_MIN_MCAST_LID - 1)
|
||||
IBWARN("illegal top mlid %x", top);
|
||||
else
|
||||
endlid = top;
|
||||
}
|
||||
|
||||
if (!startlid)
|
||||
startlid = IB_MIN_MCAST_LID;
|
||||
else if (startlid < IB_MIN_MCAST_LID) {
|
||||
IBWARN("illegal start mlid %x, set to %x", startlid,
|
||||
IB_MIN_MCAST_LID);
|
||||
startlid = IB_MIN_MCAST_LID;
|
||||
}
|
||||
|
||||
if (endlid > IB_MAX_MCAST_LID) {
|
||||
IBWARN("illegal end mlid %x, truncate to %x", endlid,
|
||||
IB_MAX_MCAST_LID);
|
||||
endlid = IB_MAX_MCAST_LID;
|
||||
}
|
||||
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
printf("Multicast mlids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64
|
||||
" (%s):\n", startlid, endlid, portid2str(portid), nodeguid,
|
||||
mapnd);
|
||||
|
||||
if (brief)
|
||||
printf(" MLid Port Mask\n");
|
||||
else {
|
||||
if (nports > 9) {
|
||||
for (i = 0, s = str; i <= nports; i++) {
|
||||
*s++ = (i % 10) ? ' ' : '0' + i / 10;
|
||||
*s++ = ' ';
|
||||
}
|
||||
*s = 0;
|
||||
printf(" %s\n", str);
|
||||
}
|
||||
for (i = 0, s = str; i <= nports; i++)
|
||||
s += sprintf(s, "%d ", i % 10);
|
||||
printf(" Ports: %s\n", str);
|
||||
printf(" MLid\n");
|
||||
}
|
||||
if (ibverbose)
|
||||
printf("Switch multicast mlid capability is %d top is 0x%x\n",
|
||||
cap, top);
|
||||
|
||||
chunks = ALIGN(nports + 1, 16) / 16;
|
||||
|
||||
startblock = startlid / IB_MLIDS_IN_BLOCK;
|
||||
lastblock = endlid / IB_MLIDS_IN_BLOCK;
|
||||
for (block = startblock; block <= lastblock; block++) {
|
||||
for (j = 0; j < chunks; j++) {
|
||||
int status;
|
||||
mod = (block - IB_MIN_MCAST_LID / IB_MLIDS_IN_BLOCK)
|
||||
| (j << 28);
|
||||
|
||||
DEBUG("reading block %x chunk %d mod %x", block, j,
|
||||
mod);
|
||||
if (!smp_query_status_via
|
||||
(mft + j, portid, IB_ATTR_MULTICASTFORWTBL, mod, 0,
|
||||
&status, mad_port)) {
|
||||
fprintf(stderr, "SubnGet(MFT) failed on switch "
|
||||
"'%s' %s Node GUID 0x%"PRIx64
|
||||
" SMA LID %d; MAD status 0x%x "
|
||||
"AM 0x%x\n",
|
||||
mapnd, portid2str(portid),
|
||||
node->guid, node->smalid,
|
||||
status, mod);
|
||||
}
|
||||
}
|
||||
|
||||
i = block * IB_MLIDS_IN_BLOCK;
|
||||
e = i + IB_MLIDS_IN_BLOCK;
|
||||
if (i < startlid)
|
||||
i = startlid;
|
||||
if (e > endlid + 1)
|
||||
e = endlid + 1;
|
||||
|
||||
for (; i < e; i++) {
|
||||
if (dump_mlid(str, sizeof str, i, nports, mft) == 0)
|
||||
continue;
|
||||
printf("0x%04x %s\n", i, str);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d %smlids dumped \n", n, dump_all ? "" : "valid ");
|
||||
|
||||
free(mapnd);
|
||||
}
|
||||
|
||||
int dump_lid(char *str, int str_len, int lid, int valid,
|
||||
ibnd_fabric_t *fabric,
|
||||
int * last_port_lid, int * base_port_lid,
|
||||
uint64_t * portguid)
|
||||
{
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
|
||||
ibnd_port_t *port = NULL;
|
||||
|
||||
char ntype[50], sguid[30];
|
||||
uint64_t nodeguid;
|
||||
int baselid, lmc, type;
|
||||
char *mapnd = NULL;
|
||||
int rc;
|
||||
|
||||
if (brief) {
|
||||
str[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lid <= *last_port_lid) {
|
||||
if (!valid)
|
||||
return snprintf(str, str_len,
|
||||
": (path #%d - illegal port)",
|
||||
lid - *base_port_lid);
|
||||
else if (!*portguid)
|
||||
return snprintf(str, str_len,
|
||||
": (path #%d out of %d)",
|
||||
lid - *base_port_lid + 1,
|
||||
*last_port_lid - *base_port_lid + 1);
|
||||
else {
|
||||
return snprintf(str, str_len,
|
||||
": (path #%d out of %d: portguid %s)",
|
||||
lid - *base_port_lid + 1,
|
||||
*last_port_lid - *base_port_lid + 1,
|
||||
mad_dump_val(IB_NODE_PORT_GUID_F, sguid,
|
||||
sizeof sguid, portguid));
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
return snprintf(str, str_len, ": (illegal port)");
|
||||
|
||||
*portguid = 0;
|
||||
|
||||
port = ibnd_find_port_lid(fabric, lid);
|
||||
if (!port) {
|
||||
return snprintf(str, str_len, ": (node info not available fabric scan)");
|
||||
}
|
||||
|
||||
nodeguid = port->node->guid;
|
||||
*portguid = port->guid;
|
||||
type = port->node->type;
|
||||
|
||||
baselid = port->base_lid;
|
||||
lmc = port->lmc;
|
||||
|
||||
memcpy(nd, port->node->nodedesc, strlen(port->node->nodedesc));
|
||||
|
||||
if (lmc > 0) {
|
||||
*base_port_lid = baselid;
|
||||
*last_port_lid = baselid + (1 << lmc) - 1;
|
||||
}
|
||||
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
rc = snprintf(str, str_len, ": (%s portguid %s: '%s')",
|
||||
mad_dump_val(IB_NODE_TYPE_F, ntype, sizeof ntype,
|
||||
&type), mad_dump_val(IB_NODE_PORT_GUID_F,
|
||||
sguid, sizeof sguid,
|
||||
portguid),
|
||||
mapnd);
|
||||
|
||||
free(mapnd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void dump_unicast_tables(ibnd_node_t * node, int startlid, int endlid,
|
||||
struct ibmad_port *mad_port, ibnd_fabric_t *fabric)
|
||||
{
|
||||
ib_portid_t * portid = &node->path_portid;
|
||||
char lft[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char str[200];
|
||||
uint64_t nodeguid;
|
||||
int block, i, e, top;
|
||||
unsigned nports;
|
||||
int n = 0, startblock, endblock;
|
||||
char *mapnd = NULL;
|
||||
int last_port_lid = 0, base_port_lid = 0;
|
||||
uint64_t portguid = 0;
|
||||
|
||||
mad_decode_field(node->switchinfo, IB_SW_LINEAR_FDB_TOP_F, &top);
|
||||
nodeguid = node->guid;
|
||||
nports = node->numports;
|
||||
memcpy(nd, node->nodedesc, strlen(node->nodedesc));
|
||||
|
||||
if (!endlid || endlid > top)
|
||||
endlid = top;
|
||||
|
||||
if (endlid > IB_MAX_UCAST_LID) {
|
||||
IBWARN("illegal lft top %d, truncate to %d", endlid,
|
||||
IB_MAX_UCAST_LID);
|
||||
endlid = IB_MAX_UCAST_LID;
|
||||
}
|
||||
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
printf("Unicast lids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64
|
||||
" (%s):\n", startlid, endlid, portid2str(portid), nodeguid,
|
||||
mapnd);
|
||||
|
||||
DEBUG("Switch top is 0x%x\n", top);
|
||||
|
||||
printf(" Lid Out Destination\n");
|
||||
printf(" Port Info \n");
|
||||
startblock = startlid / IB_SMP_DATA_SIZE;
|
||||
endblock = ALIGN(endlid, IB_SMP_DATA_SIZE) / IB_SMP_DATA_SIZE;
|
||||
for (block = startblock; block < endblock; block++) {
|
||||
int status;
|
||||
DEBUG("reading block %d", block);
|
||||
if (!smp_query_status_via(lft, portid, IB_ATTR_LINEARFORWTBL, block,
|
||||
0, &status, mad_port)) {
|
||||
fprintf(stderr, "SubnGet(LFT) failed on switch "
|
||||
"'%s' %s Node GUID 0x%"PRIx64
|
||||
" SMA LID %d; MAD status 0x%x AM 0x%x\n",
|
||||
mapnd, portid2str(portid),
|
||||
node->guid, node->smalid,
|
||||
status, block);
|
||||
}
|
||||
i = block * IB_SMP_DATA_SIZE;
|
||||
e = i + IB_SMP_DATA_SIZE;
|
||||
if (i < startlid)
|
||||
i = startlid;
|
||||
if (e > endlid + 1)
|
||||
e = endlid + 1;
|
||||
|
||||
for (; i < e; i++) {
|
||||
unsigned outport = lft[i % IB_SMP_DATA_SIZE];
|
||||
unsigned valid = (outport <= nports);
|
||||
|
||||
if (!valid && !dump_all)
|
||||
continue;
|
||||
dump_lid(str, sizeof str, i, valid, fabric,
|
||||
&last_port_lid, &base_port_lid, &portguid);
|
||||
printf("0x%04x %03u %s\n", i, outport & 0xff, str);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d %slids dumped \n", n, dump_all ? "" : "valid ");
|
||||
free(mapnd);
|
||||
}
|
||||
|
||||
void dump_node(ibnd_node_t *node, struct ibmad_port *mad_port,
|
||||
ibnd_fabric_t *fabric)
|
||||
{
|
||||
if (multicast)
|
||||
dump_multicast_tables(node, startlid, endlid, mad_port);
|
||||
else
|
||||
dump_unicast_tables(node, startlid, endlid,
|
||||
mad_port, fabric);
|
||||
}
|
||||
|
||||
void process_switch(ibnd_node_t * node, void *fabric)
|
||||
{
|
||||
dump_node(node, srcport, (ibnd_fabric_t *)fabric);
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
dump_all++;
|
||||
break;
|
||||
case 'M':
|
||||
multicast++;
|
||||
break;
|
||||
case 'n':
|
||||
brief++;
|
||||
break;
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
|
||||
struct ibnd_config config = { 0 };
|
||||
ibnd_fabric_t *fabric = NULL;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"all", 'a', 0, NULL, "show all lids, even invalid entries"},
|
||||
{"no_dests", 'n', 0, NULL,
|
||||
"do not try to resolve destinations"},
|
||||
{"Multicast", 'M', 0, NULL, "show multicast forwarding tables"},
|
||||
{"node-name-map", 1, 1, "<file>", "node name map file"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "[<dest dr_path|lid|guid> [<startlid> [<endlid>]]]";
|
||||
const char *usage_examples[] = {
|
||||
" -- Unicast examples:",
|
||||
"-a\t# same, but dump all lids, even with invalid out ports",
|
||||
"-n\t# simple dump format - no destination resolving",
|
||||
"10\t# dump lids starting from 10",
|
||||
"0x10 0x20\t# dump lid range",
|
||||
" -- Multicast examples:",
|
||||
"-M\t# dump all non empty mlids of switch with lid 4",
|
||||
"-M 0xc010 0xc020\t# same, but with range",
|
||||
"-M -n\t# simple dump format",
|
||||
NULL,
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, &config, "KGDLs", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 0)
|
||||
startlid = strtoul(argv[0], 0, 0);
|
||||
if (argc > 1)
|
||||
endlid = strtoul(argv[1], 0, 0);
|
||||
|
||||
node_name_map = open_node_name_map(node_name_map_file);
|
||||
|
||||
if (ibd_timeout)
|
||||
config.timeout_ms = ibd_timeout;
|
||||
|
||||
config.flags = ibd_ibnetdisc_flags;
|
||||
config.mkey = ibd_mkey;
|
||||
|
||||
if ((fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL,
|
||||
&config)) != NULL) {
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport) {
|
||||
fprintf(stderr,
|
||||
"Failed to open '%s' port '%d'\n", ibd_ca, ibd_ca_port);
|
||||
rc = -1;
|
||||
goto Exit;
|
||||
}
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (ibd_timeout) {
|
||||
mad_rpc_set_timeout(srcport, ibd_timeout);
|
||||
}
|
||||
|
||||
ibnd_iter_nodes_type(fabric, process_switch, IB_NODE_SWITCH, fabric);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Failed to discover fabric\n");
|
||||
rc = -1;
|
||||
}
|
||||
Exit:
|
||||
ibnd_destroy_fabric(fabric);
|
||||
|
||||
close_node_name_map(node_name_map);
|
||||
exit(rc);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static int ib_resolve_addr(ib_portid_t * portid, int portnum, int show_lid,
|
||||
int show_gid)
|
||||
{
|
||||
char gid_str[INET6_ADDRSTRLEN];
|
||||
uint8_t portinfo[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t nodeinfo[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint64_t guid, prefix;
|
||||
ibmad_gid_t gid;
|
||||
int lmc;
|
||||
|
||||
if (!smp_query_via(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return -1;
|
||||
|
||||
if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0,
|
||||
srcport))
|
||||
return -1;
|
||||
|
||||
mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid);
|
||||
mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix);
|
||||
mad_decode_field(portinfo, IB_PORT_LMC_F, &lmc);
|
||||
mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid);
|
||||
|
||||
mad_encode_field(gid, IB_GID_PREFIX_F, &prefix);
|
||||
mad_encode_field(gid, IB_GID_GUID_F, &guid);
|
||||
|
||||
if (show_gid) {
|
||||
printf("GID %s ", inet_ntop(AF_INET6, gid, gid_str,
|
||||
sizeof gid_str));
|
||||
}
|
||||
|
||||
if (show_lid > 0)
|
||||
printf("LID start 0x%x end 0x%x", portid->lid,
|
||||
portid->lid + (1 << lmc) - 1);
|
||||
else if (show_lid < 0)
|
||||
printf("LID start %u end %u", portid->lid,
|
||||
portid->lid + (1 << lmc) - 1);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_lid, show_gid;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'g':
|
||||
show_gid = 1;
|
||||
break;
|
||||
case 'l':
|
||||
show_lid++;
|
||||
break;
|
||||
case 'L':
|
||||
show_lid = -100;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
int port = 0;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"gid_show", 'g', 0, NULL, "show gid address only"},
|
||||
{"lid_show", 'l', 0, NULL, "show lid range only"},
|
||||
{"Lid_show", 'L', 0, NULL, "show lid range (in decimal) only"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "[<lid|dr_path|guid>]";
|
||||
const char *usage_examples[] = {
|
||||
"\t\t# local port's address",
|
||||
"32\t\t# show lid range and gid of lid 32",
|
||||
"-G 0x8f1040023\t# same but using guid address",
|
||||
"-l 32\t\t# show lid range only",
|
||||
"-L 32\t\t# show decimal lid range only",
|
||||
"-g 32\t\t# show gid address only",
|
||||
NULL
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "KL", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
port = strtoul(argv[1], 0, 0);
|
||||
|
||||
if (!show_lid && !show_gid)
|
||||
show_lid = show_gid = 1;
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (argc) {
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
} else {
|
||||
if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, NULL) < 0)
|
||||
IBEXIT("can't resolve self port %s", argv[0]);
|
||||
}
|
||||
|
||||
if (ib_resolve_addr(&portid, port, show_lid, show_gid) < 0)
|
||||
IBEXIT("can't resolve requested address");
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Lawrence Livermore National Lab. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
#include <infiniband/ibnetdisc.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
uint64_t switchguid_before = 0;
|
||||
uint64_t switchguid_after = 0;
|
||||
int switchguid_flag = 0;
|
||||
|
||||
uint64_t caguid_before = 0;
|
||||
uint64_t caguid_after = 0;
|
||||
int caguid_flag = 0;
|
||||
|
||||
uint64_t sysimgguid_before = 0;
|
||||
uint64_t sysimgguid_after = 0;
|
||||
int sysimgguid_flag = 0;
|
||||
|
||||
uint64_t portguid_nodeguid = 0;
|
||||
uint64_t portguid_before = 0;
|
||||
uint64_t portguid_after = 0;
|
||||
int portguid_flag = 0;
|
||||
|
||||
struct guids {
|
||||
uint64_t searchguid;
|
||||
int searchguid_found;
|
||||
uint64_t before;
|
||||
uint64_t after;
|
||||
int found;
|
||||
};
|
||||
|
||||
static int parse_beforeafter(char *arg, uint64_t *before, uint64_t *after)
|
||||
{
|
||||
char *ptr;
|
||||
char *before_str;
|
||||
char *after_str;
|
||||
|
||||
ptr = strchr(optarg, ':');
|
||||
if (!ptr || !(*(ptr + 1))) {
|
||||
fprintf(stderr, "invalid input '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
(*ptr) = '\0';
|
||||
before_str = arg;
|
||||
after_str = ptr + 1;
|
||||
|
||||
(*before) = strtoull(before_str, 0, 0);
|
||||
(*after) = strtoull(after_str, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_guidbeforeafter(char *arg,
|
||||
uint64_t *guid,
|
||||
uint64_t *before,
|
||||
uint64_t *after)
|
||||
{
|
||||
char *ptr1;
|
||||
char *ptr2;
|
||||
char *guid_str;
|
||||
char *before_str;
|
||||
char *after_str;
|
||||
|
||||
ptr1 = strchr(optarg, ':');
|
||||
if (!ptr1 || !(*(ptr1 + 1))) {
|
||||
fprintf(stderr, "invalid input '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
guid_str = arg;
|
||||
before_str = ptr1 + 1;
|
||||
|
||||
ptr2 = strchr(before_str, ':');
|
||||
if (!ptr2 || !(*(ptr2 + 1))) {
|
||||
fprintf(stderr, "invalid input '%s'\n", arg);
|
||||
return -1;
|
||||
}
|
||||
(*ptr1) = '\0';
|
||||
(*ptr2) = '\0';
|
||||
after_str = ptr2 + 1;
|
||||
|
||||
(*guid) = strtoull(guid_str, 0, 0);
|
||||
(*before) = strtoull(before_str, 0, 0);
|
||||
(*after) = strtoull(after_str, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 1:
|
||||
if (parse_beforeafter(optarg,
|
||||
&switchguid_before,
|
||||
&switchguid_after) < 0)
|
||||
return -1;
|
||||
switchguid_flag++;
|
||||
break;
|
||||
case 2:
|
||||
if (parse_beforeafter(optarg,
|
||||
&caguid_before,
|
||||
&caguid_after) < 0)
|
||||
return -1;
|
||||
caguid_flag++;
|
||||
break;
|
||||
case 3:
|
||||
if (parse_beforeafter(optarg,
|
||||
&sysimgguid_before,
|
||||
&sysimgguid_after) < 0)
|
||||
return -1;
|
||||
sysimgguid_flag++;
|
||||
break;
|
||||
case 4:
|
||||
if (parse_guidbeforeafter(optarg,
|
||||
&portguid_nodeguid,
|
||||
&portguid_before,
|
||||
&portguid_after) < 0)
|
||||
return -1;
|
||||
portguid_flag++;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_switchportguids(ibnd_node_t *node)
|
||||
{
|
||||
ibnd_port_t *port;
|
||||
int p;
|
||||
|
||||
for (p = 0; p <= node->numports; p++) {
|
||||
port = node->ports[p];
|
||||
if (port)
|
||||
port->guid = node->guid;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_node_guid(ibnd_node_t *node, void *user_data)
|
||||
{
|
||||
struct guids *guids;
|
||||
|
||||
guids = (struct guids *)user_data;
|
||||
|
||||
if (node->guid == guids->before) {
|
||||
|
||||
node->guid = guids->after;
|
||||
|
||||
/* port guids are identical to switch guids on
|
||||
* switches, so update port guids too
|
||||
*/
|
||||
if (node->type == IB_NODE_SWITCH)
|
||||
update_switchportguids(node);
|
||||
|
||||
guids->found++;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_sysimgguid(ibnd_node_t *node, void *user_data)
|
||||
{
|
||||
struct guids *guids;
|
||||
uint64_t sysimgguid;
|
||||
|
||||
guids = (struct guids *)user_data;
|
||||
|
||||
sysimgguid = mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
|
||||
if (sysimgguid == guids->before) {
|
||||
mad_set_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F,
|
||||
guids->after);
|
||||
guids->found++;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_portguid(ibnd_node_t *node, void *user_data)
|
||||
{
|
||||
struct guids *guids;
|
||||
|
||||
guids = (struct guids *)user_data;
|
||||
|
||||
if (node->guid != guids->searchguid)
|
||||
return;
|
||||
|
||||
guids->searchguid_found++;
|
||||
|
||||
if (node->type == IB_NODE_SWITCH) {
|
||||
/* port guids are identical to switch guids on
|
||||
* switches, so update switch guid too
|
||||
*/
|
||||
if (node->guid == guids->before) {
|
||||
node->guid = guids->after;
|
||||
update_switchportguids(node);
|
||||
guids->found++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ibnd_port_t *port;
|
||||
int p;
|
||||
|
||||
for (p = 1; p <= node->numports; p++) {
|
||||
port = node->ports[p];
|
||||
if (port
|
||||
&& port->guid == guids->before) {
|
||||
port->guid = guids->after;
|
||||
guids->found++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ibnd_fabric_t *fabric = NULL;
|
||||
char *orig_cache_file = NULL;
|
||||
char *new_cache_file = NULL;
|
||||
struct guids guids;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"switchguid", 1, 1, "BEFOREGUID:AFTERGUID",
|
||||
"Specify before and after switchguid to edit"},
|
||||
{"caguid", 2, 1, "BEFOREGUID:AFTERGUID",
|
||||
"Specify before and after caguid to edit"},
|
||||
{"sysimgguid", 3, 1, "BEFOREGUID:AFTERGUID",
|
||||
"Specify before and after sysimgguid to edit"},
|
||||
{"portguid", 4, 1, "NODEGUID:BEFOREGUID:AFTERGUID",
|
||||
"Specify before and after port guid to edit"},
|
||||
{0}
|
||||
};
|
||||
char *usage_args = "<orig.cache> <new.cache>";
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "CDdeGKLPstvy",
|
||||
opts, process_opt, usage_args,
|
||||
NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
orig_cache_file = argv[0];
|
||||
new_cache_file = argv[1];
|
||||
|
||||
if (!orig_cache_file)
|
||||
IBEXIT("original cache file not specified");
|
||||
|
||||
if (!new_cache_file)
|
||||
IBEXIT("new cache file not specified");
|
||||
|
||||
if ((fabric = ibnd_load_fabric(orig_cache_file, 0)) == NULL)
|
||||
IBEXIT("loading original cached fabric failed");
|
||||
|
||||
if (switchguid_flag) {
|
||||
guids.before = switchguid_before;
|
||||
guids.after = switchguid_after;
|
||||
guids.found = 0;
|
||||
ibnd_iter_nodes_type(fabric,
|
||||
replace_node_guid,
|
||||
IB_NODE_SWITCH,
|
||||
&guids);
|
||||
|
||||
if (!guids.found)
|
||||
IBEXIT("switchguid = %" PRIx64 " not found",
|
||||
switchguid_before);
|
||||
}
|
||||
|
||||
if (caguid_flag) {
|
||||
guids.before = caguid_before;
|
||||
guids.after = caguid_after;
|
||||
guids.found = 0;
|
||||
ibnd_iter_nodes_type(fabric,
|
||||
replace_node_guid,
|
||||
IB_NODE_CA,
|
||||
&guids);
|
||||
|
||||
if (!guids.found)
|
||||
IBEXIT("caguid = %" PRIx64 " not found",
|
||||
caguid_before);
|
||||
}
|
||||
|
||||
if (sysimgguid_flag) {
|
||||
guids.before = sysimgguid_before;
|
||||
guids.after = sysimgguid_after;
|
||||
guids.found = 0;
|
||||
ibnd_iter_nodes(fabric,
|
||||
replace_sysimgguid,
|
||||
&guids);
|
||||
|
||||
if (!guids.found)
|
||||
IBEXIT("sysimgguid = %" PRIx64 " not found",
|
||||
sysimgguid_before);
|
||||
}
|
||||
|
||||
if (portguid_flag) {
|
||||
guids.searchguid = portguid_nodeguid;
|
||||
guids.searchguid_found = 0;
|
||||
guids.before = portguid_before;
|
||||
guids.after = portguid_after;
|
||||
guids.found = 0;
|
||||
ibnd_iter_nodes(fabric,
|
||||
replace_portguid,
|
||||
&guids);
|
||||
|
||||
if (!guids.searchguid_found)
|
||||
IBEXIT("nodeguid = %" PRIx64 " not found",
|
||||
portguid_nodeguid);
|
||||
|
||||
if (!guids.found)
|
||||
IBEXIT("portguid = %" PRIx64 " not found",
|
||||
portguid_before);
|
||||
}
|
||||
|
||||
if (ibnd_cache_fabric(fabric, new_cache_file, 0) < 0)
|
||||
IBEXIT("caching new cache data failed");
|
||||
|
||||
ibnd_destroy_fabric(fabric);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,639 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2011 Lawrence Livermore National Lab. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static ibmad_gid_t dgid;
|
||||
static int with_grh;
|
||||
|
||||
static op_fn_t congestion_key_info;
|
||||
static op_fn_t switch_congestion_setting;
|
||||
static op_fn_t switch_port_congestion_setting;
|
||||
static op_fn_t ca_congestion_setting;
|
||||
static op_fn_t congestion_control_table;
|
||||
|
||||
static const match_rec_t match_tbl[] = {
|
||||
{"CongestionKeyInfo", "CK", congestion_key_info, 0,
|
||||
"<cckey> <cckeyprotectbit> <cckeyleaseperiod> <cckeyviolations>"},
|
||||
{"SwitchCongestionSetting", "SS", switch_congestion_setting, 0,
|
||||
"<controlmap> <victimmask> <creditmask> <threshold> <packetsize> "
|
||||
"<csthreshold> <csreturndelay> <markingrate>"},
|
||||
{"SwitchPortCongestionSetting", "SP", switch_port_congestion_setting, 1,
|
||||
"<valid> <control_type> <threshold> <packet_size> <cong_parm_marking_rate>"},
|
||||
{"CACongestionSetting", "CS", ca_congestion_setting, 0,
|
||||
"<port_control> <control_map> <ccti_timer> <ccti_increase> "
|
||||
"<trigger_threshold> <ccti_min>"},
|
||||
{"CongestionControlTable", "CT", congestion_control_table, 0,
|
||||
"<cctilimit> <index> <cctentry> <cctentry> ..."},
|
||||
{0}
|
||||
};
|
||||
|
||||
uint64_t cckey = 0;
|
||||
|
||||
/*******************************************/
|
||||
static char *parselonglongint(char *arg, uint64_t *val)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
|
||||
errno = 0;
|
||||
*val = strtoull(arg, &endptr, 0);
|
||||
if ((endptr && *endptr != '\0')
|
||||
|| errno != 0) {
|
||||
if (errno == ERANGE)
|
||||
return "value out of range";
|
||||
return "invalid integer input";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *parseint(char *arg, uint32_t *val, int hexonly)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
|
||||
errno = 0;
|
||||
*val = strtoul(arg, &endptr, hexonly ? 16 : 0);
|
||||
if ((endptr && *endptr != '\0')
|
||||
|| errno != 0) {
|
||||
if (errno == ERANGE)
|
||||
return "value out of range";
|
||||
return "invalid integer input";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_key_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t rcv[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t payload[IB_CC_DATA_SZ] = { 0 };
|
||||
uint64_t cc_key;
|
||||
uint32_t cc_keyprotectbit;
|
||||
uint32_t cc_keyleaseperiod;
|
||||
uint32_t cc_keyviolations;
|
||||
char *errstr;
|
||||
|
||||
if (argc != 4)
|
||||
return "invalid number of parameters for CongestionKeyInfo";
|
||||
|
||||
if ((errstr = parselonglongint(argv[0], &cc_key)))
|
||||
return errstr;
|
||||
if ((errstr = parseint(argv[1], &cc_keyprotectbit, 0)))
|
||||
return errstr;
|
||||
if ((errstr = parseint(argv[2], &cc_keyleaseperiod, 0)))
|
||||
return errstr;
|
||||
if ((errstr = parseint(argv[3], &cc_keyviolations, 0)))
|
||||
return errstr;
|
||||
|
||||
if (cc_keyprotectbit != 0 && cc_keyprotectbit != 1)
|
||||
return "invalid cc_keyprotectbit value";
|
||||
|
||||
if (cc_keyleaseperiod > USHRT_MAX)
|
||||
return "invalid cc_keyleaseperiod value";
|
||||
|
||||
if (cc_keyviolations > USHRT_MAX)
|
||||
return "invalid cc_keyviolations value";
|
||||
|
||||
mad_set_field64(payload,
|
||||
0,
|
||||
IB_CC_CONGESTION_KEY_INFO_CC_KEY_F,
|
||||
cc_key);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CONGESTION_KEY_INFO_CC_KEY_PROTECT_BIT_F,
|
||||
&cc_keyprotectbit);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CONGESTION_KEY_INFO_CC_KEY_LEASE_PERIOD_F,
|
||||
&cc_keyleaseperiod);
|
||||
|
||||
/* spec says "setting the counter to a value other than zero results
|
||||
* in the counter being left unchanged. So if user wants no change,
|
||||
* they gotta input non-zero
|
||||
*/
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CONGESTION_KEY_INFO_CC_KEY_VIOLATIONS_F,
|
||||
&cc_keyviolations);
|
||||
|
||||
if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CONGESTION_KEY_INFO,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "congestion key info config failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* parse like it's a hypothetical 256 bit hex code */
|
||||
static char *parse256(char *arg, uint8_t *buf)
|
||||
{
|
||||
int numdigits = 0;
|
||||
int startindex;
|
||||
char *ptr;
|
||||
int i;
|
||||
|
||||
if (!strncmp(arg, "0x", 2) || !strncmp(arg, "0X", 2))
|
||||
arg += 2;
|
||||
|
||||
for (ptr = arg; *ptr; ptr++) {
|
||||
if (!isxdigit(*ptr))
|
||||
return "invalid hex digit read";
|
||||
numdigits++;
|
||||
}
|
||||
|
||||
if (numdigits > 64)
|
||||
return "hex code too long";
|
||||
|
||||
/* we need to imagine that this is like a 256-bit int stored
|
||||
* in big endian. So we need to find the first index
|
||||
* point where the user's input would start in our array.
|
||||
*/
|
||||
startindex = 32 - ((numdigits - 1) / 2) - 1;
|
||||
|
||||
for (i = startindex; i <= 31; i++) {
|
||||
char tmp[3] = { 0 };
|
||||
uint32_t tmpint;
|
||||
char *errstr;
|
||||
|
||||
/* I can't help but think there is a strtoX that
|
||||
* will do this for me, but I can't find it.
|
||||
*/
|
||||
if (i == startindex && numdigits % 2) {
|
||||
memcpy(tmp, arg, 1);
|
||||
arg++;
|
||||
}
|
||||
else {
|
||||
memcpy(tmp, arg, 2);
|
||||
arg += 2;
|
||||
}
|
||||
|
||||
if ((errstr = parseint(tmp, &tmpint, 1)))
|
||||
return errstr;
|
||||
buf[i] = tmpint;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *parsecct(char *arg, uint32_t *shift, uint32_t *multiplier)
|
||||
{
|
||||
char buf[1024] = { 0 };
|
||||
char *errstr;
|
||||
char *ptr;
|
||||
|
||||
strcpy(buf, arg);
|
||||
|
||||
if (!(ptr = strchr(buf, ':')))
|
||||
return "ccts are formatted shift:multiplier";
|
||||
|
||||
*ptr = '\0';
|
||||
ptr++;
|
||||
|
||||
if ((errstr = parseint(buf, shift, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(ptr, multiplier, 0)))
|
||||
return errstr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *switch_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t rcv[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t payload[IB_CC_DATA_SZ] = { 0 };
|
||||
uint32_t control_map;
|
||||
uint8_t victim_mask[32] = { 0 };
|
||||
uint8_t credit_mask[32] = { 0 };
|
||||
uint32_t threshold;
|
||||
uint32_t packet_size;
|
||||
uint32_t cs_threshold;
|
||||
uint32_t cs_returndelay_s;
|
||||
uint32_t cs_returndelay_m;
|
||||
uint32_t cs_returndelay;
|
||||
uint32_t marking_rate;
|
||||
char *errstr;
|
||||
|
||||
if (argc != 8)
|
||||
return "invalid number of parameters for SwitchCongestionSetting";
|
||||
|
||||
if ((errstr = parseint(argv[0], &control_map, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parse256(argv[1], victim_mask)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parse256(argv[2], credit_mask)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[3], &threshold, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[4], &packet_size, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[5], &cs_threshold, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parsecct(argv[6], &cs_returndelay_s, &cs_returndelay_m)))
|
||||
return errstr;
|
||||
|
||||
cs_returndelay = cs_returndelay_m;
|
||||
cs_returndelay |= (cs_returndelay_s << 14);
|
||||
|
||||
if ((errstr = parseint(argv[7], &marking_rate, 0)))
|
||||
return errstr;
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_CONTROL_MAP_F,
|
||||
&control_map);
|
||||
|
||||
mad_set_array(payload,
|
||||
0,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_VICTIM_MASK_F,
|
||||
victim_mask);
|
||||
|
||||
mad_set_array(payload,
|
||||
0,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_CREDIT_MASK_F,
|
||||
credit_mask);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_THRESHOLD_F,
|
||||
&threshold);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_PACKET_SIZE_F,
|
||||
&packet_size);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_CS_THRESHOLD_F,
|
||||
&cs_threshold);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_CS_RETURN_DELAY_F,
|
||||
&cs_returndelay);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_SWITCH_CONGESTION_SETTING_MARKING_RATE_F,
|
||||
&marking_rate);
|
||||
|
||||
if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_SWITCH_CONGESTION_SETTING,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "switch congestion setting config failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *switch_port_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t rcv[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t payload[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t data[IB_CC_DATA_SZ] = { 0 };
|
||||
uint32_t portnum;
|
||||
uint32_t valid;
|
||||
uint32_t control_type;
|
||||
uint32_t threshold;
|
||||
uint32_t packet_size;
|
||||
uint32_t cong_parm_marking_rate;
|
||||
uint32_t type;
|
||||
uint32_t numports;
|
||||
uint8_t *ptr;
|
||||
char *errstr;
|
||||
|
||||
if (argc != 6)
|
||||
return "invalid number of parameters for SwitchPortCongestion";
|
||||
|
||||
if ((errstr = parseint(argv[0], &portnum, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[1], &valid, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[2], &control_type, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[3], &threshold, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[4], &packet_size, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[5], &cong_parm_marking_rate, 0)))
|
||||
return errstr;
|
||||
|
||||
/* Figure out number of ports first */
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info config failed";
|
||||
|
||||
mad_decode_field((uint8_t *)data, IB_NODE_TYPE_F, &type);
|
||||
mad_decode_field((uint8_t *)data, IB_NODE_NPORTS_F, &numports);
|
||||
|
||||
if (type != IB_NODE_SWITCH)
|
||||
return "destination not a switch";
|
||||
|
||||
if (portnum > numports)
|
||||
return "invalid port number specified";
|
||||
|
||||
/* We are modifying only 1 port, so get the current config */
|
||||
if (!cc_query_status_via(payload, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING,
|
||||
portnum / 32, 0, NULL, srcport, cckey))
|
||||
return "switch port congestion setting query failed";
|
||||
|
||||
ptr = payload + (((portnum % 32) * 4));
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_VALID_F,
|
||||
&valid);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_CONTROL_TYPE_F,
|
||||
&control_type);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_THRESHOLD_F,
|
||||
&threshold);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_PACKET_SIZE_F,
|
||||
&packet_size);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_SWITCH_PORT_CONGESTION_SETTING_ELEMENT_CONG_PARM_MARKING_RATE_F,
|
||||
&cong_parm_marking_rate);
|
||||
|
||||
if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING,
|
||||
portnum / 32, 0, NULL, srcport, cckey))
|
||||
return "switch port congestion setting config failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *ca_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t rcv[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t payload[IB_CC_DATA_SZ] = { 0 };
|
||||
uint32_t port_control;
|
||||
uint32_t control_map;
|
||||
uint32_t ccti_timer;
|
||||
uint32_t ccti_increase;
|
||||
uint32_t trigger_threshold;
|
||||
uint32_t ccti_min;
|
||||
char *errstr;
|
||||
int i;
|
||||
|
||||
if (argc != 6)
|
||||
return "invalid number of parameters for CACongestionSetting";
|
||||
|
||||
if ((errstr = parseint(argv[0], &port_control, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[1], &control_map, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[2], &ccti_timer, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[3], &ccti_increase, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[4], &trigger_threshold, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[5], &ccti_min, 0)))
|
||||
return errstr;
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CA_CONGESTION_SETTING_PORT_CONTROL_F,
|
||||
&port_control);
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CA_CONGESTION_SETTING_CONTROL_MAP_F,
|
||||
&control_map);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!(control_map & (0x1 << i)))
|
||||
continue;
|
||||
|
||||
ptr = payload + 2 + 2 + i * 8;
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_CA_CONGESTION_ENTRY_CCTI_TIMER_F,
|
||||
&ccti_timer);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_CA_CONGESTION_ENTRY_CCTI_INCREASE_F,
|
||||
&ccti_increase);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_CA_CONGESTION_ENTRY_TRIGGER_THRESHOLD_F,
|
||||
&trigger_threshold);
|
||||
|
||||
mad_encode_field(ptr,
|
||||
IB_CC_CA_CONGESTION_ENTRY_CCTI_MIN_F,
|
||||
&ccti_min);
|
||||
}
|
||||
|
||||
if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CA_CONGESTION_SETTING,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "ca congestion setting config failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_control_table(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t rcv[IB_CC_DATA_SZ] = { 0 };
|
||||
uint8_t payload[IB_CC_DATA_SZ] = { 0 };
|
||||
uint32_t ccti_limit;
|
||||
uint32_t index;
|
||||
uint32_t cctshifts[64];
|
||||
uint32_t cctmults[64];
|
||||
char *errstr;
|
||||
int i;
|
||||
|
||||
if (argc < 2 || argc > 66)
|
||||
return "invalid number of parameters for CongestionControlTable";
|
||||
|
||||
if ((errstr = parseint(argv[0], &ccti_limit, 0)))
|
||||
return errstr;
|
||||
|
||||
if ((errstr = parseint(argv[1], &index, 0)))
|
||||
return errstr;
|
||||
|
||||
if (ccti_limit && (ccti_limit + 1) != (index * 64 + (argc - 2)))
|
||||
return "invalid number of cct entries input given ccti_limit and index";
|
||||
|
||||
for (i = 0; i < (argc - 2); i++) {
|
||||
if ((errstr = parsecct(argv[i + 2], &cctshifts[i], &cctmults[i])))
|
||||
return errstr;
|
||||
}
|
||||
|
||||
mad_encode_field(payload,
|
||||
IB_CC_CONGESTION_CONTROL_TABLE_CCTI_LIMIT_F,
|
||||
&ccti_limit);
|
||||
|
||||
for (i = 0; i < (argc - 2); i++) {
|
||||
mad_encode_field(payload + 4 + i * 2,
|
||||
IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_CCT_SHIFT_F,
|
||||
&cctshifts[i]);
|
||||
|
||||
mad_encode_field(payload + 4 + i * 2,
|
||||
IB_CC_CONGESTION_CONTROL_TABLE_ENTRY_CCT_MULTIPLIER_F,
|
||||
&cctmults[i]);
|
||||
}
|
||||
|
||||
if (!cc_config_status_via(payload, rcv, dest, IB_CC_ATTR_CONGESTION_CONTROL_TABLE,
|
||||
index, 0, NULL, srcport, cckey))
|
||||
return "congestion control table config failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
cckey = (uint64_t) strtoull(optarg, 0, 0);
|
||||
break;
|
||||
case 25:
|
||||
if (!inet_pton(AF_INET6, optarg, &dgid)) {
|
||||
fprintf(stderr, "dgid format is wrong!\n");
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
with_grh = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char usage_args[1024];
|
||||
int mgmt_classes[3] = { IB_SMI_CLASS, IB_SA_CLASS, IB_CC_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
char *err;
|
||||
op_fn_t *fn;
|
||||
const match_rec_t *r;
|
||||
int n;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"cckey", 'c', 1, "<key>", "CC key"},
|
||||
{"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
|
||||
{0}
|
||||
};
|
||||
const char *usage_examples[] = {
|
||||
"SwitchCongestionSetting 2 0x1F 0x1FFFFFFFFF 0x0 0xF 8 0 0:0 1\t# Configure Switch Congestion Settings",
|
||||
"CACongestionSetting 1 0 0x3 150 1 0 0\t\t# Configure CA Congestion Settings to SL 0 and SL 1",
|
||||
"CACongestionSetting 1 0 0x4 200 1 0 0\t\t# Configure CA Congestion Settings to SL 2",
|
||||
"CongestionControlTable 1 63 0 0:0 0:1 ...\t# Configure first block of Congestion Control Table",
|
||||
"CongestionControlTable 1 127 0 0:64 0:65 ...\t# Configure second block of Congestion Control Table",
|
||||
NULL
|
||||
};
|
||||
|
||||
n = sprintf(usage_args, "[-c key] <op> <lid|guid>\n"
|
||||
"\nWARNING -- You should understand what you are "
|
||||
"doing before using this tool. Misuse of this "
|
||||
"tool could result in a broken fabric.\n"
|
||||
"\nSupported ops (and aliases, case insensitive):\n");
|
||||
for (r = match_tbl; r->name; r++) {
|
||||
n += snprintf(usage_args + n, sizeof(usage_args) - n,
|
||||
" %s (%s) <lid|guid>%s%s%s\n", r->name,
|
||||
r->alias ? r->alias : "",
|
||||
r->opt_portnum ? " <portnum>" : "",
|
||||
r->ops_extra ? " " : "",
|
||||
r->ops_extra ? r->ops_extra : "");
|
||||
if (n >= sizeof(usage_args))
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (!(fn = match_op(match_tbl, argv[0])))
|
||||
IBEXIT("operation '%s' not supported", argv[0]);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (with_grh && ibd_dest_type != IB_DEST_LID)
|
||||
IBEXIT("When using GRH, LID should be provided");
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination %s", argv[1]);
|
||||
if (with_grh) {
|
||||
portid.grh_present = 1;
|
||||
memcpy(&portid.gid, &dgid, sizeof(portid.gid));
|
||||
}
|
||||
if ((err = fn(&portid, argv + 2, argc - 2)))
|
||||
IBEXIT("operation %s: %s", argv[0], err);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2011 Lawrence Livermore National Lab. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static ibmad_gid_t dgid;
|
||||
static int with_grh;
|
||||
|
||||
static op_fn_t class_port_info;
|
||||
static op_fn_t congestion_info;
|
||||
static op_fn_t congestion_key_info;
|
||||
static op_fn_t congestion_log;
|
||||
static op_fn_t switch_congestion_setting;
|
||||
static op_fn_t switch_port_congestion_setting;
|
||||
static op_fn_t ca_congestion_setting;
|
||||
static op_fn_t congestion_control_table;
|
||||
static op_fn_t timestamp_dump;
|
||||
|
||||
static const match_rec_t match_tbl[] = {
|
||||
{"ClassPortInfo", "CP", class_port_info, 0, ""},
|
||||
{"CongestionInfo", "CI", congestion_info, 0, ""},
|
||||
{"CongestionKeyInfo", "CK", congestion_key_info, 0, ""},
|
||||
{"CongestionLog", "CL", congestion_log, 0, ""},
|
||||
{"SwitchCongestionSetting", "SS", switch_congestion_setting, 0, ""},
|
||||
{"SwitchPortCongestionSetting", "SP", switch_port_congestion_setting, 1, ""},
|
||||
{"CACongestionSetting", "CS", ca_congestion_setting, 0, ""},
|
||||
{"CongestionControlTable", "CT", congestion_control_table, 0, ""},
|
||||
{"Timestamp", "TI", timestamp_dump, 0, ""},
|
||||
{0}
|
||||
};
|
||||
|
||||
uint64_t cckey = 0;
|
||||
|
||||
/*******************************************/
|
||||
static char *class_port_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
|
||||
if (!cc_query_status_via(data, dest, CLASS_PORT_INFO,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "class port info query failed";
|
||||
|
||||
mad_dump_classportinfo(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# ClassPortInfo: %s\n%s", portid2str(dest), buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CONGESTION_INFO,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "congestion info query failed";
|
||||
|
||||
mad_dump_cc_congestioninfo(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# CongestionInfo: %s\n%s", portid2str(dest), buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_key_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CONGESTION_KEY_INFO,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "congestion key info query failed";
|
||||
|
||||
mad_dump_cc_congestionkeyinfo(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# CongestionKeyInfo: %s\n%s", portid2str(dest), buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_log(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_LOG_DATA_SZ] = { 0 };
|
||||
char emptybuf[16] = { 0 };
|
||||
int i, type;
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CONGESTION_LOG,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "congestion log query failed";
|
||||
|
||||
mad_decode_field((uint8_t *)data, IB_CC_CONGESTION_LOG_LOGTYPE_F, &type);
|
||||
|
||||
if (type != 1 && type != 2)
|
||||
return "unrecognized log type";
|
||||
|
||||
mad_dump_cc_congestionlog(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# CongestionLog: %s\n%s", portid2str(dest), buf);
|
||||
|
||||
if (type == 1) {
|
||||
mad_dump_cc_congestionlogswitch(buf, sizeof buf, data, sizeof data);
|
||||
printf("%s\n", buf);
|
||||
for (i = 0; i < 15; i++) {
|
||||
/* output only if entry not 0 */
|
||||
if (memcmp(data + 40 + i * 12, emptybuf, 12)) {
|
||||
mad_dump_cc_congestionlogentryswitch(buf, sizeof buf,
|
||||
data + 40 + i * 12,
|
||||
12);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* XXX: Q3/2010 errata lists first entry offset at 80, but we assume
|
||||
* will be updated to 96 once CurrentTimeStamp field is word aligned.
|
||||
* In addition, assume max 13 log events instead of 16. Due to
|
||||
* errata changes increasing size of CA log event, 16 log events is
|
||||
* no longer possible to fit in max MAD size.
|
||||
*/
|
||||
mad_dump_cc_congestionlogca(buf, sizeof buf, data, sizeof data);
|
||||
printf("%s\n", buf);
|
||||
for (i = 0; i < 13; i++) {
|
||||
/* output only if entry not 0 */
|
||||
if (memcmp(data + 12 + i * 16, emptybuf, 16)) {
|
||||
mad_dump_cc_congestionlogentryca(buf, sizeof buf,
|
||||
data + 12 + i * 16,
|
||||
16);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *switch_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_SWITCH_CONGESTION_SETTING,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "switch congestion setting query failed";
|
||||
|
||||
mad_dump_cc_switchcongestionsetting(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# SwitchCongestionSetting: %s\n%s", portid2str(dest), buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *switch_port_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
int type, numports, maxblocks, i, j;
|
||||
int portnum = 0;
|
||||
int outputcount = 0;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
/* Figure out number of ports first */
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_decode_field((uint8_t *)data, IB_NODE_TYPE_F, &type);
|
||||
mad_decode_field((uint8_t *)data, IB_NODE_NPORTS_F, &numports);
|
||||
|
||||
if (type != IB_NODE_SWITCH)
|
||||
return "destination not a switch";
|
||||
|
||||
printf("# SwitchPortCongestionSetting: %s\n", portid2str(dest));
|
||||
|
||||
if (portnum) {
|
||||
if (portnum > numports)
|
||||
return "invalid port number specified";
|
||||
|
||||
memset(data, '\0', sizeof data);
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING,
|
||||
portnum / 32, 0, NULL, srcport, cckey))
|
||||
return "switch port congestion setting query failed";
|
||||
|
||||
mad_dump_cc_switchportcongestionsettingelement(buf, sizeof buf,
|
||||
data + ((portnum % 32) * 4),
|
||||
4);
|
||||
printf("%s", buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* else get all port info */
|
||||
|
||||
maxblocks = numports / 32 + 1;
|
||||
|
||||
for (i = 0; i < maxblocks; i++) {
|
||||
memset(data, '\0', sizeof data);
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_SWITCH_PORT_CONGESTION_SETTING,
|
||||
i, 0, NULL, srcport, cckey))
|
||||
return "switch port congestion setting query failed";
|
||||
|
||||
for (j = 0; j < 32 && outputcount <= numports; j++) {
|
||||
printf("Port:............................%u\n", i * 32 + j);
|
||||
mad_dump_cc_switchportcongestionsettingelement(buf, sizeof buf,
|
||||
data + j * 4,
|
||||
4);
|
||||
printf("%s\n", buf);
|
||||
outputcount++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *ca_congestion_setting(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
int i;
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CA_CONGESTION_SETTING,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "ca congestion setting query failed";
|
||||
|
||||
mad_dump_cc_cacongestionsetting(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# CACongestionSetting: %s\n%s\n", portid2str(dest), buf);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("SL:..............................%u\n", i);
|
||||
mad_dump_cc_cacongestionentry(buf, sizeof buf,
|
||||
data + 4 + i * 8,
|
||||
8);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *congestion_control_table(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
int limit, outputcount = 0;
|
||||
int i, j;
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CONGESTION_CONTROL_TABLE,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "congestion control table query failed";
|
||||
|
||||
mad_decode_field((uint8_t *)data, IB_CC_CONGESTION_CONTROL_TABLE_CCTI_LIMIT_F, &limit);
|
||||
|
||||
mad_dump_cc_congestioncontroltable(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# CongestionControlTable: %s\n%s\n", portid2str(dest), buf);
|
||||
|
||||
if (!limit)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < (limit/64) + 1; i++) {
|
||||
|
||||
/* first query done */
|
||||
if (i)
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_CONGESTION_CONTROL_TABLE,
|
||||
i, 0, NULL, srcport, cckey))
|
||||
return "congestion control table query failed";
|
||||
|
||||
for (j = 0; j < 64 && outputcount <= limit; j++) {
|
||||
printf("Entry:...........................%u\n", i*64 + j);
|
||||
mad_dump_cc_congestioncontroltableentry(buf, sizeof buf,
|
||||
data + 4 + j * 2,
|
||||
sizeof data - 4 - j * 2);
|
||||
printf("%s\n", buf);
|
||||
outputcount++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *timestamp_dump(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_CC_DATA_SZ] = { 0 };
|
||||
|
||||
if (!cc_query_status_via(data, dest, IB_CC_ATTR_TIMESTAMP,
|
||||
0, 0, NULL, srcport, cckey))
|
||||
return "timestamp query failed";
|
||||
|
||||
mad_dump_cc_timestamp(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# Timestamp: %s\n%s", portid2str(dest), buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
cckey = (uint64_t) strtoull(optarg, 0, 0);
|
||||
break;
|
||||
case 25:
|
||||
if (!inet_pton(AF_INET6, optarg, &dgid)) {
|
||||
fprintf(stderr, "dgid format is wrong!\n");
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
with_grh = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char usage_args[1024];
|
||||
int mgmt_classes[3] = { IB_SMI_CLASS, IB_SA_CLASS, IB_CC_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
char *err;
|
||||
op_fn_t *fn;
|
||||
const match_rec_t *r;
|
||||
int n;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"cckey", 'c', 1, "<key>", "CC key"},
|
||||
{"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
|
||||
{0}
|
||||
};
|
||||
const char *usage_examples[] = {
|
||||
"CongestionInfo 3\t\t\t# Congestion Info by lid",
|
||||
"SwitchPortCongestionSetting 3\t# Query all Switch Port Congestion Settings",
|
||||
"SwitchPortCongestionSetting 3 1\t# Query Switch Port Congestion Setting for port 1",
|
||||
NULL
|
||||
};
|
||||
|
||||
n = sprintf(usage_args, "[-c key] <op> <lid|guid>\n"
|
||||
"\nSupported ops (and aliases, case insensitive):\n");
|
||||
for (r = match_tbl; r->name; r++) {
|
||||
n += snprintf(usage_args + n, sizeof(usage_args) - n,
|
||||
" %s (%s) <lid|guid>%s\n", r->name,
|
||||
r->alias ? r->alias : "",
|
||||
r->opt_portnum ? " [<portnum>]" : "");
|
||||
if (n >= sizeof(usage_args))
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (!(fn = match_op(match_tbl, argv[0])))
|
||||
IBEXIT("operation '%s' not supported", argv[0]);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (with_grh && ibd_dest_type != IB_DEST_LID)
|
||||
IBEXIT("When using GRH, LID should be provided");
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination %s", argv[1]);
|
||||
if (with_grh) {
|
||||
portid.grh_present = 1;
|
||||
memcpy(&portid.gid, &dgid, sizeof(portid.gid));
|
||||
}
|
||||
if ((err = fn(&portid, argv + 2, argc - 2)))
|
||||
IBEXIT("operation %s: %s", argv[0], err);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,940 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 The Regents of the University of California.
|
||||
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2011 Lawrence Livermore National Security. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define common functions which can be included in the various C based diags.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <config.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <ibdiag_common.h>
|
||||
#include <ibdiag_version.h>
|
||||
|
||||
int ibverbose;
|
||||
enum MAD_DEST ibd_dest_type = IB_DEST_LID;
|
||||
ib_portid_t *ibd_sm_id;
|
||||
static ib_portid_t sm_portid = { 0 };
|
||||
|
||||
/* general config options */
|
||||
#define IBDIAG_CONFIG_GENERAL IBDIAG_CONFIG_PATH"/ibdiag.conf"
|
||||
char *ibd_ca = NULL;
|
||||
int ibd_ca_port = 0;
|
||||
int ibd_timeout = 0;
|
||||
uint32_t ibd_ibnetdisc_flags = IBND_CONFIG_MLX_EPI;
|
||||
uint64_t ibd_mkey;
|
||||
uint64_t ibd_sakey = 0;
|
||||
int show_keys = 0;
|
||||
char *ibd_nd_format = NULL;
|
||||
|
||||
static const char *prog_name;
|
||||
static const char *prog_args;
|
||||
static const char **prog_examples;
|
||||
static struct option *long_opts = NULL;
|
||||
static const struct ibdiag_opt *opts_map[256];
|
||||
|
||||
static const char *get_build_version(void)
|
||||
{
|
||||
return "BUILD VERSION: " IBDIAG_VERSION " Build date: " __DATE__ " "
|
||||
__TIME__;
|
||||
}
|
||||
|
||||
static void pretty_print(int start, int width, const char *str)
|
||||
{
|
||||
int len = width - start;
|
||||
const char *p, *e;
|
||||
|
||||
while (1) {
|
||||
while (isspace(*str))
|
||||
str++;
|
||||
p = str;
|
||||
do {
|
||||
e = p + 1;
|
||||
p = strchr(e, ' ');
|
||||
} while (p && p - str < len);
|
||||
if (!p) {
|
||||
fprintf(stderr, "%s", str);
|
||||
break;
|
||||
}
|
||||
if (e - str == 1)
|
||||
e = p;
|
||||
fprintf(stderr, "%.*s\n%*s", (int)(e - str), str, start, "");
|
||||
str = e;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int val_str_true(const char *val_str)
|
||||
{
|
||||
return ((strncmp(val_str, "TRUE", strlen("TRUE")) == 0) ||
|
||||
(strncmp(val_str, "true", strlen("true")) == 0));
|
||||
}
|
||||
|
||||
void read_ibdiag_config(const char *file)
|
||||
{
|
||||
char buf[1024];
|
||||
FILE *config_fd = NULL;
|
||||
char *p_prefix, *p_last;
|
||||
char *name;
|
||||
char *val_str;
|
||||
struct stat statbuf;
|
||||
|
||||
/* silently ignore missing config file */
|
||||
if (stat(file, &statbuf))
|
||||
return;
|
||||
|
||||
config_fd = fopen(file, "r");
|
||||
if (!config_fd)
|
||||
return;
|
||||
|
||||
while (fgets(buf, sizeof buf, config_fd) != NULL) {
|
||||
p_prefix = strtok_r(buf, "\n", &p_last);
|
||||
if (!p_prefix)
|
||||
continue; /* ignore blank lines */
|
||||
|
||||
if (*p_prefix == '#')
|
||||
continue; /* ignore comment lines */
|
||||
|
||||
name = strtok_r(p_prefix, "=", &p_last);
|
||||
val_str = strtok_r(NULL, "\n", &p_last);
|
||||
|
||||
if (strncmp(name, "CA", strlen("CA")) == 0) {
|
||||
free(ibd_ca);
|
||||
ibd_ca = strdup(val_str);
|
||||
} else if (strncmp(name, "Port", strlen("Port")) == 0) {
|
||||
ibd_ca_port = strtoul(val_str, NULL, 0);
|
||||
} else if (strncmp(name, "timeout", strlen("timeout")) == 0) {
|
||||
ibd_timeout = strtoul(val_str, NULL, 0);
|
||||
} else if (strncmp(name, "MLX_EPI", strlen("MLX_EPI")) == 0) {
|
||||
if (val_str_true(val_str)) {
|
||||
ibd_ibnetdisc_flags |= IBND_CONFIG_MLX_EPI;
|
||||
} else {
|
||||
ibd_ibnetdisc_flags &= ~IBND_CONFIG_MLX_EPI;
|
||||
}
|
||||
} else if (strncmp(name, "m_key", strlen("m_key")) == 0) {
|
||||
ibd_mkey = strtoull(val_str, 0, 0);
|
||||
} else if (strncmp(name, "sa_key",
|
||||
strlen("sa_key")) == 0) {
|
||||
ibd_sakey = strtoull(val_str, 0, 0);
|
||||
} else if (strncmp(name, "nd_format",
|
||||
strlen("nd_format")) == 0) {
|
||||
ibd_nd_format = strdup(val_str);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(config_fd);
|
||||
}
|
||||
|
||||
|
||||
void ibdiag_show_usage()
|
||||
{
|
||||
struct option *o = long_opts;
|
||||
int n;
|
||||
|
||||
fprintf(stderr, "\nUsage: %s [options] %s\n\n", prog_name,
|
||||
prog_args ? prog_args : "");
|
||||
|
||||
if (long_opts[0].name)
|
||||
fprintf(stderr, "Options:\n");
|
||||
for (o = long_opts; o->name; o++) {
|
||||
const struct ibdiag_opt *io = opts_map[o->val];
|
||||
n = fprintf(stderr, " --%s", io->name);
|
||||
if (isprint(io->letter))
|
||||
n += fprintf(stderr, ", -%c", io->letter);
|
||||
if (io->has_arg)
|
||||
n += fprintf(stderr, " %s",
|
||||
io->arg_tmpl ? io->arg_tmpl : "<val>");
|
||||
if (io->description && *io->description) {
|
||||
n += fprintf(stderr, "%*s ", 24 - n > 0 ? 24 - n : 0,
|
||||
"");
|
||||
pretty_print(n, 74, io->description);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
if (prog_examples) {
|
||||
const char **p;
|
||||
fprintf(stderr, "\nExamples:\n");
|
||||
for (p = prog_examples; *p && **p; p++)
|
||||
fprintf(stderr, " %s %s\n", prog_name, *p);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static int process_opt(int ch, char *optarg)
|
||||
{
|
||||
char *endp;
|
||||
long val;
|
||||
|
||||
switch (ch) {
|
||||
case 'z':
|
||||
read_ibdiag_config(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
ibdiag_show_usage();
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "%s %s\n", prog_name, get_build_version());
|
||||
exit(0);
|
||||
case 'e':
|
||||
madrpc_show_errors(1);
|
||||
break;
|
||||
case 'v':
|
||||
ibverbose++;
|
||||
break;
|
||||
case 'd':
|
||||
ibdebug++;
|
||||
madrpc_show_errors(1);
|
||||
umad_debug(ibdebug - 1);
|
||||
break;
|
||||
case 'C':
|
||||
ibd_ca = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
ibd_ca_port = strtoul(optarg, 0, 0);
|
||||
if (ibd_ca_port < 0)
|
||||
IBEXIT("cannot resolve CA port %d", ibd_ca_port);
|
||||
break;
|
||||
case 'D':
|
||||
ibd_dest_type = IB_DEST_DRPATH;
|
||||
break;
|
||||
case 'L':
|
||||
ibd_dest_type = IB_DEST_LID;
|
||||
break;
|
||||
case 'G':
|
||||
ibd_dest_type = IB_DEST_GUID;
|
||||
break;
|
||||
case 't':
|
||||
errno = 0;
|
||||
val = strtol(optarg, &endp, 0);
|
||||
if (errno || (endp && *endp != '\0') || val <= 0 ||
|
||||
val > INT_MAX)
|
||||
IBEXIT("Invalid timeout \"%s\". Timeout requires a "
|
||||
"positive integer value < %d.", optarg, INT_MAX);
|
||||
else {
|
||||
madrpc_set_timeout((int)val);
|
||||
ibd_timeout = (int)val;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
/* srcport is not required when resolving via IB_DEST_LID */
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &sm_portid, optarg,
|
||||
IB_DEST_LID, 0, NULL) < 0)
|
||||
IBEXIT("cannot resolve SM destination port %s",
|
||||
optarg);
|
||||
ibd_sm_id = &sm_portid;
|
||||
break;
|
||||
case 'K':
|
||||
show_keys = 1;
|
||||
break;
|
||||
case 'y':
|
||||
errno = 0;
|
||||
ibd_mkey = strtoull(optarg, &endp, 0);
|
||||
if (errno || *endp != '\0') {
|
||||
errno = 0;
|
||||
ibd_mkey = strtoull(getpass("M_Key: "), &endp, 0);
|
||||
if (errno || *endp != '\0') {
|
||||
IBEXIT("Bad M_Key");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ibdiag_opt common_opts[] = {
|
||||
{"config", 'z', 1, "<config>", "use config file, default: " IBDIAG_CONFIG_GENERAL},
|
||||
{"Ca", 'C', 1, "<ca>", "Ca name to use"},
|
||||
{"Port", 'P', 1, "<port>", "Ca port number to use"},
|
||||
{"Direct", 'D', 0, NULL, "use Direct address argument"},
|
||||
{"Lid", 'L', 0, NULL, "use LID address argument"},
|
||||
{"Guid", 'G', 0, NULL, "use GUID address argument"},
|
||||
{"timeout", 't', 1, "<ms>", "timeout in ms"},
|
||||
{"sm_port", 's', 1, "<lid>", "SM port lid"},
|
||||
{"show_keys", 'K', 0, NULL, "display security keys in output"},
|
||||
{"m_key", 'y', 1, "<key>", "M_Key to use in request"},
|
||||
{"errors", 'e', 0, NULL, "show send and receive errors"},
|
||||
{"verbose", 'v', 0, NULL, "increase verbosity level"},
|
||||
{"debug", 'd', 0, NULL, "raise debug level"},
|
||||
{"help", 'h', 0, NULL, "help message"},
|
||||
{"version", 'V', 0, NULL, "show version"},
|
||||
{0}
|
||||
};
|
||||
|
||||
static void make_opt(struct option *l, const struct ibdiag_opt *o,
|
||||
const struct ibdiag_opt *map[])
|
||||
{
|
||||
l->name = o->name;
|
||||
l->has_arg = o->has_arg;
|
||||
l->flag = NULL;
|
||||
l->val = o->letter;
|
||||
if (!map[l->val])
|
||||
map[l->val] = o;
|
||||
}
|
||||
|
||||
static struct option *make_long_opts(const char *exclude_str,
|
||||
const struct ibdiag_opt *custom_opts,
|
||||
const struct ibdiag_opt *map[])
|
||||
{
|
||||
struct option *long_opts, *l;
|
||||
const struct ibdiag_opt *o;
|
||||
unsigned n = 0;
|
||||
|
||||
if (custom_opts)
|
||||
for (o = custom_opts; o->name; o++)
|
||||
n++;
|
||||
|
||||
long_opts = malloc((sizeof(common_opts) / sizeof(common_opts[0]) + n) *
|
||||
sizeof(*long_opts));
|
||||
if (!long_opts)
|
||||
return NULL;
|
||||
|
||||
l = long_opts;
|
||||
|
||||
if (custom_opts)
|
||||
for (o = custom_opts; o->name; o++)
|
||||
make_opt(l++, o, map);
|
||||
|
||||
for (o = common_opts; o->name; o++) {
|
||||
if (exclude_str && strchr(exclude_str, o->letter))
|
||||
continue;
|
||||
make_opt(l++, o, map);
|
||||
}
|
||||
|
||||
memset(l, 0, sizeof(*l));
|
||||
|
||||
return long_opts;
|
||||
}
|
||||
|
||||
static void make_str_opts(const struct option *o, char *p, unsigned size)
|
||||
{
|
||||
unsigned i, n = 0;
|
||||
|
||||
for (n = 0; o->name && n + 2 + o->has_arg < size; o++) {
|
||||
p[n++] = (char)o->val;
|
||||
for (i = 0; i < (unsigned)o->has_arg; i++)
|
||||
p[n++] = ':';
|
||||
}
|
||||
p[n] = '\0';
|
||||
}
|
||||
|
||||
int ibdiag_process_opts(int argc, char *const argv[], void *cxt,
|
||||
const char *exclude_common_str,
|
||||
const struct ibdiag_opt custom_opts[],
|
||||
int (*custom_handler) (void *cxt, int val,
|
||||
char *optarg),
|
||||
const char *usage_args, const char *usage_examples[])
|
||||
{
|
||||
char str_opts[1024];
|
||||
const struct ibdiag_opt *o;
|
||||
|
||||
prog_name = argv[0];
|
||||
prog_args = usage_args;
|
||||
prog_examples = usage_examples;
|
||||
|
||||
if (long_opts)
|
||||
free(long_opts);
|
||||
|
||||
long_opts = make_long_opts(exclude_common_str, custom_opts, opts_map);
|
||||
if (!long_opts)
|
||||
return -1;
|
||||
|
||||
read_ibdiag_config(IBDIAG_CONFIG_GENERAL);
|
||||
|
||||
make_str_opts(long_opts, str_opts, sizeof(str_opts));
|
||||
|
||||
while (1) {
|
||||
int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
|
||||
if (ch == -1)
|
||||
break;
|
||||
o = opts_map[ch];
|
||||
if (!o)
|
||||
ibdiag_show_usage();
|
||||
if (custom_handler) {
|
||||
if (custom_handler(cxt, ch, optarg) &&
|
||||
process_opt(ch, optarg))
|
||||
ibdiag_show_usage();
|
||||
} else if (process_opt(ch, optarg))
|
||||
ibdiag_show_usage();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ibexit(const char *fn, char *msg, ...)
|
||||
{
|
||||
char buf[512];
|
||||
va_list va;
|
||||
int n;
|
||||
|
||||
va_start(va, msg);
|
||||
n = vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
buf[n] = 0;
|
||||
|
||||
if (ibdebug)
|
||||
printf("%s: iberror: [pid %d] %s: failed: %s\n",
|
||||
prog_name ? prog_name : "", getpid(), fn, buf);
|
||||
else
|
||||
printf("%s: iberror: failed: %s\n",
|
||||
prog_name ? prog_name : "", buf);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
char *
|
||||
conv_cnt_human_readable(uint64_t val64, float *val, int data)
|
||||
{
|
||||
uint64_t tmp = val64;
|
||||
int ui = 0;
|
||||
int div = 1;
|
||||
|
||||
tmp /= 1024;
|
||||
while (tmp) {
|
||||
ui++;
|
||||
tmp /= 1024;
|
||||
div *= 1024;
|
||||
}
|
||||
|
||||
*val = (float)(val64);
|
||||
if (data) {
|
||||
*val *= 4;
|
||||
if (*val/div > 1024) {
|
||||
ui++;
|
||||
div *= 1024;
|
||||
}
|
||||
}
|
||||
*val /= div;
|
||||
|
||||
if (data) {
|
||||
switch (ui) {
|
||||
case 0:
|
||||
return ("B");
|
||||
case 1:
|
||||
return ("KB");
|
||||
case 2:
|
||||
return ("MB");
|
||||
case 3:
|
||||
return ("GB");
|
||||
case 4:
|
||||
return ("TB");
|
||||
case 5:
|
||||
return ("PB");
|
||||
case 6:
|
||||
return ("EB");
|
||||
default:
|
||||
return ("");
|
||||
}
|
||||
} else {
|
||||
switch (ui) {
|
||||
case 0:
|
||||
return ("");
|
||||
case 1:
|
||||
return ("K");
|
||||
case 2:
|
||||
return ("M");
|
||||
case 3:
|
||||
return ("G");
|
||||
case 4:
|
||||
return ("T");
|
||||
case 5:
|
||||
return ("P");
|
||||
case 6:
|
||||
return ("E");
|
||||
default:
|
||||
return ("");
|
||||
}
|
||||
}
|
||||
return ("");
|
||||
}
|
||||
|
||||
int is_port_info_extended_supported(ib_portid_t * dest, int port,
|
||||
struct ibmad_port *srcport)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint32_t cap_mask;
|
||||
uint16_t cap_mask2;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, port, 0, srcport))
|
||||
IBEXIT("port info query failed");
|
||||
|
||||
mad_decode_field(data, IB_PORT_CAPMASK_F, &cap_mask);
|
||||
if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_CAP_MASK2)) {
|
||||
mad_decode_field(data, IB_PORT_CAPMASK2_F, &cap_mask2);
|
||||
if (!(cap_mask2 &
|
||||
CL_NTOH16(IB_PORT_CAP2_IS_PORT_INFO_EXT_SUPPORTED))) {
|
||||
IBWARN("port info capability mask2 = 0x%x doesn't"
|
||||
" indicate PortInfoExtended support", cap_mask2);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
IBWARN("port info capability mask2 not supported");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int is_mlnx_ext_port_info_supported(uint32_t vendorid,
|
||||
uint16_t devid)
|
||||
{
|
||||
if (ibd_ibnetdisc_flags & IBND_CONFIG_MLX_EPI) {
|
||||
|
||||
if ((devid >= 0xc738 && devid <= 0xc73b) || devid == 0xcb20 || devid == 0xcf08 ||
|
||||
((vendorid == 0x119f) &&
|
||||
/* Bull SwitchX */
|
||||
(devid == 0x1b02 || devid == 0x1b50 ||
|
||||
/* Bull SwitchIB and SwitchIB2 */
|
||||
devid == 0x1ba0 ||
|
||||
(devid >= 0x1bd0 && devid <= 0x1bd5))))
|
||||
return 1;
|
||||
if ((devid >= 0x1003 && devid <= 0x1017) ||
|
||||
((vendorid == 0x119f) &&
|
||||
/* Bull ConnectX3 */
|
||||
(devid == 0x1b33 || devid == 0x1b73 ||
|
||||
devid == 0x1b40 || devid == 0x1b41 ||
|
||||
devid == 0x1b60 || devid == 0x1b61 ||
|
||||
/* Bull ConnectIB */
|
||||
devid == 0x1b83 ||
|
||||
devid == 0x1b93 || devid == 0x1b94 ||
|
||||
/* Bull ConnectX4 */
|
||||
devid == 0x1bb4 || devid == 0x1bb5 ||
|
||||
devid == 0x1bc4)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** =========================================================================
|
||||
* Resolve the SM portid using the umad layer rather than using
|
||||
* ib_resolve_smlid_via which requires a PortInfo query on the local port.
|
||||
*/
|
||||
int resolve_sm_portid(char *ca_name, uint8_t portnum, ib_portid_t *sm_id)
|
||||
{
|
||||
umad_port_t port;
|
||||
int rc;
|
||||
|
||||
if (!sm_id)
|
||||
return (-1);
|
||||
|
||||
if ((rc = umad_get_port(ca_name, portnum, &port)) < 0)
|
||||
return rc;
|
||||
|
||||
memset(sm_id, 0, sizeof(*sm_id));
|
||||
sm_id->lid = port.sm_lid;
|
||||
sm_id->sl = port.sm_sl;
|
||||
|
||||
umad_release_port(&port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** =========================================================================
|
||||
* Resolve local CA characteristics using the umad layer rather than using
|
||||
* ib_resolve_self_via which requires SMP queries on the local port.
|
||||
*/
|
||||
int resolve_self(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
||||
int *portnum, ibmad_gid_t *gid)
|
||||
{
|
||||
umad_port_t port;
|
||||
uint64_t prefix, guid;
|
||||
int rc;
|
||||
|
||||
if (!(portid || portnum || gid))
|
||||
return (-1);
|
||||
|
||||
if ((rc = umad_get_port(ca_name, ca_port, &port)) < 0)
|
||||
return rc;
|
||||
|
||||
if (portid) {
|
||||
memset(portid, 0, sizeof(*portid));
|
||||
portid->lid = port.base_lid;
|
||||
portid->sl = port.sm_sl;
|
||||
}
|
||||
if (portnum)
|
||||
*portnum = port.portnum;
|
||||
if (gid) {
|
||||
memset(gid, 0, sizeof(*gid));
|
||||
prefix = cl_ntoh64(port.gid_prefix);
|
||||
guid = cl_ntoh64(port.port_guid);
|
||||
mad_encode_field(*gid, IB_GID_PREFIX_F, &prefix);
|
||||
mad_encode_field(*gid, IB_GID_GUID_F, &guid);
|
||||
}
|
||||
|
||||
umad_release_port(&port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resolve_gid(char *ca_name, uint8_t ca_port, ib_portid_t * portid,
|
||||
ibmad_gid_t gid, ib_portid_t * sm_id,
|
||||
const struct ibmad_port *srcport)
|
||||
{
|
||||
ib_portid_t sm_portid;
|
||||
char buf[IB_SA_DATA_SIZE] = { 0 };
|
||||
|
||||
if (!sm_id) {
|
||||
sm_id = &sm_portid;
|
||||
if (resolve_sm_portid(ca_name, ca_port, sm_id) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((portid->lid =
|
||||
ib_path_query_via(srcport, gid, gid, sm_id, buf)) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resolve_guid(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
||||
uint64_t *guid, ib_portid_t *sm_id,
|
||||
const struct ibmad_port *srcport)
|
||||
{
|
||||
ib_portid_t sm_portid;
|
||||
uint8_t buf[IB_SA_DATA_SIZE] = { 0 };
|
||||
uint64_t prefix;
|
||||
ibmad_gid_t selfgid;
|
||||
|
||||
if (!sm_id) {
|
||||
sm_id = &sm_portid;
|
||||
if (resolve_sm_portid(ca_name, ca_port, sm_id) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (resolve_self(ca_name, ca_port, NULL, NULL, &selfgid) < 0)
|
||||
return -1;
|
||||
|
||||
memcpy(&prefix, portid->gid, sizeof(prefix));
|
||||
if (!prefix)
|
||||
mad_set_field64(portid->gid, 0, IB_GID_PREFIX_F,
|
||||
IB_DEFAULT_SUBN_PREFIX);
|
||||
if (guid)
|
||||
mad_set_field64(portid->gid, 0, IB_GID_GUID_F, *guid);
|
||||
|
||||
if ((portid->lid =
|
||||
ib_path_query_via(srcport, selfgid, portid->gid, sm_id, buf)) < 0)
|
||||
return -1;
|
||||
|
||||
mad_decode_field(buf, IB_SA_PR_SL_F, &portid->sl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callers of this function should ensure their ibmad_port has been opened with
|
||||
* IB_SA_CLASS as this function may require the SA to resolve addresses.
|
||||
*/
|
||||
int resolve_portid_str(char *ca_name, uint8_t ca_port, ib_portid_t * portid,
|
||||
char *addr_str, enum MAD_DEST dest_type,
|
||||
ib_portid_t *sm_id, const struct ibmad_port *srcport)
|
||||
{
|
||||
ibmad_gid_t gid;
|
||||
uint64_t guid;
|
||||
int lid;
|
||||
char *routepath;
|
||||
ib_portid_t selfportid = { 0 };
|
||||
int selfport = 0;
|
||||
|
||||
memset(portid, 0, sizeof *portid);
|
||||
|
||||
switch (dest_type) {
|
||||
case IB_DEST_LID:
|
||||
lid = strtol(addr_str, 0, 0);
|
||||
if (!IB_LID_VALID(lid))
|
||||
return -1;
|
||||
return ib_portid_set(portid, lid, 0, 0);
|
||||
|
||||
case IB_DEST_DRPATH:
|
||||
if (str2drpath(&portid->drpath, addr_str, 0, 0) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
case IB_DEST_GUID:
|
||||
if (!(guid = strtoull(addr_str, 0, 0)))
|
||||
return -1;
|
||||
|
||||
/* keep guid in portid? */
|
||||
return resolve_guid(ca_name, ca_port, portid, &guid, sm_id,
|
||||
srcport);
|
||||
|
||||
case IB_DEST_DRSLID:
|
||||
lid = strtol(addr_str, &routepath, 0);
|
||||
routepath++;
|
||||
if (!IB_LID_VALID(lid))
|
||||
return -1;
|
||||
ib_portid_set(portid, lid, 0, 0);
|
||||
|
||||
/* handle DR parsing and set DrSLID to local lid */
|
||||
if (resolve_self(ca_name, ca_port, &selfportid, &selfport,
|
||||
NULL) < 0)
|
||||
return -1;
|
||||
if (str2drpath(&portid->drpath, routepath, selfportid.lid, 0) <
|
||||
0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
case IB_DEST_GID:
|
||||
if (inet_pton(AF_INET6, addr_str, &gid) <= 0)
|
||||
return -1;
|
||||
return resolve_gid(ca_name, ca_port, portid, gid, sm_id,
|
||||
srcport);
|
||||
default:
|
||||
IBWARN("bad dest_type %d", dest_type);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static unsigned int get_max_width(unsigned int num)
|
||||
{
|
||||
unsigned r = 0; /* 1x */
|
||||
|
||||
if (num & 8)
|
||||
r = 3; /* 12x */
|
||||
else {
|
||||
if (num & 4)
|
||||
r = 2; /* 8x */
|
||||
else if (num & 2)
|
||||
r = 1; /* 4x */
|
||||
else if (num & 0x10)
|
||||
r = 4; /* 2x */
|
||||
}
|
||||
|
||||
return (1 << r);
|
||||
}
|
||||
|
||||
static unsigned int get_max(unsigned int num)
|
||||
{
|
||||
unsigned r = 0; // r will be lg(num)
|
||||
|
||||
while (num >>= 1) // unroll for more speed...
|
||||
r++;
|
||||
|
||||
return (1 << r);
|
||||
}
|
||||
|
||||
void get_max_msg(char *width_msg, char *speed_msg, int msg_size, ibnd_port_t * port)
|
||||
{
|
||||
char buf[64];
|
||||
uint32_t max_speed = 0;
|
||||
uint32_t cap_mask, rem_cap_mask, fdr10;
|
||||
uint8_t *info = NULL;
|
||||
|
||||
uint32_t max_width = get_max_width(mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_WIDTH_SUPPORTED_F)
|
||||
& mad_get_field(port->remoteport->info, 0,
|
||||
IB_PORT_LINK_WIDTH_SUPPORTED_F));
|
||||
if ((max_width & mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_WIDTH_ACTIVE_F)) == 0)
|
||||
// we are not at the max supported width
|
||||
// print what we could be at.
|
||||
snprintf(width_msg, msg_size, "Could be %s",
|
||||
mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F,
|
||||
buf, 64, &max_width));
|
||||
|
||||
if (port->node->type == IB_NODE_SWITCH) {
|
||||
if (port->node->ports[0])
|
||||
info = (uint8_t *)&port->node->ports[0]->info;
|
||||
}
|
||||
else
|
||||
info = (uint8_t *)&port->info;
|
||||
|
||||
if (info)
|
||||
cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
||||
else
|
||||
cap_mask = 0;
|
||||
|
||||
info = NULL;
|
||||
if (port->remoteport->node->type == IB_NODE_SWITCH) {
|
||||
if (port->remoteport->node->ports[0])
|
||||
info = (uint8_t *)&port->remoteport->node->ports[0]->info;
|
||||
} else
|
||||
info = (uint8_t *)&port->remoteport->info;
|
||||
|
||||
if (info)
|
||||
rem_cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
||||
else
|
||||
rem_cap_mask = 0;
|
||||
if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS) &&
|
||||
rem_cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS))
|
||||
goto check_ext_speed;
|
||||
check_fdr10_supp:
|
||||
fdr10 = (mad_get_field(port->ext_info, 0,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10)
|
||||
&& (mad_get_field(port->remoteport->ext_info, 0,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F) & FDR10);
|
||||
if (fdr10)
|
||||
goto check_fdr10_active;
|
||||
|
||||
max_speed = get_max(mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_SUPPORTED_F)
|
||||
& mad_get_field(port->remoteport->info, 0,
|
||||
IB_PORT_LINK_SPEED_SUPPORTED_F));
|
||||
if ((max_speed & mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_ACTIVE_F)) == 0)
|
||||
// we are not at the max supported speed
|
||||
// print what we could be at.
|
||||
snprintf(speed_msg, msg_size, "Could be %s",
|
||||
mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F,
|
||||
buf, 64, &max_speed));
|
||||
return;
|
||||
|
||||
check_ext_speed:
|
||||
if (mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0 ||
|
||||
mad_get_field(port->remoteport->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F) == 0)
|
||||
goto check_fdr10_supp;
|
||||
max_speed = get_max(mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F)
|
||||
& mad_get_field(port->remoteport->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F));
|
||||
if ((max_speed & mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_ACTIVE_F)) == 0)
|
||||
// we are not at the max supported extended speed
|
||||
// print what we could be at.
|
||||
snprintf(speed_msg, msg_size, "Could be %s",
|
||||
mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
|
||||
buf, 64, &max_speed));
|
||||
return;
|
||||
|
||||
check_fdr10_active:
|
||||
if ((mad_get_field(port->ext_info, 0,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F) & FDR10) == 0) {
|
||||
/* Special case QDR to try to avoid confusion with FDR10 */
|
||||
if (mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F) == 4) /* QDR (10.0 Gbps) */
|
||||
snprintf(speed_msg, msg_size,
|
||||
"Could be FDR10 (Found link at QDR but expected speed is FDR10)");
|
||||
else
|
||||
snprintf(speed_msg, msg_size, "Could be FDR10");
|
||||
}
|
||||
}
|
||||
|
||||
int vsnprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
||||
const char *format, va_list va_args)
|
||||
{
|
||||
int len, i, ret;
|
||||
|
||||
len = strlen(mad_field_name(f));
|
||||
if (len + 2 > n || spacing + 1 > n)
|
||||
return 0;
|
||||
|
||||
strncpy(buf, mad_field_name(f), n);
|
||||
buf[len] = ':';
|
||||
for (i = len+1; i < spacing+1; i++) {
|
||||
buf[i] = '.';
|
||||
}
|
||||
|
||||
ret = vsnprintf(&buf[spacing+1], n - spacing, format, va_args);
|
||||
if (ret >= n - spacing)
|
||||
buf[n] = '\0';
|
||||
|
||||
return ret + spacing;
|
||||
}
|
||||
|
||||
int snprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list val;
|
||||
int ret;
|
||||
|
||||
va_start(val, format);
|
||||
ret = vsnprint_field(buf, n, f, spacing, format, val);
|
||||
va_end(val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dump_portinfo(void *pi, int tabs)
|
||||
{
|
||||
int field, i;
|
||||
char val[64];
|
||||
char buf[1024];
|
||||
|
||||
for (field = IB_PORT_FIRST_F; field < IB_PORT_LAST_F; field++) {
|
||||
for (i=0;i<tabs;i++)
|
||||
printf("\t");
|
||||
if (field == IB_PORT_MKEY_F && show_keys == 0) {
|
||||
snprint_field(buf, 1024, field, 32, NOT_DISPLAYED_STR);
|
||||
} else {
|
||||
mad_decode_field(pi, field, val);
|
||||
if (!mad_dump_field(field, buf, 1024, val))
|
||||
return;
|
||||
}
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
for (field = IB_PORT_CAPMASK2_F;
|
||||
field < IB_PORT_LINK_SPEED_EXT_LAST_F; field++) {
|
||||
for (i=0;i<tabs;i++)
|
||||
printf("\t");
|
||||
mad_decode_field(pi, field, val);
|
||||
if (!mad_dump_field(field, buf, 1024, val))
|
||||
return;
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
op_fn_t *match_op(const match_rec_t match_tbl[], char *name)
|
||||
{
|
||||
const match_rec_t *r;
|
||||
for (r = match_tbl; r->name; r++)
|
||||
if (!strcasecmp(r->name, name) ||
|
||||
(r->alias && !strcasecmp(r->alias, name)))
|
||||
return r->fn;
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 The Regents of the University of California.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2011 Lawrence Livermore National Security. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IBDIAG_COMMON_H_
|
||||
#define _IBDIAG_COMMON_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <infiniband/iba/ib_types.h>
|
||||
#include <infiniband/ibnetdisc.h>
|
||||
|
||||
extern int ibverbose;
|
||||
extern char *ibd_ca;
|
||||
extern int ibd_ca_port;
|
||||
extern enum MAD_DEST ibd_dest_type;
|
||||
extern ib_portid_t *ibd_sm_id;
|
||||
extern int ibd_timeout;
|
||||
extern uint32_t ibd_ibnetdisc_flags;
|
||||
extern uint64_t ibd_mkey;
|
||||
extern uint64_t ibd_sakey;
|
||||
extern int show_keys;
|
||||
extern char *ibd_nd_format;
|
||||
|
||||
/*========================================================*/
|
||||
/* External interface */
|
||||
/*========================================================*/
|
||||
|
||||
#undef DEBUG
|
||||
#define DEBUG(fmt, ...) do { \
|
||||
if (ibdebug) IBDEBUG(fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
#define VERBOSE(fmt, ...) do { \
|
||||
if (ibverbose) IBVERBOSE(fmt, ## __VA_ARGS__); \
|
||||
} while (0)
|
||||
#define IBEXIT(fmt, ...) ibexit(__FUNCTION__, fmt, ## __VA_ARGS__)
|
||||
|
||||
#define NOT_DISPLAYED_STR "<not displayed>"
|
||||
|
||||
/* not all versions of ib_types.h will have this define */
|
||||
#ifndef IB_PM_PC_XMIT_WAIT_SUP
|
||||
#define IB_PM_PC_XMIT_WAIT_SUP (CL_HTON16(((uint16_t)1)<<12))
|
||||
#endif
|
||||
|
||||
/* PM ClassPortInfo CapabilityMask Bits */
|
||||
#ifndef IS_PM_RSFEC_COUNTERS_SUP
|
||||
#define IS_PM_RSFEC_COUNTERS_SUP (CL_HTON16(((uint16_t)1)<<14))
|
||||
#endif
|
||||
|
||||
#ifndef IB_PM_IS_QP1_DROP_SUP
|
||||
#define IB_PM_IS_QP1_DROP_SUP (CL_HTON16(((uint16_t)1)<<15))
|
||||
#endif
|
||||
|
||||
/* PM ClassPortInfo CapabilityMask2 Bits */
|
||||
#ifndef IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP
|
||||
#define IB_PM_IS_ADDL_PORT_CTRS_EXT_SUP (CL_HTON32(((uint32_t)1)<<1))
|
||||
#endif
|
||||
|
||||
/* SM PortInfo CapabilityMask2 Bits */
|
||||
#ifndef IB_PORT_CAP2_IS_PORT_INFO_EXT_SUPPORTED
|
||||
#define IB_PORT_CAP2_IS_PORT_INFO_EXT_SUPPORTED (CL_HTON16(0x0002))
|
||||
#endif
|
||||
|
||||
/* SM PortInfoExtended Fec Mode Bits */
|
||||
#ifndef IB_PORT_EXT_NO_FEC_MODE_ACTIVE
|
||||
#define IB_PORT_EXT_NO_FEC_MODE_ACTIVE 0
|
||||
#endif
|
||||
|
||||
#ifndef IB_PORT_EXT_FIRE_CODE_FEC_MODE_ACTIVE
|
||||
#define IB_PORT_EXT_FIRE_CODE_FEC_MODE_ACTIVE (CL_HTON16(0x0001))
|
||||
#endif
|
||||
|
||||
#ifndef IB_PORT_EXT_RS_FEC_MODE_ACTIVE
|
||||
#define IB_PORT_EXT_RS_FEC_MODE_ACTIVE (CL_HTON16(0x0002))
|
||||
#endif
|
||||
|
||||
#ifndef IB_PORT_EXT_LOW_LATENCY_RS_FEC_MODE_ACTIVE
|
||||
#define IB_PORT_EXT_LOW_LATENCY_RS_FEC_MODE_ACTIVE (CL_HTON16(0x0003))
|
||||
#endif
|
||||
|
||||
/* SM PortInfoExtended CapabilityMask Bits */
|
||||
#ifndef IB_PORT_EXT_CAP_IS_FEC_MODE_SUPPORTED
|
||||
#define IB_PORT_EXT_CAP_IS_FEC_MODE_SUPPORTED (CL_HTON32(0x00000001))
|
||||
#endif
|
||||
|
||||
struct ibdiag_opt {
|
||||
const char *name;
|
||||
char letter;
|
||||
unsigned has_arg;
|
||||
const char *arg_tmpl;
|
||||
const char *description;
|
||||
};
|
||||
|
||||
extern int ibdiag_process_opts(int argc, char *const argv[], void *context,
|
||||
const char *exclude_common_str,
|
||||
const struct ibdiag_opt custom_opts[],
|
||||
int (*custom_handler) (void *cxt, int val,
|
||||
char *optarg),
|
||||
const char *usage_args,
|
||||
const char *usage_examples[]);
|
||||
extern void ibdiag_show_usage();
|
||||
extern void ibexit(const char *fn, char *msg, ...);
|
||||
|
||||
/* convert counter values to a float with a unit specifier returned (using
|
||||
* binary prefix)
|
||||
* "data" is a flag indicating this counter is a byte counter multiplied by 4
|
||||
* as per PortCounters[Extended]
|
||||
*/
|
||||
extern char *conv_cnt_human_readable(uint64_t val64, float *val, int data);
|
||||
|
||||
int is_mlnx_ext_port_info_supported(uint32_t vendorid, uint16_t devid);
|
||||
|
||||
int is_port_info_extended_supported(ib_portid_t * dest, int port,
|
||||
struct ibmad_port *srcport);
|
||||
void get_max_msg(char *width_msg, char *speed_msg, int msg_size,
|
||||
ibnd_port_t * port);
|
||||
|
||||
int resolve_sm_portid(char *ca_name, uint8_t portnum, ib_portid_t *sm_id);
|
||||
int resolve_self(char *ca_name, uint8_t ca_port, ib_portid_t *portid,
|
||||
int *port, ibmad_gid_t *gid);
|
||||
int resolve_portid_str(char *ca_name, uint8_t ca_port, ib_portid_t * portid,
|
||||
char *addr_str, enum MAD_DEST dest_type,
|
||||
ib_portid_t *sm_id, const struct ibmad_port *srcport);
|
||||
int vsnprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
||||
const char *format, va_list va_args);
|
||||
int snprint_field(char *buf, size_t n, enum MAD_FIELDS f, int spacing,
|
||||
const char *format, ...);
|
||||
void dump_portinfo(void *pi, int tabs);
|
||||
|
||||
/**
|
||||
* Some common command line parsing
|
||||
*/
|
||||
typedef char *(op_fn_t) (ib_portid_t * dest, char **argv, int argc);
|
||||
|
||||
typedef struct match_rec {
|
||||
const char *name, *alias;
|
||||
op_fn_t *fn;
|
||||
unsigned opt_portnum;
|
||||
char *ops_extra;
|
||||
} match_rec_t;
|
||||
|
||||
op_fn_t *match_op(const match_rec_t match_tbl[], char *name);
|
||||
|
||||
#endif /* _IBDIAG_COMMON_H_ */
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 The Regents of the University of California.
|
||||
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2011 Lawrence Livermore National Security. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <infiniband/umad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
#include "ibdiag_sa.h"
|
||||
|
||||
/* define a common SA query structure
|
||||
* This is by no means optimal but it moves the saquery functionality out of
|
||||
* the saquery tool and provides it to other utilities.
|
||||
*/
|
||||
|
||||
struct sa_handle * sa_get_handle(void)
|
||||
{
|
||||
struct sa_handle * handle;
|
||||
handle = calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
IBPANIC("calloc failed");
|
||||
|
||||
resolve_sm_portid(ibd_ca, ibd_ca_port, &handle->dport);
|
||||
if (!handle->dport.lid) {
|
||||
IBWARN("No SM/SA found on port %s:%d",
|
||||
ibd_ca ? "" : ibd_ca,
|
||||
ibd_ca_port);
|
||||
free(handle);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
handle->dport.qp = 1;
|
||||
if (!handle->dport.qkey)
|
||||
handle->dport.qkey = IB_DEFAULT_QP1_QKEY;
|
||||
|
||||
handle->fd = umad_open_port(ibd_ca, ibd_ca_port);
|
||||
handle->agent = umad_register(handle->fd, IB_SA_CLASS, 2, 1, NULL);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int sa_set_handle(struct sa_handle * handle, int grh_present, ibmad_gid_t *gid)
|
||||
{
|
||||
if (grh_present) {
|
||||
if (gid == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
handle->dport.grh_present = 1;
|
||||
memcpy(handle->dport.gid, gid, 16);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sa_free_handle(struct sa_handle * h)
|
||||
{
|
||||
umad_unregister(h->fd, h->agent);
|
||||
umad_close_port(h->fd);
|
||||
free(h);
|
||||
}
|
||||
|
||||
int sa_query(struct sa_handle * h, uint8_t method,
|
||||
uint16_t attr, uint32_t mod, uint64_t comp_mask,
|
||||
uint64_t sm_key, void *data, size_t datasz,
|
||||
struct sa_query_result *result)
|
||||
{
|
||||
ib_rpc_t rpc;
|
||||
void *umad, *mad;
|
||||
int ret, offset, len = 256;
|
||||
|
||||
memset(&rpc, 0, sizeof(rpc));
|
||||
rpc.mgtclass = IB_SA_CLASS;
|
||||
rpc.method = method;
|
||||
rpc.attr.id = attr;
|
||||
rpc.attr.mod = mod;
|
||||
rpc.mask = comp_mask;
|
||||
rpc.datasz = datasz;
|
||||
rpc.dataoffs = IB_SA_DATA_OFFS;
|
||||
|
||||
umad = calloc(1, len + umad_size());
|
||||
if (!umad)
|
||||
IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
|
||||
|
||||
mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
|
||||
|
||||
mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
|
||||
|
||||
if (ibdebug > 1)
|
||||
xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
|
||||
|
||||
if (h->dport.grh_present) {
|
||||
ib_mad_addr_t *p_mad_addr = umad_get_mad_addr(umad);
|
||||
p_mad_addr->grh_present = 1;
|
||||
p_mad_addr->gid_index = 0;
|
||||
p_mad_addr->hop_limit = 0;
|
||||
p_mad_addr->traffic_class = 0;
|
||||
memcpy(p_mad_addr->gid, h->dport.gid, 16);
|
||||
}
|
||||
|
||||
ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
|
||||
if (ret < 0) {
|
||||
IBWARN("umad_send failed: attr 0x%x: %s\n",
|
||||
attr, strerror(errno));
|
||||
free(umad);
|
||||
return (-ret);
|
||||
}
|
||||
|
||||
recv_mad:
|
||||
ret = umad_recv(h->fd, umad, &len, ibd_timeout);
|
||||
if (ret < 0) {
|
||||
if (errno == ENOSPC) {
|
||||
umad = realloc(umad, umad_size() + len);
|
||||
goto recv_mad;
|
||||
}
|
||||
IBWARN("umad_recv failed: attr 0x%x: %s\n", attr,
|
||||
strerror(errno));
|
||||
free(umad);
|
||||
return (-ret);
|
||||
}
|
||||
|
||||
if ((ret = umad_status(umad)))
|
||||
return ret;
|
||||
|
||||
mad = umad_get_mad(umad);
|
||||
|
||||
if (ibdebug > 1)
|
||||
xdump(stdout, "SA Response:\n", mad, len);
|
||||
|
||||
method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
|
||||
offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
|
||||
result->status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
|
||||
result->p_result_madw = mad;
|
||||
if (result->status != IB_SA_MAD_STATUS_SUCCESS)
|
||||
result->result_cnt = 0;
|
||||
else if (method != IB_MAD_METHOD_GET_TABLE)
|
||||
result->result_cnt = 1;
|
||||
else if (!offset)
|
||||
result->result_cnt = 0;
|
||||
else
|
||||
result->result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sa_free_result_mad(struct sa_query_result *result)
|
||||
{
|
||||
if (result->p_result_madw) {
|
||||
free((uint8_t *) result->p_result_madw - umad_size());
|
||||
result->p_result_madw = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *sa_get_query_rec(void *mad, unsigned i)
|
||||
{
|
||||
int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
|
||||
return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
|
||||
}
|
||||
|
||||
static const char *ib_sa_error_str[] = {
|
||||
"SA_NO_ERROR",
|
||||
"SA_ERR_NO_RESOURCES",
|
||||
"SA_ERR_REQ_INVALID",
|
||||
"SA_ERR_NO_RECORDS",
|
||||
"SA_ERR_TOO_MANY_RECORDS",
|
||||
"SA_ERR_REQ_INVALID_GID",
|
||||
"SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
|
||||
"SA_ERR_REQ_DENIED",
|
||||
"SA_ERR_STATUS_PRIO_SUGGESTED",
|
||||
"SA_ERR_UNKNOWN"
|
||||
};
|
||||
|
||||
#define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
#define SA_ERR_UNKNOWN (ARR_SIZE(ib_sa_error_str) - 1)
|
||||
|
||||
static inline const char *ib_sa_err_str(IN uint8_t status)
|
||||
{
|
||||
if (status > SA_ERR_UNKNOWN)
|
||||
status = SA_ERR_UNKNOWN;
|
||||
return (ib_sa_error_str[status]);
|
||||
}
|
||||
|
||||
static const char *ib_mad_inv_field_str[] = {
|
||||
"MAD No invalid fields",
|
||||
"MAD Bad version",
|
||||
"MAD Method specified is not supported",
|
||||
"MAD Method/Attribute combination is not supported",
|
||||
"MAD Reserved",
|
||||
"MAD Reserved",
|
||||
"MAD Reserved",
|
||||
"MAD Invalid value in Attribute field(s) or Attribute Modifier"
|
||||
"MAD UNKNOWN ERROR"
|
||||
};
|
||||
#define MAD_ERR_UNKNOWN (ARR_SIZE(ib_mad_inv_field_str) - 1)
|
||||
|
||||
static inline const char *ib_mad_inv_field_err_str(IN uint8_t f)
|
||||
{
|
||||
if (f > MAD_ERR_UNKNOWN)
|
||||
f = MAD_ERR_UNKNOWN;
|
||||
return (ib_mad_inv_field_str[f]);
|
||||
}
|
||||
|
||||
void sa_report_err(int status)
|
||||
{
|
||||
int st = status & 0xff;
|
||||
char mad_err_str[64] = { 0 };
|
||||
char sa_err_str[64] = { 0 };
|
||||
|
||||
if (st)
|
||||
sprintf(mad_err_str, " (%s; %s; %s)",
|
||||
(st & 0x1) ? "BUSY" : "",
|
||||
(st & 0x2) ? "Redirection Required" : "",
|
||||
ib_mad_inv_field_err_str(st>>2));
|
||||
|
||||
|
||||
st = status >> 8;
|
||||
if (st)
|
||||
sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
|
||||
|
||||
fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
|
||||
status, mad_err_str, sa_err_str);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007 The Regents of the University of California.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2012 Lawrence Livermore National Security. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IBDIAG_SA_H_
|
||||
#define _IBDIAG_SA_H_
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
#include <infiniband/iba/ib_types.h>
|
||||
|
||||
/* define an SA query structure to be common
|
||||
* This is by no means optimal but it moves the saquery functionality out of
|
||||
* the saquery tool and provides it to other utilities.
|
||||
*/
|
||||
struct sa_handle {
|
||||
int fd, agent;
|
||||
ib_portid_t dport;
|
||||
struct ibmad_port *srcport;
|
||||
};
|
||||
|
||||
struct sa_query_result {
|
||||
uint32_t status;
|
||||
unsigned result_cnt;
|
||||
void *p_result_madw;
|
||||
};
|
||||
|
||||
/* NOTE: umad_init must be called prior to sa_get_handle */
|
||||
struct sa_handle * sa_get_handle(void);
|
||||
int sa_set_handle(struct sa_handle * handle, int grh_present, ibmad_gid_t *gid);
|
||||
void sa_free_handle(struct sa_handle * h);
|
||||
|
||||
int sa_query(struct sa_handle *h, uint8_t method,
|
||||
uint16_t attr, uint32_t mod, uint64_t comp_mask, uint64_t sm_key,
|
||||
void *data, size_t datasz, struct sa_query_result *result);
|
||||
void sa_free_result_mad(struct sa_query_result *result);
|
||||
void *sa_get_query_rec(void *mad, unsigned i);
|
||||
void sa_report_err(int status);
|
||||
|
||||
/* Macros for setting query values and ComponentMasks */
|
||||
#define cl_hton8(x) (x)
|
||||
#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
|
||||
if ((int##size##_t) val != (int##size##_t) comp_with) { \
|
||||
target = cl_hton##size((uint##size##_t) val); \
|
||||
comp_mask |= IB_##name##_COMPMASK_##mask; \
|
||||
}
|
||||
|
||||
#define CHECK_AND_SET_GID(val, target, name, mask) \
|
||||
if (valid_gid(&(val))) { \
|
||||
memcpy(&(target), &(val), sizeof(val)); \
|
||||
comp_mask |= IB_##name##_COMPMASK_##mask; \
|
||||
}
|
||||
|
||||
#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
|
||||
if (val) { \
|
||||
target = val; \
|
||||
comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
|
||||
comp_mask |= IB_##name##_COMPMASK_##mask; \
|
||||
}
|
||||
|
||||
#endif /* _IBDIAG_SA_H_ */
|
||||
+1
-1
@@ -34,6 +34,6 @@
|
||||
#ifndef _IBDIAG_VERSION_H_
|
||||
#define _IBDIAG_VERSION_H_
|
||||
|
||||
#define IBDIAG_VERSION "1.4.4"
|
||||
#define IBDIAG_VERSION "1.6.7"
|
||||
|
||||
#endif /* _IBDIAG_VERSION_H_ */
|
||||
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
|
||||
* Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
|
||||
* Copyright (c) 2010,2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <complib/cl_nodenamemap.h>
|
||||
#include <infiniband/ibnetdisc.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define DIFF_FLAG_PORT_CONNECTION 0x01
|
||||
#define DIFF_FLAG_PORT_STATE 0x02
|
||||
#define DIFF_FLAG_LID 0x04
|
||||
#define DIFF_FLAG_NODE_DESCRIPTION 0x08
|
||||
|
||||
#define DIFF_FLAG_DEFAULT (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE)
|
||||
|
||||
static char *node_name_map_file = NULL;
|
||||
static nn_map_t *node_name_map = NULL;
|
||||
static char *load_cache_file = NULL;
|
||||
static char *diff_cache_file = NULL;
|
||||
static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
|
||||
static char *filterdownports_cache_file = NULL;
|
||||
static ibnd_fabric_t *filterdownports_fabric = NULL;
|
||||
|
||||
static uint64_t guid = 0;
|
||||
static char *guid_str = NULL;
|
||||
static char *dr_path = NULL;
|
||||
static int all = 0;
|
||||
|
||||
static int down_links_only = 0;
|
||||
static int line_mode = 0;
|
||||
static int add_sw_settings = 0;
|
||||
static int only_flag = 0;
|
||||
static int only_type = 0;
|
||||
|
||||
int filterdownport_check(ibnd_node_t * node, ibnd_port_t * port)
|
||||
{
|
||||
ibnd_node_t *fsw;
|
||||
ibnd_port_t *fport;
|
||||
int fistate;
|
||||
|
||||
fsw = ibnd_find_node_guid(filterdownports_fabric, node->guid);
|
||||
|
||||
if (!fsw)
|
||||
return 0;
|
||||
|
||||
if (port->portnum > fsw->numports)
|
||||
return 0;
|
||||
|
||||
fport = fsw->ports[port->portnum];
|
||||
|
||||
if (!fport)
|
||||
return 0;
|
||||
|
||||
fistate = mad_get_field(fport->info, 0, IB_PORT_STATE_F);
|
||||
|
||||
return (fistate == IB_LINK_DOWN) ? 1 : 0;
|
||||
}
|
||||
|
||||
void print_port(ibnd_node_t * node, ibnd_port_t * port, char *out_prefix)
|
||||
{
|
||||
char width[64], speed[64], state[64], physstate[64];
|
||||
char remote_guid_str[256];
|
||||
char remote_str[256];
|
||||
char link_str[256];
|
||||
char width_msg[256];
|
||||
char speed_msg[256];
|
||||
char ext_port_str[256];
|
||||
int iwidth, ispeed, fdr10, espeed, istate, iphystate, cap_mask;
|
||||
int n = 0;
|
||||
uint8_t *info = NULL;
|
||||
|
||||
if (!port)
|
||||
return;
|
||||
|
||||
iwidth = mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
|
||||
ispeed = mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
|
||||
fdr10 = mad_get_field(port->ext_info, 0,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F) & FDR10;
|
||||
|
||||
if (port->node->type == IB_NODE_SWITCH) {
|
||||
if (port->node->ports[0])
|
||||
info = (uint8_t *)&port->node->ports[0]->info;
|
||||
}
|
||||
else
|
||||
info = (uint8_t *)&port->info;
|
||||
|
||||
if (info) {
|
||||
cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
||||
if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS))
|
||||
espeed = mad_get_field(port->info, 0,
|
||||
IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
|
||||
else
|
||||
espeed = 0;
|
||||
} else {
|
||||
ispeed = 0;
|
||||
iwidth = 0;
|
||||
espeed = 0;
|
||||
}
|
||||
|
||||
istate = mad_get_field(port->info, 0, IB_PORT_STATE_F);
|
||||
iphystate = mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F);
|
||||
|
||||
remote_guid_str[0] = '\0';
|
||||
remote_str[0] = '\0';
|
||||
link_str[0] = '\0';
|
||||
width_msg[0] = '\0';
|
||||
speed_msg[0] = '\0';
|
||||
|
||||
if (istate == IB_LINK_DOWN
|
||||
&& filterdownports_fabric
|
||||
&& filterdownport_check(node, port))
|
||||
return;
|
||||
|
||||
/* C14-24.2.1 states that a down port allows for invalid data to be
|
||||
* returned for all PortInfo components except PortState and
|
||||
* PortPhysicalState */
|
||||
if (istate != IB_LINK_DOWN) {
|
||||
if (!espeed) {
|
||||
if (fdr10)
|
||||
sprintf(speed, "10.0 Gbps (FDR10)");
|
||||
else
|
||||
mad_dump_val(IB_PORT_LINK_SPEED_ACTIVE_F, speed,
|
||||
64, &ispeed);
|
||||
} else
|
||||
mad_dump_val(IB_PORT_LINK_SPEED_EXT_ACTIVE_F, speed,
|
||||
64, &espeed);
|
||||
|
||||
n = snprintf(link_str, 256, "(%3s %18s %6s/%8s)",
|
||||
mad_dump_val(IB_PORT_LINK_WIDTH_ACTIVE_F, width, 64,
|
||||
&iwidth),
|
||||
speed,
|
||||
mad_dump_val(IB_PORT_STATE_F, state, 64, &istate),
|
||||
mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64,
|
||||
&iphystate));
|
||||
} else {
|
||||
n = snprintf(link_str, 256, "( %6s/%8s)",
|
||||
mad_dump_val(IB_PORT_STATE_F, state, 64, &istate),
|
||||
mad_dump_val(IB_PORT_PHYS_STATE_F, physstate, 64,
|
||||
&iphystate));
|
||||
}
|
||||
|
||||
/* again default values due to C14-24.2.1 */
|
||||
if (add_sw_settings && istate != IB_LINK_DOWN) {
|
||||
snprintf(link_str + n, 256 - n,
|
||||
" (HOQ:%d VL_Stall:%d)",
|
||||
mad_get_field(port->info, 0,
|
||||
IB_PORT_HOQ_LIFE_F),
|
||||
mad_get_field(port->info, 0,
|
||||
IB_PORT_VL_STALL_COUNT_F));
|
||||
}
|
||||
|
||||
if (port->remoteport) {
|
||||
char *remap =
|
||||
remap_node_name(node_name_map, port->remoteport->node->guid,
|
||||
port->remoteport->node->nodedesc);
|
||||
|
||||
if (port->remoteport->ext_portnum)
|
||||
snprintf(ext_port_str, 256, "%d",
|
||||
port->remoteport->ext_portnum);
|
||||
else
|
||||
ext_port_str[0] = '\0';
|
||||
|
||||
get_max_msg(width_msg, speed_msg, 256, port);
|
||||
|
||||
if (line_mode) {
|
||||
snprintf(remote_guid_str, 256,
|
||||
"0x%016" PRIx64 " ",
|
||||
port->remoteport->guid);
|
||||
}
|
||||
|
||||
snprintf(remote_str, 256, "%s%6d %4d[%2s] \"%s\" (%s %s)\n",
|
||||
remote_guid_str, port->remoteport->base_lid ?
|
||||
port->remoteport->base_lid :
|
||||
port->remoteport->node->smalid,
|
||||
port->remoteport->portnum, ext_port_str, remap,
|
||||
width_msg, speed_msg);
|
||||
free(remap);
|
||||
} else {
|
||||
if (istate == IB_LINK_DOWN)
|
||||
snprintf(remote_str, 256, " [ ] \"\" ( )\n");
|
||||
else
|
||||
snprintf(remote_str, 256, " \"Port not available\"\n");
|
||||
}
|
||||
|
||||
if (port->ext_portnum)
|
||||
snprintf(ext_port_str, 256, "%d", port->ext_portnum);
|
||||
else
|
||||
ext_port_str[0] = '\0';
|
||||
|
||||
if (line_mode) {
|
||||
char *remap = remap_node_name(node_name_map, node->guid,
|
||||
node->nodedesc);
|
||||
printf("%s0x%016" PRIx64 " \"%30s\" ",
|
||||
out_prefix ? out_prefix : "",
|
||||
port->guid, remap);
|
||||
free(remap);
|
||||
} else
|
||||
printf("%s ", out_prefix ? out_prefix : "");
|
||||
|
||||
if (port->node->type != IB_NODE_SWITCH) {
|
||||
if (!line_mode)
|
||||
printf("0x%016" PRIx64 " ", port->guid);
|
||||
|
||||
printf("%6d %4d[%2s] ==%s==> %s",
|
||||
port->base_lid,
|
||||
port->portnum, ext_port_str, link_str, remote_str);
|
||||
} else
|
||||
printf("%6d %4d[%2s] ==%s==> %s",
|
||||
node->smalid, port->portnum, ext_port_str,
|
||||
link_str, remote_str);
|
||||
}
|
||||
|
||||
static inline const char *nodetype_str(ibnd_node_t * node)
|
||||
{
|
||||
switch (node->type) {
|
||||
case IB_NODE_SWITCH:
|
||||
return "Switch";
|
||||
case IB_NODE_CA:
|
||||
return "CA";
|
||||
case IB_NODE_ROUTER:
|
||||
return "Router";
|
||||
}
|
||||
return "??";
|
||||
}
|
||||
|
||||
void print_node_header(ibnd_node_t *node, int *out_header_flag,
|
||||
char *out_prefix)
|
||||
{
|
||||
uint64_t guid = 0;
|
||||
if ((!out_header_flag || !(*out_header_flag)) && !line_mode) {
|
||||
char *remap =
|
||||
remap_node_name(node_name_map, node->guid, node->nodedesc);
|
||||
if (node->type == IB_NODE_SWITCH) {
|
||||
if (node->ports[0])
|
||||
guid = node->ports[0]->guid;
|
||||
else /* if (node->info) */
|
||||
guid = mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F);
|
||||
|
||||
printf("%s%s: 0x%016" PRIx64 " %s:\n",
|
||||
out_prefix ? out_prefix : "",
|
||||
nodetype_str(node),
|
||||
guid,
|
||||
remap);
|
||||
} else
|
||||
printf("%s%s: %s:\n",
|
||||
out_prefix ? out_prefix : "",
|
||||
nodetype_str(node), remap);
|
||||
(*out_header_flag)++;
|
||||
free(remap);
|
||||
}
|
||||
}
|
||||
|
||||
void print_node(ibnd_node_t * node, void *user_data)
|
||||
{
|
||||
int i = 0;
|
||||
int head_print = 0;
|
||||
char *out_prefix = (char *)user_data;
|
||||
|
||||
for (i = 1; i <= node->numports; i++) {
|
||||
ibnd_port_t *port = node->ports[i];
|
||||
if (!port)
|
||||
continue;
|
||||
if (!down_links_only ||
|
||||
mad_get_field(port->info, 0,
|
||||
IB_PORT_STATE_F) == IB_LINK_DOWN) {
|
||||
print_node_header(node, &head_print, out_prefix);
|
||||
print_port(node, port, out_prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct iter_diff_data {
|
||||
uint32_t diff_flags;
|
||||
ibnd_fabric_t *fabric1;
|
||||
ibnd_fabric_t *fabric2;
|
||||
char *fabric1_prefix;
|
||||
char *fabric2_prefix;
|
||||
};
|
||||
|
||||
void diff_node_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
|
||||
int *head_print, struct iter_diff_data *data)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 1; i <= fabric1_node->numports; i++) {
|
||||
ibnd_port_t *fabric1_port, *fabric2_port;
|
||||
int output_diff = 0;
|
||||
|
||||
fabric1_port = fabric1_node->ports[i];
|
||||
fabric2_port = fabric2_node->ports[i];
|
||||
|
||||
if (!fabric1_port && !fabric2_port)
|
||||
continue;
|
||||
|
||||
if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION) {
|
||||
if ((fabric1_port && !fabric2_port)
|
||||
|| (!fabric1_port && fabric2_port)
|
||||
|| (fabric1_port->remoteport
|
||||
&& !fabric2_port->remoteport)
|
||||
|| (!fabric1_port->remoteport
|
||||
&& fabric2_port->remoteport)
|
||||
|| (fabric1_port->remoteport
|
||||
&& fabric2_port->remoteport
|
||||
&& fabric1_port->remoteport->guid !=
|
||||
fabric2_port->remoteport->guid))
|
||||
output_diff++;
|
||||
}
|
||||
|
||||
/* if either fabric1_port or fabric2_port NULL, should be
|
||||
* handled by port connection diff code
|
||||
*/
|
||||
if (data->diff_flags & DIFF_FLAG_PORT_STATE
|
||||
&& fabric1_port
|
||||
&& fabric2_port) {
|
||||
int state1, state2;
|
||||
|
||||
state1 = mad_get_field(fabric1_port->info, 0,
|
||||
IB_PORT_STATE_F);
|
||||
state2 = mad_get_field(fabric2_port->info, 0,
|
||||
IB_PORT_STATE_F);
|
||||
|
||||
if (state1 != state2)
|
||||
output_diff++;
|
||||
}
|
||||
|
||||
if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
|
||||
&& data->diff_flags & DIFF_FLAG_LID
|
||||
&& fabric1_port && fabric2_port
|
||||
&& fabric1_port->remoteport && fabric2_port->remoteport
|
||||
&& fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid)
|
||||
output_diff++;
|
||||
|
||||
if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
|
||||
&& data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
|
||||
&& fabric1_port && fabric2_port
|
||||
&& fabric1_port->remoteport && fabric2_port->remoteport
|
||||
&& memcmp(fabric1_port->remoteport->node->nodedesc,
|
||||
fabric2_port->remoteport->node->nodedesc,
|
||||
IB_SMP_DATA_SIZE))
|
||||
output_diff++;
|
||||
|
||||
if (output_diff && fabric1_port) {
|
||||
print_node_header(fabric1_node,
|
||||
head_print,
|
||||
NULL);
|
||||
print_port(fabric1_node,
|
||||
fabric1_port,
|
||||
data->fabric1_prefix);
|
||||
}
|
||||
|
||||
if (output_diff && fabric2_port) {
|
||||
print_node_header(fabric1_node,
|
||||
head_print,
|
||||
NULL);
|
||||
print_port(fabric2_node,
|
||||
fabric2_port,
|
||||
data->fabric2_prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void diff_node_iter(ibnd_node_t * fabric1_node, void *iter_user_data)
|
||||
{
|
||||
struct iter_diff_data *data = iter_user_data;
|
||||
ibnd_node_t *fabric2_node;
|
||||
int head_print = 0;
|
||||
|
||||
DEBUG("DEBUG: fabric1_node %p\n", fabric1_node);
|
||||
|
||||
fabric2_node = ibnd_find_node_guid(data->fabric2, fabric1_node->guid);
|
||||
if (!fabric2_node)
|
||||
print_node(fabric1_node, data->fabric1_prefix);
|
||||
else if (data->diff_flags &
|
||||
(DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE
|
||||
| DIFF_FLAG_LID | DIFF_FLAG_NODE_DESCRIPTION)) {
|
||||
|
||||
if ((fabric1_node->type == IB_NODE_SWITCH
|
||||
&& data->diff_flags & DIFF_FLAG_LID
|
||||
&& fabric1_node->smalid != fabric2_node->smalid) ||
|
||||
(data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
|
||||
&& memcmp(fabric1_node->nodedesc, fabric2_node->nodedesc,
|
||||
IB_SMP_DATA_SIZE))) {
|
||||
print_node_header(fabric1_node,
|
||||
NULL,
|
||||
data->fabric1_prefix);
|
||||
print_node_header(fabric2_node,
|
||||
NULL,
|
||||
data->fabric2_prefix);
|
||||
head_print++;
|
||||
}
|
||||
|
||||
if (fabric1_node->numports != fabric2_node->numports) {
|
||||
print_node_header(fabric1_node,
|
||||
&head_print,
|
||||
NULL);
|
||||
printf("%snumports = %d\n", data->fabric1_prefix,
|
||||
fabric1_node->numports);
|
||||
printf("%snumports = %d\n", data->fabric2_prefix,
|
||||
fabric2_node->numports);
|
||||
return;
|
||||
}
|
||||
|
||||
diff_node_ports(fabric1_node, fabric2_node,
|
||||
&head_print, data);
|
||||
}
|
||||
}
|
||||
|
||||
int diff_node(ibnd_node_t * node, ibnd_fabric_t * orig_fabric,
|
||||
ibnd_fabric_t * new_fabric)
|
||||
{
|
||||
struct iter_diff_data iter_diff_data;
|
||||
|
||||
iter_diff_data.diff_flags = diffcheck_flags;
|
||||
iter_diff_data.fabric1 = orig_fabric;
|
||||
iter_diff_data.fabric2 = new_fabric;
|
||||
iter_diff_data.fabric1_prefix = "< ";
|
||||
iter_diff_data.fabric2_prefix = "> ";
|
||||
if (node)
|
||||
diff_node_iter(node, &iter_diff_data);
|
||||
else {
|
||||
if (only_flag)
|
||||
ibnd_iter_nodes_type(orig_fabric, diff_node_iter,
|
||||
only_type, &iter_diff_data);
|
||||
else
|
||||
ibnd_iter_nodes(orig_fabric, diff_node_iter,
|
||||
&iter_diff_data);
|
||||
}
|
||||
|
||||
/* Do opposite diff to find existence of node types
|
||||
* in new_fabric but not in orig_fabric.
|
||||
*
|
||||
* In this diff, we don't need to check port connections,
|
||||
* port state, lids, or node descriptions since it has already
|
||||
* been done (i.e. checks are only done when guid exists on both
|
||||
* orig and new).
|
||||
*/
|
||||
iter_diff_data.diff_flags = diffcheck_flags & ~DIFF_FLAG_PORT_CONNECTION;
|
||||
iter_diff_data.diff_flags &= ~DIFF_FLAG_PORT_STATE;
|
||||
iter_diff_data.diff_flags &= ~DIFF_FLAG_LID;
|
||||
iter_diff_data.diff_flags &= ~DIFF_FLAG_NODE_DESCRIPTION;
|
||||
iter_diff_data.fabric1 = new_fabric;
|
||||
iter_diff_data.fabric2 = orig_fabric;
|
||||
iter_diff_data.fabric1_prefix = "> ";
|
||||
iter_diff_data.fabric2_prefix = "< ";
|
||||
if (node)
|
||||
diff_node_iter(node, &iter_diff_data);
|
||||
else {
|
||||
if (only_flag)
|
||||
ibnd_iter_nodes_type(new_fabric, diff_node_iter,
|
||||
only_type, &iter_diff_data);
|
||||
else
|
||||
ibnd_iter_nodes(new_fabric, diff_node_iter,
|
||||
&iter_diff_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
struct ibnd_config *cfg = context;
|
||||
char *p;
|
||||
|
||||
switch (ch) {
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
case 2:
|
||||
load_cache_file = strdup(optarg);
|
||||
break;
|
||||
case 3:
|
||||
diff_cache_file = strdup(optarg);
|
||||
break;
|
||||
case 4:
|
||||
diffcheck_flags = 0;
|
||||
p = strtok(optarg, ",");
|
||||
while (p) {
|
||||
if (!strcasecmp(p, "port"))
|
||||
diffcheck_flags |= DIFF_FLAG_PORT_CONNECTION;
|
||||
else if (!strcasecmp(p, "state"))
|
||||
diffcheck_flags |= DIFF_FLAG_PORT_STATE;
|
||||
else if (!strcasecmp(p, "lid"))
|
||||
diffcheck_flags |= DIFF_FLAG_LID;
|
||||
else if (!strcasecmp(p, "nodedesc"))
|
||||
diffcheck_flags |= DIFF_FLAG_NODE_DESCRIPTION;
|
||||
else {
|
||||
fprintf(stderr, "invalid diff check key: %s\n",
|
||||
p);
|
||||
return -1;
|
||||
}
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
filterdownports_cache_file = strdup(optarg);
|
||||
break;
|
||||
case 6:
|
||||
only_flag = 1;
|
||||
only_type = IB_NODE_SWITCH;
|
||||
break;
|
||||
case 7:
|
||||
only_flag = 1;
|
||||
only_type = IB_NODE_CA;
|
||||
break;
|
||||
case 'S':
|
||||
case 'G':
|
||||
guid_str = optarg;
|
||||
guid = (uint64_t) strtoull(guid_str, 0, 0);
|
||||
break;
|
||||
case 'D':
|
||||
dr_path = strdup(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
all = 1;
|
||||
break;
|
||||
case 'n':
|
||||
cfg->max_hops = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'd':
|
||||
down_links_only = 1;
|
||||
break;
|
||||
case 'l':
|
||||
line_mode = 1;
|
||||
break;
|
||||
case 'p':
|
||||
add_sw_settings = 1;
|
||||
break;
|
||||
case 'R': /* nop */
|
||||
break;
|
||||
case 'o':
|
||||
cfg->max_smps = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ibnd_config config = { 0 };
|
||||
int rc = 0;
|
||||
int resolved = -1;
|
||||
ibnd_fabric_t *fabric = NULL;
|
||||
ibnd_fabric_t *diff_fabric = NULL;
|
||||
struct ibmad_port *ibmad_port;
|
||||
ib_portid_t port_id = { 0 };
|
||||
uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"node-name-map", 1, 1, "<file>", "node name map file"},
|
||||
{"switch", 'S', 1, "<port_guid>",
|
||||
"start partial scan at the port specified by <port_guid> (hex format)"},
|
||||
{"port-guid", 'G', 1, "<port_guid>",
|
||||
"(same as -S)"},
|
||||
{"Direct", 'D', 1, "<dr_path>",
|
||||
"start partial scan at the port specified by <dr_path>"},
|
||||
{"all", 'a', 0, NULL,
|
||||
"print all nodes found in a partial fabric scan"},
|
||||
{"hops", 'n', 1, "<hops>",
|
||||
"Number of hops to include away from specified node"},
|
||||
{"down", 'd', 0, NULL, "print only down links"},
|
||||
{"line", 'l', 0, NULL,
|
||||
"(line mode) print all information for each link on a single line"},
|
||||
{"additional", 'p', 0, NULL,
|
||||
"print additional port settings (PktLifeTime, HoqLife, VLStallCount)"},
|
||||
{"load-cache", 2, 1, "<file>",
|
||||
"filename of ibnetdiscover cache to load"},
|
||||
{"diff", 3, 1, "<file>",
|
||||
"filename of ibnetdiscover cache to diff"},
|
||||
{"diffcheck", 4, 1, "<key(s)>",
|
||||
"specify checks to execute for --diff"},
|
||||
{"filterdownports", 5, 1, "<file>",
|
||||
"filename of ibnetdiscover cache to filter downports"},
|
||||
{"outstanding_smps", 'o', 1, NULL,
|
||||
"specify the number of outstanding SMP's which should be "
|
||||
"issued during the scan"},
|
||||
{"switches-only", 6, 0, NULL,
|
||||
"Output only switches"},
|
||||
{"cas-only", 7, 0, NULL,
|
||||
"Output only CAs"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "";
|
||||
|
||||
ibdiag_process_opts(argc, argv, &config, "aDdGgKLlnpRS", opts,
|
||||
process_opt, usage_args, NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
ibmad_port = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!ibmad_port) {
|
||||
fprintf(stderr, "Failed to open %s port %d\n", ibd_ca,
|
||||
ibd_ca_port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
smp_mkey_set(ibmad_port, ibd_mkey);
|
||||
|
||||
if (ibd_timeout) {
|
||||
mad_rpc_set_timeout(ibmad_port, ibd_timeout);
|
||||
config.timeout_ms = ibd_timeout;
|
||||
}
|
||||
|
||||
config.flags = ibd_ibnetdisc_flags;
|
||||
config.mkey = ibd_mkey;
|
||||
|
||||
node_name_map = open_node_name_map(node_name_map_file);
|
||||
|
||||
if (dr_path && load_cache_file) {
|
||||
mad_rpc_close_port(ibmad_port);
|
||||
fprintf(stderr, "Cannot specify cache and direct route path\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (dr_path) {
|
||||
/* only scan part of the fabric */
|
||||
if ((resolved =
|
||||
resolve_portid_str(ibd_ca, ibd_ca_port, &port_id, dr_path,
|
||||
IB_DEST_DRPATH, NULL, ibmad_port)) < 0)
|
||||
IBWARN("Failed to resolve %s; attempting full scan",
|
||||
dr_path);
|
||||
} else if (guid_str) {
|
||||
if ((resolved =
|
||||
resolve_portid_str(ibd_ca, ibd_ca_port, &port_id,
|
||||
guid_str, IB_DEST_GUID, NULL,
|
||||
ibmad_port)) < 0)
|
||||
IBWARN("Failed to resolve %s; attempting full scan\n",
|
||||
guid_str);
|
||||
}
|
||||
|
||||
if (!smp_query_via(ni, &port_id, IB_ATTR_NODE_INFO, 0,
|
||||
ibd_timeout, ibmad_port)){
|
||||
mad_rpc_close_port(ibmad_port);
|
||||
fprintf(stderr,
|
||||
"Failed to get local Node Info\n");
|
||||
exit(1);
|
||||
}
|
||||
mad_rpc_close_port(ibmad_port);
|
||||
|
||||
if (diff_cache_file &&
|
||||
!(diff_fabric = ibnd_load_fabric(diff_cache_file, 0)))
|
||||
IBEXIT("loading cached fabric for diff failed\n");
|
||||
|
||||
if (filterdownports_cache_file &&
|
||||
!(filterdownports_fabric = ibnd_load_fabric(filterdownports_cache_file, 0)))
|
||||
IBEXIT("loading cached fabric for filterdownports failed\n");
|
||||
|
||||
if (load_cache_file) {
|
||||
if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL) {
|
||||
fprintf(stderr, "loading cached fabric failed\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if (resolved >= 0) {
|
||||
if (!config.max_hops)
|
||||
config.max_hops = 1;
|
||||
if (!(fabric =
|
||||
ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
|
||||
IBWARN("Partial fabric scan failed;"
|
||||
" attempting full scan\n");
|
||||
}
|
||||
|
||||
if (!fabric &&
|
||||
!(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config))) {
|
||||
fprintf(stderr, "discover failed\n");
|
||||
rc = 1;
|
||||
goto close_port;
|
||||
}
|
||||
}
|
||||
|
||||
if (!all && guid_str) {
|
||||
ibnd_port_t *p = ibnd_find_port_guid(fabric, guid);
|
||||
if (p && (!only_flag || p->node->type == only_type)) {
|
||||
ibnd_node_t *n = p->node;
|
||||
if (diff_fabric)
|
||||
diff_node(n, diff_fabric, fabric);
|
||||
else
|
||||
print_node(n, NULL);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Failed to find port: %s\n", guid_str);
|
||||
} else if (!all && dr_path) {
|
||||
ibnd_port_t *p = NULL;
|
||||
mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(guid));
|
||||
|
||||
p = ibnd_find_port_guid(fabric, guid);
|
||||
if (p && (!only_flag || p->node->type == only_type)) {
|
||||
ibnd_node_t *n = p->node;
|
||||
if (diff_fabric)
|
||||
diff_node(n, diff_fabric, fabric);
|
||||
else
|
||||
print_node(n, NULL);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Failed to find port: %s\n", dr_path);
|
||||
} else {
|
||||
if (diff_fabric)
|
||||
diff_node(NULL, diff_fabric, fabric);
|
||||
else {
|
||||
if (only_flag)
|
||||
ibnd_iter_nodes_type(fabric, print_node,
|
||||
only_type, NULL);
|
||||
else
|
||||
ibnd_iter_nodes(fabric, print_node, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ibnd_destroy_fabric(fabric);
|
||||
if (diff_fabric)
|
||||
ibnd_destroy_fabric(diff_fabric);
|
||||
|
||||
close_port:
|
||||
close_node_name_map(node_name_map);
|
||||
exit(rc);
|
||||
}
|
||||
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define IB_MLX_VENDOR_CLASS 10
|
||||
|
||||
/* Vendor specific Attribute IDs */
|
||||
#define IB_MLX_IS3_GENERAL_INFO 0x17
|
||||
|
||||
#define MAX_SWITCH_PORTS (36+1)
|
||||
static char mtx_ports[MAX_SWITCH_PORTS] = {0};
|
||||
static char mrx_ports[MAX_SWITCH_PORTS] = {0};
|
||||
static char str[4096];
|
||||
static uint8_t buf[256];
|
||||
|
||||
#define ATTRID_PM_ROUTE 0xff30
|
||||
#define ATTRID_PM_FILTER 0xff31
|
||||
#define ATTRID_PM_PORTS 0xff32
|
||||
#define ATTRID_LOSSY_CFG 0xff80
|
||||
|
||||
enum mirror_type {
|
||||
MT_DISABLED = 0,
|
||||
MT_MIRROR_NATIVE = 2,
|
||||
MT_DROP = 5,
|
||||
MT_MIRROR_ENCAP = 6,
|
||||
MT_MIRROR_DROP = 7
|
||||
};
|
||||
|
||||
enum mirror_port {
|
||||
MP_DISABLED = 0,
|
||||
MP_MIRROR_FILTER = 1,
|
||||
MP_MIRROR_ALWAYS = 2,
|
||||
MP_MIRROR_FILTER_NOT = 3,
|
||||
MT_MIRROR_AS_RX = 1
|
||||
};
|
||||
|
||||
#define PM_ENCAP_ETHERTYPE 0x1123
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
typedef struct {
|
||||
uint16_t hw_revision;
|
||||
uint16_t device_id;
|
||||
uint8_t reserved[24];
|
||||
uint32_t uptime;
|
||||
} is3_hw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t resv1;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t sub_minor;
|
||||
uint32_t build_id;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint16_t year;
|
||||
uint16_t resv2;
|
||||
uint16_t hour;
|
||||
uint8_t psid[16];
|
||||
uint32_t ini_file_version;
|
||||
} is3_fw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t resv1;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t sub_minor;
|
||||
uint8_t resv2[28];
|
||||
} is3_sw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[8];
|
||||
is3_hw_info_t hw_info;
|
||||
is3_fw_info_t fw_info;
|
||||
is3_sw_info_t sw_info;
|
||||
} is3_general_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t ignore_buffer_mask;
|
||||
uint16_t ignore_credit_mask;
|
||||
} lossy_config_t;
|
||||
|
||||
static int mirror_query, mirror_dport, mirror_dlid, mirror_clear, mirror_sl, lossy_set;
|
||||
static int set_mtx, set_mrx, packet_size = 0xfff;
|
||||
|
||||
static int parse_ports(char *ports_str, char *ports_array)
|
||||
{
|
||||
int num, i;
|
||||
char *str = strdup(ports_str);
|
||||
char *token = strtok(str, ",");
|
||||
for (i = 0; i < MAX_SWITCH_PORTS && token; i++) {
|
||||
num = strtoul(token, NULL, 0);
|
||||
if (num > 0 && num < MAX_SWITCH_PORTS)
|
||||
ports_array[num] = 1;
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void port_mirror_route(ib_portid_t * portid, int query, int clear)
|
||||
{
|
||||
int mirror_type;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
if (clear) {
|
||||
if (!smp_set_via(buf, portid, ATTRID_PM_ROUTE, 0, 0, srcport))
|
||||
IBEXIT("Clear port mirror route set failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (query) {
|
||||
if (!smp_query_via(buf, portid, ATTRID_PM_ROUTE, 0, 0, srcport))
|
||||
IBEXIT("Read port mirror route get failed");
|
||||
mad_decode_field(buf, IB_PMR_MT_F, &mirror_type);
|
||||
if (mirror_type == MT_MIRROR_ENCAP && mirror_dlid == 0)
|
||||
mad_decode_field(buf, IB_PMR_LRH_DLID_F, &mirror_dlid);
|
||||
if (mirror_type == MT_MIRROR_NATIVE && mirror_dport == 0)
|
||||
mad_decode_field(buf, IB_PMR_NM_PORT_F, &mirror_dport);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Port Mirror Route */
|
||||
mad_set_field(buf, 0, IB_PMR_ENCAP_RAW_ETH_TYPE_F, PM_ENCAP_ETHERTYPE);
|
||||
|
||||
if (mirror_dlid == 0) {
|
||||
/* Can not truncate mirrored packets in local mode */
|
||||
mad_set_field(buf, 0, IB_PMR_MAX_MIRROR_LEN_F, 0xfff);
|
||||
mad_set_field(buf, 0, IB_PMR_MT_F, MT_MIRROR_NATIVE);
|
||||
mad_set_field(buf, 0, IB_PMR_NM_PORT_F, mirror_dport);
|
||||
}
|
||||
else { /* remote mirror */
|
||||
/* convert size to dwords */
|
||||
packet_size = packet_size / 4 + 1;
|
||||
mad_set_field(buf, 0, IB_PMR_MAX_MIRROR_LEN_F, packet_size);
|
||||
mad_set_field(buf, 0, IB_PMR_MT_F, MT_MIRROR_ENCAP);
|
||||
mad_set_field(buf, 0, IB_PMR_LRH_SL_F, mirror_sl);
|
||||
mad_set_field(buf, 0, IB_PMR_LRH_DLID_F, mirror_dlid);
|
||||
mad_set_field(buf, 0, IB_PMR_LRH_SLID_F, portid->lid);
|
||||
}
|
||||
|
||||
if (!smp_set_via(buf, portid, ATTRID_PM_ROUTE, 0, 0, srcport))
|
||||
IBEXIT("port mirror route set failed");
|
||||
|
||||
Exit:
|
||||
mad_dump_portmirror_route(str, sizeof str, buf, sizeof buf);
|
||||
printf("Port Mirror Route\n%s", str);
|
||||
}
|
||||
|
||||
void port_mirror_ports(ib_portid_t * portid, int query, int clear)
|
||||
{
|
||||
int p, rqf, tqf, rqv, tqv;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
if (clear) {
|
||||
if (!smp_set_via(buf, portid, ATTRID_PM_PORTS, 0, 0, srcport))
|
||||
IBEXIT("Clear port mirror ports set failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (query) {
|
||||
if (!smp_query_via(buf, portid, ATTRID_PM_PORTS, 0, 0, srcport))
|
||||
IBEXIT("Read port mirror ports get failed");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Port Mirror Ports */
|
||||
rqf = IB_PMP_RQ_1_F;
|
||||
tqf = IB_PMP_TQ_1_F;
|
||||
|
||||
for (p = 1; p < MAX_SWITCH_PORTS; p++) {
|
||||
rqv = mrx_ports[p] ? MP_MIRROR_ALWAYS : MP_DISABLED;
|
||||
tqv = mtx_ports[p] ? MP_MIRROR_ALWAYS : MT_MIRROR_AS_RX;
|
||||
mad_set_field(buf, 0, rqf, rqv);
|
||||
mad_set_field(buf, 0, tqf, tqv);
|
||||
rqf += 2;
|
||||
tqf += 2;
|
||||
}
|
||||
|
||||
if (!smp_set_via(buf, portid, ATTRID_PM_PORTS, 0, 0, srcport))
|
||||
IBEXIT("port mirror ports set failed");
|
||||
|
||||
Exit:
|
||||
mad_dump_portmirror_ports(str, sizeof str, buf, sizeof buf);
|
||||
printf("Port Mirror Ports\n%s", str);
|
||||
}
|
||||
|
||||
int get_out_port(ib_portid_t* portid)
|
||||
{
|
||||
int block;
|
||||
int offset;
|
||||
|
||||
if (mirror_dlid) {
|
||||
block = mirror_dlid / IB_SMP_DATA_SIZE;
|
||||
offset = mirror_dlid - block * IB_SMP_DATA_SIZE;
|
||||
/* get out port from lft */
|
||||
if (!smp_query_via(buf, portid, IB_ATTR_LINEARFORWTBL, block, 0, srcport))
|
||||
IBEXIT("linear forwarding table get failed");
|
||||
block = mirror_dlid / IB_SMP_DATA_SIZE;
|
||||
offset = mirror_dlid - block * IB_SMP_DATA_SIZE;
|
||||
return buf[offset];
|
||||
}
|
||||
else
|
||||
return mirror_dport;
|
||||
}
|
||||
|
||||
int get_peer(ib_portid_t* portid, int outport, int* peerlid, int* peerport)
|
||||
{
|
||||
ib_portid_t selfportid = { 0 };
|
||||
ib_portid_t peerportid = { 0 };
|
||||
int selfport = 0;
|
||||
|
||||
/* set peerportid for peer port */
|
||||
memcpy(&peerportid, portid, sizeof(peerportid));
|
||||
peerportid.drpath.cnt = 1;
|
||||
peerportid.drpath.p[1] = outport;
|
||||
if (ib_resolve_self_via(&selfportid, &selfport, 0, srcport) < 0)
|
||||
IBEXIT("failed to resolve self portid");
|
||||
peerportid.drpath.drslid = (uint16_t) selfportid.lid;
|
||||
peerportid.drpath.drdlid = 0xffff;
|
||||
if (!smp_query_via(buf, &peerportid, IB_ATTR_PORT_INFO, 0, 0, srcport))
|
||||
IBEXIT("get peer portinfo failed - unable to configure lossy\n");
|
||||
|
||||
mad_decode_field(buf, IB_PORT_LID_F, peerlid);
|
||||
mad_decode_field(buf, IB_PORT_LOCAL_PORT_F, peerport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_mirror_vl(ib_portid_t* portid, int outport)
|
||||
{
|
||||
ib_slvl_table_t * p_slvl_tbl;
|
||||
int portnum;
|
||||
int vl;
|
||||
|
||||
/* hack; assume all sl2vl mappings are the same for any in port and outport */
|
||||
portnum = (1 << 8) | outport;
|
||||
|
||||
/* get sl2vl mapping */
|
||||
if (!smp_query_via(buf, portid, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
|
||||
IBEXIT("slvl query failed");
|
||||
|
||||
p_slvl_tbl = (ib_slvl_table_t *) buf;
|
||||
vl = ib_slvl_table_get(p_slvl_tbl, mirror_sl);
|
||||
printf("mirror_sl %d, mirror_vl %d\n", mirror_sl, vl);
|
||||
return vl;
|
||||
}
|
||||
|
||||
int lossy_config(ib_portid_t* portid, int query, int clear)
|
||||
{
|
||||
int outport;
|
||||
int peerport;
|
||||
int attr_mod;
|
||||
uint8_t mirror_vl;
|
||||
ib_portid_t peerportid = { 0 };
|
||||
ib_portid_t * p_portid;
|
||||
lossy_config_t local_lossy_cfg;
|
||||
lossy_config_t peer_lossy_cfg;
|
||||
lossy_config_t lossy_cfg;
|
||||
|
||||
outport = get_out_port(portid);
|
||||
if (outport == 0)
|
||||
IBEXIT("get_out_port failed, mirror_dlid and mirror_dport are 0");
|
||||
|
||||
get_peer(portid, outport, &peerportid.lid, &peerport);
|
||||
|
||||
printf("local lid %d / port %d\n", portid->lid, outport);
|
||||
printf("peer lid %d / port %d\n", peerportid.lid, peerport);
|
||||
|
||||
mirror_vl = get_mirror_vl(portid, outport);
|
||||
|
||||
/* read local lossy configuration */
|
||||
if (!smp_query_via(buf, portid, ATTRID_LOSSY_CFG, outport, 0, srcport))
|
||||
IBEXIT("get lossy config from lid %d port %d failed - not supported\n",
|
||||
portid->lid, outport);
|
||||
memcpy(&local_lossy_cfg, buf, sizeof(local_lossy_cfg));
|
||||
|
||||
/* read peer lossy configuration */
|
||||
if (!smp_query_via(buf, &peerportid, ATTRID_LOSSY_CFG, peerport, 0, srcport))
|
||||
IBEXIT("get lossy config from lid %d port %d failed - not supported\n",
|
||||
peerportid.lid, peerport);
|
||||
memcpy(&peer_lossy_cfg, buf, sizeof(peer_lossy_cfg));
|
||||
|
||||
if (query) {
|
||||
printf("local port lid %d port %d ignore_buffer 0x%04x, ignore_credit 0x%04x\n",
|
||||
portid->lid, outport,
|
||||
ntohs(local_lossy_cfg.ignore_buffer_mask), ntohs(local_lossy_cfg.ignore_credit_mask));
|
||||
printf("peer port lid %d port %d ignore_buffer 0x%04x, ignore_credit 0x%04x\n",
|
||||
peerportid.lid, peerport,
|
||||
ntohs(peer_lossy_cfg.ignore_buffer_mask), ntohs(peer_lossy_cfg.ignore_credit_mask));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VLs 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */
|
||||
/* ignore Buf Overrun ignore Credits */
|
||||
/* when mirror activated set ignore buffer overrun on peer port */
|
||||
/* when mirror is de-activated clear ignore credits on local port */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (clear) {
|
||||
p_portid = portid;
|
||||
attr_mod = outport;
|
||||
} else {
|
||||
/* set buffer overrun on peer port */
|
||||
p_portid = &peerportid;
|
||||
attr_mod = peerport;
|
||||
lossy_cfg.ignore_buffer_mask = htons(1<<mirror_vl);
|
||||
lossy_cfg.ignore_credit_mask = 0;
|
||||
memcpy(&buf, &lossy_cfg, sizeof(lossy_cfg));
|
||||
}
|
||||
if (!smp_set_via(buf, p_portid, ATTRID_LOSSY_CFG, attr_mod, 0, srcport))
|
||||
IBEXIT("%s lossy config on lid %d failed\n", clear?"clear":"set", p_portid->lid);
|
||||
|
||||
/* when mirror activated set ignore credit on local port */
|
||||
/* when mirror de-activated clear buffer overrun on peer */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (clear) {
|
||||
p_portid = &peerportid;
|
||||
attr_mod = peerport;
|
||||
} else {
|
||||
/* set ignore credit on local port */
|
||||
p_portid = portid;
|
||||
attr_mod = outport;
|
||||
lossy_cfg.ignore_credit_mask = htons(1<<mirror_vl);
|
||||
lossy_cfg.ignore_buffer_mask = 0;
|
||||
memcpy(&buf, &lossy_cfg, sizeof(lossy_cfg));
|
||||
}
|
||||
if (!smp_set_via(buf, p_portid, ATTRID_LOSSY_CFG, attr_mod, 0, srcport))
|
||||
IBEXIT("%s lossy config on lid %d failed\n", clear?"clear":"set", p_portid->lid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mirror_config(ib_portid_t* portid, int query, int clear)
|
||||
{
|
||||
port_mirror_route(portid, query, clear);
|
||||
/* port_mirror_filter(portid, query, clear); */
|
||||
port_mirror_ports(portid, query, clear);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'p':
|
||||
mirror_dport = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'S':
|
||||
packet_size = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'l':
|
||||
mirror_sl = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'L':
|
||||
mirror_dlid = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'R':
|
||||
set_mrx = 1;
|
||||
if (-1 == parse_ports(optarg, mrx_ports))
|
||||
return -1;
|
||||
break;
|
||||
case 'T':
|
||||
set_mtx = 1;
|
||||
if (-1 == parse_ports(optarg, mtx_ports))
|
||||
return -1;
|
||||
break;
|
||||
case 'D':
|
||||
mirror_clear = 1;
|
||||
break;
|
||||
case 'Q':
|
||||
mirror_query = 1;
|
||||
break;
|
||||
case 'y':
|
||||
lossy_set = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS,
|
||||
IB_MLX_VENDOR_CLASS
|
||||
};
|
||||
ib_portid_t portid = { 0 };
|
||||
int port = 0;
|
||||
ib_vendor_call_t call;
|
||||
is3_general_info_t *gi;
|
||||
uint32_t fw_ver;
|
||||
char op_str[32];
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"dport", 'p', 1, "<port>", "set mirror destination port"},
|
||||
{"dlid", 'L', 1, "<dlid>", "set mirror destination LID"},
|
||||
{"sl", 'l', 1, "<sl>", "set mirror SL"},
|
||||
{"size", 'S', 1, "<size>", "set packet size"},
|
||||
{"rxports", 'R', 1, NULL, "mirror receive port list"},
|
||||
{"txports", 'T', 1, NULL, "mirror transmit port list"},
|
||||
{"clear", 'D', 0, NULL, "clear ports mirroring"},
|
||||
{"query", 'Q', 0, NULL, "read mirror configuration"},
|
||||
{"lossy", 'y', 0, NULL, "set lossy configuration on out port"},
|
||||
{0}
|
||||
};
|
||||
|
||||
char usage_args[] = "<lid>";
|
||||
const char *usage_examples[] = {
|
||||
"-R 1,2,3 -T 2,5 -l1 -L25 -S100 <lid>\t# configure mirror ports",
|
||||
"-D <lid> \t# clear mirror configuration",
|
||||
"-Q <lid>\t# read mirror configuration",
|
||||
NULL
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "GDLs", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
ibdiag_show_usage();
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 4);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
if (argc) {
|
||||
if (ib_resolve_portid_str_via(&portid, argv[0], ibd_dest_type,
|
||||
ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
}
|
||||
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
memset(&call, 0, sizeof(call));
|
||||
call.mgmt_class = IB_MLX_VENDOR_CLASS;
|
||||
call.method = IB_MAD_METHOD_GET;
|
||||
call.timeout = ibd_timeout;
|
||||
call.attrid = IB_MLX_IS3_GENERAL_INFO;
|
||||
if (!ib_vendor_call_via(&buf, &portid, &call, srcport))
|
||||
IBEXIT("failed to read vendor info");
|
||||
gi = (is3_general_info_t *) & buf;
|
||||
if (ntohs(gi->hw_info.device_id) != 0x1b3)
|
||||
IBEXIT("device id 0x%x does not support mirroring", ntohs(gi->hw_info.device_id));
|
||||
|
||||
fw_ver = gi->fw_info.major * 100000 + gi->fw_info.minor * 1000 + gi->fw_info.sub_minor;
|
||||
printf("FW version %08d\n", fw_ver);
|
||||
if (lossy_set && fw_ver < 704000)
|
||||
IBEXIT("FW version %d.%d.%d does not support lossy config",
|
||||
gi->fw_info.major, gi->fw_info.minor, gi->fw_info.sub_minor);
|
||||
|
||||
if (ibdebug) {
|
||||
printf( "switch_lid = %d\n"
|
||||
"mirror_clear = %d\n"
|
||||
"mirror_dlid = %d\n"
|
||||
"mirror_sl = %d\n"
|
||||
"mirror_port = %d\n",
|
||||
portid.lid, mirror_clear, mirror_dlid,
|
||||
mirror_sl, mirror_dport);
|
||||
|
||||
for (port = 1; port < MAX_SWITCH_PORTS; port++) {
|
||||
if (mtx_ports[port])
|
||||
printf("TX: %d\n",port);
|
||||
else if(mrx_ports[port])
|
||||
printf("RX: %d\n",port);
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror_clear)
|
||||
strcpy(op_str, "Clear");
|
||||
else if (mirror_query)
|
||||
strcpy(op_str, "Read");
|
||||
else if (!mirror_dport && !mirror_dlid)
|
||||
IBEXIT("Mirror remote LID and local port are zero");
|
||||
else if (!set_mtx && !set_mrx)
|
||||
IBEXIT("Mirror Rx and Tx ports not selected");
|
||||
else
|
||||
strcpy(op_str, "Set");
|
||||
|
||||
printf("\n%s Mirror Configuration\n", op_str);
|
||||
mirror_config(&portid, mirror_query, mirror_clear);
|
||||
|
||||
if (lossy_set) {
|
||||
printf("%s Lossy Configuration\n", op_str);
|
||||
lossy_config(&portid, mirror_query, mirror_clear);
|
||||
}
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <complib/cl_timer.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static char host_and_domain[IB_VENDOR_RANGE2_DATA_SIZE];
|
||||
static char last_host[IB_VENDOR_RANGE2_DATA_SIZE];
|
||||
static ibmad_gid_t dgid;
|
||||
static int with_grh;
|
||||
|
||||
static void get_host_and_domain(char *data, int sz)
|
||||
{
|
||||
char *s = data;
|
||||
int n;
|
||||
|
||||
if (gethostname(s, sz) < 0)
|
||||
snprintf(s, sz, "?hostname?");
|
||||
|
||||
s[sz - 1] = 0;
|
||||
if ((n = strlen(s)) >= sz)
|
||||
return;
|
||||
s[n] = '.';
|
||||
s += n + 1;
|
||||
sz -= n + 1;
|
||||
|
||||
if (getdomainname(s, sz) < 0)
|
||||
snprintf(s, sz, "?domainname?");
|
||||
if (strlen(s) == 0)
|
||||
s[-1] = 0; /* no domain */
|
||||
}
|
||||
|
||||
static char *ibping_serv(void)
|
||||
{
|
||||
void *umad;
|
||||
void *mad;
|
||||
char *data;
|
||||
|
||||
DEBUG("starting to serve...");
|
||||
|
||||
while ((umad = mad_receive_via(0, -1, srcport))) {
|
||||
|
||||
if (umad_status(umad) == 0) {
|
||||
mad = umad_get_mad(umad);
|
||||
data = (char *)mad + IB_VENDOR_RANGE2_DATA_OFFS;
|
||||
|
||||
memcpy(data, host_and_domain, IB_VENDOR_RANGE2_DATA_SIZE);
|
||||
|
||||
DEBUG("Pong: %s", data);
|
||||
|
||||
if (mad_respond_via(umad, 0, 0, srcport) < 0)
|
||||
DEBUG("respond failed");
|
||||
|
||||
}
|
||||
mad_free(umad);
|
||||
}
|
||||
|
||||
DEBUG("server out");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oui = IB_OPENIB_OUI;
|
||||
|
||||
static uint64_t ibping(ib_portid_t * portid, int quiet)
|
||||
{
|
||||
char data[IB_VENDOR_RANGE2_DATA_SIZE] = { 0 };
|
||||
ib_vendor_call_t call;
|
||||
uint64_t start, rtt;
|
||||
|
||||
DEBUG("Ping..");
|
||||
|
||||
start = cl_get_time_stamp();
|
||||
|
||||
call.method = IB_MAD_METHOD_GET;
|
||||
call.mgmt_class = IB_VENDOR_OPENIB_PING_CLASS;
|
||||
call.attrid = 0;
|
||||
call.mod = 0;
|
||||
call.oui = oui;
|
||||
call.timeout = 0;
|
||||
memset(&call.rmpp, 0, sizeof call.rmpp);
|
||||
|
||||
if (!ib_vendor_call_via(data, portid, &call, srcport))
|
||||
return ~0ull;
|
||||
|
||||
rtt = cl_get_time_stamp() - start;
|
||||
|
||||
if (!last_host[0])
|
||||
memcpy(last_host, data, sizeof last_host);
|
||||
|
||||
if (!quiet)
|
||||
printf("Pong from %s (%s): time %" PRIu64 ".%03" PRIu64 " ms\n",
|
||||
data, portid2str(portid), rtt / 1000, rtt % 1000);
|
||||
|
||||
return rtt;
|
||||
}
|
||||
|
||||
static uint64_t minrtt = ~0ull, maxrtt, total_rtt;
|
||||
static uint64_t start, total_time, replied, lost, ntrans;
|
||||
static ib_portid_t portid = { 0 };
|
||||
|
||||
void report(int sig)
|
||||
{
|
||||
total_time = cl_get_time_stamp() - start;
|
||||
|
||||
DEBUG("out due signal %d", sig);
|
||||
|
||||
printf("\n--- %s (%s) ibping statistics ---\n", last_host,
|
||||
portid2str(&portid));
|
||||
printf("%" PRIu64 " packets transmitted, %" PRIu64 " received, %" PRIu64
|
||||
"%% packet loss, time %" PRIu64 " ms\n", ntrans, replied,
|
||||
(lost != 0) ? lost * 100 / ntrans : 0, total_time / 1000);
|
||||
printf("rtt min/avg/max = %" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03"
|
||||
PRIu64 "/%" PRIu64 ".%03" PRIu64 " ms\n",
|
||||
minrtt == ~0ull ? 0 : minrtt / 1000,
|
||||
minrtt == ~0ull ? 0 : minrtt % 1000,
|
||||
replied ? total_rtt / replied / 1000 : 0,
|
||||
replied ? (total_rtt / replied) % 1000 : 0, maxrtt / 1000,
|
||||
maxrtt % 1000);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int server = 0, flood = 0;
|
||||
static unsigned count = ~0;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
count = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'f':
|
||||
flood++;
|
||||
break;
|
||||
case 'o':
|
||||
oui = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'S':
|
||||
server++;
|
||||
break;
|
||||
case 25:
|
||||
if (!inet_pton(AF_INET6, optarg, &dgid)) {
|
||||
printf("dgid format is wrong!\n");
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
with_grh = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[1] = { IB_SA_CLASS };
|
||||
int ping_class = IB_VENDOR_OPENIB_PING_CLASS;
|
||||
uint64_t rtt;
|
||||
char *err;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"count", 'c', 1, "<num>", "stop after count packets"},
|
||||
{"flood", 'f', 0, NULL, "flood destination"},
|
||||
{"oui", 'o', 1, NULL, "use specified OUI number"},
|
||||
{"Server", 'S', 0, NULL, "start in server mode"},
|
||||
{"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<dest lid|guid>";
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
|
||||
usage_args, NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!argc && !server)
|
||||
ibdiag_show_usage();
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 1);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
if (server) {
|
||||
if (mad_register_server_via(ping_class, 0, 0, oui, srcport) < 0)
|
||||
IBEXIT("can't serve class %d on this port",
|
||||
ping_class);
|
||||
|
||||
get_host_and_domain(host_and_domain, sizeof host_and_domain);
|
||||
|
||||
if ((err = ibping_serv()))
|
||||
IBEXIT("ibping to %s: %s", portid2str(&portid), err);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (mad_register_client_via(ping_class, 0, srcport) < 0)
|
||||
IBEXIT("can't register ping class %d on this port",
|
||||
ping_class);
|
||||
|
||||
if (with_grh && ibd_dest_type != IB_DEST_LID)
|
||||
IBEXIT("When using GRH, LID should be provided");
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
|
||||
if (with_grh) {
|
||||
portid.grh_present = 1;
|
||||
memcpy(&portid.gid, &dgid, sizeof(portid.gid));
|
||||
}
|
||||
|
||||
signal(SIGINT, report);
|
||||
signal(SIGTERM, report);
|
||||
|
||||
start = cl_get_time_stamp();
|
||||
|
||||
while (count-- > 0) {
|
||||
ntrans++;
|
||||
if ((rtt = ibping(&portid, flood)) == ~0ull) {
|
||||
DEBUG("ibping to %s failed", portid2str(&portid));
|
||||
lost++;
|
||||
} else {
|
||||
if (rtt < minrtt)
|
||||
minrtt = rtt;
|
||||
if (rtt > maxrtt)
|
||||
maxrtt = rtt;
|
||||
total_rtt += rtt;
|
||||
replied++;
|
||||
}
|
||||
|
||||
if (!flood)
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
report(0);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
@@ -0,0 +1,767 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2010,2011 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2011,2016 Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
enum port_ops {
|
||||
QUERY,
|
||||
ENABLE,
|
||||
RESET,
|
||||
DISABLE,
|
||||
SPEED,
|
||||
ESPEED,
|
||||
FDR10SPEED,
|
||||
WIDTH,
|
||||
DOWN,
|
||||
ARM,
|
||||
ACTIVE,
|
||||
VLS,
|
||||
MTU,
|
||||
LID,
|
||||
SMLID,
|
||||
LMC,
|
||||
MKEY,
|
||||
MKEYLEASE,
|
||||
MKEYPROT,
|
||||
ON,
|
||||
OFF
|
||||
};
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
uint64_t speed = 0; /* no state change */
|
||||
uint64_t espeed = 0; /* no state change */
|
||||
uint64_t fdr10 = 0; /* no state change */
|
||||
uint64_t width = 0; /* no state change */
|
||||
uint64_t lid;
|
||||
uint64_t smlid;
|
||||
uint64_t lmc;
|
||||
uint64_t mtu;
|
||||
uint64_t vls = 0; /* no state change */
|
||||
uint64_t mkey;
|
||||
uint64_t mkeylease;
|
||||
uint64_t mkeyprot;
|
||||
|
||||
struct {
|
||||
const char *name;
|
||||
uint64_t *val;
|
||||
int set;
|
||||
} port_args[] = {
|
||||
{"query", NULL, 0}, /* QUERY */
|
||||
{"enable", NULL, 0}, /* ENABLE */
|
||||
{"reset", NULL, 0}, /* RESET */
|
||||
{"disable", NULL, 0}, /* DISABLE */
|
||||
{"speed", &speed, 0}, /* SPEED */
|
||||
{"espeed", &espeed, 0}, /* EXTENDED SPEED */
|
||||
{"fdr10", &fdr10, 0}, /* FDR10 SPEED */
|
||||
{"width", &width, 0}, /* WIDTH */
|
||||
{"down", NULL, 0}, /* DOWN */
|
||||
{"arm", NULL, 0}, /* ARM */
|
||||
{"active", NULL, 0}, /* ACTIVE */
|
||||
{"vls", &vls, 0}, /* VLS */
|
||||
{"mtu", &mtu, 0}, /* MTU */
|
||||
{"lid", &lid, 0}, /* LID */
|
||||
{"smlid", &smlid, 0}, /* SMLID */
|
||||
{"lmc", &lmc, 0}, /* LMC */
|
||||
{"mkey", &mkey, 0}, /* MKEY */
|
||||
{"mkeylease", &mkeylease, 0}, /* MKEY LEASE */
|
||||
{"mkeyprot", &mkeyprot, 0}, /* MKEY PROTECT BITS */
|
||||
{"on", NULL, 0}, /* ON */
|
||||
{"off", NULL, 0}, /* OFF */
|
||||
};
|
||||
|
||||
#define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0]))
|
||||
|
||||
/*******************************************/
|
||||
|
||||
/*
|
||||
* Return 1 if node is a switch, else zero.
|
||||
*/
|
||||
static int get_node_info(ib_portid_t * dest, uint8_t * data)
|
||||
{
|
||||
int node_type;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
IBEXIT("smp query nodeinfo failed");
|
||||
|
||||
node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
|
||||
if (node_type == IB_NODE_SWITCH) /* Switch NodeType ? */
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
|
||||
int is_switch)
|
||||
{
|
||||
uint8_t smp[IB_SMP_DATA_SIZE];
|
||||
uint8_t *info;
|
||||
int cap_mask;
|
||||
|
||||
if (is_switch) {
|
||||
if (!smp_query_via(smp, dest, IB_ATTR_PORT_INFO, 0, 0, srcport))
|
||||
IBEXIT("smp query port 0 portinfo failed");
|
||||
info = smp;
|
||||
} else
|
||||
info = data;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
|
||||
IBEXIT("smp query portinfo failed");
|
||||
cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
|
||||
return (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS));
|
||||
}
|
||||
|
||||
static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
|
||||
int espeed_cap, int is_switch)
|
||||
{
|
||||
char buf[2300];
|
||||
char val[64];
|
||||
|
||||
mad_dump_portstates(buf, sizeof buf, data, sizeof *data);
|
||||
mad_decode_field(data, IB_PORT_LID_F, val);
|
||||
mad_dump_field(IB_PORT_LID_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_SMLID_F, val);
|
||||
mad_dump_field(IB_PORT_SMLID_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LMC_F, val);
|
||||
mad_dump_field(IB_PORT_LMC_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
if (espeed_cap) {
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_SUPPORTED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
|
||||
buf + strlen(buf), sizeof buf - strlen(buf),
|
||||
val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_ENABLED_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_EXT_ENABLED_F,
|
||||
buf + strlen(buf), sizeof buf - strlen(buf),
|
||||
val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_EXT_ACTIVE_F, val);
|
||||
mad_dump_field(IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
|
||||
buf + strlen(buf), sizeof buf - strlen(buf),
|
||||
val);
|
||||
sprintf(buf + strlen(buf), "%s", "\n");
|
||||
}
|
||||
if (!is_switch || portnum == 0) {
|
||||
if (show_keys) {
|
||||
mad_decode_field(data, IB_PORT_MKEY_F, val);
|
||||
mad_dump_field(IB_PORT_MKEY_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
} else
|
||||
snprint_field(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
IB_PORT_MKEY_F, 32, NOT_DISPLAYED_STR);
|
||||
sprintf(buf+strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_MKEY_LEASE_F, val);
|
||||
mad_dump_field(IB_PORT_MKEY_LEASE_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf+strlen(buf), "%s", "\n");
|
||||
mad_decode_field(data, IB_PORT_MKEY_PROT_BITS_F, val);
|
||||
mad_dump_field(IB_PORT_MKEY_PROT_BITS_F, buf + strlen(buf),
|
||||
sizeof buf - strlen(buf), val);
|
||||
sprintf(buf+strlen(buf), "%s", "\n");
|
||||
}
|
||||
|
||||
printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
|
||||
}
|
||||
|
||||
static void set_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
|
||||
int espeed_cap, int is_switch)
|
||||
{
|
||||
unsigned mod;
|
||||
|
||||
mod = portnum;
|
||||
if (espeed_cap)
|
||||
mod |= 1<<31;
|
||||
if (!smp_set_via(data, dest, IB_ATTR_PORT_INFO, mod, 0, srcport))
|
||||
IBEXIT("smp set portinfo failed");
|
||||
|
||||
printf("\nAfter PortInfo set:\n");
|
||||
show_port_info(dest, data, portnum, espeed_cap, is_switch);
|
||||
}
|
||||
|
||||
static void get_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
|
||||
{
|
||||
if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO,
|
||||
portnum, 0, srcport))
|
||||
IBEXIT("smp query ext portinfo failed");
|
||||
}
|
||||
|
||||
static void show_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, IB_SMP_DATA_SIZE);
|
||||
|
||||
printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest),
|
||||
portnum, buf);
|
||||
}
|
||||
|
||||
static void set_mlnx_ext_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
|
||||
{
|
||||
if (!smp_set_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO,
|
||||
portnum, 0, srcport))
|
||||
IBEXIT("smp set MLNX ext portinfo failed");
|
||||
|
||||
printf("\nAfter MLNXExtendedPortInfo set:\n");
|
||||
show_mlnx_ext_port_info(dest, data, portnum);
|
||||
}
|
||||
|
||||
static int get_link_width(int lwe, int lws)
|
||||
{
|
||||
if (lwe == 255)
|
||||
return lws;
|
||||
else
|
||||
return lwe;
|
||||
}
|
||||
|
||||
static int get_link_speed(int lse, int lss)
|
||||
{
|
||||
if (lse == 15)
|
||||
return lss;
|
||||
else
|
||||
return lse;
|
||||
}
|
||||
|
||||
static int get_link_speed_ext(int lsee, int lses)
|
||||
{
|
||||
if (lsee == 31)
|
||||
return lses;
|
||||
else
|
||||
return lsee;
|
||||
}
|
||||
|
||||
static void validate_width(int width, int peerwidth, int lwa)
|
||||
{
|
||||
if ((width & peerwidth & 0x8)) {
|
||||
if (lwa != 8)
|
||||
IBWARN
|
||||
("Peer ports operating at active width %d rather than 8 (12x)",
|
||||
lwa);
|
||||
} else if ((width & peerwidth & 0x4)) {
|
||||
if (lwa != 4)
|
||||
IBWARN
|
||||
("Peer ports operating at active width %d rather than 4 (8x)",
|
||||
lwa);
|
||||
} else if ((width & peerwidth & 0x2)) {
|
||||
if (lwa != 2)
|
||||
IBWARN
|
||||
("Peer ports operating at active width %d rather than 2 (4x)",
|
||||
lwa);
|
||||
} else if ((width & peerwidth & 0x10)) {
|
||||
if (lwa != 16)
|
||||
IBWARN
|
||||
("Peer ports operating at active width %d rather than 16 (2x)",
|
||||
lwa);
|
||||
} else if ((width & peerwidth & 0x1)) {
|
||||
if (lwa != 1)
|
||||
IBWARN
|
||||
("Peer ports operating at active width %d rather than 1 (1x)",
|
||||
lwa);
|
||||
}
|
||||
}
|
||||
|
||||
static void validate_speed(int speed, int peerspeed, int lsa)
|
||||
{
|
||||
if ((speed & peerspeed & 0x4)) {
|
||||
if (lsa != 4)
|
||||
IBWARN
|
||||
("Peer ports operating at active speed %d rather than 4 (10.0 Gbps)",
|
||||
lsa);
|
||||
} else if ((speed & peerspeed & 0x2)) {
|
||||
if (lsa != 2)
|
||||
IBWARN
|
||||
("Peer ports operating at active speed %d rather than 2 (5.0 Gbps)",
|
||||
lsa);
|
||||
} else if ((speed & peerspeed & 0x1)) {
|
||||
if (lsa != 1)
|
||||
IBWARN
|
||||
("Peer ports operating at active speed %d rather than 1 (2.5 Gbps)",
|
||||
lsa);
|
||||
}
|
||||
}
|
||||
|
||||
static void validate_extended_speed(int espeed, int peerespeed, int lsea)
|
||||
{
|
||||
if ((espeed & peerespeed & 0x2)) {
|
||||
if (lsea != 2)
|
||||
IBWARN
|
||||
("Peer ports operating at active extended speed %d rather than 2 (25.78125 Gbps)",
|
||||
lsea);
|
||||
} else if ((espeed & peerespeed & 0x1)) {
|
||||
if (lsea != 1)
|
||||
IBWARN
|
||||
("Peer ports operating at active extended speed %d rather than 1 (14.0625 Gbps)",
|
||||
lsea);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
int port_op = -1;
|
||||
int is_switch, is_peer_switch, espeed_cap, peer_espeed_cap;
|
||||
int state, physstate, lwe, lws, lwa, lse, lss, lsa, lsee, lses, lsea,
|
||||
fdr10s, fdr10e, fdr10a;
|
||||
int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss,
|
||||
peerlsa, peerlsee, peerlses, peerlsea, peerfdr10s, peerfdr10e,
|
||||
peerfdr10a;
|
||||
int peerwidth, peerspeed, peerespeed;
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t data2[IB_SMP_DATA_SIZE] = { 0 };
|
||||
ib_portid_t peerportid = { 0 };
|
||||
int portnum = 0;
|
||||
ib_portid_t selfportid = { 0 };
|
||||
int selfport = 0;
|
||||
int changed = 0;
|
||||
int i;
|
||||
uint32_t vendorid, rem_vendorid;
|
||||
uint16_t devid, rem_devid;
|
||||
uint64_t val;
|
||||
char *endp;
|
||||
char usage_args[] = "<dest dr_path|lid|guid> <portnum> [<op>]\n"
|
||||
"\nSupported ops: enable, disable, on, off, reset, speed, espeed, fdr10,\n"
|
||||
"\twidth, query, down, arm, active, vls, mtu, lid, smlid, lmc,\n"
|
||||
"\tmkey, mkeylease, mkeyprot\n";
|
||||
const char *usage_examples[] = {
|
||||
"3 1 disable\t\t\t# by lid",
|
||||
"-G 0x2C9000100D051 1 enable\t# by guid",
|
||||
"-D 0 1\t\t\t# (query) by direct route",
|
||||
"3 1 reset\t\t\t# by lid",
|
||||
"3 1 speed 1\t\t\t# by lid",
|
||||
"3 1 width 1\t\t\t# by lid",
|
||||
"-D 0 1 lid 0x1234 arm\t\t# by direct route",
|
||||
NULL
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, NULL, NULL, NULL,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
ibdiag_show_usage();
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
|
||||
if (argc > 1)
|
||||
portnum = strtol(argv[1], 0, 0);
|
||||
|
||||
for (i = 2; i < argc; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < NPORT_ARGS; j++) {
|
||||
if (strcmp(argv[i], port_args[j].name))
|
||||
continue;
|
||||
port_args[j].set = 1;
|
||||
if (!port_args[j].val) {
|
||||
if (port_op >= 0)
|
||||
IBEXIT("%s only one of: ",
|
||||
"query, enable, disable, "
|
||||
"reset, down, arm, active, "
|
||||
"can be specified",
|
||||
port_args[j].name);
|
||||
port_op = j;
|
||||
break;
|
||||
}
|
||||
if (++i >= argc)
|
||||
IBEXIT("%s requires an additional parameter",
|
||||
port_args[j].name);
|
||||
val = strtoull(argv[i], 0, 0);
|
||||
switch (j) {
|
||||
case SPEED:
|
||||
if (val > 15)
|
||||
IBEXIT("invalid speed value %ld", val);
|
||||
break;
|
||||
case ESPEED:
|
||||
if (val > 31)
|
||||
IBEXIT("invalid extended speed value %ld", val);
|
||||
break;
|
||||
case FDR10SPEED:
|
||||
if (val > 1)
|
||||
IBEXIT("invalid fdr10 speed value %ld", val);
|
||||
break;
|
||||
case WIDTH:
|
||||
if ((val > 31 && val != 255))
|
||||
IBEXIT("invalid width value %ld", val);
|
||||
break;
|
||||
case VLS:
|
||||
if (val == 0 || val > 5)
|
||||
IBEXIT("invalid vls value %ld", val);
|
||||
break;
|
||||
case MTU:
|
||||
if (val == 0 || val > 5)
|
||||
IBEXIT("invalid mtu value %ld", val);
|
||||
break;
|
||||
case LID:
|
||||
if (val == 0 || val >= 0xC000)
|
||||
IBEXIT("invalid lid value 0x%lx", val);
|
||||
break;
|
||||
case SMLID:
|
||||
if (val == 0 || val >= 0xC000)
|
||||
IBEXIT("invalid smlid value 0x%lx",
|
||||
val);
|
||||
break;
|
||||
case LMC:
|
||||
if (val > 7)
|
||||
IBEXIT("invalid lmc value %ld", val);
|
||||
break;
|
||||
case MKEY:
|
||||
errno = 0;
|
||||
val = strtoull(argv[i], &endp, 0);
|
||||
if (errno || *endp != '\0') {
|
||||
errno = 0;
|
||||
val = strtoull(getpass("New M_Key: "),
|
||||
&endp, 0);
|
||||
if (errno || *endp != '\0') {
|
||||
IBEXIT("Bad new M_Key\n");
|
||||
}
|
||||
}
|
||||
/* All 64-bit values are legal */
|
||||
break;
|
||||
case MKEYLEASE:
|
||||
if (val > 0xFFFF)
|
||||
IBEXIT("invalid mkey lease time %ld", val);
|
||||
break;
|
||||
case MKEYPROT:
|
||||
if (val > 3)
|
||||
IBEXIT("invalid mkey protection bit setting %ld", val);
|
||||
}
|
||||
*port_args[j].val = val;
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
if (j == NPORT_ARGS)
|
||||
IBEXIT("invalid operation: %s", argv[i]);
|
||||
}
|
||||
if (port_op < 0)
|
||||
port_op = QUERY;
|
||||
|
||||
is_switch = get_node_info(&portid, data);
|
||||
vendorid = (uint32_t) mad_get_field(data, 0, IB_NODE_VENDORID_F);
|
||||
devid = (uint16_t) mad_get_field(data, 0, IB_NODE_DEVID_F);
|
||||
|
||||
if ((port_args[MKEY].set || port_args[MKEYLEASE].set ||
|
||||
port_args[MKEYPROT].set) && is_switch && portnum != 0)
|
||||
IBEXIT("Can't set M_Key fields on switch port != 0");
|
||||
|
||||
if (port_op != QUERY || changed)
|
||||
printf("Initial %s PortInfo:\n", is_switch ? "Switch" : "CA/RT");
|
||||
else
|
||||
printf("%s PortInfo:\n", is_switch ? "Switch" : "CA/RT");
|
||||
espeed_cap = get_port_info(&portid, data, portnum, is_switch);
|
||||
show_port_info(&portid, data, portnum, espeed_cap, is_switch);
|
||||
if (is_mlnx_ext_port_info_supported(vendorid, devid)) {
|
||||
get_mlnx_ext_port_info(&portid, data2, portnum);
|
||||
show_mlnx_ext_port_info(&portid, data2, portnum);
|
||||
}
|
||||
|
||||
if (port_op != QUERY || changed) {
|
||||
/*
|
||||
* If we aren't setting the LID and the LID is the default,
|
||||
* the SMA command will fail due to an invalid LID.
|
||||
* Set it to something unlikely but valid.
|
||||
*/
|
||||
physstate = mad_get_field(data, 0, IB_PORT_PHYS_STATE_F);
|
||||
|
||||
val = mad_get_field(data, 0, IB_PORT_LID_F);
|
||||
if (!port_args[LID].set && (!val || val == 0xFFFF))
|
||||
mad_set_field(data, 0, IB_PORT_LID_F, 0x1234);
|
||||
val = mad_get_field(data, 0, IB_PORT_SMLID_F);
|
||||
if (!port_args[SMLID].set && (!val || val == 0xFFFF))
|
||||
mad_set_field(data, 0, IB_PORT_SMLID_F, 0x1234);
|
||||
mad_set_field(data, 0, IB_PORT_STATE_F, 0); /* NOP */
|
||||
mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0); /* NOP */
|
||||
|
||||
switch (port_op) {
|
||||
case ON:
|
||||
/* Enable only if state is Disable */
|
||||
if(physstate != 3) {
|
||||
printf("Port is already in enable state\n");
|
||||
goto close_port;
|
||||
}
|
||||
case ENABLE:
|
||||
case RESET:
|
||||
/* Polling */
|
||||
mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);
|
||||
break;
|
||||
case OFF:
|
||||
case DISABLE:
|
||||
printf("Disable may be irreversible\n");
|
||||
mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3);
|
||||
break;
|
||||
case DOWN:
|
||||
mad_set_field(data, 0, IB_PORT_STATE_F, 1);
|
||||
break;
|
||||
case ARM:
|
||||
mad_set_field(data, 0, IB_PORT_STATE_F, 3);
|
||||
break;
|
||||
case ACTIVE:
|
||||
mad_set_field(data, 0, IB_PORT_STATE_F, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
/* always set enabled speeds/width - defaults to NOP */
|
||||
mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F, speed);
|
||||
mad_set_field(data, 0, IB_PORT_LINK_SPEED_EXT_ENABLED_F, espeed);
|
||||
mad_set_field(data, 0, IB_PORT_LINK_WIDTH_ENABLED_F, width);
|
||||
|
||||
if (port_args[VLS].set)
|
||||
mad_set_field(data, 0, IB_PORT_OPER_VLS_F, vls);
|
||||
if (port_args[MTU].set)
|
||||
mad_set_field(data, 0, IB_PORT_NEIGHBOR_MTU_F, mtu);
|
||||
if (port_args[LID].set)
|
||||
mad_set_field(data, 0, IB_PORT_LID_F, lid);
|
||||
if (port_args[SMLID].set)
|
||||
mad_set_field(data, 0, IB_PORT_SMLID_F, smlid);
|
||||
if (port_args[LMC].set)
|
||||
mad_set_field(data, 0, IB_PORT_LMC_F, lmc);
|
||||
|
||||
if (port_args[FDR10SPEED].set) {
|
||||
mad_set_field(data2, 0,
|
||||
IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
|
||||
FDR10);
|
||||
mad_set_field(data2, 0,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
|
||||
fdr10);
|
||||
set_mlnx_ext_port_info(&portid, data2, portnum);
|
||||
}
|
||||
|
||||
if (port_args[MKEY].set)
|
||||
mad_set_field64(data, 0, IB_PORT_MKEY_F, mkey);
|
||||
if (port_args[MKEYLEASE].set)
|
||||
mad_set_field(data, 0, IB_PORT_MKEY_LEASE_F,
|
||||
mkeylease);
|
||||
if (port_args[MKEYPROT].set)
|
||||
mad_set_field(data, 0, IB_PORT_MKEY_PROT_BITS_F,
|
||||
mkeyprot);
|
||||
|
||||
set_port_info(&portid, data, portnum, espeed_cap, is_switch);
|
||||
|
||||
} else if (is_switch && portnum) {
|
||||
/* Now, make sure PortState is Active */
|
||||
/* Or is PortPhysicalState LinkUp sufficient ? */
|
||||
mad_decode_field(data, IB_PORT_STATE_F, &state);
|
||||
mad_decode_field(data, IB_PORT_PHYS_STATE_F, &physstate);
|
||||
if (state == 4) { /* Active */
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F,
|
||||
&lwe);
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F,
|
||||
&lws);
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F,
|
||||
&lwa);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F,
|
||||
&lss);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F,
|
||||
&lsa);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F,
|
||||
&lse);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
|
||||
&fdr10s);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
|
||||
&fdr10e);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
|
||||
&fdr10a);
|
||||
if (espeed_cap) {
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
|
||||
&lses);
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
|
||||
&lsea);
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_ENABLED_F,
|
||||
&lsee);
|
||||
}
|
||||
|
||||
/* Setup portid for peer port */
|
||||
memcpy(&peerportid, &portid, sizeof(peerportid));
|
||||
if (portid.lid == 0) {
|
||||
peerportid.drpath.cnt++;
|
||||
if (peerportid.drpath.cnt == IB_SUBNET_PATH_HOPS_MAX) {
|
||||
IBEXIT("Too many hops");
|
||||
}
|
||||
} else {
|
||||
peerportid.drpath.cnt = 1;
|
||||
|
||||
/* Set DrSLID to local lid */
|
||||
if (resolve_self(ibd_ca, ibd_ca_port, &selfportid,
|
||||
&selfport, 0) < 0)
|
||||
IBEXIT("could not resolve self");
|
||||
peerportid.drpath.drslid = (uint16_t) selfportid.lid;
|
||||
peerportid.drpath.drdlid = 0xffff;
|
||||
}
|
||||
peerportid.drpath.p[peerportid.drpath.cnt] = (uint8_t) portnum;
|
||||
|
||||
/* Get peer port NodeInfo to obtain peer port number */
|
||||
is_peer_switch = get_node_info(&peerportid, data);
|
||||
rem_vendorid = (uint32_t) mad_get_field(data, 0, IB_NODE_VENDORID_F);
|
||||
rem_devid = (uint16_t) mad_get_field(data, 0, IB_NODE_DEVID_F);
|
||||
|
||||
mad_decode_field(data, IB_NODE_LOCAL_PORT_F,
|
||||
&peerlocalportnum);
|
||||
|
||||
printf("Peer PortInfo:\n");
|
||||
/* Get peer port characteristics */
|
||||
peer_espeed_cap = get_port_info(&peerportid, data,
|
||||
peerlocalportnum,
|
||||
is_peer_switch);
|
||||
if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid))
|
||||
get_mlnx_ext_port_info(&peerportid, data2,
|
||||
peerlocalportnum);
|
||||
show_port_info(&peerportid, data, peerlocalportnum,
|
||||
peer_espeed_cap, is_peer_switch);
|
||||
if (is_mlnx_ext_port_info_supported(rem_vendorid, rem_devid))
|
||||
show_mlnx_ext_port_info(&peerportid, data2,
|
||||
peerlocalportnum);
|
||||
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F,
|
||||
&peerlwe);
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F,
|
||||
&peerlws);
|
||||
mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F,
|
||||
&peerlwa);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F,
|
||||
&peerlss);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F,
|
||||
&peerlsa);
|
||||
mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F,
|
||||
&peerlse);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
|
||||
&peerfdr10s);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
|
||||
&peerfdr10e);
|
||||
mad_decode_field(data2,
|
||||
IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
|
||||
&peerfdr10a);
|
||||
if (peer_espeed_cap) {
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
|
||||
&peerlses);
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
|
||||
&peerlsea);
|
||||
mad_decode_field(data,
|
||||
IB_PORT_LINK_SPEED_EXT_ENABLED_F,
|
||||
&peerlsee);
|
||||
}
|
||||
|
||||
/* Now validate peer port characteristics */
|
||||
/* Examine Link Width */
|
||||
width = get_link_width(lwe, lws);
|
||||
peerwidth = get_link_width(peerlwe, peerlws);
|
||||
validate_width(width, peerwidth, lwa);
|
||||
|
||||
/* Examine Link Speeds */
|
||||
speed = get_link_speed(lse, lss);
|
||||
peerspeed = get_link_speed(peerlse, peerlss);
|
||||
validate_speed(speed, peerspeed, lsa);
|
||||
|
||||
if (espeed_cap && peer_espeed_cap) {
|
||||
espeed = get_link_speed_ext(lsee, lses);
|
||||
peerespeed = get_link_speed_ext(peerlsee,
|
||||
peerlses);
|
||||
validate_extended_speed(espeed, peerespeed,
|
||||
lsea);
|
||||
} else {
|
||||
if (fdr10e & FDR10 && peerfdr10e & FDR10) {
|
||||
if (!(fdr10a & FDR10))
|
||||
IBWARN("Peer ports operating at active speed %d rather than FDR10", lsa);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close_port:
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+185
-192
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -33,49 +34,44 @@
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <infiniband/common.h>
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <complib/cl_nodenamemap.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
static int dest_type = IB_DEST_LID;
|
||||
static int brief;
|
||||
static int verbose;
|
||||
static int dump_all;
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
char *argv0 = "ibroute";
|
||||
static int brief, dump_all, multicast;
|
||||
|
||||
static char *node_name_map_file = NULL;
|
||||
static nn_map_t *node_name_map = NULL;
|
||||
|
||||
/*******************************************/
|
||||
|
||||
char *
|
||||
check_switch(ib_portid_t *portid, int *nports, uint64_t *guid,
|
||||
uint8_t *sw, char *nd)
|
||||
char *check_switch(ib_portid_t * portid, unsigned int *nports, uint64_t * guid,
|
||||
uint8_t * sw, char *nd)
|
||||
{
|
||||
uint8_t ni[IB_SMP_DATA_SIZE] = {0};
|
||||
uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int type;
|
||||
|
||||
DEBUG("checking node type");
|
||||
if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, 0)) {
|
||||
if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, 0, srcport)) {
|
||||
xdump(stderr, "nodeinfo\n", ni, sizeof ni);
|
||||
return "node info failed: valid addr?";
|
||||
}
|
||||
|
||||
if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, 0))
|
||||
if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, 0, srcport))
|
||||
return "node desc failed";
|
||||
|
||||
mad_decode_field(ni, IB_NODE_TYPE_F, &type);
|
||||
@@ -86,7 +82,7 @@ check_switch(ib_portid_t *portid, int *nports, uint64_t *guid,
|
||||
mad_decode_field(ni, IB_NODE_NPORTS_F, nports);
|
||||
mad_decode_field(ni, IB_NODE_GUID_F, guid);
|
||||
|
||||
if (!smp_query(sw, portid, IB_ATTR_SWITCH_INFO, 0, 0))
|
||||
if (!smp_query_via(sw, portid, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
|
||||
return "switch info failed: is a switch node?";
|
||||
|
||||
return 0;
|
||||
@@ -94,18 +90,17 @@ check_switch(ib_portid_t *portid, int *nports, uint64_t *guid,
|
||||
|
||||
#define IB_MLIDS_IN_BLOCK (IB_SMP_DATA_SIZE/2)
|
||||
|
||||
int
|
||||
dump_mlid(char *str, int strlen, int mlid, int nports,
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK])
|
||||
int dump_mlid(char *str, int strlen, unsigned mlid, unsigned nports,
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK])
|
||||
{
|
||||
uint16_t mask;
|
||||
int i, chunk, bit;
|
||||
int nonzero = 0;
|
||||
unsigned i, chunk, bit, nonzero = 0;
|
||||
|
||||
if (brief) {
|
||||
int n = 0, chunks = ALIGN(nports + 1, 16) / 16;
|
||||
int n = 0;
|
||||
unsigned chunks = ALIGN(nports + 1, 16) / 16;
|
||||
for (i = 0; i < chunks; i++) {
|
||||
mask = ntohs(mft[i][mlid%IB_MLIDS_IN_BLOCK]);
|
||||
mask = ntohs(mft[i][mlid % IB_MLIDS_IN_BLOCK]);
|
||||
if (mask)
|
||||
nonzero++;
|
||||
n += snprintf(str + n, strlen - n, "%04hx", mask);
|
||||
@@ -124,76 +119,90 @@ dump_mlid(char *str, int strlen, int mlid, int nports,
|
||||
chunk = i / 16;
|
||||
bit = i % 16;
|
||||
|
||||
mask = ntohs(mft[chunk][mlid%IB_MLIDS_IN_BLOCK]);
|
||||
mask = ntohs(mft[chunk][mlid % IB_MLIDS_IN_BLOCK]);
|
||||
if (mask)
|
||||
nonzero++;
|
||||
str[i*2] = (mask & (1 << bit)) ? 'x' : ' ';
|
||||
str[i*2+1] = ' ';
|
||||
str[i * 2] = (mask & (1 << bit)) ? 'x' : ' ';
|
||||
str[i * 2 + 1] = ' ';
|
||||
}
|
||||
if (!nonzero && !dump_all) {
|
||||
str[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
str[i*2] = 0;
|
||||
str[i * 2] = 0;
|
||||
return i * 2;
|
||||
}
|
||||
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK];
|
||||
uint16_t mft[16][IB_MLIDS_IN_BLOCK] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0}, { 0 }, { 0 } };
|
||||
|
||||
char *
|
||||
dump_multicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
char *dump_multicast_tables(ib_portid_t * portid, unsigned startlid,
|
||||
unsigned endlid)
|
||||
{
|
||||
char nd[IB_SMP_DATA_SIZE] = {0};
|
||||
uint8_t sw[IB_SMP_DATA_SIZE] = {0};
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t sw[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char str[512];
|
||||
char *s;
|
||||
uint64_t nodeguid;
|
||||
uint32_t mod;
|
||||
int block, i, j, e, nports, cap, chunks;
|
||||
int n = 0, startblock, lastblock;
|
||||
unsigned block, i, j, e, nports, cap, chunks, startblock, lastblock,
|
||||
top;
|
||||
char *mapnd = NULL;
|
||||
int n = 0;
|
||||
|
||||
if ((s = check_switch(portid, &nports, &nodeguid, sw, nd)))
|
||||
return s;
|
||||
|
||||
mad_decode_field(sw, IB_SW_MCAST_FDB_CAP_F, &cap);
|
||||
mad_decode_field(sw, IB_SW_MCAST_FDB_TOP_F, &top);
|
||||
|
||||
if (!endlid || endlid > IB_MIN_MCAST_LID + cap - 1)
|
||||
endlid = IB_MIN_MCAST_LID + cap - 1;
|
||||
if (!dump_all && top && top < endlid) {
|
||||
if (top < IB_MIN_MCAST_LID - 1)
|
||||
IBWARN("illegal top mlid %x", top);
|
||||
else
|
||||
endlid = top;
|
||||
}
|
||||
|
||||
if (!startlid)
|
||||
startlid = IB_MIN_MCAST_LID;
|
||||
|
||||
if (startlid < IB_MIN_MCAST_LID) {
|
||||
IBWARN("illegal start mlid %x, set to %x", startlid, IB_MIN_MCAST_LID);
|
||||
else if (startlid < IB_MIN_MCAST_LID) {
|
||||
IBWARN("illegal start mlid %x, set to %x", startlid,
|
||||
IB_MIN_MCAST_LID);
|
||||
startlid = IB_MIN_MCAST_LID;
|
||||
}
|
||||
|
||||
if (endlid > IB_MAX_MCAST_LID) {
|
||||
IBWARN("illegal end mlid %x, truncate to %x", endlid, IB_MAX_MCAST_LID);
|
||||
IBWARN("illegal end mlid %x, truncate to %x", endlid,
|
||||
IB_MAX_MCAST_LID);
|
||||
endlid = IB_MAX_MCAST_LID;
|
||||
}
|
||||
|
||||
printf("Multicast mlids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64 " (%s):\n",
|
||||
startlid, endlid, portid2str(portid), nodeguid, clean_nodedesc(nd));
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
printf("Multicast mlids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64
|
||||
" (%s):\n", startlid, endlid, portid2str(portid), nodeguid,
|
||||
mapnd);
|
||||
|
||||
if (brief)
|
||||
printf(" MLid Port Mask\n");
|
||||
else {
|
||||
if (nports > 9) {
|
||||
for (i = 0, s = str; i <= nports; i++) {
|
||||
*s++ = (i%10) ? ' ' : '0' + i/10;
|
||||
*s++ = (i % 10) ? ' ' : '0' + i / 10;
|
||||
*s++ = ' ';
|
||||
}
|
||||
*s = 0;
|
||||
printf(" %s\n", str);
|
||||
}
|
||||
for (i = 0, s = str; i <= nports; i++)
|
||||
s += sprintf(s, "%d ", i%10);
|
||||
s += sprintf(s, "%d ", i % 10);
|
||||
printf(" Ports: %s\n", str);
|
||||
printf(" MLid\n");
|
||||
}
|
||||
if (verbose)
|
||||
printf("Switch muticast mlids capability is 0x%d\n", cap);
|
||||
if (ibverbose)
|
||||
printf("Switch multicast mlid capability is %d top is 0x%x\n",
|
||||
cap, top);
|
||||
|
||||
chunks = ALIGN(nports + 1, 16) / 16;
|
||||
|
||||
@@ -201,11 +210,20 @@ dump_multicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
lastblock = endlid / IB_MLIDS_IN_BLOCK;
|
||||
for (block = startblock; block <= lastblock; block++) {
|
||||
for (j = 0; j < chunks; j++) {
|
||||
mod = (block - IB_MIN_MCAST_LID/IB_MLIDS_IN_BLOCK) | (j << 28);
|
||||
int status;
|
||||
mod = (block - IB_MIN_MCAST_LID / IB_MLIDS_IN_BLOCK)
|
||||
| (j << 28);
|
||||
|
||||
DEBUG("reading block %x chunk %d mod %x", block, j, mod);
|
||||
if (!smp_query(mft + j, portid, IB_ATTR_MULTICASTFORWTBL, mod, 0))
|
||||
return "multicast forwarding table get failed";
|
||||
DEBUG("reading block %x chunk %d mod %x", block, j,
|
||||
mod);
|
||||
if (!smp_query_status_via
|
||||
(mft + j, portid, IB_ATTR_MULTICASTFORWTBL, mod, 0,
|
||||
&status, srcport)) {
|
||||
fprintf(stderr, "SubnGet() failed"
|
||||
"; MAD status 0x%x AM 0x%x\n",
|
||||
status, mod);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
i = block * IB_MLIDS_IN_BLOCK;
|
||||
@@ -224,20 +242,24 @@ dump_multicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
}
|
||||
|
||||
printf("%d %smlids dumped \n", n, dump_all ? "" : "valid ");
|
||||
|
||||
free(mapnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dump_lid(char *str, int strlen, int lid, int valid)
|
||||
int dump_lid(char *str, int strlen, int lid, int valid)
|
||||
{
|
||||
char nd[IB_SMP_DATA_SIZE] = {0};
|
||||
uint8_t ni[IB_SMP_DATA_SIZE] = {0};
|
||||
uint8_t pi[IB_SMP_DATA_SIZE] = {0};
|
||||
ib_portid_t lidport = {0};
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t pi[IB_SMP_DATA_SIZE] = { 0 };
|
||||
ib_portid_t lidport = { 0 };
|
||||
static int last_port_lid, base_port_lid;
|
||||
char ntype[50], sguid[30], desc[64];
|
||||
char ntype[50], sguid[30];
|
||||
static uint64_t portguid;
|
||||
uint64_t nodeguid;
|
||||
int baselid, lmc, type;
|
||||
char *mapnd = NULL;
|
||||
int rc;
|
||||
|
||||
if (brief) {
|
||||
str[0] = 0;
|
||||
@@ -246,7 +268,8 @@ dump_lid(char *str, int strlen, int lid, int valid)
|
||||
|
||||
if (lid <= last_port_lid) {
|
||||
if (!valid)
|
||||
return snprintf(str, strlen, ": (path #%d - illegal port)",
|
||||
return snprintf(str, strlen,
|
||||
": (path #%d - illegal port)",
|
||||
lid - base_port_lid);
|
||||
else if (!portguid)
|
||||
return snprintf(str, strlen,
|
||||
@@ -258,7 +281,8 @@ dump_lid(char *str, int strlen, int lid, int valid)
|
||||
": (path #%d out of %d: portguid %s)",
|
||||
lid - base_port_lid + 1,
|
||||
last_port_lid - base_port_lid + 1,
|
||||
mad_dump_val(IB_NODE_PORT_GUID_F, sguid, sizeof sguid, &portguid));
|
||||
mad_dump_val(IB_NODE_PORT_GUID_F, sguid,
|
||||
sizeof sguid, &portguid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,11 +292,12 @@ dump_lid(char *str, int strlen, int lid, int valid)
|
||||
portguid = 0;
|
||||
lidport.lid = lid;
|
||||
|
||||
if (!smp_query(nd, &lidport, IB_ATTR_NODE_DESC, 0, 100) ||
|
||||
!smp_query(pi, &lidport, IB_ATTR_PORT_INFO, 0, 100) ||
|
||||
!smp_query(ni, &lidport, IB_ATTR_NODE_INFO, 0, 100))
|
||||
if (!smp_query_via(nd, &lidport, IB_ATTR_NODE_DESC, 0, 100, srcport) ||
|
||||
!smp_query_via(pi, &lidport, IB_ATTR_PORT_INFO, 0, 100, srcport) ||
|
||||
!smp_query_via(ni, &lidport, IB_ATTR_NODE_INFO, 0, 100, srcport))
|
||||
return snprintf(str, strlen, ": (unknown node and type)");
|
||||
|
||||
mad_decode_field(ni, IB_NODE_GUID_F, &nodeguid);
|
||||
mad_decode_field(ni, IB_NODE_PORT_GUID_F, &portguid);
|
||||
mad_decode_field(ni, IB_NODE_TYPE_F, &type);
|
||||
|
||||
@@ -284,22 +309,30 @@ dump_lid(char *str, int strlen, int lid, int valid)
|
||||
last_port_lid = baselid + (1 << lmc) - 1;
|
||||
}
|
||||
|
||||
return snprintf(str, strlen, ": (%s portguid %s: %s)",
|
||||
mad_dump_val(IB_NODE_TYPE_F, ntype, sizeof ntype, &type),
|
||||
mad_dump_val(IB_NODE_PORT_GUID_F, sguid, sizeof sguid, &portguid),
|
||||
mad_dump_val(IB_NODE_DESC_F, desc, sizeof desc, clean_nodedesc(nd)));
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
rc = snprintf(str, strlen, ": (%s portguid %s: '%s')",
|
||||
mad_dump_val(IB_NODE_TYPE_F, ntype, sizeof ntype,
|
||||
&type), mad_dump_val(IB_NODE_PORT_GUID_F,
|
||||
sguid, sizeof sguid,
|
||||
&portguid),
|
||||
mapnd);
|
||||
|
||||
free(mapnd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
char *
|
||||
dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
char *dump_unicast_tables(ib_portid_t * portid, int startlid, int endlid)
|
||||
{
|
||||
char lft[IB_SMP_DATA_SIZE];
|
||||
char nd[IB_SMP_DATA_SIZE];
|
||||
uint8_t sw[IB_SMP_DATA_SIZE];
|
||||
char lft[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t sw[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char str[200], *s;
|
||||
uint64_t nodeguid;
|
||||
int block, i, e, nports, top;
|
||||
int block, i, e, top;
|
||||
unsigned nports;
|
||||
int n = 0, startblock, endblock;
|
||||
char *mapnd = NULL;
|
||||
|
||||
if ((s = check_switch(portid, &nports, &nodeguid, sw, nd)))
|
||||
return s;
|
||||
@@ -310,12 +343,16 @@ dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
endlid = top;
|
||||
|
||||
if (endlid > IB_MAX_UCAST_LID) {
|
||||
IBWARN("ilegal lft top %d, truncate to %d", endlid, IB_MAX_UCAST_LID);
|
||||
IBWARN("illegal lft top %d, truncate to %d", endlid,
|
||||
IB_MAX_UCAST_LID);
|
||||
endlid = IB_MAX_UCAST_LID;
|
||||
}
|
||||
|
||||
printf("Unicast lids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64 " (%s):\n",
|
||||
startlid, endlid, portid2str(portid), nodeguid, clean_nodedesc(nd));
|
||||
mapnd = remap_node_name(node_name_map, nodeguid, nd);
|
||||
|
||||
printf("Unicast lids [0x%x-0x%x] of switch %s guid 0x%016" PRIx64
|
||||
" (%s):\n", startlid, endlid, portid2str(portid), nodeguid,
|
||||
mapnd);
|
||||
|
||||
DEBUG("Switch top is 0x%x\n", top);
|
||||
|
||||
@@ -323,10 +360,16 @@ dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
printf(" Port Info \n");
|
||||
startblock = startlid / IB_SMP_DATA_SIZE;
|
||||
endblock = ALIGN(endlid, IB_SMP_DATA_SIZE) / IB_SMP_DATA_SIZE;
|
||||
for (block = startblock; block <= endblock; block++) {
|
||||
for (block = startblock; block < endblock; block++) {
|
||||
int status;
|
||||
DEBUG("reading block %d", block);
|
||||
if (!smp_query(lft, portid, IB_ATTR_LINEARFORWTBL, block, 0))
|
||||
return "linear forwarding table get failed";
|
||||
if (!smp_query_status_via(lft, portid, IB_ATTR_LINEARFORWTBL, block,
|
||||
0, &status, srcport)) {
|
||||
fprintf(stderr, "SubnGet() failed"
|
||||
"; MAD status 0x%x AM 0x%x\n",
|
||||
status, block);
|
||||
return NULL;
|
||||
}
|
||||
i = block * IB_SMP_DATA_SIZE;
|
||||
e = i + IB_SMP_DATA_SIZE;
|
||||
if (i < startlid)
|
||||
@@ -334,7 +377,7 @@ dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
if (e > endlid + 1)
|
||||
e = endlid + 1;
|
||||
|
||||
for (;i < e; i++) {
|
||||
for (; i < e; i++) {
|
||||
unsigned outport = lft[i % IB_SMP_DATA_SIZE];
|
||||
unsigned valid = (outport <= nports);
|
||||
|
||||
@@ -347,141 +390,89 @@ dump_unicast_tables(ib_portid_t *portid, int startlid, int endlid)
|
||||
}
|
||||
|
||||
printf("%d %slids dumped \n", n, dump_all ? "" : "valid ");
|
||||
free(mapnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
char *basename;
|
||||
|
||||
if (!(basename = strrchr(argv0, '/')))
|
||||
basename = argv0;
|
||||
else
|
||||
basename++;
|
||||
|
||||
fprintf(stderr, "Usage: %s [-d(ebug)] -a(ll) -n(o_dests) -v(erbose) -D(irect) -G(uid) -M(ulticast) -s smlid -V(ersion) -C ca_name -P ca_port "
|
||||
"-t(imeout) timeout_ms] [<dest dr_path|lid|guid> [<startlid> [<endlid>]]]\n",
|
||||
basename);
|
||||
fprintf(stderr, "\n\tUnicast examples:\n");
|
||||
fprintf(stderr, "\t\t%s 4\t# dump all lids with valid out ports of switch with lid 4\n", basename);
|
||||
fprintf(stderr, "\t\t%s -a 4\t# same, but dump all lids, even with invalid out ports\n", basename);
|
||||
fprintf(stderr, "\t\t%s -n 4\t# simple dump format - no destination resolving\n", basename);
|
||||
fprintf(stderr, "\t\t%s 4 10\t# dump lids starting from 10\n", basename);
|
||||
fprintf(stderr, "\t\t%s 4 0x10 0x20\t# dump lid range\n", basename);
|
||||
fprintf(stderr, "\t\t%s -G 0x08f1040023\t# resolve switch by GUID\n", basename);
|
||||
fprintf(stderr, "\t\t%s -D 0,1\t# resolve switch by direct path\n", basename);
|
||||
|
||||
fprintf(stderr, "\n\tMulticast examples:\n");
|
||||
fprintf(stderr, "\t\t%s -M 4\t# dump all non empty mlids of switch with lid 4\n", basename);
|
||||
fprintf(stderr, "\t\t%s -M 4 0xc010 0xc020\t# same, but with range\n", basename);
|
||||
fprintf(stderr, "\t\t%s -M -n 4\t# simple dump format\n", basename);
|
||||
exit(-1);
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
dump_all++;
|
||||
break;
|
||||
case 'M':
|
||||
multicast++;
|
||||
break;
|
||||
case 'n':
|
||||
brief++;
|
||||
break;
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
|
||||
ib_portid_t portid = {0};
|
||||
ib_portid_t *sm_id = 0, sm_portid = {0};
|
||||
int timeout;
|
||||
int multicast = 0, startlid = 0, endlid = 0;
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
unsigned startlid = 0, endlid = 0;
|
||||
char *err;
|
||||
char *ca = 0;
|
||||
int ca_port = 0;
|
||||
|
||||
static char const str_opts[] = "C:P:t:s:danvDGMVhu";
|
||||
static const struct option long_opts[] = {
|
||||
{ "C", 1, 0, 'C'},
|
||||
{ "P", 1, 0, 'P'},
|
||||
{ "debug", 0, 0, 'd'},
|
||||
{ "all", 0, 0, 'a'},
|
||||
{ "no_dests", 0, 0, 'n'},
|
||||
{ "verbose", 0, 0, 'v'},
|
||||
{ "Direct", 0, 0, 'D'},
|
||||
{ "Guid", 0, 0, 'G'},
|
||||
{ "Multicast", 0, 0, 'M'},
|
||||
{ "timeout", 1, 0, 't'},
|
||||
{ "s", 1, 0, 's'},
|
||||
{ "Version", 0, 0, 'V'},
|
||||
{ "help", 0, 0, 'h'},
|
||||
{ "usage", 0, 0, 'u'},
|
||||
{ }
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"all", 'a', 0, NULL, "show all lids, even invalid entries"},
|
||||
{"no_dests", 'n', 0, NULL,
|
||||
"do not try to resolve destinations"},
|
||||
{"Multicast", 'M', 0, NULL, "show multicast forwarding tables"},
|
||||
{"node-name-map", 1, 1, "<file>", "node name map file"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "[<dest dr_path|lid|guid> [<startlid> [<endlid>]]]";
|
||||
const char *usage_examples[] = {
|
||||
" -- Unicast examples:",
|
||||
"4\t# dump all lids with valid out ports of switch with lid 4",
|
||||
"-a 4\t# same, but dump all lids, even with invalid out ports",
|
||||
"-n 4\t# simple dump format - no destination resolving",
|
||||
"4 10\t# dump lids starting from 10",
|
||||
"4 0x10 0x20\t# dump lid range",
|
||||
"-G 0x08f1040023\t# resolve switch by GUID",
|
||||
"-D 0,1\t# resolve switch by direct path",
|
||||
" -- Multicast examples:",
|
||||
"-M 4\t# dump all non empty mlids of switch with lid 4",
|
||||
"-M 4 0xc010 0xc020\t# same, but with range",
|
||||
"-M -n 4\t# simple dump format",
|
||||
NULL,
|
||||
};
|
||||
|
||||
argv0 = argv[0];
|
||||
ibdiag_process_opts(argc, argv, NULL, "K", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
while (1) {
|
||||
int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
|
||||
if ( ch == -1 )
|
||||
break;
|
||||
switch(ch) {
|
||||
case 'C':
|
||||
ca = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
ca_port = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'a':
|
||||
dump_all++;
|
||||
break;
|
||||
case 'd':
|
||||
ibdebug++;
|
||||
break;
|
||||
case 'D':
|
||||
dest_type = IB_DEST_DRPATH;
|
||||
break;
|
||||
case 'G':
|
||||
dest_type = IB_DEST_GUID;
|
||||
break;
|
||||
case 'M':
|
||||
multicast++;
|
||||
break;
|
||||
case 'n':
|
||||
brief++;
|
||||
break;
|
||||
case 's':
|
||||
if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)
|
||||
IBERROR("can't resolve SM destination port %s", optarg);
|
||||
sm_id = &sm_portid;
|
||||
break;
|
||||
case 't':
|
||||
timeout = strtoul(optarg, 0, 0);
|
||||
madrpc_set_timeout(timeout);
|
||||
break;
|
||||
case 'v':
|
||||
madrpc_show_errors(1);
|
||||
verbose++;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "%s %s\n", argv0, get_build_version() );
|
||||
exit(-1);
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!argc)
|
||||
usage();
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (argc > 1)
|
||||
startlid = strtoul(argv[1], 0, 0);
|
||||
if (argc > 2)
|
||||
endlid = strtoul(argv[2], 0, 0);
|
||||
|
||||
madrpc_init(ca, ca_port, mgmt_classes, 3);
|
||||
node_name_map = open_node_name_map(node_name_map_file);
|
||||
|
||||
if (!argc) {
|
||||
if (ib_resolve_self(&portid, 0, 0) < 0)
|
||||
IBERROR("can't resolve self addr");
|
||||
} else {
|
||||
if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)
|
||||
IBERROR("can't resolve destination port %s", argv[1]);
|
||||
}
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
|
||||
if (multicast)
|
||||
err = dump_multicast_tables(&portid, startlid, endlid);
|
||||
@@ -489,7 +480,9 @@ main(int argc, char **argv)
|
||||
err = dump_unicast_tables(&portid, startlid, endlid);
|
||||
|
||||
if (err)
|
||||
IBERROR("dump tables: %s", err);
|
||||
IBEXIT("dump tables: %s", err);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
close_node_name_map(node_name_map);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Lawrence Livermore National Security
|
||||
* Copyright (c) 2008-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* Produced at Lawrence Livermore National Laboratory.
|
||||
* Written by Ira Weiny <weiny2@llnl.gov>.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
#include <iba/ib_types.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
/* for local link integrity */
|
||||
int error_port = 1;
|
||||
|
||||
static uint16_t get_node_type(ib_portid_t * port)
|
||||
{
|
||||
uint16_t node_type = IB_NODE_TYPE_CA;
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
|
||||
if (smp_query_via(data, port, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
node_type = (uint16_t) mad_get_field(data, 0, IB_NODE_TYPE_F);
|
||||
return node_type;
|
||||
}
|
||||
|
||||
static uint32_t get_cap_mask(ib_portid_t * port)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint32_t cap_mask = 0;
|
||||
|
||||
if (smp_query_via(data, port, IB_ATTR_PORT_INFO, 0, 0, srcport))
|
||||
cap_mask = (uint32_t) mad_get_field(data, 0, IB_PORT_CAPMASK_F);
|
||||
return cap_mask;
|
||||
}
|
||||
|
||||
static void build_trap145(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
|
||||
n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
|
||||
n->g_or_v.generic.trap_num = cl_hton16(145);
|
||||
n->issuer_lid = cl_hton16((uint16_t) port->lid);
|
||||
n->data_details.ntc_145.new_sys_guid = cl_hton64(0x1234567812345678);
|
||||
}
|
||||
|
||||
static void build_trap144_local(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
|
||||
n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
|
||||
n->g_or_v.generic.trap_num = cl_hton16(144);
|
||||
n->issuer_lid = cl_hton16((uint16_t) port->lid);
|
||||
n->data_details.ntc_144.lid = n->issuer_lid;
|
||||
n->data_details.ntc_144.new_cap_mask = cl_hton32(get_cap_mask(port));
|
||||
n->data_details.ntc_144.local_changes =
|
||||
TRAP_144_MASK_OTHER_LOCAL_CHANGES;
|
||||
}
|
||||
|
||||
static void build_trap144_nodedesc(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
build_trap144_local(n, port);
|
||||
n->data_details.ntc_144.change_flgs =
|
||||
TRAP_144_MASK_NODE_DESCRIPTION_CHANGE;
|
||||
}
|
||||
|
||||
static void build_trap144_linkspeed(ib_mad_notice_attr_t * n,
|
||||
ib_portid_t * port)
|
||||
{
|
||||
build_trap144_local(n, port);
|
||||
n->data_details.ntc_144.change_flgs =
|
||||
TRAP_144_MASK_LINK_SPEED_ENABLE_CHANGE;
|
||||
}
|
||||
|
||||
static void build_trap129(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
n->generic_type = 0x80 | IB_NOTICE_TYPE_URGENT;
|
||||
n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
|
||||
n->g_or_v.generic.trap_num = cl_hton16(129);
|
||||
n->issuer_lid = cl_hton16((uint16_t) port->lid);
|
||||
n->data_details.ntc_129_131.lid = n->issuer_lid;
|
||||
n->data_details.ntc_129_131.pad = 0;
|
||||
n->data_details.ntc_129_131.port_num = (uint8_t) error_port;
|
||||
}
|
||||
|
||||
static void build_trap256_local(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
n->generic_type = 0x80 | IB_NOTICE_TYPE_SECURITY;
|
||||
n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
|
||||
n->g_or_v.generic.trap_num = cl_hton16(256);
|
||||
n->issuer_lid = cl_hton16((uint16_t) port->lid);
|
||||
n->data_details.ntc_256.lid = n->issuer_lid;
|
||||
n->data_details.ntc_256.dr_slid = 0xffff;
|
||||
n->data_details.ntc_256.method = 1;
|
||||
n->data_details.ntc_256.attr_id = cl_ntoh16(0x15);
|
||||
n->data_details.ntc_256.attr_mod = cl_ntoh32(0x12);
|
||||
n->data_details.ntc_256.mkey = cl_ntoh64(0x1234567812345678);
|
||||
}
|
||||
|
||||
static void build_trap256_lid(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
build_trap256_local(n, port);
|
||||
n->data_details.ntc_256.dr_trunc_hop = 0;
|
||||
}
|
||||
|
||||
static void build_trap256_dr(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
build_trap256_local(n, port);
|
||||
n->data_details.ntc_256.dr_trunc_hop = 0x80 | 0x4;
|
||||
n->data_details.ntc_256.dr_rtn_path[0] = 5;
|
||||
n->data_details.ntc_256.dr_rtn_path[1] = 6;
|
||||
n->data_details.ntc_256.dr_rtn_path[2] = 7;
|
||||
n->data_details.ntc_256.dr_rtn_path[3] = 8;
|
||||
}
|
||||
|
||||
static void build_trap257_258(ib_mad_notice_attr_t * n, ib_portid_t * port,
|
||||
uint16_t trap_num)
|
||||
{
|
||||
n->generic_type = 0x80 | IB_NOTICE_TYPE_SECURITY;
|
||||
n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
|
||||
n->g_or_v.generic.trap_num = cl_hton16(trap_num);
|
||||
n->issuer_lid = cl_hton16((uint16_t) port->lid);
|
||||
n->data_details.ntc_257_258.lid1 = cl_hton16(1);
|
||||
n->data_details.ntc_257_258.lid2 = cl_hton16(2);
|
||||
n->data_details.ntc_257_258.key = cl_hton32(0x12345678);
|
||||
n->data_details.ntc_257_258.qp1 = cl_hton32(0x010101);
|
||||
n->data_details.ntc_257_258.qp2 = cl_hton32(0x020202);
|
||||
n->data_details.ntc_257_258.gid1.unicast.prefix = cl_ntoh64(0xf8c0000000000001);
|
||||
n->data_details.ntc_257_258.gid1.unicast.interface_id = cl_ntoh64(0x1111222233334444);
|
||||
n->data_details.ntc_257_258.gid2.unicast.prefix = cl_ntoh64(0xf8c0000000000001);
|
||||
n->data_details.ntc_257_258.gid2.unicast.interface_id = cl_ntoh64(0x5678567812341234);
|
||||
}
|
||||
|
||||
static void build_trap257(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
build_trap257_258(n, port, 257);
|
||||
}
|
||||
|
||||
static void build_trap258(ib_mad_notice_attr_t * n, ib_portid_t * port)
|
||||
{
|
||||
build_trap257_258(n, port, 258);
|
||||
}
|
||||
|
||||
static int send_trap(void (*build) (ib_mad_notice_attr_t *, ib_portid_t *))
|
||||
{
|
||||
ib_portid_t sm_port;
|
||||
ib_portid_t selfportid;
|
||||
int selfport;
|
||||
ib_rpc_t trap_rpc;
|
||||
ib_mad_notice_attr_t notice;
|
||||
|
||||
if (resolve_self(ibd_ca, ibd_ca_port, &selfportid, &selfport, NULL))
|
||||
IBEXIT("can't resolve self");
|
||||
|
||||
if (resolve_sm_portid(ibd_ca, ibd_ca_port, &sm_port))
|
||||
IBEXIT("can't resolve SM destination port");
|
||||
|
||||
memset(&trap_rpc, 0, sizeof(trap_rpc));
|
||||
trap_rpc.mgtclass = IB_SMI_CLASS;
|
||||
trap_rpc.method = IB_MAD_METHOD_TRAP;
|
||||
trap_rpc.trid = mad_trid();
|
||||
trap_rpc.attr.id = NOTICE;
|
||||
trap_rpc.datasz = IB_SMP_DATA_SIZE;
|
||||
trap_rpc.dataoffs = IB_SMP_DATA_OFFS;
|
||||
|
||||
memset(¬ice, 0, sizeof(notice));
|
||||
build(¬ice, &selfportid);
|
||||
|
||||
return mad_send_via(&trap_rpc, &sm_port, NULL, ¬ice, srcport);
|
||||
}
|
||||
|
||||
typedef struct _trap_def {
|
||||
char *trap_name;
|
||||
void (*build_func) (ib_mad_notice_attr_t *, ib_portid_t *);
|
||||
} trap_def_t;
|
||||
|
||||
static const trap_def_t traps[] = {
|
||||
{"node_desc_change", build_trap144_nodedesc},
|
||||
{"link_speed_enabled_change", build_trap144_linkspeed},
|
||||
{"local_link_integrity", build_trap129},
|
||||
{"sys_image_guid_change", build_trap145},
|
||||
{"mkey_lid", build_trap256_lid},
|
||||
{"mkey_dr", build_trap256_dr},
|
||||
{"pkey", build_trap257},
|
||||
{"qkey", build_trap258},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int process_send_trap(char *trap_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; traps[i].trap_name; i++)
|
||||
if (strcmp(traps[i].trap_name, trap_name) == 0)
|
||||
return send_trap(traps[i].build_func);
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char usage_args[1024];
|
||||
int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
|
||||
char *trap_name = NULL;
|
||||
int i, n, rc;
|
||||
|
||||
n = sprintf(usage_args, "[<trap_name>] [<error_port>]\n"
|
||||
"\nArgument <trap_name> can be one of the following:\n");
|
||||
for (i = 0; traps[i].trap_name; i++) {
|
||||
n += snprintf(usage_args + n, sizeof(usage_args) - n,
|
||||
" %s\n", traps[i].trap_name);
|
||||
if (n >= sizeof(usage_args))
|
||||
exit(-1);
|
||||
}
|
||||
snprintf(usage_args + n, sizeof(usage_args) - n,
|
||||
"\n default behavior is to send \"%s\"", traps[0].trap_name);
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DGKL", NULL, NULL,
|
||||
usage_args, NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
trap_name = argv[0] ? argv[0] : traps[0].trap_name;
|
||||
|
||||
if (argc > 1)
|
||||
error_port = atoi(argv[1]);
|
||||
|
||||
madrpc_show_errors(1);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
rc = process_send_trap(trap_name);
|
||||
mad_rpc_close_port(srcport);
|
||||
return rc;
|
||||
}
|
||||
+141
-98
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -35,38 +36,23 @@
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#include <sys/poll.h>
|
||||
#include <syslog.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <infiniband/common.h>
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include <ibdiag_common.h>
|
||||
|
||||
static int debug;
|
||||
|
||||
char *argv0 = "ibstat";
|
||||
|
||||
static char *node_type_str[] = {
|
||||
"???",
|
||||
"CA",
|
||||
@@ -75,18 +61,24 @@ static char *node_type_str[] = {
|
||||
"iWARP RNIC"
|
||||
};
|
||||
|
||||
static void
|
||||
ca_dump(umad_ca_t *ca)
|
||||
static void ca_dump(umad_ca_t * ca)
|
||||
{
|
||||
if (!ca->node_type)
|
||||
return;
|
||||
printf("%s '%s'\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"), ca->ca_name);
|
||||
printf("\t%s type: %s\n", ((uint)ca->node_type <= IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),ca->ca_type);
|
||||
printf("%s '%s'\n",
|
||||
((unsigned)ca->node_type <=
|
||||
IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),
|
||||
ca->ca_name);
|
||||
printf("\t%s type: %s\n",
|
||||
((unsigned)ca->node_type <=
|
||||
IB_NODE_MAX ? node_type_str[ca->node_type] : "???"),
|
||||
ca->ca_type);
|
||||
printf("\tNumber of ports: %d\n", ca->numports);
|
||||
printf("\tFirmware version: %s\n", ca->fw_ver);
|
||||
printf("\tHardware version: %s\n", ca->hw_ver);
|
||||
printf("\tNode GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->node_guid));
|
||||
printf("\tSystem image GUID: 0x%016llx\n", (long long unsigned)ntohll(ca->system_guid));
|
||||
printf("\tNode GUID: 0x%016" PRIx64 "\n", ntohll(ca->node_guid));
|
||||
printf("\tSystem image GUID: 0x%016" PRIx64 "\n",
|
||||
ntohll(ca->system_guid));
|
||||
}
|
||||
|
||||
static char *port_state_str[] = {
|
||||
@@ -108,8 +100,63 @@ static char *port_phy_state_str[] = {
|
||||
"PhyTest"
|
||||
};
|
||||
|
||||
static int
|
||||
port_dump(umad_port_t *port, int alone)
|
||||
static int ret_code(void)
|
||||
{
|
||||
int e = errno;
|
||||
|
||||
if (e > 0)
|
||||
return -e;
|
||||
return e;
|
||||
}
|
||||
|
||||
int sys_read_string(const char *dir_name, const char *file_name, char *str, int max_len)
|
||||
{
|
||||
char path[256], *s;
|
||||
size_t len;
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", dir_name, file_name);
|
||||
|
||||
for (s = &path[0]; *s != '\0'; s++)
|
||||
if (*s == '/')
|
||||
*s = '.';
|
||||
|
||||
len = max_len;
|
||||
if (sysctlbyname(&path[1], str, &len, NULL, 0) == -1)
|
||||
return ret_code();
|
||||
|
||||
str[(len < max_len) ? len : max_len - 1] = 0;
|
||||
|
||||
if ((s = strrchr(str, '\n')))
|
||||
*s = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_fdr10(umad_port_t *port)
|
||||
{
|
||||
char port_dir[256];
|
||||
char rate[32];
|
||||
int len, fdr10 = 0;
|
||||
char *p;
|
||||
|
||||
len = snprintf(port_dir, sizeof(port_dir), "%s/%s/%s/%d",
|
||||
SYS_INFINIBAND, port->ca_name, SYS_CA_PORTS_DIR,
|
||||
port->portnum);
|
||||
if (len < 0 || len > sizeof(port_dir))
|
||||
goto done;
|
||||
|
||||
if (sys_read_string(port_dir, SYS_PORT_RATE, rate, sizeof(rate)) == 0) {
|
||||
if ((p = strchr(rate, ')'))) {
|
||||
if (!strncasecmp(p - 5, "fdr10", 5))
|
||||
fdr10 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return fdr10;
|
||||
}
|
||||
|
||||
static int port_dump(umad_port_t * port, int alone)
|
||||
{
|
||||
char *pre = "";
|
||||
char *hdrpre = "";
|
||||
@@ -123,19 +170,31 @@ port_dump(umad_port_t *port, int alone)
|
||||
}
|
||||
|
||||
printf("%sPort %d:\n", hdrpre, port->portnum);
|
||||
printf("%sState: %s\n", pre, (uint)port->state <= 4 ? port_state_str[port->state] : "???");
|
||||
printf("%sPhysical state: %s\n", pre, (uint)port->state <= 7 ? port_phy_state_str[port->phys_state] : "???");
|
||||
printf("%sRate: %d\n", pre, port->rate);
|
||||
printf("%sState: %s\n", pre,
|
||||
(unsigned)port->state <=
|
||||
4 ? port_state_str[port->state] : "???");
|
||||
printf("%sPhysical state: %s\n", pre,
|
||||
(unsigned)port->phys_state <=
|
||||
7 ? port_phy_state_str[port->phys_state] : "???");
|
||||
if (is_fdr10(port))
|
||||
printf("%sRate: %d (FDR10)\n", pre, port->rate);
|
||||
else
|
||||
if (port->rate != 2)
|
||||
printf("%sRate: %d\n", pre, port->rate);
|
||||
else
|
||||
printf("%sRate: 2.5\n", pre);
|
||||
printf("%sBase lid: %d\n", pre, port->base_lid);
|
||||
printf("%sLMC: %d\n", pre, port->lmc);
|
||||
printf("%sSM lid: %d\n", pre, port->sm_lid);
|
||||
printf("%sCapability mask: 0x%08x\n", pre, (unsigned)ntohl(port->capmask));
|
||||
printf("%sPort GUID: 0x%016llx\n", pre, (long long unsigned)ntohll(port->port_guid));
|
||||
printf("%sCapability mask: 0x%08x\n", pre, ntohl(port->capmask));
|
||||
printf("%sPort GUID: 0x%016" PRIx64 "\n", pre, ntohll(port->port_guid));
|
||||
#ifdef HAVE_UMAD_PORT_LINK_LAYER
|
||||
printf("%sLink layer: %s\n", pre, port->link_layer);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ca_stat(char *ca_name, int portnum, int no_ports)
|
||||
static int ca_stat(char *ca_name, int portnum, int no_ports)
|
||||
{
|
||||
umad_ca_t ca;
|
||||
int r;
|
||||
@@ -149,11 +208,15 @@ ca_stat(char *ca_name, int portnum, int no_ports)
|
||||
if (!no_ports && portnum >= 0) {
|
||||
if (portnum > ca.numports || !ca.ports[portnum]) {
|
||||
IBWARN("%s: '%s' has no port number %d - max (%d)",
|
||||
((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"),
|
||||
ca_name, portnum, ca.numports);
|
||||
((unsigned)ca.node_type <=
|
||||
IB_NODE_MAX ? node_type_str[ca.node_type] :
|
||||
"???"), ca_name, portnum, ca.numports);
|
||||
return -1;
|
||||
}
|
||||
printf("%s: '%s'\n", ((uint)ca.node_type <= IB_NODE_MAX ? node_type_str[ca.node_type] : "???"), ca.ca_name);
|
||||
printf("%s: '%s'\n",
|
||||
((unsigned)ca.node_type <=
|
||||
IB_NODE_MAX ? node_type_str[ca.node_type] : "???"),
|
||||
ca.ca_name);
|
||||
port_dump(ca.ports[portnum], 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -170,81 +233,67 @@ ca_stat(char *ca_name, int portnum, int no_ports)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ports_list(char names[][UMAD_CA_NAME_LEN], int n)
|
||||
static int ports_list(char names[][UMAD_CA_NAME_LEN], int n)
|
||||
{
|
||||
uint64_t guids[64];
|
||||
int found, ports, i;
|
||||
|
||||
for (i = 0, found = 0; i < n && found < 64; i++) {
|
||||
if ((ports = umad_get_ca_portguids(names[i], guids + found, 64 - found)) < 0)
|
||||
if ((ports =
|
||||
umad_get_ca_portguids(names[i], guids + found,
|
||||
64 - found)) < 0)
|
||||
return -1;
|
||||
found += ports;
|
||||
}
|
||||
|
||||
for (i = 0; i < found; i++)
|
||||
if (guids[i])
|
||||
printf("0x%016llx\n", (long long unsigned)ntohll(guids[i]));
|
||||
printf("0x%016" PRIx64 "\n", ntohll(guids[i]));
|
||||
return found;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
static int list_only, short_format, list_ports;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d(ebug) -l(ist_of_cas) -s(hort) -p(ort_list) -V(ersion)] <ca_name> [portnum]\n", argv0);
|
||||
fprintf(stderr, "\tExamples:\n");
|
||||
fprintf(stderr, "\t\t%s -l # list all IB devices\n", argv0);
|
||||
fprintf(stderr, "\t\t%s mthca0 2 # stat port 2 of 'mthca0'\n", argv0);
|
||||
exit(-1);
|
||||
switch (ch) {
|
||||
case 'l':
|
||||
list_only++;
|
||||
break;
|
||||
case 's':
|
||||
short_format++;
|
||||
break;
|
||||
case 'p':
|
||||
list_ports++;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char names[UMAD_MAX_DEVICES][UMAD_CA_NAME_LEN];
|
||||
int dev_port = -1;
|
||||
int list_only = 0, short_format = 0, list_ports = 0;
|
||||
int n, i;
|
||||
|
||||
static char const str_opts[] = "dlspVhu";
|
||||
static const struct option long_opts[] = {
|
||||
{ "debug", 0, 0, 'd'},
|
||||
{ "list_of_cas", 0, 0, 'l'},
|
||||
{ "short", 0, 0, 's'},
|
||||
{ "port_list", 0, 0, 'p'},
|
||||
{ "Version", 0, 0, 'V'},
|
||||
{ "help", 0, 0, 'h'},
|
||||
{ "usage", 0, 0, 'u'},
|
||||
{ }
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"list_of_cas", 'l', 0, NULL, "list all IB devices"},
|
||||
{"short", 's', 0, NULL, "short output"},
|
||||
{"port_list", 'p', 0, NULL, "show port list"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<ca_name> [portnum]";
|
||||
const char *usage_examples[] = {
|
||||
"-l # list all IB devices",
|
||||
"mthca0 2 # stat port 2 of 'mthca0'",
|
||||
NULL
|
||||
};
|
||||
|
||||
argv0 = argv[0];
|
||||
ibdiag_process_opts(argc, argv, NULL, "CDeGKLPsty", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
while (1) {
|
||||
int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
|
||||
if ( ch == -1 )
|
||||
break;
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
case 'l':
|
||||
list_only++;
|
||||
break;
|
||||
case 's':
|
||||
short_format++;
|
||||
break;
|
||||
case 'p':
|
||||
list_ports++;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "%s %s\n", argv0, get_build_version() );
|
||||
exit(-1);
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
@@ -264,7 +313,8 @@ main(int argc, char *argv[])
|
||||
if (i >= n)
|
||||
IBPANIC("'%s' IB device can't be found", argv[0]);
|
||||
|
||||
strncpy(names[i], argv[0], sizeof names[i]);
|
||||
strncpy(names[0], argv[0], sizeof(names[0])-1);
|
||||
names[0][sizeof(names[0])-1] = '\0';
|
||||
n = 1;
|
||||
}
|
||||
|
||||
@@ -274,18 +324,11 @@ main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!list_only && argc) {
|
||||
if (ca_stat(argv[0], dev_port, short_format) < 0)
|
||||
IBPANIC("stat of IB device '%s' failed", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (list_only)
|
||||
printf("%s\n", names[i]);
|
||||
else
|
||||
if (ca_stat(names[i], -1, short_format) < 0)
|
||||
IBPANIC("stat of IB device '%s' failed", names[i]);
|
||||
else if (ca_stat(names[i], dev_port, short_format) < 0)
|
||||
IBPANIC("stat of IB device '%s' failed", names[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define MAX_CPUS 8
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static ibmad_gid_t dgid;
|
||||
static int with_grh;
|
||||
|
||||
enum ib_sysstat_attr_t {
|
||||
IB_PING_ATTR = 0x10,
|
||||
IB_HOSTINFO_ATTR = 0x11,
|
||||
IB_CPUINFO_ATTR = 0x12,
|
||||
};
|
||||
|
||||
typedef struct cpu_info {
|
||||
char *model;
|
||||
char *mhz;
|
||||
} cpu_info;
|
||||
|
||||
static cpu_info cpus[MAX_CPUS];
|
||||
static int host_ncpu;
|
||||
static int server = 0, oui = IB_OPENIB_OUI;
|
||||
|
||||
static int server_respond(void *umad, int size)
|
||||
{
|
||||
ib_rpc_t rpc = { 0 };
|
||||
ib_rmpp_hdr_t rmpp = { 0 };
|
||||
ib_portid_t rport;
|
||||
uint8_t *mad = umad_get_mad(umad);
|
||||
ib_mad_addr_t *mad_addr;
|
||||
|
||||
if (!(mad_addr = umad_get_mad_addr(umad)))
|
||||
return -1;
|
||||
|
||||
memset(&rport, 0, sizeof(rport));
|
||||
|
||||
rport.lid = ntohs(mad_addr->lid);
|
||||
rport.qp = ntohl(mad_addr->qpn);
|
||||
rport.qkey = ntohl(mad_addr->qkey);
|
||||
rport.sl = mad_addr->sl;
|
||||
if (!rport.qkey && rport.qp == 1)
|
||||
rport.qkey = IB_DEFAULT_QP1_QKEY;
|
||||
rport.grh_present = mad_addr->grh_present;
|
||||
if (rport.grh_present)
|
||||
memcpy(rport.gid, mad_addr->gid, 16);
|
||||
|
||||
rpc.mgtclass = mad_get_field(mad, 0, IB_MAD_MGMTCLASS_F);
|
||||
rpc.method = IB_MAD_METHOD_GET | IB_MAD_RESPONSE;
|
||||
rpc.attr.id = mad_get_field(mad, 0, IB_MAD_ATTRID_F);
|
||||
rpc.attr.mod = mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);
|
||||
rpc.oui = mad_get_field(mad, 0, IB_VEND2_OUI_F);
|
||||
rpc.trid = mad_get_field64(mad, 0, IB_MAD_TRID_F);
|
||||
|
||||
if (size > IB_MAD_SIZE)
|
||||
rmpp.flags = IB_RMPP_FLAG_ACTIVE;
|
||||
|
||||
DEBUG("responding %d bytes to %s, attr 0x%x mod 0x%x qkey %x",
|
||||
size, portid2str(&rport), rpc.attr.id, rpc.attr.mod, rport.qkey);
|
||||
|
||||
if (mad_build_pkt(umad, &rpc, &rport, &rmpp, 0) < 0)
|
||||
return -1;
|
||||
|
||||
if (ibdebug > 1)
|
||||
xdump(stderr, "mad respond pkt\n", mad, IB_MAD_SIZE);
|
||||
|
||||
if (umad_send(mad_rpc_portid(srcport),
|
||||
mad_rpc_class_agent(srcport, rpc.mgtclass), umad, size,
|
||||
rpc.timeout, 0) < 0) {
|
||||
DEBUG("send failed; %m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mk_reply(int attr, void *data, int sz)
|
||||
{
|
||||
char *s = data;
|
||||
int n, i, ret = 0;
|
||||
|
||||
switch (attr) {
|
||||
case IB_PING_ATTR:
|
||||
break; /* nothing to do here, just reply */
|
||||
case IB_HOSTINFO_ATTR:
|
||||
if (gethostname(s, sz) < 0)
|
||||
snprintf(s, sz, "?hostname?");
|
||||
s[sz - 1] = 0;
|
||||
if ((n = strlen(s)) >= sz - 1) {
|
||||
ret = sz;
|
||||
break;
|
||||
}
|
||||
s[n] = '.';
|
||||
s += n + 1;
|
||||
sz -= n + 1;
|
||||
ret += n + 1;
|
||||
if (getdomainname(s, sz) < 0)
|
||||
snprintf(s, sz, "?domainname?");
|
||||
if ((n = strlen(s)) == 0)
|
||||
s[-1] = 0; /* no domain */
|
||||
else
|
||||
ret += n;
|
||||
break;
|
||||
case IB_CPUINFO_ATTR:
|
||||
s[0] = '\0';
|
||||
for (i = 0; i < host_ncpu && sz > 0; i++) {
|
||||
n = snprintf(s, sz, "cpu %d: model %s MHZ %s\n",
|
||||
i, cpus[i].model, cpus[i].mhz);
|
||||
if (n >= sz) {
|
||||
IBWARN("cpuinfo truncated");
|
||||
ret = sz;
|
||||
break;
|
||||
}
|
||||
sz -= n;
|
||||
s += n;
|
||||
ret += n;
|
||||
}
|
||||
ret++;
|
||||
break;
|
||||
default:
|
||||
DEBUG("unknown attr %d", attr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t buf[2048];
|
||||
|
||||
static char *ibsystat_serv(void)
|
||||
{
|
||||
void *umad;
|
||||
void *mad;
|
||||
int attr, mod, size;
|
||||
|
||||
DEBUG("starting to serve...");
|
||||
|
||||
while ((umad = mad_receive_via(buf, -1, srcport))) {
|
||||
if (umad_status(buf)) {
|
||||
DEBUG("drop mad with status %x: %s", umad_status(buf),
|
||||
strerror(umad_status(buf)));
|
||||
continue;
|
||||
}
|
||||
|
||||
mad = umad_get_mad(umad);
|
||||
|
||||
attr = mad_get_field(mad, 0, IB_MAD_ATTRID_F);
|
||||
mod = mad_get_field(mad, 0, IB_MAD_ATTRMOD_F);
|
||||
|
||||
DEBUG("got packet: attr 0x%x mod 0x%x", attr, mod);
|
||||
|
||||
size =
|
||||
mk_reply(attr, (uint8_t *) mad + IB_VENDOR_RANGE2_DATA_OFFS,
|
||||
sizeof(buf) - umad_size() -
|
||||
IB_VENDOR_RANGE2_DATA_OFFS);
|
||||
|
||||
if (server_respond(umad, IB_VENDOR_RANGE2_DATA_OFFS + size) < 0)
|
||||
DEBUG("respond failed");
|
||||
}
|
||||
|
||||
DEBUG("server out");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int match_attr(char *str)
|
||||
{
|
||||
if (!strcmp(str, "ping"))
|
||||
return IB_PING_ATTR;
|
||||
if (!strcmp(str, "host"))
|
||||
return IB_HOSTINFO_ATTR;
|
||||
if (!strcmp(str, "cpu"))
|
||||
return IB_CPUINFO_ATTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *ibsystat(ib_portid_t * portid, int attr)
|
||||
{
|
||||
ib_rpc_t rpc = { 0 };
|
||||
int fd, agent, timeout, len;
|
||||
void *data = (uint8_t *) umad_get_mad(buf) + IB_VENDOR_RANGE2_DATA_OFFS;
|
||||
|
||||
DEBUG("Sysstat ping..");
|
||||
|
||||
rpc.mgtclass = IB_VENDOR_OPENIB_SYSSTAT_CLASS;
|
||||
rpc.method = IB_MAD_METHOD_GET;
|
||||
rpc.attr.id = attr;
|
||||
rpc.attr.mod = 0;
|
||||
rpc.oui = oui;
|
||||
rpc.timeout = 0;
|
||||
rpc.datasz = IB_VENDOR_RANGE2_DATA_SIZE;
|
||||
rpc.dataoffs = IB_VENDOR_RANGE2_DATA_OFFS;
|
||||
|
||||
portid->qp = 1;
|
||||
if (!portid->qkey)
|
||||
portid->qkey = IB_DEFAULT_QP1_QKEY;
|
||||
|
||||
if ((len = mad_build_pkt(buf, &rpc, portid, NULL, NULL)) < 0)
|
||||
IBPANIC("cannot build packet.");
|
||||
|
||||
fd = mad_rpc_portid(srcport);
|
||||
agent = mad_rpc_class_agent(srcport, rpc.mgtclass);
|
||||
timeout = ibd_timeout ? ibd_timeout : MAD_DEF_TIMEOUT_MS;
|
||||
|
||||
if (umad_send(fd, agent, buf, len, timeout, 0) < 0)
|
||||
IBPANIC("umad_send failed.");
|
||||
|
||||
len = sizeof(buf) - umad_size();
|
||||
if (umad_recv(fd, buf, &len, timeout) < 0)
|
||||
IBPANIC("umad_recv failed.");
|
||||
|
||||
if (umad_status(buf))
|
||||
return strerror(umad_status(buf));
|
||||
|
||||
DEBUG("Got sysstat pong..");
|
||||
if (attr != IB_PING_ATTR)
|
||||
puts(data);
|
||||
else
|
||||
printf("sysstat ping succeeded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_cpuinfo(void)
|
||||
{
|
||||
int ret;
|
||||
size_t size = sizeof(ret);
|
||||
|
||||
if (sysctlbyname("hw.ncpu", &ret, &size, NULL, 0) != 0 || ret < 1)
|
||||
ret = 1;
|
||||
return ret;
|
||||
|
||||
DEBUG("ncpu %d", ret);
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
oui = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'S':
|
||||
server++;
|
||||
break;
|
||||
case 25:
|
||||
if (!inet_pton(AF_INET6, optarg, &dgid)) {
|
||||
fprintf(stderr, "dgid format is wrong!\n");
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
with_grh = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
int sysstat_class = IB_VENDOR_OPENIB_SYSSTAT_CLASS;
|
||||
ib_portid_t portid = { 0 };
|
||||
int attr = IB_PING_ATTR;
|
||||
char *err;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"oui", 'o', 1, NULL, "use specified OUI number"},
|
||||
{"Server", 'S', 0, NULL, "start in server mode"},
|
||||
{"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<dest lid|guid> [<op>]";
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
|
||||
usage_args, NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (!argc && !server)
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (argc > 1 && (attr = match_attr(argv[1])) < 0)
|
||||
ibdiag_show_usage();
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
if (server) {
|
||||
if (mad_register_server_via(sysstat_class, 1, 0, oui, srcport) <
|
||||
0)
|
||||
IBEXIT("can't serve class %d", sysstat_class);
|
||||
|
||||
host_ncpu = build_cpuinfo();
|
||||
|
||||
if ((err = ibsystat_serv()))
|
||||
IBEXIT("ibssystat to %s: %s", portid2str(&portid),
|
||||
err);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (mad_register_client_via(sysstat_class, 1, srcport) < 0)
|
||||
IBEXIT("can't register to sysstat class %d", sysstat_class);
|
||||
|
||||
if (with_grh && ibd_dest_type != IB_DEST_LID)
|
||||
IBEXIT("When using GRH, LID should be provided");
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
if (with_grh) {
|
||||
portid.grh_present = 1;
|
||||
memcpy(&portid.gid, &dgid, sizeof(portid.gid));
|
||||
}
|
||||
|
||||
if ((err = ibsystat(&portid, attr)))
|
||||
IBEXIT("ibsystat to %s: %s", portid2str(&portid), err);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
+273
-257
@@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2009 HNR Consulting. All rights reserved.
|
||||
* Copyright (c) 2010,2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -33,26 +35,25 @@
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <infiniband/common.h>
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <complib/cl_nodenamemap.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
#define MAXHOPS 63
|
||||
|
||||
static char *node_type_str[] = {
|
||||
@@ -64,12 +65,9 @@ static char *node_type_str[] = {
|
||||
};
|
||||
|
||||
static int timeout = 0; /* ms */
|
||||
static int verbose;
|
||||
static int force;
|
||||
static FILE *f;
|
||||
|
||||
char *argv0 = "ibtracert";
|
||||
|
||||
static char *node_name_map_file = NULL;
|
||||
static nn_map_t *node_name_map = NULL;
|
||||
|
||||
@@ -94,6 +92,7 @@ struct Switch {
|
||||
int mccap;
|
||||
int linearFDBtop;
|
||||
int fdb_base;
|
||||
int enhsp0;
|
||||
int8_t fdb[64];
|
||||
char switchinfo[64];
|
||||
};
|
||||
@@ -116,16 +115,35 @@ struct Node {
|
||||
Node *nodesdist[MAXHOPS];
|
||||
uint64_t target_portguid;
|
||||
|
||||
static int
|
||||
get_node(Node *node, Port *port, ib_portid_t *portid)
|
||||
/*
|
||||
* is_port_inactive
|
||||
* Checks whether or not the port state is other than active.
|
||||
* The "sw" argument is only relevant when the port is on a
|
||||
* switch; for HCAs and routers, this argument is ignored.
|
||||
* Returns 1 when port is not active and 0 when active.
|
||||
* Base switch port 0 is considered always active.
|
||||
*/
|
||||
static int is_port_inactive(Node * node, Port * port, Switch * sw)
|
||||
{
|
||||
int res = 0;
|
||||
if (port->state != 4 &&
|
||||
(node->type != IB_NODE_SWITCH ||
|
||||
(node->type == IB_NODE_SWITCH && sw->enhsp0)))
|
||||
res = 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int get_node(Node * node, Port * port, ib_portid_t * portid)
|
||||
{
|
||||
void *pi = port->portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
|
||||
char *s, *e;
|
||||
|
||||
if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout))
|
||||
memset(ni, 0, sizeof(node->nodeinfo));
|
||||
if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, timeout, srcport))
|
||||
return -1;
|
||||
|
||||
if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout))
|
||||
memset(nd, 0, sizeof(node->nodedesc));
|
||||
if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout, srcport))
|
||||
return -1;
|
||||
|
||||
for (s = nd, e = s + 64; s < e; s++) {
|
||||
@@ -135,7 +153,8 @@ get_node(Node *node, Port *port, ib_portid_t *portid)
|
||||
*s = ' ';
|
||||
}
|
||||
|
||||
if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout))
|
||||
memset(pi, 0, sizeof(port->portinfo));
|
||||
if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, 0, timeout, srcport))
|
||||
return -1;
|
||||
|
||||
mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid);
|
||||
@@ -148,50 +167,52 @@ get_node(Node *node, Port *port, ib_portid_t *portid)
|
||||
mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc);
|
||||
mad_decode_field(pi, IB_PORT_STATE_F, &port->state);
|
||||
|
||||
DEBUG("portid %s: got node %" PRIx64 " '%s'", portid2str(portid), node->nodeguid, node->nodedesc);
|
||||
DEBUG("portid %s: got node %" PRIx64 " '%s'", portid2str(portid),
|
||||
node->nodeguid, node->nodedesc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
switch_lookup(Switch *sw, ib_portid_t *portid, int lid)
|
||||
static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
|
||||
{
|
||||
void *si = sw->switchinfo, *fdb = sw->fdb;
|
||||
|
||||
if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
|
||||
memset(si, 0, sizeof(sw->switchinfo));
|
||||
if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
|
||||
srcport))
|
||||
return -1;
|
||||
|
||||
mad_decode_field(si, IB_SW_LINEAR_FDB_CAP_F, &sw->linearcap);
|
||||
mad_decode_field(si, IB_SW_LINEAR_FDB_TOP_F, &sw->linearFDBtop);
|
||||
mad_decode_field(si, IB_SW_ENHANCED_PORT0_F, &sw->enhsp0);
|
||||
|
||||
if (lid > sw->linearcap && lid > sw->linearFDBtop)
|
||||
if (lid >= sw->linearcap && lid > sw->linearFDBtop)
|
||||
return -1;
|
||||
|
||||
if (!smp_query(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64, timeout))
|
||||
memset(fdb, 0, sizeof(sw->fdb));
|
||||
if (!smp_query_via(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64,
|
||||
timeout, srcport))
|
||||
return -1;
|
||||
|
||||
DEBUG("portid %s: forward lid %d to port %d",
|
||||
portid2str(portid), lid, sw->fdb[lid % 64]);
|
||||
portid2str(portid), lid, sw->fdb[lid % 64]);
|
||||
return sw->fdb[lid % 64];
|
||||
}
|
||||
|
||||
static int
|
||||
sameport(Port *a, Port *b)
|
||||
static int sameport(Port * a, Port * b)
|
||||
{
|
||||
return a->portguid == b->portguid || (force && a->lid == b->lid);
|
||||
}
|
||||
|
||||
static int
|
||||
extend_dpath(ib_dr_path_t *path, int nextport)
|
||||
static int extend_dpath(ib_dr_path_t * path, int nextport)
|
||||
{
|
||||
if (path->cnt+2 >= sizeof(path->p))
|
||||
if (path->cnt + 2 >= sizeof(path->p))
|
||||
return -1;
|
||||
++path->cnt;
|
||||
path->p[path->cnt] = nextport;
|
||||
path->p[path->cnt] = (uint8_t) nextport;
|
||||
return path->cnt;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_endnode(int dump, char *prompt, Node *node, Port *port)
|
||||
static void dump_endnode(int dump, char *prompt, Node * node, Port * port)
|
||||
{
|
||||
char *nodename = NULL;
|
||||
|
||||
@@ -204,50 +225,57 @@ dump_endnode(int dump, char *prompt, Node *node, Port *port)
|
||||
return;
|
||||
}
|
||||
|
||||
nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
nodename =
|
||||
remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
|
||||
fprintf(f, "%s %s {0x%016" PRIx64 "} portnum %d lid %u-%u \"%s\"\n",
|
||||
prompt,
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->type == IB_NODE_SWITCH ? 0 : port->portnum,
|
||||
port->lid, port->lid + (1 << port->lmc) - 1,
|
||||
nodename);
|
||||
node->nodeguid,
|
||||
node->type == IB_NODE_SWITCH ? 0 : port->portnum, port->lid,
|
||||
port->lid + (1 << port->lmc) - 1, nodename);
|
||||
|
||||
free(nodename);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_route(int dump, Node *node, int outport, Port *port)
|
||||
static void dump_route(int dump, Node * node, int outport, Port * port)
|
||||
{
|
||||
char *nodename = NULL;
|
||||
|
||||
if (!dump && !verbose)
|
||||
if (!dump && !ibverbose)
|
||||
return;
|
||||
|
||||
nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
nodename =
|
||||
remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
|
||||
if (dump == 1)
|
||||
fprintf(f, "[%d] -> {0x%016" PRIx64 "}[%d]\n",
|
||||
outport, port->portguid, port->portnum);
|
||||
else
|
||||
fprintf(f, "[%d] -> %s port {0x%016" PRIx64 "}[%d] lid %u-%u \"%s\"\n",
|
||||
outport,
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
port->portguid, port->portnum,
|
||||
port->lid, port->lid + (1 << port->lmc) - 1,
|
||||
nodename);
|
||||
fprintf(f, "[%d] -> %s port {0x%016" PRIx64
|
||||
"}[%d] lid %u-%u \"%s\"\n", outport,
|
||||
(node->type <=
|
||||
IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
port->portguid, port->portnum, port->lid,
|
||||
port->lid + (1 << port->lmc) - 1, nodename);
|
||||
|
||||
free(nodename);
|
||||
}
|
||||
|
||||
static int
|
||||
find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
static int find_route(ib_portid_t * from, ib_portid_t * to, int dump)
|
||||
{
|
||||
Node *node, fromnode, tonode, nextnode;
|
||||
Port *port, fromport, toport, nextport;
|
||||
Switch sw;
|
||||
int maxhops = MAXHOPS;
|
||||
int portnum, outport;
|
||||
int portnum, outport = 255, next_sw_outport = 255;
|
||||
|
||||
memset(&fromnode,0,sizeof(Node));
|
||||
memset(&tonode,0,sizeof(Node));
|
||||
memset(&nextnode,0,sizeof(Node));
|
||||
memset(&fromport,0,sizeof(Port));
|
||||
memset(&toport,0,sizeof(Port));
|
||||
memset(&nextport,0,sizeof(Port));
|
||||
|
||||
DEBUG("from %s", portid2str(from));
|
||||
|
||||
@@ -266,26 +294,32 @@ find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
portnum = port->portnum;
|
||||
|
||||
dump_endnode(dump, "From", node, port);
|
||||
if (node->type == IB_NODE_SWITCH) {
|
||||
next_sw_outport = switch_lookup(&sw, from, to->lid);
|
||||
if (next_sw_outport < 0 || next_sw_outport > node->numports) {
|
||||
/* Need to print the port in badtbl */
|
||||
outport = next_sw_outport;
|
||||
goto badtbl;
|
||||
}
|
||||
}
|
||||
|
||||
while (maxhops--) {
|
||||
if (port->state != 4)
|
||||
if (is_port_inactive(node, port, &sw))
|
||||
goto badport;
|
||||
|
||||
if (sameport(port, &toport))
|
||||
break; /* found */
|
||||
|
||||
outport = portnum;
|
||||
if (node->type == IB_NODE_SWITCH) {
|
||||
DEBUG("switch node");
|
||||
if ((outport = switch_lookup(&sw, from, to->lid)) < 0 ||
|
||||
outport > node->numports)
|
||||
goto badtbl;
|
||||
outport = next_sw_outport;
|
||||
|
||||
if (extend_dpath(&from->drpath, outport) < 0)
|
||||
goto badpath;
|
||||
|
||||
if (get_node(&nextnode, &nextport, from) < 0) {
|
||||
IBWARN("can't reach port at %s", portid2str(from));
|
||||
IBWARN("can't reach port at %s",
|
||||
portid2str(from));
|
||||
return -1;
|
||||
}
|
||||
if (outport == 0) {
|
||||
@@ -298,10 +332,13 @@ find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
(node->type == IB_NODE_ROUTER)) {
|
||||
int ca_src = 0;
|
||||
|
||||
outport = portnum;
|
||||
DEBUG("ca or router node");
|
||||
if (!sameport(port, &fromport)) {
|
||||
IBWARN("can't continue: reached CA or router port %" PRIx64 ", lid %d",
|
||||
port->portguid, port->lid);
|
||||
IBWARN
|
||||
("can't continue: reached CA or router port %"
|
||||
PRIx64 ", lid %d", port->portguid,
|
||||
port->lid);
|
||||
return -1;
|
||||
}
|
||||
/* we are at CA or router "from" - go one hop back to (hopefully) a switch */
|
||||
@@ -310,19 +347,33 @@ find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
from->drpath.cnt--;
|
||||
} else {
|
||||
ca_src = 1;
|
||||
if (portnum && extend_dpath(&from->drpath, portnum) < 0)
|
||||
if (portnum
|
||||
&& extend_dpath(&from->drpath, portnum) < 0)
|
||||
goto badpath;
|
||||
}
|
||||
if (get_node(&nextnode, &nextport, from) < 0) {
|
||||
IBWARN("can't reach port at %s", portid2str(from));
|
||||
IBWARN("can't reach port at %s",
|
||||
portid2str(from));
|
||||
return -1;
|
||||
}
|
||||
/* fix port num to be seen from the CA or router side */
|
||||
if (!ca_src)
|
||||
nextport.portnum = from->drpath.p[from->drpath.cnt+1];
|
||||
nextport.portnum =
|
||||
from->drpath.p[from->drpath.cnt + 1];
|
||||
}
|
||||
/* only if the next node is a switch, get switch info */
|
||||
if (nextnode.type == IB_NODE_SWITCH) {
|
||||
next_sw_outport = switch_lookup(&sw, from, to->lid);
|
||||
if (next_sw_outport < 0 ||
|
||||
next_sw_outport > nextnode.numports) {
|
||||
/* needed to print the port in badtbl */
|
||||
outport = next_sw_outport;
|
||||
goto badtbl;
|
||||
}
|
||||
}
|
||||
|
||||
port = &nextport;
|
||||
if (port->state != 4)
|
||||
if (is_port_inactive(&nextnode, port, &sw))
|
||||
goto badoutport;
|
||||
node = &nextnode;
|
||||
portnum = port->portnum;
|
||||
@@ -338,22 +389,22 @@ find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
|
||||
badport:
|
||||
IBWARN("Bad port state found: node \"%s\" port %d state %d",
|
||||
clean_nodedesc(node->nodedesc), portnum, port->state);
|
||||
clean_nodedesc(node->nodedesc), portnum, port->state);
|
||||
return -1;
|
||||
badoutport:
|
||||
IBWARN("Bad out port state found: node \"%s\" outport %d state %d",
|
||||
clean_nodedesc(node->nodedesc), outport, port->state);
|
||||
clean_nodedesc(node->nodedesc), outport, port->state);
|
||||
return -1;
|
||||
badtbl:
|
||||
IBWARN("Bad forwarding table entry found at: node \"%s\" lid entry %d is %d (top %d)",
|
||||
clean_nodedesc(node->nodedesc), to->lid, outport, sw.linearFDBtop);
|
||||
IBWARN
|
||||
("Bad forwarding table entry found at: node \"%s\" lid entry %d is %d (top %d)",
|
||||
clean_nodedesc(node->nodedesc), to->lid, outport, sw.linearFDBtop);
|
||||
return -1;
|
||||
badpath:
|
||||
IBWARN("Direct path too long!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
* MC span part
|
||||
*/
|
||||
@@ -361,12 +412,11 @@ find_route(ib_portid_t *from, ib_portid_t *to, int dump)
|
||||
#define HASHGUID(guid) ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103)))
|
||||
#define HTSZ 137
|
||||
|
||||
static int
|
||||
insert_node(Node *new)
|
||||
static int insert_node(Node * new)
|
||||
{
|
||||
static Node *nodestbl[HTSZ];
|
||||
int hash = HASHGUID(new->nodeguid) % HTSZ;
|
||||
Node *node ;
|
||||
Node *node;
|
||||
|
||||
for (node = nodestbl[hash]; node; node = node->htnext)
|
||||
if (node->nodeguid == new->nodeguid) {
|
||||
@@ -380,15 +430,15 @@ insert_node(Node *new)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_port(Port *port, int portnum, ib_portid_t *portid)
|
||||
static int get_port(Port * port, int portnum, ib_portid_t * portid)
|
||||
{
|
||||
char portinfo[64];
|
||||
char portinfo[64] = { 0 };
|
||||
void *pi = portinfo;
|
||||
|
||||
port->portnum = portnum;
|
||||
|
||||
if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout))
|
||||
if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout,
|
||||
srcport))
|
||||
return -1;
|
||||
|
||||
mad_decode_field(pi, IB_PORT_LID_F, &port->lid);
|
||||
@@ -397,24 +447,23 @@ get_port(Port *port, int portnum, ib_portid_t *portid)
|
||||
mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate);
|
||||
|
||||
VERBOSE("portid %s portnum %d: lid %d state %d physstate %d",
|
||||
portid2str(portid), portnum, port->lid, port->state, port->physstate);
|
||||
portid2str(portid), portnum, port->lid, port->state,
|
||||
port->physstate);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
link_port(Port *port, Node *node)
|
||||
static void link_port(Port * port, Node * node)
|
||||
{
|
||||
port->next = node->ports;
|
||||
node->ports = port;
|
||||
}
|
||||
|
||||
static int
|
||||
new_node(Node *node, Port *port, ib_portid_t *path, int dist)
|
||||
static int new_node(Node * node, Port * port, ib_portid_t * path, int dist)
|
||||
{
|
||||
if (port->portguid == target_portguid) {
|
||||
node->dist = -1; /* tag as target */
|
||||
node->dist = -1; /* tag as target */
|
||||
link_port(port, node);
|
||||
dump_endnode(verbose, "found target", node, port);
|
||||
dump_endnode(ibverbose, "found target", node, port);
|
||||
return 1; /* found; */
|
||||
}
|
||||
|
||||
@@ -422,7 +471,8 @@ new_node(Node *node, Port *port, ib_portid_t *path, int dist)
|
||||
if (insert_node(node) < 0)
|
||||
return -1; /* known switch */
|
||||
|
||||
VERBOSE("insert dist %d node %p port %d lid %d", dist, node, port->portnum, port->lid);
|
||||
VERBOSE("insert dist %d node %p port %d lid %d", dist, node,
|
||||
port->portnum, port->lid);
|
||||
|
||||
link_port(port, node);
|
||||
|
||||
@@ -434,33 +484,36 @@ new_node(Node *node, Port *port, ib_portid_t *path, int dist)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map)
|
||||
static int switch_mclookup(Node * node, ib_portid_t * portid, int mlid,
|
||||
char *map)
|
||||
{
|
||||
Switch sw;
|
||||
char mdb[64];
|
||||
void *si = sw.switchinfo;
|
||||
uint16_t *msets = (uint16_t *)mdb;
|
||||
uint16_t *msets = (uint16_t *) mdb;
|
||||
int maxsets, block, i, set;
|
||||
|
||||
memset(map, 0, 256);
|
||||
|
||||
if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
|
||||
memset(si, 0, sizeof(sw.switchinfo));
|
||||
if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
|
||||
srcport))
|
||||
return -1;
|
||||
|
||||
mlid -= 0xc000;
|
||||
|
||||
mad_decode_field(si, IB_SW_MCAST_FDB_CAP_F, &sw.mccap);
|
||||
|
||||
if (mlid > sw.mccap)
|
||||
if (mlid >= sw.mccap)
|
||||
return -1;
|
||||
|
||||
block = mlid / 32;
|
||||
maxsets = (node->numports + 15) / 16; /* round up */
|
||||
maxsets = (node->numports + 15) / 16; /* round up */
|
||||
|
||||
for (set = 0; set < maxsets; set++) {
|
||||
if (!smp_query(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
|
||||
block | (set << 28), timeout))
|
||||
memset(mdb, 0, sizeof(mdb));
|
||||
if (!smp_query_via(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
|
||||
block | (set << 28), timeout, srcport))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < 16; i++, map++) {
|
||||
@@ -469,7 +522,8 @@ switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map)
|
||||
*map = 1;
|
||||
else
|
||||
continue;
|
||||
VERBOSE("Switch guid 0x%" PRIx64 ": mlid 0x%x is forwarded to port %d",
|
||||
VERBOSE("Switch guid 0x%" PRIx64
|
||||
": mlid 0x%x is forwarded to port %d",
|
||||
node->nodeguid, mlid + 0xc000, i + set * 16);
|
||||
}
|
||||
}
|
||||
@@ -480,8 +534,7 @@ switch_mclookup(Node *node, ib_portid_t *portid, int mlid, char *map)
|
||||
/*
|
||||
* Return 1 if found, 0 if not, -1 on errors.
|
||||
*/
|
||||
static Node *
|
||||
find_mcpath(ib_portid_t *from, int mlid)
|
||||
static Node *find_mcpath(ib_portid_t * from, int mlid)
|
||||
{
|
||||
Node *node, *remotenode;
|
||||
Port *port, *remoteport;
|
||||
@@ -493,25 +546,24 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
DEBUG("from %s", portid2str(from));
|
||||
|
||||
if (!(node = calloc(1, sizeof(Node))))
|
||||
IBERROR("out of memory");
|
||||
IBEXIT("out of memory");
|
||||
|
||||
if (!(port = calloc(1, sizeof(Port))))
|
||||
IBERROR("out of memory");
|
||||
IBEXIT("out of memory");
|
||||
|
||||
if (get_node(node, port, from) < 0) {
|
||||
IBWARN("can't reach node %s", portid2str(from));
|
||||
return 0;
|
||||
}
|
||||
|
||||
node->upnode = 0; /* root */
|
||||
node->upnode = 0; /* root */
|
||||
if ((r = new_node(node, port, from, 0)) > 0) {
|
||||
if (node->type != IB_NODE_SWITCH) {
|
||||
IBWARN("ibtracert from CA to CA is unsupported");
|
||||
return 0; /* ibtracert from host to itself is unsupported */
|
||||
}
|
||||
|
||||
if (switch_mclookup(node, from, mlid, map) < 0 ||
|
||||
!map[0])
|
||||
if (switch_mclookup(node, from, mlid, map) < 0 || !map[0])
|
||||
return 0;
|
||||
return node;
|
||||
}
|
||||
@@ -523,7 +575,8 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
path = &node->path;
|
||||
|
||||
VERBOSE("dist %d node %p", dist, node);
|
||||
dump_endnode(verbose, "processing", node, node->ports);
|
||||
dump_endnode(ibverbose, "processing", node,
|
||||
node->ports);
|
||||
|
||||
memset(map, 0, sizeof(map));
|
||||
|
||||
@@ -533,8 +586,10 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
leafport = path->drpath.p[path->drpath.cnt];
|
||||
map[port->portnum] = 1;
|
||||
node->upport = 0; /* starting here */
|
||||
DEBUG("Starting from CA 0x%" PRIx64 " lid %d port %d (leafport %d)",
|
||||
node->nodeguid, port->lid, port->portnum, leafport);
|
||||
DEBUG("Starting from CA 0x%" PRIx64
|
||||
" lid %d port %d (leafport %d)",
|
||||
node->nodeguid, port->lid, port->portnum,
|
||||
leafport);
|
||||
} else { /* switch */
|
||||
|
||||
/* if starting from a leaf port fix up port (up port) */
|
||||
@@ -542,8 +597,8 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
node->upport = leafport;
|
||||
|
||||
if (switch_mclookup(node, path, mlid, map) < 0) {
|
||||
IBWARN("skipping bad Switch 0x%" PRIx64 "",
|
||||
node->nodeguid);
|
||||
IBWARN("skipping bad Switch 0x%" PRIx64
|
||||
"", node->nodeguid);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -557,10 +612,13 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
path->drpath.cnt--;
|
||||
} else {
|
||||
if (!(port = calloc(1, sizeof(Port))))
|
||||
IBERROR("out of memory");
|
||||
IBEXIT("out of memory");
|
||||
|
||||
if (get_port(port, i, path) < 0) {
|
||||
IBWARN("can't reach node %s port %d", portid2str(path), i);
|
||||
IBWARN
|
||||
("can't reach node %s port %d",
|
||||
portid2str(path), i);
|
||||
free(port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -568,24 +626,26 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
free(port);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
link_port(port, node);
|
||||
#endif
|
||||
|
||||
if (extend_dpath(&path->drpath, i) < 0)
|
||||
if (extend_dpath(&path->drpath, i) < 0) {
|
||||
free(port);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(remotenode = calloc(1, sizeof(Node))))
|
||||
IBERROR("out of memory");
|
||||
IBEXIT("out of memory");
|
||||
|
||||
if (!(remoteport = calloc(1, sizeof(Port))))
|
||||
IBERROR("out of memory");
|
||||
IBEXIT("out of memory");
|
||||
|
||||
if (get_node(remotenode, remoteport, path) < 0) {
|
||||
IBWARN("NodeInfo on %s port %d failed, skipping port",
|
||||
portid2str(path), i);
|
||||
IBWARN
|
||||
("NodeInfo on %s port %d failed, skipping port",
|
||||
portid2str(path), i);
|
||||
path->drpath.cnt--; /* restore path */
|
||||
free(remotenode);
|
||||
free(remoteport);
|
||||
@@ -596,15 +656,17 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
remotenode->upport = remoteport->portnum;
|
||||
remoteport->remoteport = port;
|
||||
|
||||
if ((r = new_node(remotenode, remoteport, path, dist+1)) > 0)
|
||||
if ((r = new_node(remotenode, remoteport, path,
|
||||
dist + 1)) > 0)
|
||||
return remotenode;
|
||||
|
||||
if (r == 0)
|
||||
dump_endnode(verbose, "new remote",
|
||||
remotenode, remoteport);
|
||||
dump_endnode(ibverbose, "new remote",
|
||||
remotenode, remoteport);
|
||||
else if (remotenode->type == IB_NODE_SWITCH)
|
||||
dump_endnode(2, "ERR: circle discovered at",
|
||||
remotenode, remoteport);
|
||||
dump_endnode(2,
|
||||
"ERR: circle discovered at",
|
||||
remotenode, remoteport);
|
||||
|
||||
path->drpath.cnt--; /* restore path */
|
||||
}
|
||||
@@ -614,8 +676,7 @@ find_mcpath(ib_portid_t *from, int mlid)
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
find_target_portguid(ib_portid_t *to)
|
||||
static uint64_t find_target_portguid(ib_portid_t * to)
|
||||
{
|
||||
Node tonode;
|
||||
Port toport;
|
||||
@@ -628,54 +689,58 @@ find_target_portguid(ib_portid_t *to)
|
||||
return toport.portguid;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_mcpath(Node *node, int dumplevel)
|
||||
static void dump_mcpath(Node * node, int dumplevel)
|
||||
{
|
||||
char *nodename = NULL;
|
||||
|
||||
if (node->upnode)
|
||||
dump_mcpath(node->upnode, dumplevel);
|
||||
|
||||
nodename = remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
nodename =
|
||||
remap_node_name(node_name_map, node->nodeguid, node->nodedesc);
|
||||
|
||||
if (!node->dist) {
|
||||
printf("From %s 0x%" PRIx64 " port %d lid %u-%u \"%s\"\n",
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->ports->portnum, node->ports->lid,
|
||||
node->ports->lid + (1 << node->ports->lmc) - 1,
|
||||
nodename);
|
||||
(node->type <=
|
||||
IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->ports->portnum, node->ports->lid,
|
||||
node->ports->lid + (1 << node->ports->lmc) - 1,
|
||||
nodename);
|
||||
goto free_name;
|
||||
}
|
||||
|
||||
if (node->dist) {
|
||||
if (dumplevel == 1)
|
||||
printf("[%d] -> %s {0x%016" PRIx64 "}[%d]\n",
|
||||
node->ports->remoteport->portnum,
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->upport);
|
||||
node->ports->remoteport->portnum,
|
||||
(node->type <=
|
||||
IB_NODE_MAX ? node_type_str[node->type] :
|
||||
"???"), node->nodeguid, node->upport);
|
||||
else
|
||||
printf("[%d] -> %s 0x%" PRIx64 "[%d] lid %u \"%s\"\n",
|
||||
node->ports->remoteport->portnum,
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->upport,
|
||||
node->ports->lid, nodename);
|
||||
node->ports->remoteport->portnum,
|
||||
(node->type <=
|
||||
IB_NODE_MAX ? node_type_str[node->type] :
|
||||
"???"), node->nodeguid, node->upport,
|
||||
node->ports->lid, nodename);
|
||||
}
|
||||
|
||||
if (node->dist < 0)
|
||||
/* target node */
|
||||
/* target node */
|
||||
printf("To %s 0x%" PRIx64 " port %d lid %u-%u \"%s\"\n",
|
||||
(node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->ports->portnum, node->ports->lid,
|
||||
node->ports->lid + (1 << node->ports->lmc) - 1,
|
||||
nodename);
|
||||
(node->type <=
|
||||
IB_NODE_MAX ? node_type_str[node->type] : "???"),
|
||||
node->nodeguid, node->ports->portnum, node->ports->lid,
|
||||
node->ports->lid + (1 << node->ports->lmc) - 1,
|
||||
nodename);
|
||||
|
||||
free_name:
|
||||
free(nodename);
|
||||
}
|
||||
|
||||
static int resolve_lid(ib_portid_t *portid, const void *srcport)
|
||||
static int resolve_lid(ib_portid_t * portid, const void *srcport)
|
||||
{
|
||||
uint8_t portinfo[64];
|
||||
uint8_t portinfo[64] = { 0 };
|
||||
uint16_t lid;
|
||||
|
||||
if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, 0, 0, srcport))
|
||||
@@ -687,164 +752,112 @@ static int resolve_lid(ib_portid_t *portid, const void *srcport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
static int dumplevel = 2, multicast, mlid;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
char *basename;
|
||||
|
||||
if (!(basename = strrchr(argv0, '/')))
|
||||
basename = argv0;
|
||||
else
|
||||
basename++;
|
||||
|
||||
fprintf(stderr, "Usage: %s [-d(ebug) -v(erbose) -D(irect) -G(uids) -n(o_info) -C ca_name -P ca_port "
|
||||
"-s smlid -t(imeout) timeout_ms -m mlid --node-name-map node-name-map ] <src-addr> <dest-addr>\n",
|
||||
basename);
|
||||
fprintf(stderr, "\n\tUnicast examples:\n");
|
||||
fprintf(stderr, "\t\t%s 4 16\t\t\t# show path between lids 4 and 16\n", basename);
|
||||
fprintf(stderr, "\t\t%s -n 4 16\t\t# same, but using simple output format\n", basename);
|
||||
fprintf(stderr, "\t\t%s -G 0x8f1040396522d 0x002c9000100d051\t# use guid addresses\n", basename);
|
||||
|
||||
fprintf(stderr, "\n\tMulticast example:\n");
|
||||
fprintf(stderr, "\t\t%s -m 0xc000 4 16\t# show multicast path of mlid 0xc000 between lids 4 and 16\n", basename);
|
||||
exit(-1);
|
||||
switch (ch) {
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
multicast++;
|
||||
mlid = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'f':
|
||||
force++;
|
||||
break;
|
||||
case 'n':
|
||||
dumplevel = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
|
||||
ib_portid_t my_portid = {0};
|
||||
ib_portid_t src_portid = {0};
|
||||
ib_portid_t dest_portid = {0};
|
||||
ib_portid_t *sm_id = 0, sm_portid = {0};
|
||||
int dumplevel = 2, dest_type = IB_DEST_LID, multicast = 0, mlid = 0;
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
ib_portid_t my_portid = { 0 };
|
||||
ib_portid_t src_portid = { 0 };
|
||||
ib_portid_t dest_portid = { 0 };
|
||||
Node *endnode;
|
||||
int udebug = 0;
|
||||
char *ca = 0;
|
||||
int ca_port = 0;
|
||||
|
||||
static char const str_opts[] = "C:P:t:s:m:dvfDGnVhu";
|
||||
static const struct option long_opts[] = {
|
||||
{ "C", 1, 0, 'C'},
|
||||
{ "P", 1, 0, 'P'},
|
||||
{ "debug", 0, 0, 'd'},
|
||||
{ "verbose", 0, 0, 'v'},
|
||||
{ "force", 0, 0, 'f'},
|
||||
{ "Direct", 0, 0, 'D'},
|
||||
{ "Guids", 0, 0, 'G'},
|
||||
{ "no_info", 0, 0, 'n'},
|
||||
{ "timeout", 1, 0, 't'},
|
||||
{ "s", 1, 0, 's'},
|
||||
{ "m", 1, 0, 'm'},
|
||||
{ "Version", 0, 0, 'V'},
|
||||
{ "help", 0, 0, 'h'},
|
||||
{ "usage", 0, 0, 'u'},
|
||||
{ "node-name-map", 1, 0, 1},
|
||||
{ }
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"force", 'f', 0, NULL, "force"},
|
||||
{"no_info", 'n', 0, NULL, "simple format"},
|
||||
{"mlid", 'm', 1, "<mlid>", "multicast trace of the mlid"},
|
||||
{"node-name-map", 1, 1, "<file>", "node name map file"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<src-addr> <dest-addr>";
|
||||
const char *usage_examples[] = {
|
||||
"- Unicast examples:",
|
||||
"4 16\t\t\t# show path between lids 4 and 16",
|
||||
"-n 4 16\t\t# same, but using simple output format",
|
||||
"-G 0x8f1040396522d 0x002c9000100d051\t# use guid addresses",
|
||||
|
||||
" - Multicast examples:",
|
||||
"-m 0xc000 4 16\t# show multicast path of mlid 0xc000 between lids 4 and 16",
|
||||
NULL,
|
||||
};
|
||||
|
||||
argv0 = argv[0];
|
||||
ibdiag_process_opts(argc, argv, NULL, "DK", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
f = stdout;
|
||||
|
||||
while (1) {
|
||||
int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
|
||||
if ( ch == -1 )
|
||||
break;
|
||||
switch(ch) {
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
ca = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
ca_port = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'd':
|
||||
ibdebug++;
|
||||
madrpc_show_errors(1);
|
||||
umad_debug(udebug);
|
||||
udebug++;
|
||||
break;
|
||||
case 'D':
|
||||
dest_type = IB_DEST_DRPATH;
|
||||
break;
|
||||
case 'G':
|
||||
dest_type = IB_DEST_GUID;
|
||||
break;
|
||||
case 'm':
|
||||
multicast++;
|
||||
mlid = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'f':
|
||||
force++;
|
||||
break;
|
||||
case 'n':
|
||||
dumplevel = 1;
|
||||
break;
|
||||
case 's':
|
||||
if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)
|
||||
IBERROR("can't resolve SM destination port %s", optarg);
|
||||
sm_id = &sm_portid;
|
||||
break;
|
||||
case 't':
|
||||
timeout = strtoul(optarg, 0, 0);
|
||||
madrpc_set_timeout(timeout);
|
||||
break;
|
||||
case 'v':
|
||||
madrpc_show_errors(1);
|
||||
verbose++;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "%s %s\n", argv0, get_build_version() );
|
||||
exit(-1);
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (ibd_timeout)
|
||||
timeout = ibd_timeout;
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
madrpc_init(ca, ca_port, mgmt_classes, 3);
|
||||
node_name_map = open_node_name_map(node_name_map_file);
|
||||
|
||||
if (ib_resolve_portid_str(&src_portid, argv[0], dest_type, sm_id) < 0)
|
||||
IBERROR("can't resolve source port %s", argv[0]);
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &src_portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve source port %s", argv[0]);
|
||||
|
||||
if (ib_resolve_portid_str(&dest_portid, argv[1], dest_type, sm_id) < 0)
|
||||
IBERROR("can't resolve destination port %s", argv[1]);
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &dest_portid, argv[1],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[1]);
|
||||
|
||||
if (dest_type == IB_DEST_DRPATH) {
|
||||
if (ibd_dest_type == IB_DEST_DRPATH) {
|
||||
if (resolve_lid(&src_portid, NULL) < 0)
|
||||
IBERROR("cannot resolve lid for port \'%s\'",
|
||||
IBEXIT("cannot resolve lid for port \'%s\'",
|
||||
portid2str(&src_portid));
|
||||
if (resolve_lid(&dest_portid, NULL) < 0)
|
||||
IBERROR("cannot resolve lid for port \'%s\'",
|
||||
IBEXIT("cannot resolve lid for port \'%s\'",
|
||||
portid2str(&dest_portid));
|
||||
}
|
||||
|
||||
if (dest_portid.lid == 0 || src_portid.lid == 0) {
|
||||
IBWARN("bad src/dest lid");
|
||||
usage();
|
||||
ibdiag_show_usage();
|
||||
}
|
||||
|
||||
if (dest_type != IB_DEST_DRPATH) {
|
||||
if (ibd_dest_type != IB_DEST_DRPATH) {
|
||||
/* first find a direct path to the src port */
|
||||
if (find_route(&my_portid, &src_portid, 0) < 0)
|
||||
IBERROR("can't find a route to the src port");
|
||||
IBEXIT("can't find a route to the src port");
|
||||
|
||||
src_portid = my_portid;
|
||||
}
|
||||
|
||||
if (!multicast) {
|
||||
if (find_route(&src_portid, &dest_portid, dumplevel) < 0)
|
||||
IBERROR("can't find a route from src to dest");
|
||||
IBEXIT("can't find a route from src to dest");
|
||||
exit(0);
|
||||
} else {
|
||||
if (mlid < 0xc000)
|
||||
@@ -852,14 +865,17 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (!(target_portguid = find_target_portguid(&dest_portid)))
|
||||
IBERROR("can't reach target lid %d", dest_portid.lid);
|
||||
IBEXIT("can't reach target lid %d", dest_portid.lid);
|
||||
|
||||
if (!(endnode = find_mcpath(&src_portid, mlid)))
|
||||
IBERROR("can't find a multicast route from src to dest");
|
||||
IBEXIT("can't find a multicast route from src to dest");
|
||||
|
||||
/* dump multicast path */
|
||||
dump_mcpath(endnode, dumplevel);
|
||||
|
||||
close_node_name_map(node_name_map);
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
+71
-161
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Voltaire, Inc. All rights reserved.
|
||||
* Copyright (c) 2006-2009 Voltaire, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -31,6 +31,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@@ -38,55 +42,40 @@
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <infiniband/iba/ib_types.h>
|
||||
|
||||
#define info(fmt, arg...) fprintf(stderr, "INFO: " fmt, ##arg )
|
||||
#define err(fmt, arg...) fprintf(stderr, "ERR: " fmt, ##arg )
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define info(fmt, ...) fprintf(stderr, "INFO: " fmt, ## __VA_ARGS__ )
|
||||
#define err(fmt, ...) fprintf(stderr, "ERR: " fmt, ## __VA_ARGS__ )
|
||||
#ifdef NOISY_DEBUG
|
||||
#define dbg(fmt, arg...) fprintf(stderr, "DBG: " fmt, ##arg )
|
||||
#define dbg(fmt, ...) fprintf(stderr, "DBG: " fmt, ## __VA_ARGS__ )
|
||||
#else
|
||||
#define dbg(fmt, arg...)
|
||||
#define dbg(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define TMO 100
|
||||
|
||||
/* Multicast Member Record Component Masks */
|
||||
#define IB_MCR_COMPMASK_MGID (1ULL<<0)
|
||||
#define IB_MCR_COMPMASK_PORT_GID (1ULL<<1)
|
||||
#define IB_MCR_COMPMASK_QKEY (1ULL<<2)
|
||||
#define IB_MCR_COMPMASK_MLID (1ULL<<3)
|
||||
#define IB_MCR_COMPMASK_MTU_SEL (1ULL<<4)
|
||||
#define IB_MCR_COMPMASK_MTU (1ULL<<5)
|
||||
#define IB_MCR_COMPMASK_TCLASS (1ULL<<6)
|
||||
#define IB_MCR_COMPMASK_PKEY (1ULL<<7)
|
||||
#define IB_MCR_COMPMASK_RATE_SEL (1ULL<<8)
|
||||
#define IB_MCR_COMPMASK_RATE (1ULL<<9)
|
||||
#define IB_MCR_COMPMASK_LIFE_SEL (1ULL<<10)
|
||||
#define IB_MCR_COMPMASK_LIFE (1ULL<<11)
|
||||
#define IB_MCR_COMPMASK_SL (1ULL<<12)
|
||||
#define IB_MCR_COMPMASK_FLOW (1ULL<<13)
|
||||
#define IB_MCR_COMPMASK_HOP (1ULL<<14)
|
||||
#define IB_MCR_COMPMASK_SCOPE (1ULL<<15)
|
||||
#define IB_MCR_COMPMASK_JOIN_STATE (1ULL<<16)
|
||||
#define IB_MCR_COMPMASK_PROXY (1ULL<<17)
|
||||
|
||||
static ibmad_gid_t mgid_ipoib = {
|
||||
0xff, 0x12, 0x40, 0x1b, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
uint64_t build_mcm_rec(uint8_t *data, ibmad_gid_t mgid, ibmad_gid_t port_gid)
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
uint64_t build_mcm_rec(uint8_t * data, ibmad_gid_t mgid, ibmad_gid_t port_gid)
|
||||
{
|
||||
memset(data, 0, IB_SA_DATA_SIZE);
|
||||
mad_set_array(data, 0, IB_SA_MCM_MGID_F, mgid);
|
||||
mad_set_array(data, 0, IB_SA_MCM_PORTGID_F, port_gid);
|
||||
mad_set_field(data, 0, IB_SA_MCM_JOIN_STATE_F, 1);
|
||||
|
||||
return IB_MCR_COMPMASK_MGID|IB_MCR_COMPMASK_PORT_GID|
|
||||
IB_MCR_COMPMASK_JOIN_STATE;
|
||||
return IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
|
||||
IB_MCR_COMPMASK_JOIN_STATE;
|
||||
}
|
||||
|
||||
static void build_mcm_rec_umad(void *umad, ib_portid_t *dport, int method,
|
||||
uint64_t comp_mask, uint8_t *data)
|
||||
static void build_mcm_rec_umad(void *umad, ib_portid_t * dport, int method,
|
||||
uint64_t comp_mask, uint8_t * data)
|
||||
{
|
||||
ib_rpc_t rpc;
|
||||
|
||||
@@ -94,7 +83,7 @@ static void build_mcm_rec_umad(void *umad, ib_portid_t *dport, int method,
|
||||
rpc.mgtclass = IB_SA_CLASS;
|
||||
rpc.method = method;
|
||||
rpc.attr.id = IB_SA_ATTR_MCRECORD;
|
||||
rpc.attr.mod = 0; // ???
|
||||
rpc.attr.mod = 0; // ???
|
||||
rpc.mask = comp_mask;
|
||||
rpc.datasz = IB_SA_DATA_SIZE;
|
||||
rpc.dataoffs = IB_SA_DATA_OFFS;
|
||||
@@ -102,8 +91,8 @@ static void build_mcm_rec_umad(void *umad, ib_portid_t *dport, int method,
|
||||
mad_build_pkt(umad, &rpc, dport, NULL, data);
|
||||
}
|
||||
|
||||
static int rereg_send(int port, int agent, ib_portid_t *dport,
|
||||
uint8_t *umad, int len, int method, ibmad_gid_t port_gid)
|
||||
static int rereg_send(int port, int agent, ib_portid_t * dport,
|
||||
uint8_t * umad, int len, int method, ibmad_gid_t port_gid)
|
||||
{
|
||||
uint8_t data[IB_SA_DATA_SIZE];
|
||||
uint64_t comp_mask;
|
||||
@@ -111,8 +100,10 @@ static int rereg_send(int port, int agent, ib_portid_t *dport,
|
||||
comp_mask = build_mcm_rec(data, mgid_ipoib, port_gid);
|
||||
|
||||
build_mcm_rec_umad(umad, dport, method, comp_mask, data);
|
||||
if(umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
err("umad_send leave failed: %s\n", strerror(errno));
|
||||
if (umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
err("umad_send %s failed: %s\n",
|
||||
(method == IB_MAD_METHOD_GET) ? "query" : "non query",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
dbg("umad_send %d: tid = 0x%016" PRIx64 "\n", method,
|
||||
@@ -121,26 +112,24 @@ static int rereg_send(int port, int agent, ib_portid_t *dport,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rereg_port_gid(int port, int agent, ib_portid_t *dport,
|
||||
uint8_t *umad, int len, ibmad_gid_t port_gid)
|
||||
static int rereg_port_gid(int port, int agent, ib_portid_t * dport,
|
||||
uint8_t * umad, int len, ibmad_gid_t port_gid)
|
||||
{
|
||||
uint8_t data[IB_SA_DATA_SIZE];
|
||||
uint64_t comp_mask;
|
||||
|
||||
comp_mask = build_mcm_rec(data, mgid_ipoib, port_gid);
|
||||
|
||||
build_mcm_rec_umad(umad, dport, IB_MAD_METHOD_DELETE,
|
||||
comp_mask, data);
|
||||
if(umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
build_mcm_rec_umad(umad, dport, IB_MAD_METHOD_DELETE, comp_mask, data);
|
||||
if (umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
err("umad_send leave failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
dbg("umad_send leave: tid = 0x%016" PRIx64 "\n",
|
||||
mad_get_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F));
|
||||
|
||||
build_mcm_rec_umad(umad, dport, IB_MAD_METHOD_SET,
|
||||
comp_mask, data);
|
||||
if(umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
build_mcm_rec_umad(umad, dport, IB_MAD_METHOD_SET, comp_mask, data);
|
||||
if (umad_send(port, agent, umad, len, TMO, 0) < 0) {
|
||||
err("umad_send join failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@@ -156,12 +145,13 @@ struct guid_trid {
|
||||
uint64_t trid;
|
||||
};
|
||||
|
||||
static int rereg_send_all(int port, int agent, ib_portid_t *dport,
|
||||
static int rereg_send_all(int port, int agent, ib_portid_t * dport,
|
||||
struct guid_trid *list, unsigned cnt)
|
||||
{
|
||||
uint8_t *umad;
|
||||
int len = umad_size() + 256;
|
||||
int i, ret;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
info("rereg_send_all... cnt = %u\n", cnt);
|
||||
|
||||
@@ -172,59 +162,32 @@ static int rereg_send_all(int port, int agent, ib_portid_t *dport,
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
ret = rereg_port_gid(port, agent, dport, umad, len, list[i].gid);
|
||||
ret =
|
||||
rereg_port_gid(port, agent, dport, umad, len, list[i].gid);
|
||||
if (ret < 0) {
|
||||
err("rereg_send_all: rereg_port_gid 0x%016" PRIx64
|
||||
" failed\n", list[i].guid);
|
||||
" failed\n", ntohll(list[i].guid));
|
||||
continue;
|
||||
}
|
||||
list[i].trid = mad_get_field64(umad_get_mad(umad), 0,
|
||||
IB_MAD_TRID_F);
|
||||
}
|
||||
|
||||
info("rereg_send_all: sent %u requests\n", cnt*2);
|
||||
info("rereg_send_all: sent %u requests\n", cnt * 2);
|
||||
|
||||
free(umad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int rereg_mcm_rec_send(int port, int agent, ib_portid_t *dport, int cnt)
|
||||
{
|
||||
ib_portid_t portid;
|
||||
ibmad_gid_t port_gid;
|
||||
uint8_t *umad;
|
||||
int len, ret = 0;
|
||||
|
||||
ib_resolve_self(&portid, NULL, &port_gid);
|
||||
|
||||
len = umad_size() + 256;
|
||||
umad = calloc(1, len);
|
||||
if (!umad) {
|
||||
err("cannot alloc mem for umad: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(cnt--) {
|
||||
if (!rereg_port_gid(port, agent, dport, umad, len, port_gid))
|
||||
ret += 2;
|
||||
}
|
||||
|
||||
free(umad);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rereg_recv(int port, int agent, ib_portid_t *dport,
|
||||
uint8_t *umad, int length, int tmo)
|
||||
static int rereg_recv(int port, int agent, ib_portid_t * dport,
|
||||
uint8_t * umad, int length, int tmo)
|
||||
{
|
||||
int ret, retry = 0;
|
||||
int len = length;
|
||||
|
||||
while((ret = umad_recv(port, umad, &len, tmo)) < 0 &&
|
||||
errno == ETIMEDOUT) {
|
||||
while ((ret = umad_recv(port, umad, &len, tmo)) < 0 &&
|
||||
errno == ETIMEDOUT) {
|
||||
if (retry++ > 3)
|
||||
return 0;
|
||||
}
|
||||
@@ -232,22 +195,22 @@ static int rereg_recv(int port, int agent, ib_portid_t *dport,
|
||||
err("umad_recv %d failed: %s\n", ret, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
dbg("umad_recv (retries %d), tid = 0x%016" PRIx64 ": len = %d, status = %d\n",
|
||||
retry,
|
||||
mad_get_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F),
|
||||
len, umad_status(umad));
|
||||
dbg("umad_recv (retries %d), tid = 0x%016" PRIx64
|
||||
": len = %d, status = %d\n", retry,
|
||||
mad_get_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F), len,
|
||||
umad_status(umad));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rereg_recv_all(int port, int agent, ib_portid_t *dport,
|
||||
static int rereg_recv_all(int port, int agent, ib_portid_t * dport,
|
||||
struct guid_trid *list, unsigned cnt)
|
||||
{
|
||||
uint8_t *umad, *mad;
|
||||
int len = umad_size() + 256;
|
||||
uint64_t trid;
|
||||
unsigned n, method, status;
|
||||
int i;
|
||||
unsigned i;
|
||||
|
||||
info("rereg_recv_all...\n");
|
||||
|
||||
@@ -270,7 +233,7 @@ static int rereg_recv_all(int port, int agent, ib_portid_t *dport,
|
||||
dbg("MAD status %x, method %x\n", status, method);
|
||||
|
||||
if (status &&
|
||||
(method&0x7f) == (IB_MAD_METHOD_GET_RESPONSE&0x7f)) {
|
||||
(method & 0x7f) == (IB_MAD_METHOD_GET_RESPONSE & 0x7f)) {
|
||||
trid = mad_get_field64(mad, 0, IB_MAD_TRID_F);
|
||||
for (i = 0; i < cnt; i++)
|
||||
if (trid == list[i].trid)
|
||||
@@ -280,12 +243,14 @@ static int rereg_recv_all(int port, int agent, ib_portid_t *dport,
|
||||
trid);
|
||||
continue;
|
||||
}
|
||||
info("guid 0x%016" PRIx64 ": method = %x status = %x. Resending\n",
|
||||
info("guid 0x%016" PRIx64
|
||||
": method = %x status = %x. Resending\n",
|
||||
ntohll(list[i].guid), method, status);
|
||||
rereg_port_gid(port, agent, dport, umad, len,
|
||||
list[i].gid);
|
||||
list[i].trid = mad_get_field64(umad_get_mad(umad), 0,
|
||||
IB_MAD_TRID_F);
|
||||
list[i].trid =
|
||||
mad_get_field64(umad_get_mad(umad), 0,
|
||||
IB_MAD_TRID_F);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,13 +260,14 @@ static int rereg_recv_all(int port, int agent, ib_portid_t *dport,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rereg_query_all(int port, int agent, ib_portid_t *dport,
|
||||
static int rereg_query_all(int port, int agent, ib_portid_t * dport,
|
||||
struct guid_trid *list, unsigned cnt)
|
||||
{
|
||||
uint8_t *umad, *mad;
|
||||
int len = umad_size() + 256;
|
||||
unsigned method, status;
|
||||
int i, ret;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
info("rereg_query_all...\n");
|
||||
|
||||
@@ -311,7 +277,7 @@ static int rereg_query_all(int port, int agent, ib_portid_t *dport,
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( i = 0; i < cnt; i++ ) {
|
||||
for (i = 0; i < cnt; i++) {
|
||||
ret = rereg_send(port, agent, dport, umad, len,
|
||||
IB_MAD_METHOD_GET, list[i].gid);
|
||||
if (ret < 0) {
|
||||
@@ -341,57 +307,23 @@ static int rereg_query_all(int port, int agent, ib_portid_t *dport,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int rereg_mcm_rec_recv(int port, int agent, int cnt)
|
||||
{
|
||||
uint8_t *umad, *mad;
|
||||
int len = umad_size() + 256;
|
||||
int i;
|
||||
|
||||
umad = calloc(1, len);
|
||||
if (!umad) {
|
||||
err("cannot alloc mem for umad: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( i = 0; i < cnt; i++ ) {
|
||||
int retry;
|
||||
retry = 0;
|
||||
while (umad_recv(port, umad, &len, TMO) < 0 &&
|
||||
errno == ETIMEDOUT)
|
||||
if (retry++ > 3) {
|
||||
err("umad_recv %d failed: %s\n",
|
||||
i, strerror(errno));
|
||||
free(umad);
|
||||
return -1;
|
||||
}
|
||||
dbg("umad_recv %d (retries %d), tid = 0x%016" PRIx64 ": len = %d, status = %d\n",
|
||||
i, retry,
|
||||
mad_get_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F),
|
||||
len, umad_status(umad));
|
||||
mad = umad_get_mad(umad);
|
||||
}
|
||||
|
||||
free(umad);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_CLIENTS 50
|
||||
|
||||
static int rereg_and_test_port(char *guid_file, int port, int agent, ib_portid_t *dport, int timeout)
|
||||
static int rereg_and_test_port(char *guid_file, int port, int agent,
|
||||
ib_portid_t * dport, int timeout)
|
||||
{
|
||||
char line[256];
|
||||
FILE *f;
|
||||
ibmad_gid_t port_gid;
|
||||
uint64_t prefix = htonll(0xfe80000000000000llu);
|
||||
uint64_t guid = htonll(0x0002c90200223825llu);
|
||||
uint64_t prefix = htonll(0xfe80000000000000ull);
|
||||
uint64_t guid = htonll(0x0002c90200223825ull);
|
||||
struct guid_trid *list;
|
||||
int i = 0;
|
||||
|
||||
list = calloc(MAX_CLIENTS, sizeof(*list));
|
||||
if (!list) {
|
||||
err("cannot alloc mem for guid/trid list: %s\n", strerror(errno));
|
||||
err("cannot alloc mem for guid/trid list: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -427,7 +359,7 @@ static int rereg_and_test_port(char *guid_file, int port, int agent, ib_portid_t
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *guid_file = "port_guids.list";
|
||||
int mgmt_classes[2] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS};
|
||||
int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
|
||||
ib_portid_t dport_id;
|
||||
int port, agent;
|
||||
uint8_t *umad, *mad;
|
||||
@@ -436,48 +368,26 @@ int main(int argc, char **argv)
|
||||
if (argc > 1)
|
||||
guid_file = argv[1];
|
||||
|
||||
madrpc_init(NULL, 0, mgmt_classes, 2);
|
||||
srcport = mad_rpc_open_port(NULL, 0, mgmt_classes, 2);
|
||||
if (!srcport)
|
||||
err("Failed to open port");
|
||||
|
||||
#if 1
|
||||
ib_resolve_smlid(&dport_id, TMO);
|
||||
#else
|
||||
memset(&dport_id, 0, sizeof(dport_id));
|
||||
dport_id.lid = 1;
|
||||
#endif
|
||||
resolve_sm_portid(NULL, 0, &dport_id);
|
||||
dport_id.qp = 1;
|
||||
if (!dport_id.qkey)
|
||||
dport_id.qkey = IB_DEFAULT_QP1_QKEY;
|
||||
|
||||
|
||||
len = umad_size() + 256;
|
||||
umad = calloc(1, len);
|
||||
if (!umad) {
|
||||
err("cannot alloc mem for umad: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
port = madrpc_portid();
|
||||
#else
|
||||
ret = umad_init();
|
||||
|
||||
port = umad_open_port(NULL, 0);
|
||||
if (port < 0) {
|
||||
err("umad_open_port failed: %s\n", strerror(errno));
|
||||
return port;
|
||||
}
|
||||
#endif
|
||||
port = mad_rpc_portid(srcport);
|
||||
|
||||
agent = umad_register(port, IB_SA_CLASS, 2, 0, NULL);
|
||||
|
||||
#if 0
|
||||
int cnt;
|
||||
cnt = rereg_mcm_rec_send(port, agent, &dport_id, cnt);
|
||||
|
||||
rereg_recv_all(port, agent, &dport_id);
|
||||
#else
|
||||
rereg_and_test_port(guid_file, port, agent, &dport_id, TMO);
|
||||
#endif
|
||||
mad = umad_get_mad(umad);
|
||||
|
||||
free(umad);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Intel Corporation. All Rights Reserved
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libudev.h>
|
||||
|
||||
struct udev *udev;
|
||||
struct udev_monitor *mon;
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define SYS_HOSTNAME "/proc/sys/kernel/hostname"
|
||||
#define DEF_SYS_DIR "/sys"
|
||||
char *sys_dir = DEF_SYS_DIR;
|
||||
#define SYS_INFINIBAND "class/infiniband"
|
||||
#define DEFAULT_RETRY_RATE 60
|
||||
#define DEFAULT_RETRY_COUNT 0
|
||||
#define DEFAULT_ND_FORMAT "%h %d"
|
||||
|
||||
int failure_retry_rate = DEFAULT_RETRY_RATE;
|
||||
int set_retry_cnt = DEFAULT_RETRY_COUNT;
|
||||
int foreground = 0;
|
||||
char *pidfile = NULL;
|
||||
|
||||
static void newline_to_null(char *str)
|
||||
{
|
||||
char *term = index(str, '\n');
|
||||
if (term)
|
||||
*term = '\0';
|
||||
}
|
||||
|
||||
static void strip_domain(char *str)
|
||||
{
|
||||
char *term = index(str, '.');
|
||||
if (term)
|
||||
*term = '\0';
|
||||
}
|
||||
|
||||
static void build_node_desc(char *dest, size_t len,
|
||||
const char *device, const char *hostname)
|
||||
{
|
||||
char *end = dest + len-1;
|
||||
const char *field;
|
||||
char *src = ibd_nd_format;
|
||||
|
||||
while (*src && (dest < end)) {
|
||||
if (*src != '%') {
|
||||
*dest++ = *src++;
|
||||
} else {
|
||||
src++;
|
||||
switch (*src) {
|
||||
case 'h':
|
||||
field = hostname;
|
||||
while (*field && (*field != '.') && (dest < end))
|
||||
*dest++ = *field++;
|
||||
break;
|
||||
case 'd':
|
||||
field = device;
|
||||
while (*field && (dest < end))
|
||||
*dest++ = *field++;
|
||||
break;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
}
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
static int update_node_desc(const char *device, const char *hostname, int force)
|
||||
{
|
||||
int rc;
|
||||
char nd[128];
|
||||
char new_nd[64];
|
||||
char nd_file[PATH_MAX];
|
||||
FILE *f;
|
||||
|
||||
snprintf(nd_file, sizeof(nd_file), "%s/%s/%s/node_desc",
|
||||
sys_dir, SYS_INFINIBAND, device);
|
||||
nd_file[sizeof(nd_file)-1] = '\0';
|
||||
|
||||
f = fopen(nd_file, "r+");
|
||||
if (!f) {
|
||||
syslog(LOG_ERR, "Failed to open %s\n", nd_file);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!fgets(nd, sizeof(nd), f)) {
|
||||
syslog(LOG_ERR, "Failed to read %s\n", nd_file);
|
||||
rc = -EIO;
|
||||
goto error;
|
||||
}
|
||||
newline_to_null(nd);
|
||||
|
||||
build_node_desc(new_nd, sizeof(new_nd), device, hostname);
|
||||
|
||||
if (!force && strncmp(new_nd, nd, sizeof(new_nd)) == 0) {
|
||||
syslog(LOG_INFO, "%s: no change (%s)\n", device, new_nd);
|
||||
} else {
|
||||
syslog(LOG_INFO, "%s: change (%s) -> (%s)\n",
|
||||
device, nd, new_nd);
|
||||
rewind(f);
|
||||
fprintf(f, new_nd);
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
error:
|
||||
fclose(f);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int set_rdma_node_desc(const char *hostname, int force)
|
||||
{
|
||||
DIR *class_dir;
|
||||
struct dirent *dent;
|
||||
char dev_dir[PATH_MAX];
|
||||
|
||||
snprintf(dev_dir, sizeof(dev_dir), "%s/%s", sys_dir, SYS_INFINIBAND);
|
||||
dev_dir[sizeof(dev_dir)-1] = '\0';
|
||||
|
||||
class_dir = opendir(dev_dir);
|
||||
if (!class_dir) {
|
||||
syslog(LOG_INFO, "Failed to open %s", dev_dir);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
while ((dent = readdir(class_dir))) {
|
||||
int retry = set_retry_cnt;
|
||||
if (dent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
while (update_node_desc(dent->d_name, hostname, force) && retry > 0) {
|
||||
syslog(LOG_ERR, "retrying set Node Description on %s\n",
|
||||
dent->d_name);
|
||||
retry--;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(class_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_hostname(int fd, char *name, size_t len)
|
||||
{
|
||||
int rc;
|
||||
memset(name, 0, len);
|
||||
if (read(fd, name, len-1) >= 0) {
|
||||
newline_to_null(name);
|
||||
strip_domain(name);
|
||||
rc = 0;
|
||||
} else {
|
||||
syslog(LOG_ERR, "Read %s Failed\n", SYS_HOSTNAME);
|
||||
rc = -EIO;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int process_opts(void *context, int ch, char *optarg)
|
||||
{
|
||||
unsigned long tmp;
|
||||
switch (ch) {
|
||||
case 0:
|
||||
pidfile = optarg;
|
||||
break;
|
||||
case 'f':
|
||||
foreground = 1;
|
||||
break;
|
||||
case 't':
|
||||
tmp = strtoul(optarg, NULL, 0);
|
||||
if (tmp >= INT_MAX) {
|
||||
syslog(LOG_ERR,
|
||||
"Invalid retry rate specified: %lu s\n",
|
||||
tmp);
|
||||
} else {
|
||||
failure_retry_rate = (int)tmp;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
tmp = strtoul(optarg, NULL, 0);
|
||||
if (tmp >= INT_MAX) {
|
||||
syslog(LOG_ERR,
|
||||
"Invalid retry count specified: %lu\n",
|
||||
tmp);
|
||||
} else {
|
||||
set_retry_cnt = (int)tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MSG_MAX 2048
|
||||
static void udev_log_fn(struct udev *ud, int priority, const char *file, int line,
|
||||
const char *fn, const char *format, va_list args)
|
||||
{
|
||||
int off = 0;
|
||||
char msg[MSG_MAX];
|
||||
off = snprintf(msg, MSG_MAX, "libudev: %s:%d %s",
|
||||
file, line, fn);
|
||||
if (off < MSG_MAX-1)
|
||||
vsnprintf(msg+off, MSG_MAX-off, format, args);
|
||||
syslog(LOG_ERR, msg);
|
||||
}
|
||||
|
||||
static void setup_udev(void)
|
||||
{
|
||||
udev = udev_new();
|
||||
if (!udev) {
|
||||
syslog(LOG_ERR, "udev_new failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
udev_set_log_fn(udev, udev_log_fn);
|
||||
udev_set_log_priority(udev, LOG_INFO);
|
||||
#if HAVE_UDEV_GET_SYS_PATH
|
||||
sys_dir = (char *)udev_get_sys_path(udev);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int get_udev_fd(void)
|
||||
{
|
||||
mon = udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (!mon) {
|
||||
syslog(LOG_ERR, "udev monitoring failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
udev_monitor_filter_add_match_subsystem_devtype(mon, "infiniband", NULL);
|
||||
udev_monitor_enable_receiving(mon);
|
||||
return udev_monitor_get_fd(mon);
|
||||
}
|
||||
|
||||
static void process_udev_event(int ud_fd, const char *hostname)
|
||||
{
|
||||
struct udev_device *dev;
|
||||
|
||||
dev = udev_monitor_receive_device(mon);
|
||||
if (dev) {
|
||||
const char *device = udev_device_get_sysname(dev);
|
||||
const char *action = udev_device_get_action(dev);
|
||||
|
||||
syslog(LOG_INFO, "Device event: %s, %s, %s\n",
|
||||
udev_device_get_subsystem(dev),
|
||||
device, action);
|
||||
|
||||
if (device && action
|
||||
&& strncmp(action, "add", sizeof("add")) == 0)
|
||||
update_node_desc(device, hostname, 1);
|
||||
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor(void)
|
||||
{
|
||||
char hostname[128];
|
||||
int hn_fd;
|
||||
int rc;
|
||||
struct pollfd fds[2];
|
||||
int numfds = 1;
|
||||
int ud_fd;
|
||||
|
||||
ud_fd = get_udev_fd();
|
||||
if (ud_fd >= 0)
|
||||
numfds = 2;
|
||||
|
||||
while (1) {
|
||||
hn_fd = open(SYS_HOSTNAME, O_RDONLY);
|
||||
if (hn_fd < 0) {
|
||||
syslog(LOG_ERR,
|
||||
"Open %s Failed: retry in %d seconds\n",
|
||||
SYS_HOSTNAME, failure_retry_rate);
|
||||
sleep(failure_retry_rate);
|
||||
continue;
|
||||
}
|
||||
|
||||
fds[0].fd = hn_fd;
|
||||
fds[0].events = 0;
|
||||
fds[0].revents = 0;
|
||||
|
||||
fds[1].fd = ud_fd;
|
||||
fds[1].events = POLLIN;
|
||||
fds[1].revents = 0;
|
||||
|
||||
rc = poll(fds, numfds, -1);
|
||||
|
||||
if (rc > 0) {
|
||||
if (read_hostname(hn_fd, hostname, sizeof(hostname)) != 0)
|
||||
hostname[0] = '\0';
|
||||
|
||||
if (fds[0].revents != 0)
|
||||
syslog(LOG_ERR, "Hostname change: %s\n", hostname);
|
||||
|
||||
if (fds[1].revents != 0)
|
||||
process_udev_event(ud_fd, hostname);
|
||||
|
||||
rc = set_rdma_node_desc((const char *)hostname, 0);
|
||||
} else {
|
||||
syslog(LOG_ERR, "Poll %s Failed\n", SYS_HOSTNAME);
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
close(hn_fd);
|
||||
|
||||
if (rc)
|
||||
sleep(failure_retry_rate);
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_pidfile(void)
|
||||
{
|
||||
if (pidfile)
|
||||
unlink(pidfile);
|
||||
}
|
||||
|
||||
static void write_pidfile(void)
|
||||
{
|
||||
FILE *f;
|
||||
if (pidfile) {
|
||||
remove_pidfile();
|
||||
f = fopen(pidfile, "w");
|
||||
if (f) {
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
} else {
|
||||
syslog(LOG_ERR, "Failed to write pidfile : %s\n",
|
||||
pidfile);
|
||||
exit(errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
char hostname[128];
|
||||
|
||||
openlog("rdma-ndd", LOG_PID | LOG_PERROR, LOG_DAEMON);
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"retry_timer", 't', 1, "<retry_timer>",
|
||||
"Length of time to sleep when system errors occur "
|
||||
"when attempting to poll and or read the hostname "
|
||||
"from the system.\n"},
|
||||
{"retry_count", 'r', 1, "<retry_count>",
|
||||
"Number of times to attempt to retry setting "
|
||||
"of the node description on failure\n"},
|
||||
{"foreground", 'f', 0, NULL, "run in the foreground instead of as a daemon\n"},
|
||||
{"pidfile", 0, 1, "<pidfile>", "specify a pid file (daemon mode only)\n"},
|
||||
{0}
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "CPDLGtsKyevd", opts,
|
||||
process_opts, "", NULL);
|
||||
|
||||
if (!ibd_nd_format)
|
||||
ibd_nd_format = DEFAULT_ND_FORMAT;
|
||||
|
||||
if (!foreground) {
|
||||
closelog();
|
||||
openlog("rdma-ndd", LOG_PID, LOG_DAEMON);
|
||||
if (daemon(0, 0) != 0) {
|
||||
syslog(LOG_ERR, "Failed to daemonize\n");
|
||||
exit(errno);
|
||||
}
|
||||
write_pidfile();
|
||||
}
|
||||
|
||||
setup_udev();
|
||||
|
||||
syslog(LOG_INFO, "Node Descriptor format (%s)\n", ibd_nd_format);
|
||||
|
||||
fd = open(SYS_HOSTNAME, O_RDONLY);
|
||||
if (read_hostname(fd, hostname, sizeof(hostname)) != 0)
|
||||
hostname[0] = '\0';
|
||||
set_rdma_node_desc((const char *)hostname, 1);
|
||||
close(fd);
|
||||
|
||||
monitor();
|
||||
|
||||
remove_pidfile();
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
static uint8_t sminfo[1024] = { 0 };
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
int strdata, xdata = 1, bindata;
|
||||
|
||||
enum {
|
||||
SMINFO_NOTACT,
|
||||
SMINFO_DISCOVER,
|
||||
SMINFO_STANDBY,
|
||||
SMINFO_MASTER,
|
||||
|
||||
SMINFO_STATE_LAST,
|
||||
};
|
||||
|
||||
char *statestr[] = {
|
||||
"SMINFO_NOTACT",
|
||||
"SMINFO_DISCOVER",
|
||||
"SMINFO_STANDBY",
|
||||
"SMINFO_MASTER",
|
||||
};
|
||||
|
||||
#define STATESTR(s) (((unsigned)(s)) < SMINFO_STATE_LAST ? statestr[s] : "???")
|
||||
|
||||
static unsigned act;
|
||||
static int prio, state = SMINFO_STANDBY;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
act = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 's':
|
||||
state = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
case 'p':
|
||||
prio = strtoul(optarg, 0, 0);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
int mod = 0;
|
||||
ib_portid_t portid = { 0 };
|
||||
uint8_t *p;
|
||||
uint64_t guid = 0, key = 0;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"state", 's', 1, "<0-3>", "set SM state"},
|
||||
{"priority", 'p', 1, "<0-15>", "set SM priority"},
|
||||
{"activity", 'a', 1, NULL, "set activity count"},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<sm_lid|sm_dr_path> [modifier]";
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "sK", opts, process_opt,
|
||||
usage_args, NULL);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
mod = atoi(argv[1]);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
if (argc) {
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, 0, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
} else {
|
||||
if (resolve_sm_portid(ibd_ca, ibd_ca_port, &portid) < 0)
|
||||
IBEXIT("can't resolve sm port %s", argv[0]);
|
||||
}
|
||||
|
||||
mad_encode_field(sminfo, IB_SMINFO_GUID_F, &guid);
|
||||
mad_encode_field(sminfo, IB_SMINFO_ACT_F, &act);
|
||||
mad_encode_field(sminfo, IB_SMINFO_KEY_F, &key);
|
||||
mad_encode_field(sminfo, IB_SMINFO_PRIO_F, &prio);
|
||||
mad_encode_field(sminfo, IB_SMINFO_STATE_F, &state);
|
||||
|
||||
if (mod) {
|
||||
if (!(p = smp_set_via(sminfo, &portid, IB_ATTR_SMINFO, mod,
|
||||
ibd_timeout, srcport)))
|
||||
IBEXIT("query");
|
||||
} else if (!(p = smp_query_via(sminfo, &portid, IB_ATTR_SMINFO, 0,
|
||||
ibd_timeout, srcport)))
|
||||
IBEXIT("query");
|
||||
|
||||
mad_decode_field(sminfo, IB_SMINFO_GUID_F, &guid);
|
||||
mad_decode_field(sminfo, IB_SMINFO_ACT_F, &act);
|
||||
mad_decode_field(sminfo, IB_SMINFO_KEY_F, &key);
|
||||
mad_decode_field(sminfo, IB_SMINFO_PRIO_F, &prio);
|
||||
mad_decode_field(sminfo, IB_SMINFO_STATE_F, &state);
|
||||
|
||||
printf("sminfo: sm lid %d sm guid 0x%" PRIx64
|
||||
", activity count %u priority %d state %d %s\n", portid.lid,
|
||||
guid, act, prio, state, STATESTR(state));
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <infiniband/mad.h>
|
||||
#include <infiniband/umad.h>
|
||||
|
||||
#include <ibdiag_common.h>
|
||||
|
||||
static int mad_agent;
|
||||
static int drmad_tid = 0x123;
|
||||
|
||||
typedef struct {
|
||||
char path[64];
|
||||
int hop_cnt;
|
||||
} DRPath;
|
||||
|
||||
struct drsmp {
|
||||
uint8_t base_version;
|
||||
uint8_t mgmt_class;
|
||||
uint8_t class_version;
|
||||
uint8_t method;
|
||||
uint16_t status;
|
||||
uint8_t hop_ptr;
|
||||
uint8_t hop_cnt;
|
||||
uint64_t tid;
|
||||
uint16_t attr_id;
|
||||
uint16_t resv;
|
||||
uint32_t attr_mod;
|
||||
uint64_t mkey;
|
||||
uint16_t dr_slid;
|
||||
uint16_t dr_dlid;
|
||||
uint8_t reserved[28];
|
||||
uint8_t data[64];
|
||||
uint8_t initial_path[64];
|
||||
uint8_t return_path[64];
|
||||
};
|
||||
|
||||
void drsmp_get_init(void *umad, DRPath * path, int attr, int mod)
|
||||
{
|
||||
struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
|
||||
|
||||
memset(smp, 0, sizeof(*smp));
|
||||
|
||||
smp->base_version = 1;
|
||||
smp->mgmt_class = IB_SMI_DIRECT_CLASS;
|
||||
smp->class_version = 1;
|
||||
|
||||
smp->method = 1;
|
||||
smp->attr_id = (uint16_t) htons((uint16_t) attr);
|
||||
smp->attr_mod = htonl(mod);
|
||||
smp->tid = htonll(drmad_tid++);
|
||||
smp->dr_slid = 0xffff;
|
||||
smp->dr_dlid = 0xffff;
|
||||
|
||||
umad_set_addr(umad, 0xffff, 0, 0, 0);
|
||||
|
||||
if (path)
|
||||
memcpy(smp->initial_path, path->path, path->hop_cnt + 1);
|
||||
|
||||
smp->hop_cnt = (uint8_t) path->hop_cnt;
|
||||
}
|
||||
|
||||
void smp_get_init(void *umad, int lid, int attr, int mod)
|
||||
{
|
||||
struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
|
||||
|
||||
memset(smp, 0, sizeof(*smp));
|
||||
|
||||
smp->base_version = 1;
|
||||
smp->mgmt_class = IB_SMI_CLASS;
|
||||
smp->class_version = 1;
|
||||
|
||||
smp->method = 1;
|
||||
smp->attr_id = (uint16_t) htons((uint16_t) attr);
|
||||
smp->attr_mod = htonl(mod);
|
||||
smp->tid = htonll(drmad_tid++);
|
||||
|
||||
umad_set_addr(umad, lid, 0, 0, 0);
|
||||
}
|
||||
|
||||
void drsmp_set_init(void *umad, DRPath * path, int attr, int mod, void *data)
|
||||
{
|
||||
struct drsmp *smp = (struct drsmp *)(umad_get_mad(umad));
|
||||
|
||||
memset(smp, 0, sizeof(*smp));
|
||||
|
||||
smp->method = 2; /* SET */
|
||||
smp->attr_id = (uint16_t) htons((uint16_t) attr);
|
||||
smp->attr_mod = htonl(mod);
|
||||
smp->tid = htonll(drmad_tid++);
|
||||
smp->dr_slid = 0xffff;
|
||||
smp->dr_dlid = 0xffff;
|
||||
|
||||
umad_set_addr(umad, 0xffff, 0, 0, 0);
|
||||
|
||||
if (path)
|
||||
memcpy(smp->initial_path, path->path, path->hop_cnt + 1);
|
||||
|
||||
if (data)
|
||||
memcpy(smp->data, data, sizeof smp->data);
|
||||
|
||||
smp->hop_cnt = (uint8_t) path->hop_cnt;
|
||||
}
|
||||
|
||||
char *drmad_status_str(struct drsmp *drsmp)
|
||||
{
|
||||
switch (drsmp->status) {
|
||||
case 0:
|
||||
return "success";
|
||||
case ETIMEDOUT:
|
||||
return "timeout";
|
||||
}
|
||||
return "unknown error";
|
||||
}
|
||||
|
||||
int str2DRPath(char *str, DRPath * path)
|
||||
{
|
||||
char *s;
|
||||
|
||||
path->hop_cnt = -1;
|
||||
|
||||
DEBUG("DR str: %s", str);
|
||||
while (str && *str) {
|
||||
if ((s = strchr(str, ',')))
|
||||
*s = 0;
|
||||
path->path[++path->hop_cnt] = (char)atoi(str);
|
||||
if (!s)
|
||||
break;
|
||||
str = s + 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (path->path[0] != 0 ||
|
||||
(path->hop_cnt > 0 && dev_port && path->path[1] != dev_port)) {
|
||||
DEBUG("hop 0 != 0 or hop 1 != dev_port");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return path->hop_cnt;
|
||||
}
|
||||
|
||||
static int dump_char, mgmt_class = IB_SMI_CLASS;
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 's':
|
||||
dump_char++;
|
||||
break;
|
||||
case 'D':
|
||||
mgmt_class = IB_SMI_DIRECT_CLASS;
|
||||
break;
|
||||
case 'L':
|
||||
mgmt_class = IB_SMI_CLASS;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef strdupa
|
||||
#define strdupa(_s) \
|
||||
({ \
|
||||
char *_d; \
|
||||
int _len; \
|
||||
\
|
||||
_len = strlen(_s) + 1; \
|
||||
_d = alloca(_len); \
|
||||
if (_d) \
|
||||
memcpy(_d, _s, _len); \
|
||||
_d; \
|
||||
})
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int dlid = 0;
|
||||
void *umad;
|
||||
struct drsmp *smp;
|
||||
int i, portid, mod = 0, attr;
|
||||
DRPath path;
|
||||
uint8_t *desc;
|
||||
int length;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"string", 's', 0, NULL, ""},
|
||||
{0}
|
||||
};
|
||||
char usage_args[] = "<dlid|dr_path> <attr> [mod]";
|
||||
const char *usage_examples[] = {
|
||||
" -- DR routed examples:",
|
||||
"-D 0,1,2,3,5 16 # NODE DESC",
|
||||
"-D 0,1,2 0x15 2 # PORT INFO, port 2",
|
||||
" -- LID routed examples:",
|
||||
"3 0x15 2 # PORT INFO, lid 3 port 2",
|
||||
"0xa0 0x11 # NODE INFO, lid 0xa0",
|
||||
NULL
|
||||
};
|
||||
|
||||
ibd_timeout = 1000;
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "GKs", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (mgmt_class == IB_SMI_DIRECT_CLASS &&
|
||||
str2DRPath(strdupa(argv[0]), &path) < 0)
|
||||
IBPANIC("bad path str '%s'", argv[0]);
|
||||
|
||||
if (mgmt_class == IB_SMI_CLASS)
|
||||
dlid = strtoul(argv[0], 0, 0);
|
||||
|
||||
attr = strtoul(argv[1], 0, 0);
|
||||
if (argc > 2)
|
||||
mod = strtoul(argv[2], 0, 0);
|
||||
|
||||
if (umad_init() < 0)
|
||||
IBPANIC("can't init UMAD library");
|
||||
|
||||
if ((portid = umad_open_port(ibd_ca, ibd_ca_port)) < 0)
|
||||
IBPANIC("can't open UMAD port (%s:%d)", ibd_ca, ibd_ca_port);
|
||||
|
||||
if ((mad_agent = umad_register(portid, mgmt_class, 1, 0, 0)) < 0)
|
||||
IBPANIC("Couldn't register agent for SMPs");
|
||||
|
||||
if (!(umad = umad_alloc(1, umad_size() + IB_MAD_SIZE)))
|
||||
IBPANIC("can't alloc MAD");
|
||||
|
||||
smp = umad_get_mad(umad);
|
||||
|
||||
if (mgmt_class == IB_SMI_DIRECT_CLASS)
|
||||
drsmp_get_init(umad, &path, attr, mod);
|
||||
else
|
||||
smp_get_init(umad, dlid, attr, mod);
|
||||
|
||||
if (ibdebug > 1)
|
||||
xdump(stderr, "before send:\n", smp, 256);
|
||||
|
||||
length = IB_MAD_SIZE;
|
||||
if (umad_send(portid, mad_agent, umad, length, ibd_timeout, 0) < 0)
|
||||
IBPANIC("send failed");
|
||||
|
||||
if (umad_recv(portid, umad, &length, -1) != mad_agent)
|
||||
IBPANIC("recv error: %s", drmad_status_str(smp));
|
||||
|
||||
if (!dump_char) {
|
||||
xdump(stdout, 0, smp->data, 64);
|
||||
if (smp->status)
|
||||
fprintf(stdout, "SMP status: 0x%x\n",
|
||||
ntohs(smp->status));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
desc = smp->data;
|
||||
for (i = 0; i < 64; ++i) {
|
||||
if (!desc[i])
|
||||
break;
|
||||
putchar(desc[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
if (smp->status)
|
||||
fprintf(stdout, "SMP status: 0x%x\n", ntohs(smp->status));
|
||||
|
||||
exit:
|
||||
umad_free(umad);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
* Copyright (c) 2011 Mellanox Technologies LTD. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
#include <complib/cl_nodenamemap.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table,
|
||||
sl2vl_table, vlarb_table, guid_info, mlnx_ext_port_info, port_info_extended;
|
||||
|
||||
static const match_rec_t match_tbl[] = {
|
||||
{"NodeInfo", "NI", node_info, 0, ""},
|
||||
{"NodeDesc", "ND", node_desc, 0, ""},
|
||||
{"PortInfo", "PI", port_info, 1, ""},
|
||||
{"PortInfoExtended", "PIE", port_info_extended, 1, ""},
|
||||
{"SwitchInfo", "SI", switch_info, 0, ""},
|
||||
{"PKeyTable", "PKeys", pkey_table, 1, ""},
|
||||
{"SL2VLTable", "SL2VL", sl2vl_table, 1, ""},
|
||||
{"VLArbitration", "VLArb", vlarb_table, 1, ""},
|
||||
{"GUIDInfo", "GI", guid_info, 0, ""},
|
||||
{"MlnxExtPortInfo", "MEPI", mlnx_ext_port_info, 1, ""},
|
||||
{0}
|
||||
};
|
||||
|
||||
static char *node_name_map_file = NULL;
|
||||
static nn_map_t *node_name_map = NULL;
|
||||
static int extended_speeds = 0;
|
||||
|
||||
/*******************************************/
|
||||
static char *node_desc(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
int node_type, l;
|
||||
uint64_t node_guid;
|
||||
char nd[IB_SMP_DATA_SIZE] = { 0 };
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
char dots[128];
|
||||
char *nodename = NULL;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_decode_field(data, IB_NODE_TYPE_F, &node_type);
|
||||
mad_decode_field(data, IB_NODE_GUID_F, &node_guid);
|
||||
|
||||
if (!smp_query_via(nd, dest, IB_ATTR_NODE_DESC, 0, 0, srcport))
|
||||
return "node desc query failed";
|
||||
|
||||
nodename = remap_node_name(node_name_map, node_guid, nd);
|
||||
|
||||
l = strlen(nodename);
|
||||
if (l < 32) {
|
||||
memset(dots, '.', 32 - l);
|
||||
dots[32 - l] = '\0';
|
||||
} else {
|
||||
dots[0] = '.';
|
||||
dots[1] = '\0';
|
||||
}
|
||||
|
||||
printf("Node Description:%s%s\n", dots, nodename);
|
||||
free(nodename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *node_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_dump_nodeinfo(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# Node info: %s\n%s", portid2str(dest), buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *port_info_extended(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int portnum = 0;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
if (!is_port_info_extended_supported(dest, portnum, srcport))
|
||||
return "port info extended not supported";
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO_EXT, portnum, 0,
|
||||
srcport))
|
||||
return "port info extended query failed";
|
||||
|
||||
mad_dump_portinfo_ext(buf, sizeof buf, data, sizeof data);
|
||||
printf("# Port info Extended: %s port %d\n%s", portid2str(dest),
|
||||
portnum, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *port_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int portnum = 0, orig_portnum;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
orig_portnum = portnum;
|
||||
if (extended_speeds)
|
||||
portnum |= 1 << 31;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
|
||||
return "port info query failed";
|
||||
|
||||
printf("# Port info: %s port %d\n", portid2str(dest), orig_portnum);
|
||||
dump_portinfo(data, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *mlnx_ext_port_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2300];
|
||||
char data[IB_SMP_DATA_SIZE];
|
||||
int portnum = 0;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, portnum, 0, srcport))
|
||||
return "Mellanox ext port info query failed";
|
||||
|
||||
mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *switch_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
|
||||
return "switch info query failed";
|
||||
|
||||
mad_dump_switchinfo(buf, sizeof buf, data, sizeof data);
|
||||
|
||||
printf("# Switch info: %s\n%s", portid2str(dest), buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int i, j, k;
|
||||
uint16_t *p;
|
||||
unsigned mod;
|
||||
int n, t, phy_ports;
|
||||
int portnum = 0;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
/* Get the partition capacity */
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_decode_field(data, IB_NODE_TYPE_F, &t);
|
||||
mad_decode_field(data, IB_NODE_NPORTS_F, &phy_ports);
|
||||
if (portnum > phy_ports)
|
||||
return "invalid port number";
|
||||
|
||||
if ((t == IB_NODE_SWITCH) && (portnum != 0)) {
|
||||
if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0,
|
||||
srcport))
|
||||
return "switch info failed";
|
||||
mad_decode_field(data, IB_SW_PARTITION_ENFORCE_CAP_F, &n);
|
||||
} else
|
||||
mad_decode_field(data, IB_NODE_PARTITION_CAP_F, &n);
|
||||
|
||||
for (i = 0; i < (n + 31) / 32; i++) {
|
||||
mod = i | (portnum << 16);
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PKEY_TBL, mod, 0,
|
||||
srcport))
|
||||
return "pkey table query failed";
|
||||
if (i + 1 == (n + 31) / 32)
|
||||
k = ((n + 7 - i * 32) / 8) * 8;
|
||||
else
|
||||
k = 32;
|
||||
p = (uint16_t *) data;
|
||||
for (j = 0; j < k; j += 8, p += 8) {
|
||||
printf
|
||||
("%4u: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n",
|
||||
(i * 32) + j, ntohs(p[0]), ntohs(p[1]),
|
||||
ntohs(p[2]), ntohs(p[3]), ntohs(p[4]), ntohs(p[5]),
|
||||
ntohs(p[6]), ntohs(p[7]));
|
||||
}
|
||||
}
|
||||
printf("%d pkeys capacity for this port\n", n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int portnum = (in << 8) | out;
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
|
||||
return "slvl query failed";
|
||||
|
||||
mad_dump_sltovl(buf, sizeof buf, data, sizeof data);
|
||||
printf("ports: in %2d, out %2d: ", in, out);
|
||||
printf("%s", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *sl2vl_table(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int type, num_ports, portnum = 0;
|
||||
int i;
|
||||
char *ret;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_decode_field(data, IB_NODE_TYPE_F, &type);
|
||||
mad_decode_field(data, IB_NODE_NPORTS_F, &num_ports);
|
||||
if (portnum > num_ports)
|
||||
return "invalid port number";
|
||||
|
||||
printf("# SL2VL table: %s\n", portid2str(dest));
|
||||
printf("# SL: |");
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("%2d|", i);
|
||||
printf("\n");
|
||||
|
||||
if (type != IB_NODE_SWITCH)
|
||||
return sl2vl_dump_table_entry(dest, 0, 0);
|
||||
|
||||
for (i = 0; i <= num_ports; i++) {
|
||||
ret = sl2vl_dump_table_entry(dest, i, portnum);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *vlarb_dump_table_entry(ib_portid_t * dest, int portnum, int offset,
|
||||
unsigned cap)
|
||||
{
|
||||
char buf[2048];
|
||||
char data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_VL_ARBITRATION,
|
||||
(offset << 16) | portnum, 0, srcport))
|
||||
return "vl arb query failed";
|
||||
mad_dump_vlarbitration(buf, sizeof(buf), data, cap * 2);
|
||||
printf("%s", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *vlarb_dump_table(ib_portid_t * dest, int portnum,
|
||||
char *name, int offset, int cap)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
printf("# %s priority VL Arbitration Table:", name);
|
||||
ret = vlarb_dump_table_entry(dest, portnum, offset,
|
||||
cap < 32 ? cap : 32);
|
||||
if (!ret && cap > 32)
|
||||
ret = vlarb_dump_table_entry(dest, portnum, offset + 1,
|
||||
cap - 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int portnum = 0;
|
||||
int type, enhsp0, lowcap, highcap;
|
||||
char *ret = 0;
|
||||
|
||||
if (argc > 0)
|
||||
portnum = strtol(argv[0], 0, 0);
|
||||
|
||||
/* port number of 0 could mean SP0 or port MAD arrives on */
|
||||
if (portnum == 0) {
|
||||
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0,
|
||||
srcport))
|
||||
return "node info query failed";
|
||||
|
||||
mad_decode_field(data, IB_NODE_TYPE_F, &type);
|
||||
if (type == IB_NODE_SWITCH) {
|
||||
memset(data, 0, sizeof(data));
|
||||
if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0,
|
||||
0, srcport))
|
||||
return "switch info query failed";
|
||||
mad_decode_field(data, IB_SW_ENHANCED_PORT0_F, &enhsp0);
|
||||
if (!enhsp0) {
|
||||
printf
|
||||
("# No VLArbitration tables (BSP0): %s port %d\n",
|
||||
portid2str(dest), 0);
|
||||
return 0;
|
||||
}
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
}
|
||||
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
|
||||
return "port info query failed";
|
||||
|
||||
mad_decode_field(data, IB_PORT_VL_ARBITRATION_LOW_CAP_F, &lowcap);
|
||||
mad_decode_field(data, IB_PORT_VL_ARBITRATION_HIGH_CAP_F, &highcap);
|
||||
|
||||
printf("# VLArbitration tables: %s port %d LowCap %d HighCap %d\n",
|
||||
portid2str(dest), portnum, lowcap, highcap);
|
||||
|
||||
if (lowcap > 0)
|
||||
ret = vlarb_dump_table(dest, portnum, "Low", 1, lowcap);
|
||||
|
||||
if (!ret && highcap > 0)
|
||||
ret = vlarb_dump_table(dest, portnum, "High", 3, highcap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *guid_info(ib_portid_t * dest, char **argv, int argc)
|
||||
{
|
||||
uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
|
||||
int i, j, k;
|
||||
uint64_t *p;
|
||||
unsigned mod;
|
||||
int n;
|
||||
|
||||
/* Get the guid capacity */
|
||||
if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, 0, 0, srcport))
|
||||
return "port info failed";
|
||||
mad_decode_field(data, IB_PORT_GUID_CAP_F, &n);
|
||||
|
||||
for (i = 0; i < (n + 7) / 8; i++) {
|
||||
mod = i;
|
||||
if (!smp_query_via(data, dest, IB_ATTR_GUID_INFO, mod, 0,
|
||||
srcport))
|
||||
return "guid info query failed";
|
||||
if (i + 1 == (n + 7) / 8)
|
||||
k = ((n + 1 - i * 8) / 2) * 2;
|
||||
else
|
||||
k = 8;
|
||||
p = (uint64_t *) data;
|
||||
for (j = 0; j < k; j += 2, p += 2) {
|
||||
printf("%4u: 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
|
||||
(i * 8) + j, ntohll(p[0]), ntohll(p[1]));
|
||||
}
|
||||
}
|
||||
printf("%d guids capacity for this port\n", n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 1:
|
||||
node_name_map_file = strdup(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
ibd_dest_type = IB_DEST_DRSLID;
|
||||
break;
|
||||
case 'x':
|
||||
extended_speeds = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char usage_args[1024];
|
||||
int mgmt_classes[3] =
|
||||
{ IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
char *err;
|
||||
op_fn_t *fn;
|
||||
const match_rec_t *r;
|
||||
int n;
|
||||
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"combined", 'c', 0, NULL,
|
||||
"use Combined route address argument"},
|
||||
{"node-name-map", 1, 1, "<file>", "node name map file"},
|
||||
{"extended", 'x', 0, NULL, "use extended speeds"},
|
||||
{0}
|
||||
};
|
||||
const char *usage_examples[] = {
|
||||
"portinfo 3 1\t\t\t\t# portinfo by lid, with port modifier",
|
||||
"-G switchinfo 0x2C9000100D051 1\t# switchinfo by guid",
|
||||
"-D nodeinfo 0\t\t\t\t# nodeinfo by direct route",
|
||||
"-c nodeinfo 6 0,12\t\t\t# nodeinfo by combined route",
|
||||
NULL
|
||||
};
|
||||
|
||||
n = sprintf(usage_args, "<op> <dest dr_path|lid|guid> [op params]\n"
|
||||
"\nSupported ops (and aliases, case insensitive):\n");
|
||||
for (r = match_tbl; r->name; r++) {
|
||||
n += snprintf(usage_args + n, sizeof(usage_args) - n,
|
||||
" %s (%s) <addr>%s\n", r->name,
|
||||
r->alias ? r->alias : "",
|
||||
r->opt_portnum ? " [<portnum>]" : "");
|
||||
if (n >= sizeof(usage_args))
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, NULL, opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2)
|
||||
ibdiag_show_usage();
|
||||
|
||||
if (!(fn = match_op(match_tbl, argv[0])))
|
||||
IBEXIT("operation '%s' not supported", argv[0]);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 3);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
smp_mkey_set(srcport, ibd_mkey);
|
||||
|
||||
node_name_map = open_node_name_map(node_name_map_file);
|
||||
|
||||
if (ibd_dest_type != IB_DEST_DRSLID) {
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[1],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", argv[1]);
|
||||
if ((err = fn(&portid, argv + 2, argc - 2)))
|
||||
IBEXIT("operation %s: %s", argv[0], err);
|
||||
} else {
|
||||
char concat[64];
|
||||
|
||||
memset(concat, 0, 64);
|
||||
snprintf(concat, sizeof(concat), "%s %s", argv[1], argv[2]);
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, concat,
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0)
|
||||
IBEXIT("can't resolve destination port %s", concat);
|
||||
if ((err = fn(&portid, argv + 3, argc - 3)))
|
||||
IBEXIT("operation %s: %s", argv[0], err);
|
||||
}
|
||||
close_node_name_map(node_name_map);
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Mellanox Technologies LTD. All rights reserved.
|
||||
* Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <infiniband/umad.h>
|
||||
#include <infiniband/mad.h>
|
||||
|
||||
#include "ibdiag_common.h"
|
||||
|
||||
#define IS3_DEVICE_ID 47396
|
||||
|
||||
#define IB_MLX_VENDOR_CLASS 10
|
||||
/* Vendor specific Attribute IDs */
|
||||
#define IB_MLX_IS3_GENERAL_INFO 0x17
|
||||
#define IB_MLX_IS3_CONFIG_SPACE_ACCESS 0x50
|
||||
#define IB_MLX_IS4_COUNTER_GROUP_INFO 0x90
|
||||
#define IB_MLX_IS4_CONFIG_COUNTER_GROUP 0x91
|
||||
/* Config space addresses */
|
||||
#define IB_MLX_IS3_PORT_XMIT_WAIT 0x10013C
|
||||
|
||||
|
||||
struct ibmad_port *srcport;
|
||||
|
||||
static ibmad_gid_t dgid;
|
||||
static int with_grh;
|
||||
|
||||
typedef struct {
|
||||
uint16_t hw_revision;
|
||||
uint16_t device_id;
|
||||
uint8_t reserved[24];
|
||||
uint32_t uptime;
|
||||
} is3_hw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t resv1;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t sub_minor;
|
||||
uint32_t build_id;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint16_t year;
|
||||
uint16_t resv2;
|
||||
uint16_t hour;
|
||||
uint8_t psid[16];
|
||||
uint32_t ini_file_version;
|
||||
} is3_fw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ext_major;
|
||||
uint32_t ext_minor;
|
||||
uint32_t ext_sub_minor;
|
||||
uint32_t reserved[4];
|
||||
} is4_fw_ext_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t resv1;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t sub_minor;
|
||||
uint8_t resv2[28];
|
||||
} is3_sw_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[8];
|
||||
is3_hw_info_t hw_info;
|
||||
is3_fw_info_t fw_info;
|
||||
is3_sw_info_t sw_info;
|
||||
} is3_general_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[8];
|
||||
is3_hw_info_t hw_info;
|
||||
is3_fw_info_t fw_info;
|
||||
is4_fw_ext_info_t ext_fw_info;
|
||||
is3_sw_info_t sw_info;
|
||||
} is4_general_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[8];
|
||||
struct is3_record {
|
||||
uint32_t address;
|
||||
uint32_t data;
|
||||
uint32_t mask;
|
||||
} record[18];
|
||||
} is3_config_space_t;
|
||||
|
||||
#define COUNTER_GROUPS_NUM 2
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved1[8];
|
||||
uint8_t reserved[3];
|
||||
uint8_t num_of_counter_groups;
|
||||
uint32_t group_masks[COUNTER_GROUPS_NUM];
|
||||
} is4_counter_group_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved[3];
|
||||
uint8_t group_select;
|
||||
} is4_group_select_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reserved1[8];
|
||||
uint8_t reserved[4];
|
||||
is4_group_select_t group_selects[COUNTER_GROUPS_NUM];
|
||||
} is4_config_counter_groups_t;
|
||||
|
||||
static uint16_t ext_fw_info_device[][2] = {
|
||||
{0x0245, 0x0245}, /* Switch-X */
|
||||
{0xc738, 0xc73b}, /* Switch-X */
|
||||
{0xcb20, 0xcb20}, /* Switch-IB */
|
||||
{0xcf08, 0xcf08}, /* Switch-IB2*/
|
||||
{0x01b3, 0x01b3}, /* IS-4 */
|
||||
{0x1003, 0x1017}, /* Connect-X */
|
||||
{0x1b02, 0x1b02}, /* Bull SwitchX */
|
||||
{0x1b50, 0x1b50}, /* Bull SwitchX */
|
||||
{0x1ba0, 0x1ba0}, /* Bull SwitchIB */
|
||||
{0x1bd0, 0x1bd5}, /* Bull SwitchIB and SwitchIB2 */
|
||||
{0x1b33, 0x1b33}, /* Bull ConnectX3 */
|
||||
{0x1b73, 0x1b73}, /* Bull ConnectX3 */
|
||||
{0x1b40, 0x1b41}, /* Bull ConnectX3 */
|
||||
{0x1b60, 0x1b61}, /* Bull ConnectX3 */
|
||||
{0x1b83, 0x1b83}, /* Bull ConnectIB */
|
||||
{0x1b93, 0x1b94}, /* Bull ConnectIB */
|
||||
{0x1bb4, 0x1bb5}, /* Bull ConnectX4 */
|
||||
{0x1bc4, 0x1bc4}, /* Bull ConnectX4 */
|
||||
{0x0000, 0x0000}};
|
||||
|
||||
static int is_ext_fw_info_supported(uint16_t device_id) {
|
||||
int i;
|
||||
for (i = 0; ext_fw_info_device[i][0]; i++)
|
||||
if (ext_fw_info_device[i][0] <= device_id &&
|
||||
device_id <= ext_fw_info_device[i][1])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_vendor(ib_portid_t *portid, struct ibmad_port *srcport,
|
||||
uint8_t class, uint8_t method, uint16_t attr_id,
|
||||
uint32_t attr_mod, void *data)
|
||||
{
|
||||
ib_vendor_call_t call;
|
||||
|
||||
memset(&call, 0, sizeof(call));
|
||||
call.mgmt_class = class;
|
||||
call.method = method;
|
||||
call.timeout = ibd_timeout;
|
||||
call.attrid = attr_id;
|
||||
call.mod = attr_mod;
|
||||
|
||||
if (!ib_vendor_call_via(data, portid, &call, srcport)) {
|
||||
fprintf(stderr,"vendstat: method %u, attribute %u failure\n", method, attr_id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_config_space_records(ib_portid_t *portid, unsigned set,
|
||||
is3_config_space_t *cs, unsigned records)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (records > 18)
|
||||
records = 18;
|
||||
for (i = 0; i < records; i++) {
|
||||
cs->record[i].address = htonl(cs->record[i].address);
|
||||
cs->record[i].data = htonl(cs->record[i].data);
|
||||
cs->record[i].mask = htonl(cs->record[i].mask);
|
||||
}
|
||||
|
||||
if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS,
|
||||
set ? IB_MAD_METHOD_SET : IB_MAD_METHOD_GET,
|
||||
IB_MLX_IS3_CONFIG_SPACE_ACCESS, 2 << 22 | records << 16,
|
||||
cs)) {
|
||||
fprintf(stderr,"cannot %s config space records\n", set ? "set" : "get");
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < records; i++) {
|
||||
printf("Config space record at 0x%x: 0x%x\n",
|
||||
ntohl(cs->record[i].address),
|
||||
ntohl(cs->record[i].data & cs->record[i].mask));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int counter_groups_info(ib_portid_t * portid, int port)
|
||||
{
|
||||
char buf[1024];
|
||||
is4_counter_group_info_t *cg_info;
|
||||
int i, num_cg;
|
||||
|
||||
/* Counter Group Info */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
||||
IB_MLX_IS4_COUNTER_GROUP_INFO, port, buf)) {
|
||||
fprintf(stderr,"counter group info query failure\n");
|
||||
return -1;
|
||||
}
|
||||
cg_info = (is4_counter_group_info_t *) & buf;
|
||||
num_cg = cg_info->num_of_counter_groups;
|
||||
printf("counter_group_info:\n");
|
||||
printf("%d counter groups\n", num_cg);
|
||||
for (i = 0; i < num_cg; i++)
|
||||
printf("group%d mask %#x\n", i, ntohl(cg_info->group_masks[i]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Group0 counter config values */
|
||||
#define IS4_G0_PortXmtDataSL_0_7 0
|
||||
#define IS4_G0_PortXmtDataSL_8_15 1
|
||||
#define IS4_G0_PortRcvDataSL_0_7 2
|
||||
|
||||
/* Group1 counter config values */
|
||||
#define IS4_G1_PortXmtDataSL_8_15 1
|
||||
#define IS4_G1_PortRcvDataSL_0_7 2
|
||||
#define IS4_G1_PortRcvDataSL_8_15 8
|
||||
|
||||
static int cg0, cg1;
|
||||
|
||||
static int config_counter_groups(ib_portid_t * portid, int port)
|
||||
{
|
||||
char buf[1024];
|
||||
is4_config_counter_groups_t *cg_config;
|
||||
|
||||
/* configure counter groups for groups 0 and 1 */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
cg_config = (is4_config_counter_groups_t *) & buf;
|
||||
|
||||
printf("counter_groups_config: configuring group0 %d group1 %d\n", cg0,
|
||||
cg1);
|
||||
cg_config->group_selects[0].group_select = (uint8_t) cg0;
|
||||
cg_config->group_selects[1].group_select = (uint8_t) cg1;
|
||||
|
||||
if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_SET,
|
||||
IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
|
||||
fprintf(stderr, "config counter group set failure\n");
|
||||
return -1;
|
||||
}
|
||||
/* get config counter groups */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
if (do_vendor(portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
||||
IB_MLX_IS4_CONFIG_COUNTER_GROUP, port, buf)) {
|
||||
fprintf(stderr, "config counter group query failure\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int general_info, xmit_wait, counter_group_info, config_counter_group;
|
||||
static is3_config_space_t write_cs, read_cs;
|
||||
static unsigned write_cs_records, read_cs_records;
|
||||
|
||||
|
||||
static int process_opt(void *context, int ch, char *optarg)
|
||||
{
|
||||
int ret;
|
||||
switch (ch) {
|
||||
case 'N':
|
||||
general_info = 1;
|
||||
break;
|
||||
case 'w':
|
||||
xmit_wait = 1;
|
||||
break;
|
||||
case 'i':
|
||||
counter_group_info = 1;
|
||||
break;
|
||||
case 'c':
|
||||
config_counter_group = 1;
|
||||
ret = sscanf(optarg, "%d,%d", &cg0, &cg1);
|
||||
if (ret != 2)
|
||||
return -1;
|
||||
break;
|
||||
case 'R':
|
||||
if (read_cs_records >= 18)
|
||||
break;
|
||||
ret = sscanf(optarg, "%x,%x",
|
||||
&read_cs.record[read_cs_records].address,
|
||||
&read_cs.record[read_cs_records].mask);
|
||||
if (ret < 1)
|
||||
return -1;
|
||||
else if (ret == 1)
|
||||
read_cs.record[read_cs_records].mask = 0xffffffff;
|
||||
read_cs_records++;
|
||||
break;
|
||||
case 'W':
|
||||
if (write_cs_records >= 18)
|
||||
break;
|
||||
ret = sscanf(optarg, "%x,%x,%x",
|
||||
&write_cs.record[write_cs_records].address,
|
||||
&write_cs.record[write_cs_records].data,
|
||||
&write_cs.record[write_cs_records].mask);
|
||||
if (ret < 2)
|
||||
return -1;
|
||||
else if (ret == 2)
|
||||
write_cs.record[write_cs_records].mask = 0xffffffff;
|
||||
write_cs_records++;
|
||||
break;
|
||||
case 25:
|
||||
if (!inet_pton(AF_INET6, optarg, &dgid)) {
|
||||
fprintf(stderr, "dgid format is wrong!\n");
|
||||
ibdiag_show_usage();
|
||||
return 1;
|
||||
}
|
||||
with_grh = 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mgmt_classes[2] = { IB_SA_CLASS, IB_MLX_VENDOR_CLASS };
|
||||
ib_portid_t portid = { 0 };
|
||||
int port = 0;
|
||||
char buf[1024];
|
||||
uint32_t fw_ver_major = 0;
|
||||
uint32_t fw_ver_minor = 0;
|
||||
uint32_t fw_ver_sub_minor = 0;
|
||||
uint8_t sw_ver_major = 0, sw_ver_minor = 0, sw_ver_sub_minor = 0;
|
||||
is3_general_info_t *gi_is3;
|
||||
is4_general_info_t *gi_is4;
|
||||
const struct ibdiag_opt opts[] = {
|
||||
{"N", 'N', 0, NULL, "show IS3 or IS4 general information"},
|
||||
{"w", 'w', 0, NULL, "show IS3 port xmit wait counters"},
|
||||
{"i", 'i', 0, NULL, "show IS4 counter group info"},
|
||||
{"c", 'c', 1, "<num,num>", "configure IS4 counter groups"},
|
||||
{"Read", 'R', 1, "<addr,mask>", "Read configuration space record at addr"},
|
||||
{"Write", 'W', 1, "<addr,val,mask>", "Write configuration space record at addr"},
|
||||
{"dgid", 25, 1, NULL, "remote gid (IPv6 format)"},
|
||||
{0}
|
||||
};
|
||||
|
||||
char usage_args[] = "<lid|guid> [port]";
|
||||
const char *usage_examples[] = {
|
||||
"-N 6\t\t# read IS3 or IS4 general information",
|
||||
"-w 6\t\t# read IS3 port xmit wait counters",
|
||||
"-i 6 12\t# read IS4 port 12 counter group info",
|
||||
"-c 0,1 6 12\t# configure IS4 port 12 counter groups for PortXmitDataSL",
|
||||
"-c 2,8 6 12\t# configure IS4 port 12 counter groups for PortRcvDataSL",
|
||||
NULL
|
||||
};
|
||||
|
||||
ibdiag_process_opts(argc, argv, NULL, "DKy", opts, process_opt,
|
||||
usage_args, usage_examples);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
port = strtoul(argv[1], 0, 0);
|
||||
|
||||
srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
|
||||
if (!srcport)
|
||||
IBEXIT("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
|
||||
|
||||
if (argc) {
|
||||
if (with_grh && ibd_dest_type != IB_DEST_LID) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("When using GRH, LID should be provided");
|
||||
}
|
||||
if (resolve_portid_str(ibd_ca, ibd_ca_port, &portid, argv[0],
|
||||
ibd_dest_type, ibd_sm_id, srcport) < 0) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("can't resolve destination port %s", argv[0]);
|
||||
}
|
||||
if (with_grh) {
|
||||
portid.grh_present = 1;
|
||||
memcpy(&portid.gid, &dgid, sizeof(portid.gid));
|
||||
}
|
||||
} else {
|
||||
if (resolve_self(ibd_ca, ibd_ca_port, &portid, &port, 0) < 0) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("can't resolve self port %s", argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (counter_group_info) {
|
||||
counter_groups_info(&portid, port);
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (config_counter_group) {
|
||||
config_counter_groups(&portid, port);
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (read_cs_records || write_cs_records) {
|
||||
if (read_cs_records)
|
||||
do_config_space_records(&portid, 0, &read_cs,
|
||||
read_cs_records);
|
||||
if (write_cs_records)
|
||||
do_config_space_records(&portid, 1, &write_cs,
|
||||
write_cs_records);
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* These are Mellanox specific vendor MADs */
|
||||
/* but vendors change the VendorId so how know for sure ? */
|
||||
/* Only General Info and Port Xmit Wait Counters */
|
||||
/* queries are currently supported */
|
||||
if (!general_info && !xmit_wait) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("at least one of -N and -w must be specified");
|
||||
}
|
||||
/* Would need a list of these and it might not be complete */
|
||||
/* so for right now, punt on this */
|
||||
|
||||
/* vendor ClassPortInfo is required attribute if class supported */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
||||
CLASS_PORT_INFO, 0, buf)) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("classportinfo query");
|
||||
}
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
gi_is3 = (is3_general_info_t *) &buf;
|
||||
if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
|
||||
IB_MLX_IS3_GENERAL_INFO, 0, gi_is3)) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("generalinfo query");
|
||||
}
|
||||
|
||||
if (is_ext_fw_info_supported(ntohs(gi_is3->hw_info.device_id))) {
|
||||
gi_is4 = (is4_general_info_t *) &buf;
|
||||
fw_ver_major = ntohl(gi_is4->ext_fw_info.ext_major);
|
||||
fw_ver_minor = ntohl(gi_is4->ext_fw_info.ext_minor);
|
||||
fw_ver_sub_minor = ntohl(gi_is4->ext_fw_info.ext_sub_minor);
|
||||
sw_ver_major = gi_is4->sw_info.major;
|
||||
sw_ver_minor = gi_is4->sw_info.minor;
|
||||
sw_ver_sub_minor = gi_is4->sw_info.sub_minor;
|
||||
} else {
|
||||
fw_ver_major = gi_is3->fw_info.major;
|
||||
fw_ver_minor = gi_is3->fw_info.minor;
|
||||
fw_ver_sub_minor = gi_is3->fw_info.sub_minor;
|
||||
sw_ver_major = gi_is3->sw_info.major;
|
||||
sw_ver_minor = gi_is3->sw_info.minor;
|
||||
sw_ver_sub_minor = gi_is3->sw_info.sub_minor;
|
||||
}
|
||||
|
||||
if (general_info) {
|
||||
/* dump IS3 or IS4 general info here */
|
||||
printf("hw_dev_rev: 0x%04x\n", ntohs(gi_is3->hw_info.hw_revision));
|
||||
printf("hw_dev_id: 0x%04x\n", ntohs(gi_is3->hw_info.device_id));
|
||||
printf("hw_uptime: 0x%08x\n", ntohl(gi_is3->hw_info.uptime));
|
||||
printf("fw_version: %02d.%02d.%02d\n",
|
||||
fw_ver_major, fw_ver_minor, fw_ver_sub_minor);
|
||||
printf("fw_build_id: 0x%04x\n", ntohl(gi_is3->fw_info.build_id));
|
||||
printf("fw_date: %02x/%02x/%04x\n",
|
||||
gi_is3->fw_info.month, gi_is3->fw_info.day,
|
||||
ntohs(gi_is3->fw_info.year));
|
||||
printf("fw_psid: '%s'\n", gi_is3->fw_info.psid);
|
||||
printf("fw_ini_ver: %d\n",
|
||||
ntohl(gi_is3->fw_info.ini_file_version));
|
||||
printf("sw_version: %02d.%02d.%02d\n", sw_ver_major,
|
||||
sw_ver_minor, sw_ver_sub_minor);
|
||||
}
|
||||
|
||||
if (xmit_wait) {
|
||||
is3_config_space_t *cs;
|
||||
unsigned i;
|
||||
|
||||
if (ntohs(gi_is3->hw_info.device_id) != IS3_DEVICE_ID) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("Unsupported device ID 0x%x",
|
||||
ntohs(gi_is3->hw_info.device_id));
|
||||
}
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
/* Set record addresses for each port */
|
||||
cs = (is3_config_space_t *) & buf;
|
||||
for (i = 0; i < 16; i++)
|
||||
cs->record[i].address =
|
||||
htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 1) << 12));
|
||||
if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS,
|
||||
IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
|
||||
2 << 22 | 16 << 16, cs)) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("vendstat");
|
||||
}
|
||||
for (i = 0; i < 16; i++)
|
||||
if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
|
||||
printf("Port %d: PortXmitWait 0x%x\n", i + 4, ntohl(cs->record[i].data)); /* port 4 is first port */
|
||||
|
||||
/* Last 8 ports is another query */
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
/* Set record addresses for each port */
|
||||
cs = (is3_config_space_t *) & buf;
|
||||
for (i = 0; i < 8; i++)
|
||||
cs->record[i].address =
|
||||
htonl(IB_MLX_IS3_PORT_XMIT_WAIT + ((i + 17) << 12));
|
||||
if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS,
|
||||
IB_MAD_METHOD_GET, IB_MLX_IS3_CONFIG_SPACE_ACCESS,
|
||||
2 << 22 | 8 << 16, cs)) {
|
||||
mad_rpc_close_port(srcport);
|
||||
IBEXIT("vendstat");
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (cs->record[i].data) /* PortXmitWait is 32 bit counter */
|
||||
printf("Port %d: PortXmitWait 0x%x\n",
|
||||
i < 4 ? i + 21 : i - 3,
|
||||
ntohl(cs->record[i].data));
|
||||
}
|
||||
|
||||
mad_rpc_close_port(srcport);
|
||||
exit(0);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
Chelsio Communications, Inc.
|
||||
@@ -1,29 +0,0 @@
|
||||
Copyright (c) 2010-2013. Chelsio Communications. All rights reserved.
|
||||
|
||||
This software is available to you under a choice of one of two
|
||||
licenses. You may choose to be licensed under the terms of the GNU
|
||||
General Public License (GPL) Version 2, available from the file
|
||||
COPYING in the main directory of this source tree, or the
|
||||
OpenIB.org BSD license below:
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}
|
||||
|
||||
SHLIBDIR?= /usr/lib
|
||||
LIB= cxgb4
|
||||
SHLIB_MAJOR= 1
|
||||
MK_PROFILE= no
|
||||
|
||||
SRCS= \
|
||||
cq.c \
|
||||
dev.c \
|
||||
qp.c \
|
||||
verbs.c
|
||||
|
||||
LIBADD= ibverbs pthread
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,19 +0,0 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
libcxgb4 is a userspace driver for the Chelsio T5 iWARP RNICs. It works
|
||||
as a plug-in module for libibverbs that allows programs to use Chelsio
|
||||
RNICs directly from userspace. See the libibverbs package for more
|
||||
information.
|
||||
|
||||
Using libcxgb4
|
||||
===================
|
||||
|
||||
libcxgb4 will be loaded and used automatically by programs linked with
|
||||
libibverbs. The iw_cxgbe kernel module must be loaded for Chelsio RNIC
|
||||
devices to be detected and used.
|
||||
|
||||
Supported Hardware
|
||||
==================
|
||||
|
||||
libcxgb4 supports the Chelsio T5 family of adapters.
|
||||
@@ -0,0 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#define ENODATA ECONNREFUSED
|
||||
#define likely(x) __predict_true(x)
|
||||
#define unlikely(x) __predict_false(x)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006-2016 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -29,15 +29,12 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <infiniband/opcode.h>
|
||||
#include "libcxgb4.h"
|
||||
#include "cxgb4-abi.h"
|
||||
@@ -49,12 +46,12 @@ static void insert_recv_cqe(struct t4_wq *wq, struct t4_cq *cq)
|
||||
PDBG("%s wq %p cq %p sw_cidx %u sw_pidx %u\n", __func__,
|
||||
wq, cq, cq->sw_cidx, cq->sw_pidx);
|
||||
memset(&cqe, 0, sizeof(cqe));
|
||||
cqe.header = cpu_to_be32(V_CQE_STATUS(T4_ERR_SWFLUSH) |
|
||||
cqe.header = htobe32(V_CQE_STATUS(T4_ERR_SWFLUSH) |
|
||||
V_CQE_OPCODE(FW_RI_SEND) |
|
||||
V_CQE_TYPE(0) |
|
||||
V_CQE_SWCQE(1) |
|
||||
V_CQE_QPID(wq->sq.qid));
|
||||
cqe.bits_type_ts = cpu_to_be64(V_CQE_GENBIT((u64)cq->gen));
|
||||
cqe.bits_type_ts = htobe64(V_CQE_GENBIT((u64)cq->gen));
|
||||
cq->sw_queue[cq->sw_pidx] = cqe;
|
||||
t4_swcq_produce(cq);
|
||||
}
|
||||
@@ -82,13 +79,13 @@ static void insert_sq_cqe(struct t4_wq *wq, struct t4_cq *cq,
|
||||
PDBG("%s wq %p cq %p sw_cidx %u sw_pidx %u\n", __func__,
|
||||
wq, cq, cq->sw_cidx, cq->sw_pidx);
|
||||
memset(&cqe, 0, sizeof(cqe));
|
||||
cqe.header = cpu_to_be32(V_CQE_STATUS(T4_ERR_SWFLUSH) |
|
||||
cqe.header = htobe32(V_CQE_STATUS(T4_ERR_SWFLUSH) |
|
||||
V_CQE_OPCODE(swcqe->opcode) |
|
||||
V_CQE_TYPE(1) |
|
||||
V_CQE_SWCQE(1) |
|
||||
V_CQE_QPID(wq->sq.qid));
|
||||
CQE_WRID_SQ_IDX(&cqe) = swcqe->idx;
|
||||
cqe.bits_type_ts = cpu_to_be64(V_CQE_GENBIT((u64)cq->gen));
|
||||
cqe.bits_type_ts = htobe64(V_CQE_GENBIT((u64)cq->gen));
|
||||
cq->sw_queue[cq->sw_pidx] = cqe;
|
||||
t4_swcq_produce(cq);
|
||||
}
|
||||
@@ -151,7 +148,7 @@ static void flush_completed_wrs(struct t4_wq *wq, struct t4_cq *cq)
|
||||
PDBG("%s moving cqe into swcq sq idx %u cq idx %u\n",
|
||||
__func__, cidx, cq->sw_pidx);
|
||||
|
||||
swsqe->cqe.header |= htonl(V_CQE_SWCQE(1));
|
||||
swsqe->cqe.header |= htobe32(V_CQE_SWCQE(1));
|
||||
cq->sw_queue[cq->sw_pidx] = swsqe->cqe;
|
||||
t4_swcq_produce(cq);
|
||||
swsqe->flushed = 1;
|
||||
@@ -167,8 +164,8 @@ static void create_read_req_cqe(struct t4_wq *wq, struct t4_cqe *hw_cqe,
|
||||
struct t4_cqe *read_cqe)
|
||||
{
|
||||
read_cqe->u.scqe.cidx = wq->sq.oldest_read->idx;
|
||||
read_cqe->len = ntohl(wq->sq.oldest_read->read_len);
|
||||
read_cqe->header = htonl(V_CQE_QPID(CQE_QPID(hw_cqe)) |
|
||||
read_cqe->len = be32toh(wq->sq.oldest_read->read_len);
|
||||
read_cqe->header = htobe32(V_CQE_QPID(CQE_QPID(hw_cqe)) |
|
||||
V_CQE_SWCQE(SW_CQE(hw_cqe)) |
|
||||
V_CQE_OPCODE(FW_RI_READ_REQ) |
|
||||
V_CQE_TYPE(1));
|
||||
@@ -275,7 +272,7 @@ void c4iw_flush_hw_cq(struct c4iw_cq *chp)
|
||||
} else {
|
||||
swcqe = &chp->cq.sw_queue[chp->cq.sw_pidx];
|
||||
*swcqe = *hw_cqe;
|
||||
swcqe->header |= cpu_to_be32(V_CQE_SWCQE(1));
|
||||
swcqe->header |= htobe32(V_CQE_SWCQE(1));
|
||||
t4_swcq_produce(&chp->cq);
|
||||
}
|
||||
next_cqe:
|
||||
@@ -322,11 +319,11 @@ void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count)
|
||||
static void dump_cqe(void *arg)
|
||||
{
|
||||
u64 *p = arg;
|
||||
syslog(LOG_NOTICE, "cxgb4 err cqe %016lx %016lx %016lx %016lx\n",
|
||||
be64_to_cpu(p[0]),
|
||||
be64_to_cpu(p[1]),
|
||||
be64_to_cpu(p[2]),
|
||||
be64_to_cpu(p[3]));
|
||||
syslog(LOG_NOTICE, "cxgb4 err cqe %016llx %016llx %016llx %016llx\n",
|
||||
(long long)be64toh(p[0]),
|
||||
(long long)be64toh(p[1]),
|
||||
(long long)be64toh(p[2]),
|
||||
(long long)be64toh(p[3]));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -428,6 +425,11 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
|
||||
advance_oldest_read(wq);
|
||||
}
|
||||
|
||||
if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) {
|
||||
ret = -EAGAIN;
|
||||
goto skip_cqe;
|
||||
}
|
||||
|
||||
if (CQE_STATUS(hw_cqe) || t4_wq_in_error(wq)) {
|
||||
*cqe_flushed = (CQE_STATUS(hw_cqe) == T4_ERR_SWFLUSH);
|
||||
wq->error = 1;
|
||||
@@ -439,11 +441,6 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
|
||||
goto proc_cqe;
|
||||
}
|
||||
|
||||
if (CQE_OPCODE(hw_cqe) == FW_RI_TERMINATE) {
|
||||
ret = -EAGAIN;
|
||||
goto skip_cqe;
|
||||
}
|
||||
|
||||
/*
|
||||
* RECV completion.
|
||||
*/
|
||||
@@ -463,7 +460,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe,
|
||||
}
|
||||
if (unlikely((CQE_WRID_MSN(hw_cqe) != (wq->rq.msn)))) {
|
||||
t4_set_wq_in_error(wq);
|
||||
hw_cqe->header |= htonl(V_CQE_STATUS(T4_ERR_MSN));
|
||||
hw_cqe->header |= htobe32(V_CQE_STATUS(T4_ERR_MSN));
|
||||
goto proc_cqe;
|
||||
}
|
||||
goto proc_cqe;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2006-2016 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@@ -32,6 +32,7 @@
|
||||
#ifndef IWCH_ABI_H
|
||||
#define IWCH_ABI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <infiniband/kern-abi.h>
|
||||
|
||||
struct c4iw_alloc_ucontext_resp {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user