예제 #1
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #2
0
int
ib_resolve_self_via(ib_portid_t *portid, int *portnum, ibmad_gid_t *gid,
		    const void *srcport)
{
	ib_portid_t self = {0};
	uint8_t portinfo[64];
	uint8_t nodeinfo[64];
	uint64_t guid, prefix;

	if (!smp_query_via(nodeinfo, &self, IB_ATTR_NODE_INFO, 0, 0, srcport))
		return -1;

	if (!smp_query_via(portinfo, &self, IB_ATTR_PORT_INFO, 0, 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(nodeinfo, IB_NODE_PORT_GUID_F, &guid);

	if (portnum)
		mad_decode_field(nodeinfo, IB_NODE_LOCAL_PORT_F, portnum);
	if (gid) {
		mad_encode_field(*gid, IB_GID_PREFIX_F, &prefix);
		mad_encode_field(*gid, IB_GID_GUID_F, &guid);
	}
	return 0;
}
예제 #3
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #4
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #5
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #6
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #7
0
파일: ibsendtrap.c 프로젝트: Cai900205/test
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;
}
예제 #8
0
파일: ibsendtrap.c 프로젝트: Cai900205/test
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;
}
예제 #9
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));
}
예제 #10
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;
}
예제 #11
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #12
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #13
0
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;

	memset(ni, 0, sizeof(node->nodeinfo));
	if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, timeout, srcport))
		return -1;

	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++) {
		if (!*s)
			break;
		if (!isprint(*s))
			*s = ' ';
	}

	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);
	mad_decode_field(ni, IB_NODE_TYPE_F, &node->type);
	mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports);

	mad_decode_field(ni, IB_NODE_PORT_GUID_F, &port->portguid);
	mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &port->portnum);
	mad_decode_field(pi, IB_PORT_LID_F, &port->lid);
	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);
	return 0;
}
예제 #14
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #15
0
static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
{
	void *si = sw->switchinfo, *fdb = sw->fdb;

	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);

	if (lid >= sw->linearcap && lid > sw->linearFDBtop)
		return -1;

	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]);
	return sw->fdb[lid % 64];
}
예제 #16
0
int
ib_resolve_smlid_via(ib_portid_t *sm_id, int timeout, const void *srcport)
{
	ib_portid_t self = {0};
	uint8_t portinfo[64];
	int lid;

	memset(sm_id, 0, sizeof(*sm_id));

	if (!smp_query_via(portinfo, &self, IB_ATTR_PORT_INFO,
			   0, 0, srcport))
		return -1;

	mad_decode_field(portinfo, IB_PORT_SMLID_F, &lid);

	return ib_portid_set(sm_id, lid, 0, 0);
}
예제 #17
0
파일: smpquery.c 프로젝트: Cai900205/test
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;
}
예제 #18
0
파일: smpquery.c 프로젝트: Cai900205/test
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, sizeof data, 0);
	return 0;
}
예제 #19
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;
}
예제 #20
0
int ib_resolve_guid_via(ib_portid_t * portid, uint64_t * guid,
			ib_portid_t * sm_id, int timeout,
			const struct ibmad_port *srcport)
{
	ib_portid_t sm_portid;
	uint8_t buf[IB_SA_DATA_SIZE] = { 0 };
	ib_portid_t self = { 0 };
	uint64_t selfguid, prefix;
	ibmad_gid_t selfgid;
	uint8_t nodeinfo[64];

	if (!sm_id) {
		sm_id = &sm_portid;
		if (ib_resolve_smlid_via(sm_id, timeout, srcport) < 0)
			return -1;
	}

	if (!smp_query_via(nodeinfo, &self, IB_ATTR_NODE_INFO, 0, 0, srcport))
		return -1;
	mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &selfguid);
	mad_set_field64(selfgid, 0, IB_GID_PREFIX_F, IB_DEFAULT_SUBN_PREFIX);
	mad_set_field64(selfgid, 0, IB_GID_GUID_F, selfguid);

	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;
}
예제 #21
0
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");
}
예제 #22
0
파일: ib_sw.c 프로젝트: TACC/tacc_stats
static void collect_hca_port(struct stats *stats, char *hca_name, int hca_port)
{
  struct ibmad_port *mad_port = NULL;
  int mad_timeout = 15;
  int mad_classes[] = { IB_SMI_DIRECT_CLASS, IB_PERFORMANCE_CLASS, };

  mad_port = mad_rpc_open_port(hca_name, hca_port, mad_classes, 2);
  if (mad_port == NULL) {
    ERROR("cannot open MAD port for HCA `%s' port %d\n", hca_name, hca_port);
    goto out;
  }

  /* For reasons we don't understand, PMA queries can only be LID
     addressed.  But we don't know the LID of the switch to which the
     HCA is connected, so we send a SMP on the directed route 0,1 and
     ask the port to identify itself. */

  ib_portid_t sw_port_id = {
    .drpath = {
      .cnt = 1,
      .p = { 0, 1, },
    },
  };

  uint8_t sw_info[64];
  memset(sw_info, 0, sizeof(sw_info));
  if (smp_query_via(sw_info, &sw_port_id, IB_ATTR_PORT_INFO, 0, mad_timeout, mad_port) == NULL) {
    ERROR("cannot query port info: %m\n");
    goto out;
  }

  int sw_lid, sw_port;
  mad_decode_field(sw_info, IB_PORT_LID_F, &sw_lid);
  mad_decode_field(sw_info, IB_PORT_LOCAL_PORT_F, &sw_port);
  printf("IB_ATTR_PORT_INFO(drpath.p = {0, 1}): switch_lid %d, switch_local_port %d\n",
          sw_lid, sw_port);

  sw_port_id.lid = sw_lid;

  uint8_t sw_pma[1024];
  memset(sw_pma, 0, sizeof(sw_pma));
  if (pma_query_via(sw_pma, &sw_port_id, sw_port, mad_timeout, IB_GSI_PORT_COUNTERS_EXT, mad_port) == NULL) {
    ERROR("cannot query performance counters of switch LID %d, port %d: %m\n", sw_lid, sw_port);
    goto out;
  }

  uint64_t sw_rx_bytes, sw_rx_packets, sw_tx_bytes, sw_tx_packets;
  mad_decode_field(sw_pma, IB_PC_EXT_RCV_BYTES_F, &sw_rx_bytes);
  mad_decode_field(sw_pma, IB_PC_EXT_RCV_PKTS_F,  &sw_rx_packets);
  mad_decode_field(sw_pma, IB_PC_EXT_XMT_BYTES_F, &sw_tx_bytes);
  mad_decode_field(sw_pma, IB_PC_EXT_XMT_PKTS_F,  &sw_tx_packets);

  TRACE("sw_rx_bytes %lu, sw_rx_packets %lu, sw_tx_bytes %lu, sw_tx_packets %lu\n",
        sw_rx_bytes, sw_rx_packets, sw_tx_bytes, sw_tx_packets);

  /* The transposition of tx and rx is intentional: the switch port
     receives what we send, and conversely. */
  stats_set(stats, "rx_bytes",   sw_tx_bytes);
  stats_set(stats, "rx_packets", sw_tx_packets);
  stats_set(stats, "tx_bytes",   sw_rx_bytes);
  stats_set(stats, "tx_packets", sw_rx_packets);

 out:
  if (mad_port != NULL)
    mad_rpc_close_port(mad_port);
}
예제 #23
0
uint8_t *smp_query(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
		   unsigned mod, unsigned timeout)
{
	return smp_query_via(rcvbuf, portid, attrid, mod, timeout, ibmp);
}
예제 #24
0
int main(int argc, char **argv)
{
	struct ibnd_config config = { 0 };
	int resolved = -1;
	ib_portid_t portid = { 0 };
	ib_portid_t self_portid = { 0 };
	int rc = 0;
	ibnd_fabric_t *fabric = NULL;
	ib_gid_t self_gid;
	int port = 0;

	int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS,
		IB_PERFORMANCE_CLASS
	};

	const struct ibdiag_opt opts[] = {
		{"suppress", 's', 1, "<err1,err2,...>",
		 "suppress errors listed"},
		{"suppress-common", 'c', 0, NULL,
		 "suppress some of the common counters"},
		{"node-name-map", 1, 1, "<file>", "node name map file"},
		{"port-guid", 'G', 1, "<port_guid>",
		 "report the node containing the port specified by <port_guid>"},
		{"", 'S', 1, "<port_guid>",
		 "Same as \"-G\" for backward compatibility"},
		{"Direct", 'D', 1, "<dr_path>",
		 "report the node containing the port specified by <dr_path>"},
		{"skip-sl", 10, 0, NULL,"don't obtain SL to all destinations"},
		{"report-port", 'r', 0, NULL,
		 "report port link information"},
		{"threshold-file", 8, 1, NULL,
		 "specify an alternate threshold file, default: " DEF_THRES_FILE},
		{"GNDN", 'R', 0, NULL,
		 "(This option is obsolete and does nothing)"},
		{"data", 2, 0, NULL, "include data counters for ports with errors"},
		{"switch", 3, 0, NULL, "print data for switches only"},
		{"ca", 4, 0, NULL, "print data for CA's only"},
		{"router", 5, 0, NULL, "print data for routers only"},
		{"details", 6, 0, NULL, "include transmit discard details"},
		{"counters", 9, 0, NULL, "print data counters only"},
		{"clear-errors", 'k', 0, NULL,
		 "Clear error counters after read"},
		{"clear-counts", 'K', 0, NULL,
		 "Clear data counters after read"},
		{"load-cache", 7, 1, "<file>",
		 "filename of ibnetdiscover cache to load"},
		{"outstanding_smps", 'o', 1, NULL,
		 "specify the number of outstanding SMP's which should be "
		 "issued during the scan"},
		{0}
	};
	char usage_args[] = "";

	memset(suppressed_fields, 0, sizeof suppressed_fields);
	ibdiag_process_opts(argc, argv, &config, "cDGKLnRrSs", opts, process_opt,
			    usage_args, NULL);

	argc -= optind;
	argv += optind;

	if (!node_type_to_print)
		node_type_to_print = PRINT_ALL;

	ibmad_port = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 4);
	if (!ibmad_port)
		IBEXIT("Failed to open port; %s:%d\n", ibd_ca, ibd_ca_port);

	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) {
		fprintf(stderr, "Cannot specify cache and direct route path\n");
		exit(-1);
	}

	if (resolve_self(ibd_ca, ibd_ca_port, &self_portid, &port, &self_gid.raw) < 0) {
		IBEXIT("can't resolve self port %s", argv[0]);
		goto close_port;
	}

	/* limit the scan the fabric around the target */
	if (dr_path) {
		if ((resolved =
		     resolve_portid_str(ibd_ca, ibd_ca_port, &portid, dr_path,
					IB_DEST_DRPATH, NULL, ibmad_port)) < 0)
			IBWARN("Failed to resolve %s; attempting full scan",
			       dr_path);
	} else if (port_guid_str) {
		if ((resolved =
		     resolve_portid_str(ibd_ca, ibd_ca_port, &portid,
					port_guid_str, IB_DEST_GUID, ibd_sm_id,
					       ibmad_port)) < 0)
			IBWARN("Failed to resolve %s; attempting full scan",
			       port_guid_str);
		if(obtain_sl)
			lid2sl_table[portid.lid] = portid.sl;
	}

	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,
						    &portid, &config)))
				IBWARN("Single node discover failed;"
				       " attempting full scan");
		}

		if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
							       ibd_ca_port,
							       NULL,
							       &config))) {
			fprintf(stderr, "discover failed\n");
			rc = -1;
			goto close_port;
		}
	}

	set_thresholds(threshold_file);

	if (port_guid_str) {
		ibnd_port_t *port = ibnd_find_port_guid(fabric, port_guid);
		if (port)
			print_node(port->node, NULL);
		else
			fprintf(stderr, "Failed to find node: %s\n",
				port_guid_str);
	} else if (dr_path) {
		ibnd_port_t *port = ibnd_find_port_dr(fabric, dr_path);
		uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };

		if (!smp_query_via(ni, &portid, IB_ATTR_NODE_INFO, 0,
				   ibd_timeout, ibmad_port)) {
			rc = -1;
			goto destroy_fabric;
		}
		mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(port_guid));

		port = ibnd_find_port_guid(fabric, port_guid);
		if (port) {
			if(obtain_sl)
				if(path_record_query(self_gid,port->guid))
					goto destroy_fabric;
			print_node(port->node, NULL);
		} else
			fprintf(stderr, "Failed to find node: %s\n", dr_path);
	} else {
		if(obtain_sl)
			if(path_record_query(self_gid,0))
				goto destroy_fabric;
		ibnd_iter_nodes(fabric, print_node, NULL);
	}

	rc = print_summary();
	if (rc)
		rc = 1;

destroy_fabric:
	ibnd_destroy_fabric(fabric);

close_port:
	mad_rpc_close_port(ibmad_port);
	close_node_name_map(node_name_map);
	exit(rc);
}
예제 #25
0
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;
}