예제 #1
0
int main(int argc, char **argv)
{
	struct ibnd_config config = { 0 };
	ibnd_fabric_t *fabric = NULL;
	ibnd_fabric_t *diff_fabric = NULL;

	const struct ibdiag_opt opts[] = {
		{"full", 'f', 0, NULL, "show full information (ports' speed and width)"},
		{"show", 's', 0, NULL, "show more information"},
		{"list", 'l', 0, NULL, "list of connected nodes"},
		{"grouping", 'g', 0, NULL, "show grouping"},
		{"Hca_list", 'H', 0, NULL, "list of connected CAs"},
		{"Switch_list", 'S', 0, NULL, "list of connected switches"},
		{"Router_list", 'R', 0, NULL, "list of connected routers"},
		{"node-name-map", 1, 1, "<file>", "node name map file"},
		{"cache", 2, 1, "<file>",
		 "filename to cache ibnetdiscover data to"},
		{"load-cache", 3, 1, "<file>",
		 "filename of ibnetdiscover cache to load"},
		{"diff", 4, 1, "<file>",
		 "filename of ibnetdiscover cache to diff"},
		{"diffcheck", 5, 1, "<key(s)>",
		 "specify checks to execute for --diff"},
		{"ports", 'p', 0, NULL, "obtain a ports report"},
		{"max_hops", 'm', 0, NULL,
		 "report max hops discovered by the library"},
		{"outstanding_smps", 'o', 1, NULL,
		 "specify the number of outstanding SMP's which should be "
		 "issued during the scan"},
		{0}
	};
	char usage_args[] = "[topology-file]";

	ibdiag_process_opts(argc, argv, &config, "DGKLs", opts, process_opt,
			    usage_args, NULL);

	f = stdout;

	argc -= optind;
	argv += optind;

	if (ibd_timeout)
		config.timeout_ms = ibd_timeout;

	config.flags = ibd_ibnetdisc_flags;

	if (argc && !(f = fopen(argv[0], "w")))
		IBERROR("can't open file %s for writing", argv[0]);

	config.mkey = ibd_mkey;

	node_name_map = open_node_name_map(node_name_map_file);

	if (diff_cache_file &&
	    !(diff_fabric = ibnd_load_fabric(diff_cache_file, 0)))
		IBERROR("loading cached fabric for diff failed\n");

	if (load_cache_file) {
		if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL)
			IBERROR("loading cached fabric failed\n");
	} else {
		if ((fabric =
		     ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config)) == NULL)
			IBERROR("discover failed\n");
	}

	if (ports_report)
		ibnd_iter_nodes(fabric, dump_ports_report, NULL);
	else if (list)
		list_nodes(fabric, list);
	else if (diff_fabric)
		diff(diff_fabric, fabric);
	else
		dump_topology(group, fabric);

	if (cache_file)
		if (ibnd_cache_fabric(fabric, cache_file, 0) < 0)
			IBERROR("caching ibnetdiscover data failed\n");

	ibnd_destroy_fabric(fabric);
	if (diff_fabric)
		ibnd_destroy_fabric(diff_fabric);
	close_node_name_map(node_name_map);
	exit(0);
}
예제 #2
0
ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
				    ib_portid_t * from,
				    struct ibnd_config *cfg)
{
	struct ibnd_config config = { 0 };
	ibnd_fabric_t *fabric = NULL;
	ib_portid_t my_portid = { 0 };
	smp_engine_t engine;
	ibnd_scan_t scan;
	int nc = 2;
	int mc[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };

	/* If not specified start from "my" port */
	if (!from)
		from = &my_portid;

	if (set_config(&config, cfg)) {
		IBND_ERROR("Invalid ibnd_config\n");
		return NULL;
	}

	fabric = calloc(1, sizeof(*fabric));
	if (!fabric) {
		IBND_ERROR("OOM: failed to calloc ibnd_fabric_t\n");
		return NULL;
	}

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

	memset(&scan.selfportid, 0, sizeof(scan.selfportid));
	scan.fabric = fabric;
	scan.cfg = &config;
	scan.initial_hops = from->drpath.cnt;

	if (smp_engine_init(&engine, ca_name, ca_port, &scan, &config)) {
		free(fabric);
		return (NULL);
	}

	scan.ibmad_port = mad_rpc_open_port(ca_name, ca_port, mc, nc);
	if (!scan.ibmad_port) {
		IBND_ERROR("can't open MAD port (%s:%d)\n", ca_name, ca_port);
		smp_engine_destroy(&engine);
		return (NULL);
	}
	mad_rpc_set_timeout(scan.ibmad_port, cfg->timeout_ms);
	mad_rpc_set_retries(scan.ibmad_port, cfg->retries);
	smp_mkey_set(scan.ibmad_port, cfg->mkey);

	IBND_DEBUG("from %s\n", portid2str(from));

	if (!query_node_info(&engine, from, NULL))
		if (process_mads(&engine) != 0)
			goto error;

	fabric->total_mads_used = engine.total_smps;
	fabric->maxhops_discovered += scan.initial_hops;

	if (group_nodes(fabric))
		goto error;

	smp_engine_destroy(&engine);
	mad_rpc_close_port(scan.ibmad_port);
	return fabric;
error:
	smp_engine_destroy(&engine);
	mad_rpc_close_port(scan.ibmad_port);
	ibnd_destroy_fabric(fabric);
	return NULL;
}
예제 #3
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);
}
예제 #4
0
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)
		IBERROR("original cache file not specified");

	if (!new_cache_file)
		IBERROR("new cache file not specified");

	if ((fabric = ibnd_load_fabric(orig_cache_file, 0)) == NULL)
		IBERROR("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)
			IBERROR("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)
			IBERROR("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)
			IBERROR("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)
			IBERROR("nodeguid = %" PRIx64 " not found",
				portguid_nodeguid);

		if (!guids.found)
			IBERROR("portguid = %" PRIx64 " not found",
				portguid_before);
	}

	if (ibnd_cache_fabric(fabric, new_cache_file, 0) < 0)
		IBERROR("caching new cache data failed");

	ibnd_destroy_fabric(fabric);
	exit(0);
}