ib_net64_t get_port_guid(IN osmtest_t * p_osmt, uint64_t port_guid) { ib_api_status_t status; uint32_t num_ports = GUID_ARRAY_SIZE; ib_port_attr_t attr_array[GUID_ARRAY_SIZE]; int i; /* Call the transport layer for a list of local port GUID values. */ /* "local ports" is(?) phys, shouldn't this exclude port 0 then ? */ status = osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array, &num_ports); if (status != IB_SUCCESS) { printf("\nError from osm_vendor_get_all_port_attr (%x)\n", status); return (0); } if (num_ports == 1) { printf("using default guid 0x%" PRIx64 "\n", cl_hton64(attr_array[0].port_guid)); return (attr_array[0].port_guid); } for (i = 0; i < num_ports; i++) { if (attr_array[i].port_guid == port_guid || (!port_guid && attr_array[i].link_state > IB_LINK_DOWN)) return attr_array[i].port_guid; } return 0; }
static void print_all_guids(IN osmtest_t * p_osmt) { ib_api_status_t status; uint32_t num_ports = GUID_ARRAY_SIZE; ib_port_attr_t attr_array[GUID_ARRAY_SIZE]; int i; /* Call the transport layer for a list of local port GUID values. */ status = osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array, &num_ports); if (status != IB_SUCCESS) { printf("\nError from osm_vendor_get_all_port_attr (%x)\n", status); return; } printf("\nListing GUIDs:\n"); for (i = 0; i < num_ports; i++) printf("Port %i: 0x%" PRIx64 "\n", i, cl_hton64(attr_array[i].port_guid)); }
uint8_t osm_vendor_get_port_num(IN osm_vendor_t * const p_vend, IN const ib_net64_t port_guid) { uint8_t index; uint8_t num_ports; uint32_t num_guids = 0; osm_ca_info_t *p_ca_info; uint32_t ca; OSM_LOG_ENTER(p_vend->p_log); CL_ASSERT(port_guid); /* First, locate the HCA that owns this port. */ if (p_vend->p_ca_info == NULL) { /* Initialize the osm_ca_info_t array which allows us to match port GUID to CA. */ osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids); } CL_ASSERT(p_vend->p_ca_info); CL_ASSERT(p_vend->ca_count); for (ca = 0; ca < p_vend->ca_count; ca++) { p_ca_info = &p_vend->p_ca_info[ca]; num_ports = osm_ca_info_get_num_ports(p_ca_info); CL_ASSERT(num_ports); for (index = 0; index < num_ports; index++) { if (port_guid == osm_ca_info_get_port_guid(p_ca_info, index)) { OSM_LOG_EXIT(p_vend->p_log); return (osm_ca_info_get_port_num (p_ca_info, index)); } } } /* No local CA owns this guid! */ osm_log(p_vend->p_log, OSM_LOG_ERROR, "osm_vendor_get_port_num: ERR 3B30: " "Unable to determine CA guid.\n"); OSM_LOG_EXIT(p_vend->p_log); return (0); }
/** * Get the OpenSM bind handle */ static int _get_bind_handle(nodeupdown_t nodeupdown_handle, osm_bind_handle_t *handle) { uint32_t i = 0; uint64_t port_guid = (uint64_t)-1; osm_bind_handle_t bind_handle; ib_api_status_t status; ib_port_attr_t attr_array[OPENIB_MAX_PORTS]; uint32_t num_ports = OPENIB_MAX_PORTS; complib_init(); osm_log_construct(&_openib_log_osm); if ((status = osm_log_init( &_openib_log_osm, TRUE, 0x0001, NULL, TRUE )) != IB_SUCCESS) { #ifndef NDEBUG fprintf(stderr, "Failed to init osm_log: %s\n", ib_get_err_str(status)); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (-1); } #if 0 osm_log_set_level(&_openib_log_osm, OSM_LOG_DEFAULT_LEVEL); #else osm_log_set_level(&_openib_log_osm, OSM_LOG_NONE); #endif _openib_vendor = osm_vendor_new(&_openib_log_osm, 100); osm_mad_pool_construct(&_openib_mad_pool); #ifdef HAVE_FUNC_OSM_MAD_POOL_INIT_2 if ((status = osm_mad_pool_init(&_openib_mad_pool, &_openib_log_osm)) != IB_SUCCESS) { #else if ((status = osm_mad_pool_init(&_openib_mad_pool)) != IB_SUCCESS) { #endif #ifndef NDEBUG fprintf(stderr, "Failed to init mad pool: %s\n", ib_get_err_str(status)); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (-1); } if ((status = osm_vendor_get_all_port_attr(_openib_vendor, attr_array, &num_ports)) != IB_SUCCESS) { #ifndef NDEBUG fprintf(stderr, "Failed to get port attributes: %s\n", ib_get_err_str(status)); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (-1); } for (i = 0; i < num_ports; i++) { if (attr_array[i].link_state == IB_LINK_ACTIVE) port_guid = attr_array[i].port_guid; } if (port_guid == (uint64_t)-1) { #ifndef NDEBUG fprintf(stderr, "Failed to find active port, check port status with \"ibstat\"\n"); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (-1); } bind_handle = osmv_bind_sa(_openib_vendor, &_openib_mad_pool, port_guid); if (bind_handle == OSM_BIND_INVALID_HANDLE) { #ifndef NDEBUG fprintf(stderr, "Failed to bind to SA\n"); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return(-1); } *handle = bind_handle; return (0); } /** * Get all the records available for requested query type. */ static ib_api_status_t _get_all_records(nodeupdown_t nodeupdown_handle, osm_bind_handle_t bind_handle, ib_net16_t query_id, ib_net16_t attr_offset, int trusted) { ib_api_status_t status; osmv_query_req_t req; osmv_user_query_t user; memset( &req, 0, sizeof( req ) ); memset( &user, 0, sizeof( user ) ); user.attr_id = query_id; user.attr_offset = attr_offset; req.query_type = OSMV_QUERY_USER_DEFINED; req.timeout_ms = 100; req.retry_cnt = 1; req.flags = OSM_SA_FLAGS_SYNC; req.query_context = NULL; req.pfn_query_cb = _query_res_cb; req.p_query_input = &user; if (trusted) req.sm_key = OSM_DEFAULT_SM_KEY; else req.sm_key = 0; if ((status = osmv_query_sa(bind_handle, &req)) != IB_SUCCESS) { #ifndef NDEBUG fprintf(stderr, "Query SA failed: %s\n", ib_get_err_str(status)); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (status); } if (_openib_result.status != IB_SUCCESS) { #ifndef NDEBUG fprintf(stderr, "Query _openib_result returned: %s\n", ib_get_err_str(_openib_result.status)); #endif /* NDEBUG */ nodeupdown_set_errnum(nodeupdown_handle, NODEUPDOWN_ERR_BACKEND_MODULE); return (_openib_result.status); } return (status); }
/***************************************************************************** This routine needs to be invoked on every send - since the SM LID and Local lid might change. To do that without any major perfoermance impact we cache the results and time they were obtained. Refresh only twice a minute. To avoid the need to use statics and risk a race - we require the refresh time to be stored in the context of the results. Also this coveres cases were we query for multiple guids. *****************************************************************************/ ib_api_status_t __osmv_get_lid_and_sm_lid_by_port_guid(IN osm_vendor_t * const p_vend, IN ib_net64_t port_guid, IN OUT uint64_t * p_lids_update_time_sec, OUT uint16_t * lid, OUT uint16_t * sm_lid) { ib_api_status_t status; ib_port_attr_t *p_attr_array; uint32_t num_ports; uint32_t port_num; OSM_LOG_ENTER(p_vend->p_log); /* use prevous values if current time is close enough to previous query */ if (cl_get_time_stamp_sec() <= *p_lids_update_time_sec + 30) { osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osmv_get_lid_and_sm_lid_by_port_guid: " "Using previously stored lid:0x%04x sm_lid:0x%04x\n", *lid, *sm_lid); status = IB_SUCCESS; goto Exit; } /* obtain the number of available ports */ num_ports = 0; status = osm_vendor_get_all_port_attr(p_vend, NULL, &num_ports); if (status != IB_INSUFFICIENT_MEMORY) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0503: " "expected to get the IB_INSUFFICIENT_MEMORY but got: %s\n", ib_get_err_str(status) ); status = IB_ERROR; goto Exit; } osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osmv_get_lid_and_sm_lid_by_port_guid: " "Found total of %u ports. Looking for guid:0x%016" PRIx64 "\n", num_ports, cl_ntoh64(port_guid) ); /* allocate the attributes */ p_attr_array = (ib_port_attr_t *) malloc(sizeof(ib_port_attr_t) * num_ports); /* obtain the attributes */ status = osm_vendor_get_all_port_attr(p_vend, p_attr_array, &num_ports); if (status != IB_SUCCESS) { osm_log(p_vend->p_log, OSM_LOG_ERROR, "__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0504: " "Fail to get port attributes (error: %s)\n", ib_get_err_str(status) ); free(p_attr_array); goto Exit; } status = IB_ERROR; /* find the port requested in the list */ for (port_num = 0; (port_num < num_ports) && (status == IB_ERROR); port_num++) { if (p_attr_array[port_num].port_guid == port_guid) { *lid = p_attr_array[port_num].lid; *sm_lid = p_attr_array[port_num].sm_lid; *p_lids_update_time_sec = cl_get_time_stamp_sec(); status = IB_SUCCESS; osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osmv_get_lid_and_sm_lid_by_port_guid: " "Found guid:0x%016" PRIx64 " with idx:%d\n", cl_ntoh64(port_guid), port_num); } } free(p_attr_array); Exit: OSM_LOG_EXIT(p_vend->p_log); return (status); }