/********************************************************************** Notifies the transport layer that the local LID has changed, which give it a chance to update address vectors, etc.. **********************************************************************/ static ib_api_status_t state_mgr_notify_lid_change(IN osm_sm_t * sm) { ib_api_status_t status; osm_bind_handle_t h_bind; OSM_LOG_ENTER(sm->p_log); /* * First, get the bind handle. */ h_bind = osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl); if (h_bind == OSM_BIND_INVALID_HANDLE) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3306: " "No bound ports\n"); status = IB_ERROR; goto Exit; } /* * Notify the transport layer that we changed the local LID. */ status = osm_vendor_local_lid_change(h_bind); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3307: " "Vendor LID update failed (%s)\n", ib_get_err_str(status)); Exit: OSM_LOG_EXIT(sm->p_log); return status; }
/********************************************************************** Initiates a thorough sweep of the subnet. Used when there is suspicion that something on the subnet has changed. **********************************************************************/ static ib_api_status_t state_mgr_sweep_hop_0(IN osm_sm_t * sm) { ib_api_status_t status; osm_dr_path_t dr_path; osm_bind_handle_t h_bind; uint8_t path_array[IB_SUBNET_PATH_HOPS_MAX]; OSM_LOG_ENTER(sm->p_log); memset(path_array, 0, sizeof(path_array)); /* * First, get the bind handle. */ h_bind = osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl); if (h_bind != OSM_BIND_INVALID_HANDLE) { OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "INITIATING HEAVY SWEEP"); /* * Start the sweep by clearing the port counts, then * get our own NodeInfo at 0 hops. */ CL_PLOCK_ACQUIRE(sm->p_lock); cl_qmap_apply_func(&sm->p_subn->node_guid_tbl, state_mgr_reset_node_count, sm); cl_qmap_apply_func(&sm->p_subn->port_guid_tbl, state_mgr_reset_port_count, sm); cl_qmap_apply_func(&sm->p_subn->sw_guid_tbl, state_mgr_reset_switch_count, sm); /* Set the in_sweep_hop_0 flag in subn to be TRUE. * This will indicate the sweeping not to continue beyond the * the current node. * This is relevant for the case of SM on switch, since in the * switch info we need to signal somehow not to continue * the sweeping. */ sm->p_subn->in_sweep_hop_0 = TRUE; CL_PLOCK_RELEASE(sm->p_lock); osm_dr_path_init(&dr_path, h_bind, 0, path_array); status = osm_req_get(sm, &dr_path, IB_MAD_ATTR_NODE_INFO, 0, CL_DISP_MSGID_NONE, NULL); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3305: " "Request for NodeInfo failed (%s)\n", ib_get_err_str(status)); } else { OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "No bound ports. Deferring sweep...\n"); status = IB_INVALID_STATE; } OSM_LOG_EXIT(sm->p_log); return status; }
/********************************************************************** Initiates a lightweight sweep of the subnet. Used during normal sweeps after the subnet is up. **********************************************************************/ static ib_api_status_t state_mgr_light_sweep_start(IN osm_sm_t * sm) { ib_api_status_t status = IB_SUCCESS; osm_bind_handle_t h_bind; cl_qmap_t *p_sw_tbl; cl_map_item_t *p_next; osm_node_t *p_node; osm_physp_t *p_physp; uint8_t port_num; OSM_LOG_ENTER(sm->p_log); p_sw_tbl = &sm->p_subn->sw_guid_tbl; /* * First, get the bind handle. */ h_bind = osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl); if (h_bind == OSM_BIND_INVALID_HANDLE) { OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "No bound ports. Deferring sweep...\n"); status = IB_INVALID_STATE; goto _exit; } OSM_LOG_MSG_BOX(sm->p_log, OSM_LOG_VERBOSE, "INITIATING LIGHT SWEEP"); CL_PLOCK_ACQUIRE(sm->p_lock); cl_qmap_apply_func(p_sw_tbl, state_mgr_get_sw_info, sm); CL_PLOCK_RELEASE(sm->p_lock); CL_PLOCK_ACQUIRE(sm->p_lock); cl_qmap_apply_func(&sm->p_subn->node_guid_tbl, state_mgr_get_node_desc, sm); CL_PLOCK_RELEASE(sm->p_lock); /* now scan the list of physical ports that were not down but have no remote port */ CL_PLOCK_ACQUIRE(sm->p_lock); p_next = cl_qmap_head(&sm->p_subn->node_guid_tbl); while (p_next != cl_qmap_end(&sm->p_subn->node_guid_tbl)) { p_node = (osm_node_t *) p_next; p_next = cl_qmap_next(p_next); for (port_num = 1; port_num < osm_node_get_num_physp(p_node); port_num++) { p_physp = osm_node_get_physp_ptr(p_node, port_num); if (p_physp && (osm_physp_get_port_state(p_physp) != IB_LINK_DOWN) && !osm_physp_get_remote(p_physp)) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3315: " "Unknown remote side for node 0x%016" PRIx64 " (%s) port %u. Adding to light sweep sampling list\n", cl_ntoh64(osm_node_get_node_guid (p_node)), p_node->print_desc, port_num); osm_dump_dr_path(sm->p_log, osm_physp_get_dr_path_ptr (p_physp), OSM_LOG_ERROR); state_mgr_get_remote_port_info(sm, p_physp); } } } cl_qmap_apply_func(&sm->p_subn->sm_guid_tbl, query_sm_info, sm); CL_PLOCK_RELEASE(sm->p_lock); _exit: OSM_LOG_EXIT(sm->p_log); return status; }
int osm_send_trap144(osm_sm_t * sm, ib_net16_t local) { osm_madw_t *madw; ib_smp_t *smp; ib_mad_notice_attr_t *ntc; osm_port_t *port, *smport; ib_port_info_t *pi; port = osm_get_port_by_guid(sm->p_subn, sm->p_subn->sm_port_guid); if (!port) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 1104: cannot find SM port by guid 0x%" PRIx64 "\n", cl_ntoh64(sm->p_subn->sm_port_guid)); return -1; } pi = &port->p_physp->port_info; /* don't bother with sending trap when SMA supports this */ if (!local && pi->capability_mask&(IB_PORT_CAP_HAS_TRAP|IB_PORT_CAP_HAS_CAP_NTC)) return 0; smport = osm_get_port_by_guid(sm->p_subn, sm->master_sm_guid); if (!smport) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 1106: cannot find master SM port by guid 0x%" PRIx64 "\n", cl_ntoh64(sm->master_sm_guid)); return -1; } madw = osm_mad_pool_get(sm->p_mad_pool, osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl), MAD_BLOCK_SIZE, NULL); if (madw == NULL) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 1105: Unable to acquire MAD\n"); return -1; } madw->mad_addr.dest_lid = smport->p_physp->port_info.base_lid; madw->mad_addr.addr_type.smi.source_lid = pi->base_lid; madw->resp_expected = TRUE; madw->fail_msg = CL_DISP_MSGID_NONE; smp = osm_madw_get_smp_ptr(madw); memset(smp, 0, sizeof(*smp)); smp->base_ver = 1; smp->mgmt_class = IB_MCLASS_SUBN_LID; smp->class_ver = 1; smp->method = IB_MAD_METHOD_TRAP; smp->trans_id = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id) & (uint64_t)(0xFFFFFFFF)); if (smp->trans_id == 0) smp->trans_id = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id) & (uint64_t)(0xFFFFFFFF)); smp->attr_id = IB_MAD_ATTR_NOTICE; ntc = (ib_mad_notice_attr_t *) smp->data; ntc->generic_type = 0x80 | IB_NOTICE_TYPE_INFO; ib_notice_set_prod_type_ho(ntc, osm_node_get_type(port->p_node)); ntc->g_or_v.generic.trap_num = cl_hton16(SM_LOCAL_CHANGES_TRAP); /* 144 */ ntc->issuer_lid = pi->base_lid; ntc->data_details.ntc_144.lid = pi->base_lid; ntc->data_details.ntc_144.local_changes = local ? TRAP_144_MASK_OTHER_LOCAL_CHANGES : 0; ntc->data_details.ntc_144.new_cap_mask = pi->capability_mask; ntc->data_details.ntc_144.change_flgs = local; OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Sending Trap 144, TID 0x%" PRIx64 " to SM lid %u\n", cl_ntoh64(smp->trans_id), cl_ntoh16(madw->mad_addr.dest_lid)); osm_vl15_post(sm->p_vl15, madw); return 0; }