|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2006-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2012 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* Implementation of osm_prtn_t.
|
|
Packit |
13e616 |
* This object represents an IBA partition.
|
|
Packit |
13e616 |
* This object is part of the opensm family of objects.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <stdio.h>
|
|
Packit |
13e616 |
#include <sys/stat.h>
|
|
Packit |
13e616 |
#include <complib/cl_debug.h>
|
|
Packit |
13e616 |
#include <iba/ib_types.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_PRTN_C
|
|
Packit |
13e616 |
#include <opensm/osm_opensm.h>
|
|
Packit |
13e616 |
#include <opensm/osm_partition.h>
|
|
Packit |
13e616 |
#include <opensm/osm_node.h>
|
|
Packit |
13e616 |
#include <opensm/osm_sa.h>
|
|
Packit |
13e616 |
#include <opensm/osm_multicast.h>
|
|
Packit |
13e616 |
#include <arpa/inet.h>
|
|
Packit |
13e616 |
#include <errno.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
extern int osm_prtn_config_parse_file(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
const char *file_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static uint16_t global_pkey_counter;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_prtn_t *osm_prtn_new(IN const char *name, IN uint16_t pkey)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_prtn_t *p = malloc(sizeof(*p));
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p, 0, sizeof(*p));
|
|
Packit |
13e616 |
p->pkey = pkey;
|
|
Packit |
13e616 |
p->sl = OSM_DEFAULT_SL;
|
|
Packit |
13e616 |
p->mgrps = NULL;
|
|
Packit |
13e616 |
p->nmgrps = 0;
|
|
Packit |
13e616 |
cl_map_construct(&p->full_guid_tbl);
|
|
Packit |
13e616 |
cl_map_init(&p->full_guid_tbl, 32);
|
|
Packit |
13e616 |
cl_map_construct(&p->part_guid_tbl);
|
|
Packit |
13e616 |
cl_map_init(&p->part_guid_tbl, 32);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (name && *name) {
|
|
Packit |
13e616 |
strncpy(p->name, name, sizeof(p->name) - 1);
|
|
Packit |
13e616 |
p->name[sizeof(p->name) - 1] = '\0';
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
snprintf(p->name, sizeof(p->name), "%04x", cl_ntoh16(pkey));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_prtn_delete(IN osm_subn_t * p_subn, IN OUT osm_prtn_t ** pp_prtn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char gid_str[INET6_ADDRSTRLEN];
|
|
Packit |
13e616 |
int i = 0;
|
|
Packit |
13e616 |
osm_prtn_t *p = *pp_prtn;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_map_remove_all(&p->full_guid_tbl);
|
|
Packit |
13e616 |
cl_map_destroy(&p->full_guid_tbl);
|
|
Packit |
13e616 |
cl_map_remove_all(&p->part_guid_tbl);
|
|
Packit |
13e616 |
cl_map_destroy(&p->part_guid_tbl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p->mgrps) {
|
|
Packit |
13e616 |
/* Clean up mgrps */
|
|
Packit |
13e616 |
for (i = 0; i < p->nmgrps; i++) {
|
|
Packit |
13e616 |
/* osm_mgrp_cleanup will not delete
|
|
Packit |
13e616 |
* "well_known" groups */
|
|
Packit |
13e616 |
p->mgrps[i]->well_known = FALSE;
|
|
Packit |
13e616 |
OSM_LOG(&p_subn->p_osm->log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"removing mgroup %s from partition (0x%x)\n",
|
|
Packit |
13e616 |
inet_ntop(AF_INET6,
|
|
Packit |
13e616 |
p->mgrps[i]->mcmember_rec.mgid.raw,
|
|
Packit |
13e616 |
gid_str, sizeof gid_str),
|
|
Packit |
13e616 |
cl_hton16(p->pkey));
|
|
Packit |
13e616 |
osm_mgrp_cleanup(p_subn, p->mgrps[i]);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p->mgrps);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p);
|
|
Packit |
13e616 |
*pp_prtn = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_prtn_add_port(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
osm_prtn_t * p, ib_net64_t guid,
|
|
Packit |
13e616 |
boolean_t full, boolean_t indx0)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
cl_map_t *p_tbl;
|
|
Packit |
13e616 |
osm_port_t *p_port;
|
|
Packit |
13e616 |
osm_physp_t *p_physp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_port = osm_get_port_by_guid(p_subn, guid);
|
|
Packit |
13e616 |
if (!p_port) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"port 0x%" PRIx64 " not found\n", cl_ntoh64(guid));
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_physp = p_port->p_physp;
|
|
Packit |
13e616 |
if (!p_physp) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"no physical for port 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
cl_ntoh64(guid));
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* Set the pkey to be inserted to block 0 index 0 */
|
|
Packit |
13e616 |
if (indx0) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "Setting pkey 0x%04x at indx0 "
|
|
Packit |
13e616 |
"for port 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
cl_ntoh16(p->pkey), cl_ntoh64(guid));
|
|
Packit |
13e616 |
osm_pkey_tbl_set_indx0_pkey(p_log, p->pkey, full,
|
|
Packit |
13e616 |
&p_physp->pkeys);
|
|
Packit |
13e616 |
} else if (ib_pkey_get_base(p_physp->pkeys.indx0_pkey) ==
|
|
Packit |
13e616 |
ib_pkey_get_base(p->pkey))
|
|
Packit |
13e616 |
p_physp->pkeys.indx0_pkey = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_tbl = (full == TRUE) ? &p->full_guid_tbl : &p->part_guid_tbl;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_subn->opt.allow_both_pkeys) {
|
|
Packit |
13e616 |
if (cl_map_remove(p_tbl, guid))
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "port 0x%" PRIx64
|
|
Packit |
13e616 |
" already in partition \'%s\' (0x%04x) full %d."
|
|
Packit |
13e616 |
" Will overwrite\n",
|
|
Packit |
13e616 |
cl_ntoh64(guid), p->name, cl_ntoh16(p->pkey),
|
|
Packit |
13e616 |
full);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
if (cl_map_remove(&p->part_guid_tbl, guid) ||
|
|
Packit |
13e616 |
cl_map_remove(&p->full_guid_tbl, guid))
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "port 0x%" PRIx64
|
|
Packit |
13e616 |
" already in partition \'%s\' (0x%04x)."
|
|
Packit |
13e616 |
" Will overwrite\n",
|
|
Packit |
13e616 |
cl_ntoh64(guid), p->name, cl_ntoh16(p->pkey));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (cl_map_insert(p_tbl, guid, p_physp) == NULL)
|
|
Packit |
13e616 |
return IB_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_prtn_add_all(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
osm_prtn_t * p, unsigned type,
|
|
Packit |
13e616 |
boolean_t full, boolean_t indx0)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_qmap_t *p_port_tbl = &p_subn->port_guid_tbl;
|
|
Packit |
13e616 |
cl_map_item_t *p_item;
|
|
Packit |
13e616 |
osm_port_t *p_port;
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_item = cl_qmap_head(p_port_tbl);
|
|
Packit |
13e616 |
while (p_item != cl_qmap_end(p_port_tbl)) {
|
|
Packit |
13e616 |
p_port = (osm_port_t *) p_item;
|
|
Packit |
13e616 |
p_item = cl_qmap_next(p_item);
|
|
Packit |
13e616 |
if (!type || osm_node_get_type(p_port->p_node) == type) {
|
|
Packit |
13e616 |
status = osm_prtn_add_port(p_log, p_subn, p,
|
|
Packit |
13e616 |
osm_port_get_guid(p_port),
|
|
Packit |
13e616 |
full, indx0);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto _err;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_err:
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
track_mgrp_w_partition(osm_log_t *p_log, osm_prtn_t *p, osm_mgrp_t *mgrp,
|
|
Packit |
13e616 |
osm_subn_t *p_subn, const ib_gid_t *mgid,
|
|
Packit |
13e616 |
ib_net16_t pkey)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char gid_str[INET6_ADDRSTRLEN];
|
|
Packit |
13e616 |
osm_mgrp_t **tmp;
|
|
Packit |
13e616 |
int i = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* check if we are already tracking this group */
|
|
Packit |
13e616 |
for (i = 0; i < p->nmgrps; i++)
|
|
Packit |
13e616 |
if (p->mgrps[i] == mgrp)
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* otherwise add it to our list */
|
|
Packit |
13e616 |
tmp = realloc(p->mgrps, (p->nmgrps +1) * sizeof(*p->mgrps));
|
|
Packit |
13e616 |
if (tmp) {
|
|
Packit |
13e616 |
p->mgrps = tmp;
|
|
Packit |
13e616 |
p->mgrps[p->nmgrps] = mgrp;
|
|
Packit |
13e616 |
p->nmgrps++;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"realloc error to create MC group (%s) in "
|
|
Packit |
13e616 |
"partition (pkey 0x%04x)\n",
|
|
Packit |
13e616 |
inet_ntop(AF_INET6, mgid->raw,
|
|
Packit |
13e616 |
gid_str, sizeof gid_str),
|
|
Packit |
13e616 |
cl_ntoh16(pkey));
|
|
Packit |
13e616 |
mgrp->well_known = FALSE;
|
|
Packit |
13e616 |
osm_mgrp_cleanup(p_subn, mgrp);
|
|
Packit |
13e616 |
return (IB_ERROR);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
mgrp->well_known = TRUE;
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_prtn_add_mcgroup(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
osm_prtn_t * p, uint8_t rate, uint8_t mtu,
|
|
Packit |
13e616 |
uint8_t sl, uint8_t scope, uint32_t Q_Key,
|
|
Packit |
13e616 |
uint8_t tclass, uint32_t FlowLabel,
|
|
Packit |
13e616 |
const ib_gid_t *mgid)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char gid_str[INET6_ADDRSTRLEN];
|
|
Packit |
13e616 |
ib_member_rec_t mc_rec;
|
|
Packit |
13e616 |
ib_net64_t comp_mask;
|
|
Packit |
13e616 |
ib_net16_t pkey;
|
|
Packit |
13e616 |
osm_mgrp_t *mgrp;
|
|
Packit |
13e616 |
osm_sa_t *p_sa = &p_subn->p_osm->sa;
|
|
Packit |
13e616 |
uint8_t hop_limit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pkey = p->pkey | cl_hton16(0x8000);
|
|
Packit |
13e616 |
if (!scope)
|
|
Packit |
13e616 |
scope = OSM_DEFAULT_MGRP_SCOPE;
|
|
Packit |
13e616 |
hop_limit = (scope == IB_MC_SCOPE_LINK_LOCAL) ? 0 : IB_HOPLIMIT_MAX;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(&mc_rec, 0, sizeof(mc_rec));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
mc_rec.mgid = *mgid;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
mc_rec.qkey = CL_HTON32(Q_Key);
|
|
Packit |
13e616 |
mc_rec.mtu = mtu | (IB_PATH_SELECTOR_EXACTLY << 6);
|
|
Packit |
13e616 |
mc_rec.tclass = tclass;
|
|
Packit |
13e616 |
mc_rec.pkey = pkey;
|
|
Packit |
13e616 |
mc_rec.rate = rate | (IB_PATH_SELECTOR_EXACTLY << 6);
|
|
Packit |
13e616 |
mc_rec.pkt_life = p_subn->opt.subnet_timeout;
|
|
Packit |
13e616 |
mc_rec.sl_flow_hop = ib_member_set_sl_flow_hop(sl, FlowLabel, hop_limit);
|
|
Packit |
13e616 |
/* Scope in MCMemberRecord (if present) needs to be consistent with MGID */
|
|
Packit |
13e616 |
mc_rec.scope_state =
|
|
Packit |
13e616 |
ib_member_set_scope_state(scope, IB_MC_REC_STATE_FULL_MEMBER);
|
|
Packit |
13e616 |
ib_mgid_set_scope(&mc_rec.mgid, scope);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* don't update rate, mtu */
|
|
Packit |
13e616 |
comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL |
|
|
Packit |
13e616 |
IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
|
|
Packit |
13e616 |
mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(p_sa, comp_mask, &mc_rec);
|
|
Packit |
13e616 |
if (!mgrp) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Failed to create MC group (%s) with pkey 0x%04x\n",
|
|
Packit |
13e616 |
inet_ntop(AF_INET6, mgid->raw, gid_str, sizeof gid_str),
|
|
Packit |
13e616 |
cl_ntoh16(pkey));
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (track_mgrp_w_partition(p_log, p, mgrp, p_subn, mgid, pkey));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static uint16_t generate_pkey(osm_subn_t * p_subn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
uint16_t pkey;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qmap_t *m = &p_subn->prtn_pkey_tbl;
|
|
Packit |
13e616 |
while (global_pkey_counter < cl_ntoh16(IB_DEFAULT_PARTIAL_PKEY) - 1) {
|
|
Packit |
13e616 |
pkey = ++global_pkey_counter;
|
|
Packit |
13e616 |
pkey = cl_hton16(pkey);
|
|
Packit |
13e616 |
if (cl_qmap_get(m, pkey) == cl_qmap_end(m))
|
|
Packit |
13e616 |
return pkey;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_prtn_t *osm_prtn_find_by_name(osm_subn_t * p_subn, const char *name)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_map_item_t *p_next;
|
|
Packit |
13e616 |
osm_prtn_t *p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next = cl_qmap_head(&p_subn->prtn_pkey_tbl);
|
|
Packit |
13e616 |
while (p_next != cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
|
|
Packit |
13e616 |
p = (osm_prtn_t *) p_next;
|
|
Packit |
13e616 |
p_next = cl_qmap_next(&p->map_item);
|
|
Packit |
13e616 |
if (!strncmp(p->name, name, sizeof(p->name)))
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_prtn_t *osm_prtn_make_new(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
const char *name, uint16_t pkey)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_prtn_t *p = NULL, *p_check;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
pkey &= cl_hton16((uint16_t) ~ 0x8000);
|
|
Packit |
13e616 |
if (!pkey) {
|
|
Packit |
13e616 |
if (name && (p = osm_prtn_find_by_name(p_subn, name)))
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
if (!(pkey = generate_pkey(p_subn)))
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p = osm_prtn_new(name, pkey);
|
|
Packit |
13e616 |
if (!p) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "Unable to create"
|
|
Packit |
13e616 |
" partition \'%s\' (0x%04x)\n", name, cl_ntoh16(pkey));
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_check = (osm_prtn_t *) cl_qmap_insert(&p_subn->prtn_pkey_tbl,
|
|
Packit |
13e616 |
p->pkey, &p->map_item);
|
|
Packit |
13e616 |
if (p != p_check) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "Duplicated partition"
|
|
Packit |
13e616 |
" definition: \'%s\' (0x%04x) prev name \'%s\'"
|
|
Packit |
13e616 |
". Will use it\n",
|
|
Packit |
13e616 |
name, cl_ntoh16(pkey), p_check->name);
|
|
Packit |
13e616 |
osm_prtn_delete(p_subn, &p);
|
|
Packit |
13e616 |
p = p_check;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t prtn_make_default(osm_log_t * p_log, osm_subn_t * p_subn,
|
|
Packit |
13e616 |
boolean_t no_config)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_UNKNOWN_ERROR;
|
|
Packit |
13e616 |
osm_prtn_t *p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p = osm_prtn_make_new(p_log, p_subn, "Default",
|
|
Packit |
13e616 |
IB_DEFAULT_PARTIAL_PKEY);
|
|
Packit |
13e616 |
if (!p)
|
|
Packit |
13e616 |
goto _err;
|
|
Packit |
13e616 |
status = osm_prtn_add_all(p_log, p_subn, p, 0, no_config, FALSE);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto _err;
|
|
Packit |
13e616 |
cl_map_remove(&p->part_guid_tbl, p_subn->sm_port_guid);
|
|
Packit |
13e616 |
status =
|
|
Packit |
13e616 |
osm_prtn_add_port(p_log, p_subn, p, p_subn->sm_port_guid, TRUE, FALSE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* ipv4 broadcast group */
|
|
Packit |
13e616 |
if (no_config)
|
|
Packit |
13e616 |
osm_prtn_add_mcgroup(p_log, p_subn, p, OSM_DEFAULT_MGRP_RATE,
|
|
Packit |
13e616 |
OSM_DEFAULT_MGRP_MTU, OSM_DEFAULT_SL,
|
|
Packit |
13e616 |
0, OSM_IPOIB_BROADCAST_MGRP_QKEY, 0, 0,
|
|
Packit |
13e616 |
&osm_ipoib_broadcast_mgid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_err:
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_prtn_make_partitions(osm_log_t * p_log, osm_subn_t * p_subn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct stat statbuf;
|
|
Packit |
13e616 |
const char *file_name;
|
|
Packit |
13e616 |
boolean_t is_config = TRUE;
|
|
Packit |
13e616 |
boolean_t is_wrong_config = FALSE;
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
cl_map_item_t *p_next;
|
|
Packit |
13e616 |
osm_prtn_t *p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
file_name = p_subn->opt.partition_config_file ?
|
|
Packit |
13e616 |
p_subn->opt.partition_config_file : OSM_DEFAULT_PARTITION_CONFIG_FILE;
|
|
Packit |
13e616 |
if (stat(file_name, &statbuf)) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "Partition configuration "
|
|
Packit |
13e616 |
"%s is not accessible (%s)\n", file_name,
|
|
Packit |
13e616 |
strerror(errno));
|
|
Packit |
13e616 |
is_config = FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
retry_default:
|
|
Packit |
13e616 |
/* clean up current port maps */
|
|
Packit |
13e616 |
p_next = cl_qmap_head(&p_subn->prtn_pkey_tbl);
|
|
Packit |
13e616 |
while (p_next != cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
|
|
Packit |
13e616 |
p = (osm_prtn_t *) p_next;
|
|
Packit |
13e616 |
p_next = cl_qmap_next(&p->map_item);
|
|
Packit |
13e616 |
cl_map_remove_all(&p->part_guid_tbl);
|
|
Packit |
13e616 |
cl_map_remove_all(&p->full_guid_tbl);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
global_pkey_counter = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = prtn_make_default(p_log, p_subn, !is_config);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto _err;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (is_config && osm_prtn_config_parse_file(p_log, p_subn, file_name)) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_VERBOSE, "Partition configuration "
|
|
Packit |
13e616 |
"was not fully processed\n");
|
|
Packit |
13e616 |
is_wrong_config = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* and now clean up empty partitions */
|
|
Packit |
13e616 |
p_next = cl_qmap_head(&p_subn->prtn_pkey_tbl);
|
|
Packit |
13e616 |
while (p_next != cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
|
|
Packit |
13e616 |
p = (osm_prtn_t *) p_next;
|
|
Packit |
13e616 |
p_next = cl_qmap_next(&p->map_item);
|
|
Packit |
13e616 |
if (cl_map_count(&p->part_guid_tbl) == 0 &&
|
|
Packit |
13e616 |
cl_map_count(&p->full_guid_tbl) == 0) {
|
|
Packit |
13e616 |
cl_qmap_remove_item(&p_subn->prtn_pkey_tbl,
|
|
Packit |
13e616 |
(cl_map_item_t *) p);
|
|
Packit |
13e616 |
osm_prtn_delete(p_subn, &p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (is_config && is_wrong_config) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "Partition configuration "
|
|
Packit |
13e616 |
"in error; retrying with default config\n");
|
|
Packit |
13e616 |
is_config = FALSE;
|
|
Packit |
13e616 |
goto retry_default;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_err:
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|