/* Main grouping function Algorithm: 1. pass on every Voltaire node 2. catch spine chip for every Voltaire node 2.1 build/interpolate chassis around this chip 2.2 go to 1. 3. pass on non Voltaire nodes (SystemImageGUID based grouping) 4. now group non Voltaire nodes by SystemImageGUID Returns: 0 on success, -1 on failure */ int group_nodes(ibnd_fabric_t * fabric) { ibnd_node_t *node; int chassisnum = 0; ibnd_chassis_t *chassis; ibnd_chassis_t *ch, *ch_next; chassis_scan_t chassis_scan; int vendor_id; chassis_scan.first_chassis = NULL; chassis_scan.current_chassis = NULL; chassis_scan.last_chassis = NULL; /* first pass on switches and build for every Voltaire node */ /* an appropriate chassis record (slotnum and position) */ /* according to internal connectivity */ /* not very efficient but clear code so... */ for (node = fabric->switches; node; node = node->type_next) { vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F); if (vendor_id == VTR_VENDOR_ID && fill_voltaire_chassis_record(node)) goto cleanup; else if (vendor_id == MLX_VENDOR_ID && fill_mellanox_chassis_record(node)) goto cleanup; } /* separate every Voltaire chassis from each other and build linked list of them */ /* algorithm: catch spine and find all surrounding nodes */ for (node = fabric->switches; node; node = node->type_next) { if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID) continue; if (!node->ch_found || (node->chassis && node->chassis->chassisnum) || !is_spine(node)) continue; if (add_chassis(&chassis_scan)) goto cleanup; chassis_scan.current_chassis->chassisnum = ++chassisnum; if (build_chassis(node, chassis_scan.current_chassis)) goto cleanup; } /* now make pass on nodes for chassis which are not Voltaire */ /* grouped by common SystemImageGUID */ for (node = fabric->nodes; node; node = node->next) { if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) == VTR_VENDOR_ID) continue; if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) { chassis = find_chassisguid(fabric, node); if (chassis) chassis->nodecount++; else { /* Possible new chassis */ if (add_chassis(&chassis_scan)) goto cleanup; chassis_scan.current_chassis->chassisguid = get_chassisguid(node); chassis_scan.current_chassis->nodecount = 1; if (!fabric->chassis) fabric->chassis = chassis_scan.first_chassis; } } } /* now, make another pass to see which nodes are part of chassis */ /* (defined as chassis->nodecount > 1) */ for (node = fabric->nodes; node; node = node->next) { vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F); if (vendor_id == VTR_VENDOR_ID) continue; if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) { chassis = find_chassisguid(fabric, node); if (chassis && chassis->nodecount > 1) { if (!chassis->chassisnum) chassis->chassisnum = ++chassisnum; if (!node->ch_found) { node->ch_found = 1; add_node_to_chassis(chassis, node); } else if (vendor_id == MLX_VENDOR_ID){ insert_mellanox_line_and_spine(node, chassis); } } } } fabric->chassis = chassis_scan.first_chassis; return 0; cleanup: ch = chassis_scan.first_chassis; while (ch) { ch_next = ch->next; free(ch); ch = ch_next; } fabric->chassis = NULL; return -1; }
/* Main grouping function Algorithm: 1. pass on every Voltaire node 2. catch spine chip for every Voltaire node 2.1 build/interpolate chassis around this chip 2.2 go to 1. 3. pass on non Voltaire nodes (SystemImageGUID based grouping) 4. now group non Voltaire nodes by SystemImageGUID */ ChassisList *group_nodes() { Node *node; int dist; int chassisnum = 0; struct ChassisList *chassis; mylist.first = NULL; mylist.current = NULL; mylist.last = NULL; /* first pass on switches and build for every Voltaire node */ /* an appropriate chassis record (slotnum and position) */ /* according to internal connectivity */ /* not very efficient but clear code so... */ for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { if (node->vendid == VTR_VENDOR_ID) fill_chassis_record(node); } } /* separate every Voltaire chassis from each other and build linked list of them */ /* algorithm: catch spine and find all surrounding nodes */ for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { if (node->vendid != VTR_VENDOR_ID) continue; if (!node->chrecord || node->chrecord->chassisnum || !is_spine(node)) continue; add_chassislist(); mylist.current->chassisnum = ++chassisnum; build_chassis(node, mylist.current); } } /* now make pass on nodes for chassis which are not Voltaire */ /* grouped by common SystemImageGUID */ for (dist = 0; dist <= maxhops_discovered; dist++) { for (node = nodesdist[dist]; node; node = node->dnext) { if (node->vendid == VTR_VENDOR_ID) continue; if (node->sysimgguid) { chassis = find_chassisguid(node); if (chassis) chassis->nodecount++; else { /* Possible new chassis */ add_chassislist(); mylist.current->chassisguid = get_chassisguid(node); mylist.current->nodecount = 1; } } } } /* now, make another pass to see which nodes are part of chassis */ /* (defined as chassis->nodecount > 1) */ for (dist = 0; dist <= MAXHOPS; ) { for (node = nodesdist[dist]; node; node = node->dnext) { if (node->vendid == VTR_VENDOR_ID) continue; if (node->sysimgguid) { chassis = find_chassisguid(node); if (chassis && chassis->nodecount > 1) { if (!chassis->chassisnum) chassis->chassisnum = ++chassisnum; if (!node->chrecord) { if (!(node->chrecord = calloc(1, sizeof(ChassisRecord)))) IBPANIC("out of mem"); node->chrecord->chassisnum = chassis->chassisnum; } } } } if (dist == maxhops_discovered) dist = MAXHOPS; /* skip to CAs */ else dist++; } return (mylist.first); }