/********************************************************************** * Clear all the counters from the db **********************************************************************/ void perfmgr_db_clear_counters(perfmgr_db_t * db) { cl_plock_excl_acquire(&db->lock); cl_qmap_apply_func(&db->pc_data, clear_counters, (void *)db); cl_plock_release(&db->lock); #if 0 if (db->db_impl->clear_counters) db->db_impl->clear_counters(db->db_data); #endif }
perfmgr_db_err_t perfmgr_db_mark_active(perfmgr_db_t *db, uint64_t guid, boolean_t active) { db_node_t *node = NULL; cl_plock_excl_acquire(&db->lock); node = get(db, guid); if (node) node->active = active; cl_plock_release(&db->lock); return (PERFMGR_EVENT_DB_SUCCESS); }
perfmgr_db_err_t perfmgr_db_update_name(perfmgr_db_t * db, uint64_t node_guid, char *name) { db_node_t *node = NULL; cl_plock_excl_acquire(&db->lock); node = get(db, node_guid); if (node) snprintf(node->node_name, sizeof(node->node_name), "%s", name); cl_plock_release(&db->lock); return (PERFMGR_EVENT_DB_SUCCESS); }
/********************************************************************** * print all node data to fp **********************************************************************/ void perfmgr_db_print_all(perfmgr_db_t * db, FILE *fp, int err_only) { cl_map_item_t *item; db_node_t *node; cl_plock_acquire(&db->lock); item = cl_qmap_head(&db->pc_data); while (item != cl_qmap_end(&db->pc_data)) { node = (db_node_t *)item; dump_node_hr(node, fp, NULL, err_only); item = cl_qmap_next(item); } cl_plock_release(&db->lock); }
/********************************************************************** * dump the data to the file "file" **********************************************************************/ perfmgr_db_err_t perfmgr_db_dump(perfmgr_db_t * db, char *file, perfmgr_db_dump_t dump_type) { dump_context_t context; context.fp = fopen(file, "w+"); if (!context.fp) return PERFMGR_EVENT_DB_FAIL; context.dump_type = dump_type; cl_plock_acquire(&db->lock); cl_qmap_apply_func(&db->pc_data, db_dump, (void *)&context); cl_plock_release(&db->lock); fclose(context.fp); return PERFMGR_EVENT_DB_SUCCESS; }
/********************************************************************** * print node data to fp **********************************************************************/ void perfmgr_db_print_by_guid(perfmgr_db_t * db, uint64_t nodeguid, FILE *fp, char *port, int err_only) { cl_map_item_t *node; cl_plock_acquire(&db->lock); node = cl_qmap_get(&db->pc_data, nodeguid); if (node != cl_qmap_end(&db->pc_data)) dump_node_hr((db_node_t *)node, fp, port, err_only); else fprintf(fp, "Node 0x%" PRIx64 " not found...\n", nodeguid); cl_plock_release(&db->lock); }
/* * SA DB Loader */ static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid, ib_member_rec_t * p_mcm_rec, unsigned well_known) { ib_net64_t comp_mask; osm_mgrp_t *p_mgrp; cl_plock_excl_acquire(&p_osm->lock); p_mgrp = osm_get_mgrp_by_mgid(&p_osm->subn, &p_mcm_rec->mgid); if (p_mgrp) { if (p_mgrp->mlid == mlid) { OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "mgrp %04x is already here.", cl_ntoh16(mlid)); goto _out; } OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, "mlid %04x is already used by another MC group. Will " "request clients reregistration.\n", cl_ntoh16(mlid)); p_mgrp = NULL; goto _out; } comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL; if (!(p_mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa, comp_mask, p_mcm_rec)) || p_mgrp->mlid != mlid) { OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "cannot create MC group with mlid 0x%04x and mgid " "0x%016" PRIx64 ":0x%016" PRIx64 "\n", cl_ntoh16(mlid), cl_ntoh64(p_mcm_rec->mgid.unicast.prefix), cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id)); p_mgrp = NULL; } else if (well_known) p_mgrp->well_known = TRUE; _out: cl_plock_release(&p_osm->lock); return p_mgrp; }
perfmgr_db_err_t perfmgr_db_get_prev_dc(perfmgr_db_t * db, uint64_t guid, uint8_t port, perfmgr_db_data_cnt_reading_t * reading) { db_node_t *node = NULL; perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS; cl_plock_acquire(&db->lock); node = get(db, guid); if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS) goto Exit; *reading = node->ports[port].dc_previous; Exit: cl_plock_release(&db->lock); return rc; }
perfmgr_db_err_t perfmgr_db_clear_prev_dc(perfmgr_db_t * db, uint64_t guid, uint8_t port) { db_node_t *node = NULL; perfmgr_db_data_cnt_reading_t *previous = NULL; perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS; cl_plock_excl_acquire(&db->lock); node = get(db, guid); if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS) goto Exit; previous = &node->ports[port].dc_previous; memset(previous, 0, sizeof(*previous)); node->ports[port].dc_previous.time = time(NULL); Exit: cl_plock_release(&db->lock); return rc; }
static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file) { struct opensm_dump_context dump_context; osm_mgrp_t *p_mgrp; dump_context.p_osm = p_osm; dump_context.file = file; OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n"); cl_plock_acquire(&p_osm->lock); for (p_mgrp = (osm_mgrp_t *) cl_fmap_head(&p_osm->subn.mgrp_mgid_tbl); p_mgrp != (osm_mgrp_t *) cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl); p_mgrp = (osm_mgrp_t *) cl_fmap_next(&p_mgrp->map_item)) sa_dump_one_mgrp(p_mgrp, &dump_context); OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n"); cl_qlist_apply_func(&p_osm->subn.sa_infr_list, sa_dump_one_inform, &dump_context); OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services\n"); cl_qlist_apply_func(&p_osm->subn.sa_sr_list, sa_dump_one_service, &dump_context); cl_plock_release(&p_osm->lock); }
static int load_svcr(osm_opensm_t * p_osm, ib_service_record_t * sr, uint32_t modified_time, uint32_t lease_period) { osm_svcr_t *p_svcr; int ret = 0; cl_plock_excl_acquire(&p_osm->lock); if (osm_svcr_get_by_rid(&p_osm->subn, &p_osm->log, sr)) { OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, "ServiceRecord already exists\n"); goto _out; } if (!(p_svcr = osm_svcr_new(sr))) { OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "cannot allocate new service struct\n"); ret = -1; goto _out; } p_svcr->modified_time = modified_time; p_svcr->lease_period = lease_period; OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding ServiceRecord...\n"); osm_svcr_insert_to_db(&p_osm->subn, &p_osm->log, p_svcr); if (lease_period != 0xffffffff) cl_timer_trim(&p_osm->sa.sr_timer, 1000); _out: cl_plock_release(&p_osm->lock); return ret; }
/********************************************************************** * print node data to fp **********************************************************************/ void perfmgr_db_print_by_name(perfmgr_db_t * db, char *nodename, FILE *fp, char *port, int err_only) { cl_map_item_t *item; db_node_t *node; cl_plock_acquire(&db->lock); /* find the node */ item = cl_qmap_head(&db->pc_data); while (item != cl_qmap_end(&db->pc_data)) { node = (db_node_t *)item; if (strcmp(node->node_name, nodename) == 0) { dump_node_hr(node, fp, port, err_only); goto done; } item = cl_qmap_next(item); } fprintf(fp, "Node %s not found...\n", nodename); done: cl_plock_release(&db->lock); }
static int load_infr(osm_opensm_t * p_osm, ib_inform_info_record_t * iir, osm_mad_addr_t * addr) { osm_infr_t infr, *p_infr; int ret = 0; infr.h_bind = p_osm->sa.mad_ctrl.h_bind; infr.sa = &p_osm->sa; /* other possible way to restore mad_addr partially is to extract qpn from InformInfo and to find lid by gid */ infr.report_addr = *addr; infr.inform_record = *iir; cl_plock_excl_acquire(&p_osm->lock); if (osm_infr_get_by_rec(&p_osm->subn, &p_osm->log, &infr)) { OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, "InformInfo Record already exists\n"); goto _out; } if (!(p_infr = osm_infr_new(&infr))) { OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "cannot allocate new infr struct\n"); ret = -1; goto _out; } OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding InformInfo Record...\n"); osm_infr_insert_to_db(&p_osm->subn, &p_osm->log, p_infr); _out: cl_plock_release(&p_osm->lock); return ret; }
perfmgr_db_err_t perfmgr_db_create_entry(perfmgr_db_t * db, uint64_t guid, boolean_t esp0, uint8_t num_ports, char *name) { perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS; cl_plock_excl_acquire(&db->lock); if (!get(db, guid)) { db_node_t *pc_node = malloc_node(guid, esp0, num_ports, name); if (!pc_node) { rc = PERFMGR_EVENT_DB_NOMEM; goto Exit; } if (insert(db, pc_node)) { free_node(pc_node); rc = PERFMGR_EVENT_DB_FAIL; goto Exit; } } Exit: cl_plock_release(&db->lock); return rc; }
/********************************************************************* Received a Set(InformInfo) MAD **********************************************************************/ static void osm_infr_rcv_process_set_method(IN osm_sa_t * sa, IN osm_madw_t * const p_madw) { ib_sa_mad_t *p_sa_mad; ib_inform_info_t *p_recvd_inform_info; osm_infr_t inform_info_rec; /* actual inform record to be stored for reports */ osm_infr_t *p_infr; ib_net32_t qpn; uint8_t resp_time_val; ib_api_status_t res; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_recvd_inform_info = (ib_inform_info_t *) ib_sa_mad_get_payload_ptr(p_sa_mad); #if 0 if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG)) osm_dump_inform_info(sa->p_log, p_recvd_inform_info, OSM_LOG_DEBUG); #endif /* Grab the lock */ cl_plock_excl_acquire(sa->p_lock); /* define the inform record */ inform_info_rec.inform_record.inform_info = *p_recvd_inform_info; /* following C13-32.1.2 Tbl 120: we only copy the source address vector */ inform_info_rec.report_addr = p_madw->mad_addr; /* we will need to know the mad srvc to send back through */ inform_info_rec.h_bind = p_madw->h_bind; inform_info_rec.sa = sa; /* update the subscriber GID according to mad address */ res = osm_get_gid_by_mad_addr(sa->p_log, sa->p_subn, &p_madw->mad_addr, &inform_info_rec.inform_record. subscriber_gid); if (res != IB_SUCCESS) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4308 " "Subscribe Request from unknown LID: %u\n", cl_ntoh16(p_madw->mad_addr.dest_lid)); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* HACK: enum is always 0 (currently) */ inform_info_rec.inform_record.subscriber_enum = 0; /* Subscribe values above 1 are undefined */ if (p_recvd_inform_info->subscribe > 1) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4308 " "Invalid subscribe: %d\n", p_recvd_inform_info->subscribe); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* * MODIFICATIONS DONE ON INCOMING REQUEST: * * QPN: * Internally we keep the QPN field of the InformInfo updated * so we can simply compare it in the record - when finding such. */ if (p_recvd_inform_info->subscribe) { ib_inform_info_set_qpn(&inform_info_rec.inform_record. inform_info, inform_info_rec.report_addr.addr_type. gsi.remote_qp); OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Subscribe Request with QPN: 0x%06X\n", cl_ntoh32(inform_info_rec.report_addr.addr_type.gsi. remote_qp)); } else { ib_inform_info_get_qpn_resp_time(p_recvd_inform_info->g_or_v. generic.qpn_resp_time_val, &qpn, &resp_time_val); OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "UnSubscribe Request with QPN: 0x%06X\n", cl_ntoh32(qpn)); } /* If record exists with matching InformInfo */ p_infr = osm_infr_get_by_rec(sa->p_subn, sa->p_log, &inform_info_rec); /* check to see if the request was for subscribe */ if (p_recvd_inform_info->subscribe) { /* validate the request for a new or update InformInfo */ if (__validate_infr(sa, &inform_info_rec) != TRUE) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4305: " "Failed to validate a new inform object\n"); /* o13-13.1.1: we need to set the subscribe bit to 0 */ p_recvd_inform_info->subscribe = 0; osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* ok - we can try and create a new entry */ if (p_infr == NULL) { /* Create the instance of the osm_infr_t object */ p_infr = osm_infr_new(&inform_info_rec); if (p_infr == NULL) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4306: " "Failed to create a new inform object\n"); /* o13-13.1.1: we need to set the subscribe bit to 0 */ p_recvd_inform_info->subscribe = 0; osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES); goto Exit; } /* Add this new osm_infr_t object to subnet object */ osm_infr_insert_to_db(sa->p_subn, sa->p_log, p_infr); } else /* Update the old instance of the osm_infr_t object */ p_infr->inform_record = inform_info_rec.inform_record; /* We got an UnSubscribe request */ } else if (p_infr == NULL) { cl_plock_release(sa->p_lock); /* No Such Item - So Error */ OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4307: " "Failed to UnSubscribe to non existing inform object\n"); /* o13-13.1.1: we need to set the subscribe bit to 0 */ p_recvd_inform_info->subscribe = 0; osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } else /* Delete this object from the subnet list of informs */ osm_infr_remove_from_db(sa->p_subn, sa->p_log, p_infr); cl_plock_release(sa->p_lock); /* send the success response */ __osm_infr_rcv_respond(sa, p_madw); Exit: OSM_LOG_EXIT(sa->p_log); }
/********************************************************************** Received a Get(InformInfoRecord) or GetTable(InformInfoRecord) MAD **********************************************************************/ static void osm_infr_rcv_process_get_method(IN osm_sa_t * sa, IN osm_madw_t * const p_madw) { char gid_str[INET6_ADDRSTRLEN]; ib_sa_mad_t *p_rcvd_mad; const ib_inform_info_record_t *p_rcvd_rec; cl_qlist_t rec_list; osm_iir_search_ctxt_t context; osm_physp_t *p_req_physp; osm_iir_item_t *item; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_inform_info_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); /* update the requester physical port. */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4309: " "Cannot find requester physical port\n"); goto Exit; } if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG)) osm_dump_inform_info_record(sa->p_log, p_rcvd_rec, OSM_LOG_DEBUG); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.subscriber_gid = p_rcvd_rec->subscriber_gid; context.subscriber_enum = p_rcvd_rec->subscriber_enum; context.sa = sa; context.p_req_physp = p_req_physp; OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Query Subscriber GID:%s(%02X) Enum:0x%X(%02X)\n", inet_ntop(AF_INET6, p_rcvd_rec->subscriber_gid.raw, gid_str, sizeof gid_str), (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID) != 0, cl_ntoh16(p_rcvd_rec->subscriber_enum), (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) != 0); cl_plock_acquire(sa->p_lock); cl_qlist_apply_func(&sa->p_subn->sa_infr_list, __osm_sa_inform_info_rec_by_comp_mask_cb, &context); cl_plock_release(sa->p_lock); /* clear reserved and pad fields in InformInfoRecord */ for (item = (osm_iir_item_t *) cl_qlist_head(&rec_list); item != (osm_iir_item_t *) cl_qlist_end(&rec_list); item = (osm_iir_item_t *)cl_qlist_next(&item->list_item)) { memset(item->rec.reserved, 0, sizeof(item->rec.reserved)); memset(item->rec.pad, 0, sizeof(item->rec.pad)); } osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_pkey_table_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; const ib_pkey_table_t *p_pkey; cl_qlist_t rec_list; osm_pkey_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_pkey_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); comp_mask = p_rcvd_mad->comp_mask; CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_PKEY_TBL_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4605: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* p922 - P_KeyTableRecords shall only be provided in response to trusted requests. Check that the requester is a trusted one. */ if (p_rcvd_mad->sm_key != sa->p_subn->opt.sa_key) { /* This is not a trusted requester! */ OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4608: " "Request from non-trusted requester: " "Given SM_Key:0x%016" PRIx64 "\n", cl_ntoh64(p_rcvd_mad->sm_key)); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* update the requester physical port. */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4604: " "Cannot find requester physical port\n"); goto Exit; } p_pkey = (ib_pkey_table_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.block_num = p_rcvd_rec->block_num; context.p_req_physp = p_req_physp; OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Got Query Lid:%u(%02X), Block:0x%02X(%02X), Port:0x%02X(%02X)\n", cl_ntoh16(p_rcvd_rec->lid), (comp_mask & IB_PKEY_COMPMASK_LID) != 0, p_rcvd_rec->port_num, (comp_mask & IB_PKEY_COMPMASK_PORT) != 0, p_rcvd_rec->block_num, (comp_mask & IB_PKEY_COMPMASK_BLOCK) != 0); cl_plock_acquire(sa->p_lock); /* If the user specified a LID, it obviously narrows our work load, since we don't have to search every port */ if (comp_mask & IB_PKEY_COMPMASK_LID) { status = osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid, &p_port); if (status != IB_SUCCESS || p_port == NULL) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 460B: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* if we got a unique port - no need for a port search */ if (p_port) /* this does the loop on all the port phys ports */ __osm_sa_pkey_by_comp_mask(sa, p_port, &context); else cl_qmap_apply_func(&sa->p_subn->port_guid_tbl, __osm_sa_pkey_by_comp_mask_cb, &context); } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_pkey_table_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
osm_signal_t osm_qos_setup(osm_opensm_t * p_osm) { struct qos_config ca_config, sw0_config, swe_config, rtr_config; struct qos_config *cfg; cl_qmap_t *p_tbl; cl_map_item_t *p_next; osm_port_t *p_port; uint32_t num_physp; osm_physp_t *p_physp; osm_node_t *p_node; ib_api_status_t status; unsigned force_update; uint8_t i; if (!p_osm->subn.opt.qos) return OSM_SIGNAL_DONE; OSM_LOG_ENTER(&p_osm->log); qos_build_config(&ca_config, &p_osm->subn.opt.qos_ca_options, &p_osm->subn.opt.qos_options); qos_build_config(&sw0_config, &p_osm->subn.opt.qos_sw0_options, &p_osm->subn.opt.qos_options); qos_build_config(&swe_config, &p_osm->subn.opt.qos_swe_options, &p_osm->subn.opt.qos_options); qos_build_config(&rtr_config, &p_osm->subn.opt.qos_rtr_options, &p_osm->subn.opt.qos_options); cl_plock_excl_acquire(&p_osm->lock); /* read QoS policy config file */ osm_qos_parse_policy_file(&p_osm->subn); p_tbl = &p_osm->subn.port_guid_tbl; p_next = cl_qmap_head(p_tbl); while (p_next != cl_qmap_end(p_tbl)) { p_port = (osm_port_t *) p_next; p_next = cl_qmap_next(p_next); p_node = p_port->p_node; if (p_node->sw) { num_physp = osm_node_get_num_physp(p_node); for (i = 1; i < num_physp; i++) { p_physp = osm_node_get_physp_ptr(p_node, i); if (!p_physp) continue; force_update = p_physp->need_update || p_osm->subn.need_update; status = qos_physp_setup(&p_osm->log, &p_osm->sm, p_port, p_physp, i, force_update, &swe_config); } /* skip base port 0 */ if (!ib_switch_info_is_enhanced_port0 (&p_node->sw->switch_info)) continue; cfg = &sw0_config; } else if (osm_node_get_type(p_node) == IB_NODE_TYPE_ROUTER) cfg = &rtr_config; else cfg = &ca_config; p_physp = p_port->p_physp; if (!p_physp) continue; force_update = p_physp->need_update || p_osm->subn.need_update; status = qos_physp_setup(&p_osm->log, &p_osm->sm, p_port, p_physp, 0, force_update, cfg); } cl_plock_release(&p_osm->lock); OSM_LOG_EXIT(&p_osm->log); return OSM_SIGNAL_DONE; }
void osm_lftr_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_lft_record_t *p_rcvd_rec; cl_qlist_t rec_list; osm_lftr_search_ctxt_t context; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_lft_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_LFT_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4408: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4407: " "Cannot find requester physical port\n"); goto Exit; } OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); /* Go over all switches */ cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, lftr_rcv_by_comp_mask, &context); cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_lft_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
void osm_smir_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *sad_mad; const ib_sminfo_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; const ib_sm_info_t *p_smi; cl_qlist_t rec_list; osm_smir_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; ib_net64_t port_guid; osm_physp_t *p_req_physp; osm_port_t *local_port; osm_remote_sm_t *p_rem_sm; cl_qmap_t *p_sm_guid_tbl; uint8_t pri_state; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); sad_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_sminfo_record_t *) ib_sa_mad_get_payload_ptr(sad_mad); comp_mask = sad_mad->comp_mask; CL_ASSERT(sad_mad->attr_id == IB_MAD_ATTR_SMINFO_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (sad_mad->method != IB_MAD_METHOD_GET && sad_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2804: " "Unsupported Method (%s)\n", ib_get_sa_method_str(sad_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2803: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); osm_dump_sm_info_record_v2(sa->p_log, p_rcvd_rec, FILE_ID, OSM_LOG_DEBUG); } p_smi = &p_rcvd_rec->sm_info; cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = sad_mad->comp_mask; context.sa = sa; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); /* If the user specified a LID, it obviously narrows our work load, since we don't have to search every port */ if (comp_mask & IB_SMIR_COMPMASK_LID) { p_port = osm_get_port_by_lid(sa->p_subn, p_rcvd_rec->lid); if (!p_port) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2806: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* Handle our own SM first */ local_port = osm_get_port_by_guid(sa->p_subn, sa->p_subn->sm_port_guid); if (!local_port) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2809: " "No port found with GUID 0x%016" PRIx64 "\n", cl_ntoh64(sa->p_subn->sm_port_guid)); goto Exit; } if (!p_port || local_port == p_port) { if (FALSE == osm_physp_share_pkey(sa->p_log, p_req_physp, local_port->p_physp, sa->p_subn->opt.allow_both_pkeys)) { cl_plock_release(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2805: " "Cannot get SMInfo record due to pkey violation\n"); goto Exit; } /* Check that other search components specified match */ if ((comp_mask & IB_SMIR_COMPMASK_GUID) && sa->p_subn->sm_port_guid != p_smi->guid) goto Remotes; if ((comp_mask & IB_SMIR_COMPMASK_PRIORITY) && sa->p_subn->opt.sm_priority != ib_sminfo_get_priority(p_smi)) goto Remotes; if ((comp_mask & IB_SMIR_COMPMASK_SMSTATE) && sa->p_subn->sm_state != ib_sminfo_get_state(p_smi)) goto Remotes; /* Now, add local SMInfo to list */ pri_state = sa->p_subn->sm_state & 0x0F; pri_state |= (sa->p_subn->opt.sm_priority & 0x0F) << 4; smir_rcv_new_smir(sa, local_port, context.p_list, sa->p_subn->sm_port_guid, cl_ntoh32(sa->p_subn->p_osm->stats. qp0_mads_sent), pri_state, p_req_physp); } Remotes: if (p_port && p_port != local_port) { /* Find remote SM corresponding to p_port */ port_guid = osm_port_get_guid(p_port); p_sm_guid_tbl = &sa->p_subn->sm_guid_tbl; p_rem_sm = (osm_remote_sm_t *) cl_qmap_get(p_sm_guid_tbl, port_guid); if (p_rem_sm != (osm_remote_sm_t *) cl_qmap_end(p_sm_guid_tbl)) sa_smir_by_comp_mask(sa, p_rem_sm, &context); else OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 280A: " "No remote SM for GUID 0x%016" PRIx64 "\n", cl_ntoh64(port_guid)); } else { /* Go over all other known (remote) SMs */ cl_qmap_apply_func(&sa->p_subn->sm_guid_tbl, sa_smir_by_comp_mask_cb, &context); } } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_sminfo_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
void osm_lr_rcv_process(IN void *context, IN void *data) { osm_sa_t *sa = context; osm_madw_t *p_madw = data; const ib_link_record_t *p_lr; const ib_sa_mad_t *p_sa_mad; const osm_port_t *p_src_port; const osm_port_t *p_dest_port; cl_qlist_t lr_list; ib_net16_t status; osm_physp_t *p_req_physp; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_lr = ib_sa_mad_get_payload_ptr(p_sa_mad); CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_LINK_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_sa_mad->method != IB_MAD_METHOD_GET && p_sa_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1804: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_sa_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1805: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_physp_get_port_guid(p_req_physp))); osm_dump_link_record_v2(sa->p_log, p_lr, FILE_ID, OSM_LOG_DEBUG); } cl_qlist_init(&lr_list); /* Most SA functions (including this one) are read-only on the subnet object, so we grab the lock non-exclusively. */ cl_plock_acquire(sa->p_lock); status = lr_rcv_get_end_points(sa, p_madw, &p_src_port, &p_dest_port); if (status == IB_SA_MAD_STATUS_SUCCESS) lr_rcv_get_port_links(sa, p_lr, p_src_port, p_dest_port, p_sa_mad->comp_mask, &lr_list, p_req_physp); cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_link_record_t), &lr_list); Exit: OSM_LOG_EXIT(sa->p_log); }
void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data) { osm_sa_t *sa = ctx; osm_madw_t *p_madw = data; const ib_sa_mad_t *p_rcvd_mad; const ib_slvl_table_record_t *p_rcvd_rec; const osm_port_t *p_port = NULL; cl_qlist_t rec_list; osm_slvl_search_ctxt_t context; ib_api_status_t status = IB_SUCCESS; ib_net64_t comp_mask; osm_physp_t *p_req_physp; CL_ASSERT(sa); OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw); p_rcvd_rec = (ib_slvl_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad); comp_mask = p_rcvd_mad->comp_mask; CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_SLVL_RECORD); /* we only support SubnAdmGet and SubnAdmGetTable methods */ if (p_rcvd_mad->method != IB_MAD_METHOD_GET && p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2604: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_rcvd_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port. */ p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (p_req_physp == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2603: " "Cannot find requester physical port\n"); goto Exit; } cl_qlist_init(&rec_list); context.p_rcvd_rec = p_rcvd_rec; context.p_list = &rec_list; context.comp_mask = p_rcvd_mad->comp_mask; context.sa = sa; context.in_port_num = p_rcvd_rec->in_port_num; context.p_req_physp = p_req_physp; cl_plock_acquire(sa->p_lock); OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Got Query Lid:%u(%02X), In-Port:0x%02X(%02X), Out-Port:0x%02X(%02X)\n", cl_ntoh16(p_rcvd_rec->lid), (comp_mask & IB_SLVL_COMPMASK_LID) != 0, p_rcvd_rec->in_port_num, (comp_mask & IB_SLVL_COMPMASK_IN_PORT) != 0, p_rcvd_rec->out_port_num, (comp_mask & IB_SLVL_COMPMASK_OUT_PORT) != 0); /* If the user specified a LID, it obviously narrows our work load, since we don't have to search every port */ if (comp_mask & IB_SLVL_COMPMASK_LID) { status = osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid, &p_port); if ((status != IB_SUCCESS) || (p_port == NULL)) { status = IB_NOT_FOUND; OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2608: " "No port found with LID %u\n", cl_ntoh16(p_rcvd_rec->lid)); } } if (status == IB_SUCCESS) { /* if we have a unique port - no need for a port search */ if (p_port) /* this does the loop on all the port phys ports */ __osm_sa_slvl_by_comp_mask(sa, p_port, &context); else cl_qmap_apply_func(&sa->p_subn->port_guid_tbl, __osm_sa_slvl_by_comp_mask_cb, &context); } cl_plock_release(sa->p_lock); osm_sa_respond(sa, p_madw, sizeof(ib_slvl_table_record_t), &rec_list); Exit: OSM_LOG_EXIT(sa->p_log); }
/********************************************************************** * perfmgr_db_data_cnt_reading_t functions **********************************************************************/ perfmgr_db_err_t perfmgr_db_add_dc_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port, perfmgr_db_data_cnt_reading_t * reading, int ietf_sup) { db_port_t *p_port = NULL; db_node_t *node = NULL; perfmgr_db_data_cnt_reading_t *previous = NULL; perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS; osm_epi_dc_event_t epi_dc_data; cl_plock_excl_acquire(&db->lock); node = get(db, guid); if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS) goto Exit; mark_port_valid(node, port); p_port = &node->ports[port]; previous = &node->ports[port].dc_previous; debug_dump_dc_reading(db, guid, port, p_port, reading); epi_dc_data.time_diff_s = reading->time - previous->time; osm_epi_create_port_id(&epi_dc_data.port_id, guid, port, node->node_name); /* calculate changes from previous reading */ epi_dc_data.xmit_data = reading->xmit_data - previous->xmit_data; p_port->dc_total.xmit_data += epi_dc_data.xmit_data; epi_dc_data.rcv_data = reading->rcv_data - previous->rcv_data; p_port->dc_total.rcv_data += epi_dc_data.rcv_data; epi_dc_data.xmit_pkts = reading->xmit_pkts - previous->xmit_pkts; p_port->dc_total.xmit_pkts += epi_dc_data.xmit_pkts; epi_dc_data.rcv_pkts = reading->rcv_pkts - previous->rcv_pkts; p_port->dc_total.rcv_pkts += epi_dc_data.rcv_pkts; if (ietf_sup) { epi_dc_data.unicast_xmit_pkts = reading->unicast_xmit_pkts - previous->unicast_xmit_pkts; p_port->dc_total.unicast_xmit_pkts += epi_dc_data.unicast_xmit_pkts; epi_dc_data.unicast_rcv_pkts = reading->unicast_rcv_pkts - previous->unicast_rcv_pkts; p_port->dc_total.unicast_rcv_pkts += epi_dc_data.unicast_rcv_pkts; epi_dc_data.multicast_xmit_pkts = reading->multicast_xmit_pkts - previous->multicast_xmit_pkts; p_port->dc_total.multicast_xmit_pkts += epi_dc_data.multicast_xmit_pkts; epi_dc_data.multicast_rcv_pkts = reading->multicast_rcv_pkts - previous->multicast_rcv_pkts; p_port->dc_total.multicast_rcv_pkts += epi_dc_data.multicast_rcv_pkts; } p_port->dc_previous = *reading; /* mark the time this total was updated */ p_port->dc_total.time = reading->time; osm_opensm_report_event(db->perfmgr->osm, OSM_EVENT_ID_PORT_DATA_COUNTERS, &epi_dc_data); Exit: cl_plock_release(&db->lock); return rc; }
/********************************************************************** * perfmgr_db_err_reading_t functions **********************************************************************/ perfmgr_db_err_t perfmgr_db_add_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port, perfmgr_db_err_reading_t * reading) { db_port_t *p_port = NULL; db_node_t *node = NULL; perfmgr_db_err_reading_t *previous = NULL; perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS; osm_epi_pe_event_t epi_pe_data; cl_plock_excl_acquire(&db->lock); node = get(db, guid); if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS) goto Exit; mark_port_valid(node, port); p_port = &(node->ports[port]); previous = &(node->ports[port].err_previous); debug_dump_err_reading(db, guid, port, p_port, reading); epi_pe_data.time_diff_s = (reading->time - previous->time); osm_epi_create_port_id(&epi_pe_data.port_id, guid, port, node->node_name); /* calculate changes from previous reading */ epi_pe_data.symbol_err_cnt = (reading->symbol_err_cnt - previous->symbol_err_cnt); p_port->err_total.symbol_err_cnt += epi_pe_data.symbol_err_cnt; epi_pe_data.link_err_recover = (reading->link_err_recover - previous->link_err_recover); p_port->err_total.link_err_recover += epi_pe_data.link_err_recover; epi_pe_data.link_downed = (reading->link_downed - previous->link_downed); p_port->err_total.link_downed += epi_pe_data.link_downed; epi_pe_data.rcv_err = (reading->rcv_err - previous->rcv_err); p_port->err_total.rcv_err += epi_pe_data.rcv_err; epi_pe_data.rcv_rem_phys_err = (reading->rcv_rem_phys_err - previous->rcv_rem_phys_err); p_port->err_total.rcv_rem_phys_err += epi_pe_data.rcv_rem_phys_err; epi_pe_data.rcv_switch_relay_err = (reading->rcv_switch_relay_err - previous->rcv_switch_relay_err); p_port->err_total.rcv_switch_relay_err += epi_pe_data.rcv_switch_relay_err; epi_pe_data.xmit_discards = (reading->xmit_discards - previous->xmit_discards); p_port->err_total.xmit_discards += epi_pe_data.xmit_discards; epi_pe_data.xmit_constraint_err = (reading->xmit_constraint_err - previous->xmit_constraint_err); p_port->err_total.xmit_constraint_err += epi_pe_data.xmit_constraint_err; epi_pe_data.rcv_constraint_err = (reading->rcv_constraint_err - previous->rcv_constraint_err); p_port->err_total.rcv_constraint_err += epi_pe_data.rcv_constraint_err; epi_pe_data.link_integrity = (reading->link_integrity - previous->link_integrity); p_port->err_total.link_integrity += epi_pe_data.link_integrity; epi_pe_data.buffer_overrun = (reading->buffer_overrun - previous->buffer_overrun); p_port->err_total.buffer_overrun += epi_pe_data.buffer_overrun; epi_pe_data.vl15_dropped = (reading->vl15_dropped - previous->vl15_dropped); p_port->err_total.vl15_dropped += epi_pe_data.vl15_dropped; epi_pe_data.xmit_wait = (reading->xmit_wait - previous->xmit_wait); p_port->err_total.xmit_wait += epi_pe_data.xmit_wait; p_port->err_previous = *reading; /* mark the time this total was updated */ p_port->err_total.time = reading->time; osm_opensm_report_event(db->perfmgr->osm, OSM_EVENT_ID_PORT_ERRORS, &epi_pe_data); Exit: cl_plock_release(&db->lock); return rc; }
void osm_mpr_rcv_process(IN void *context, IN void *data) { osm_sa_t *sa = context; osm_madw_t *p_madw = data; const ib_multipath_rec_t *p_mpr; ib_sa_mad_t *p_sa_mad; osm_port_t *requester_port; osm_alias_guid_t *pp_alias_guids[IB_MULTIPATH_MAX_GIDS]; cl_qlist_t pr_list; ib_net16_t sa_status; int nsrc, ndest; uint8_t rate, mtu; OSM_LOG_ENTER(sa->p_log); CL_ASSERT(p_madw); p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); p_mpr = (ib_multipath_rec_t *) ib_sa_mad_get_payload_ptr(p_sa_mad); CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD); if ((p_sa_mad->rmpp_flags & IB_RMPP_FLAG_ACTIVE) != IB_RMPP_FLAG_ACTIVE) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4510: " "Invalid request since RMPP_FLAG_ACTIVE is not set\n"); osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } /* we only support SubnAdmGetMulti method */ if (p_sa_mad->method != IB_MAD_METHOD_GETMULTI) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4513: " "Unsupported Method (%s)\n", ib_get_sa_method_str(p_sa_mad->method)); osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR); goto Exit; } /* update the requester physical port */ requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn, osm_madw_get_mad_addr_ptr (p_madw)); if (requester_port == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4517: " "Cannot find requester physical port\n"); goto Exit; } if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) { OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Requester port GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_port_get_guid(requester_port))); osm_dump_multipath_record_v2(sa->p_log, p_mpr, FILE_ID, OSM_LOG_DEBUG); } /* Make sure required components (S/DGIDCount) are supplied */ if (!(p_sa_mad->comp_mask & IB_MPR_COMPMASK_SGIDCOUNT) || !(p_sa_mad->comp_mask & IB_MPR_COMPMASK_DGIDCOUNT)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS); goto Exit; } /* Validate rate if supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATESELEC) && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATE)) { rate = ib_multipath_rec_rate(p_mpr); if (!ib_rate_is_valid(rate)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } } /* Validate MTU if supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTUSELEC) && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTU)) { mtu = ib_multipath_rec_mtu(p_mpr); if (!ib_mtu_is_valid(mtu)) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); goto Exit; } } /* Make sure either none or both ServiceID parameters are supplied */ if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) != 0 && (p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) != IB_MPR_COMPMASK_SERVICEID) { osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS); goto Exit; } cl_qlist_init(&pr_list); /* Most SA functions (including this one) are read-only on the subnet object, so we grab the lock non-exclusively. */ cl_plock_acquire(sa->p_lock); sa_status = mpr_rcv_get_end_points(sa, p_madw, pp_alias_guids, &nsrc, &ndest); if (sa_status != IB_SA_MAD_STATUS_SUCCESS || !nsrc || !ndest) { if (sa_status == IB_SA_MAD_STATUS_SUCCESS && (!nsrc || !ndest)) OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4512: " "mpr_rcv_get_end_points failed, # GIDs found; " "src %d; dest %d)\n", nsrc, ndest); cl_plock_release(sa->p_lock); if (sa_status == IB_SA_MAD_STATUS_SUCCESS) osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID); else osm_sa_send_error(sa, p_madw, sa_status); goto Exit; } /* APM request */ if (nsrc == 2 && ndest == 2 && (p_mpr->num_path & 0x7F) == 2) mpr_rcv_get_apm_paths(sa, p_mpr, requester_port, pp_alias_guids, p_sa_mad->comp_mask, &pr_list); else mpr_rcv_process_pairs(sa, p_mpr, requester_port, pp_alias_guids, nsrc, ndest, p_sa_mad->comp_mask, &pr_list); cl_plock_release(sa->p_lock); /* o15-0.2.7: If MultiPath is supported, then SA shall respond to a SubnAdmGetMulti() containing a valid MultiPathRecord attribute with a set of zero or more PathRecords satisfying the constraints indicated in the MultiPathRecord received. The PathRecord Attribute ID shall be used in the response. */ p_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD; osm_sa_respond(sa, p_madw, sizeof(ib_path_rec_t), &pr_list); Exit: OSM_LOG_EXIT(sa->p_log); }
int osm_qos_setup(osm_opensm_t * p_osm) { struct qos_config ca_config, sw0_config, swe_config, rtr_config; struct qos_config *cfg; cl_qmap_t *p_tbl; cl_map_item_t *p_next; osm_port_t *p_port; osm_node_t *p_node; int ret = 0; int vlarb_only; qos_mad_list_t *p_list, *p_list_next; qos_mad_item_t *p_port_mad; cl_qlist_t qos_mad_list; if (!p_osm->subn.opt.qos) return 0; OSM_LOG_ENTER(&p_osm->log); qos_build_config(&ca_config, &p_osm->subn.opt.qos_ca_options, &p_osm->subn.opt.qos_options); qos_build_config(&sw0_config, &p_osm->subn.opt.qos_sw0_options, &p_osm->subn.opt.qos_options); qos_build_config(&swe_config, &p_osm->subn.opt.qos_swe_options, &p_osm->subn.opt.qos_options); qos_build_config(&rtr_config, &p_osm->subn.opt.qos_rtr_options, &p_osm->subn.opt.qos_options); cl_qlist_init(&qos_mad_list); cl_plock_excl_acquire(&p_osm->lock); /* read QoS policy config file */ osm_qos_parse_policy_file(&p_osm->subn); p_tbl = &p_osm->subn.port_guid_tbl; p_next = cl_qmap_head(p_tbl); while (p_next != cl_qmap_end(p_tbl)) { vlarb_only = 0; p_port = (osm_port_t *) p_next; p_next = cl_qmap_next(p_next); p_list = (qos_mad_list_t *) malloc(sizeof(*p_list)); if (!p_list) return -1; memset(p_list, 0, sizeof(*p_list)); cl_qlist_init(&p_list->port_mad_list); p_node = p_port->p_node; if (p_node->sw) { if (qos_extports_setup(&p_osm->sm, p_node, &swe_config, &p_list->port_mad_list)) ret = -1; /* skip base port 0 */ if (!ib_switch_info_is_enhanced_port0 (&p_node->sw->switch_info)) goto Continue; if (ib_switch_info_get_opt_sl2vlmapping(&p_node->sw->switch_info) && p_osm->sm.p_subn->opt.use_optimized_slvl && !memcmp(&swe_config.sl2vl, &sw0_config.sl2vl, sizeof(swe_config.sl2vl))) vlarb_only = 1; cfg = &sw0_config; } else if (osm_node_get_type(p_node) == IB_NODE_TYPE_ROUTER) cfg = &rtr_config; else cfg = &ca_config; if (qos_endport_setup(&p_osm->sm, p_port->p_physp, cfg, vlarb_only, &p_list->port_mad_list)) ret = -1; Continue: /* if MAD list is not empty, add it to the global MAD list */ if (cl_qlist_count(&p_list->port_mad_list)) { cl_qlist_insert_tail(&qos_mad_list, &p_list->list_item); } else { free(p_list); } } while (cl_qlist_count(&qos_mad_list)) { p_list_next = (qos_mad_list_t *) cl_qlist_head(&qos_mad_list); while (p_list_next != (qos_mad_list_t *) cl_qlist_end(&qos_mad_list)) { p_list = p_list_next; p_list_next = (qos_mad_list_t *) cl_qlist_next(&p_list->list_item); /* next MAD to send*/ p_port_mad = (qos_mad_item_t *) cl_qlist_remove_head(&p_list->port_mad_list); osm_send_req_mad(&p_osm->sm, p_port_mad->p_madw); osm_qos_mad_delete(&p_port_mad); /* remove the QoS MAD from global MAD list */ if (cl_qlist_count(&p_list->port_mad_list) == 0) { cl_qlist_remove_item(&qos_mad_list, &p_list->list_item); free(p_list); } } } cl_plock_release(&p_osm->lock); OSM_LOG_EXIT(&p_osm->log); return ret; }