[openib-general] [PATCH] OpenSM/osm_sa_link_record.c: Fix LMC > 0 handling
Hal Rosenstock
halr at voltaire.com
Mon Jun 19 09:39:54 PDT 2006
OpenSM/osm_sa_link_record.c: Fix LMC > 0 handling
In osm_sa_link_record.c, properly handle non base LID requests
per C15-0.1.11: Query responses shall contain a port's base LID in
any LID component of a RID. So when LMC is non 0, the only records that
appear are those with the base LID and not with any masked LIDs.
Furthermore, if a query comes in on a non base LID, the LID in the RID
returned is only with the base LID.
To do this, added new routine osm_get_port_by_base_lid in osm_port.c for
use by other SA records.
Also, fixed some error handling for SA GetTable LinkRecord requests.
Also, added more SA LinkRecord test cases to osmtest/osmtest.c
Signed-off-by: Hal Rosenstock <halr at voltaire.com>
Index: include/opensm/osm_port.h
===================================================================
--- include/opensm/osm_port.h (revision 8108)
+++ include/opensm/osm_port.h (working copy)
@@ -1737,6 +1737,42 @@ osm_port_get_lid_range_ho(
* Port
*********/
+/****f* OpenSM: Port/osm_get_port_by_base_lid
+* NAME
+* osm_get_port_by_base_lid
+*
+* DESCRIPTION
+* Returns a status on whether a Port was able to be
+* determined based on the LID supplied and if so, return the Port.
+*
+* SYNOPSIS
+*/
+ib_api_status_t
+osm_get_port_by_base_lid(
+ IN const osm_subn_t* const p_subn,
+ IN const ib_net16_t lid,
+ IN OUT const osm_port_t** const pp_port );
+/*
+* PARAMETERS
+* p_subn
+* [in] Pointer to the subnet data structure.
+*
+* lid
+* [in] LID requested.
+*
+* pp_port
+* [in][out] Pointer to pointer to Port object.
+*
+* RETURN VALUES
+* IB_SUCCESS
+* IB_NOT_FOUND
+*
+* NOTES
+*
+* SEE ALSO
+* Port
+*********/
+
/****f* OpenSM: Port/osm_port_add_new_physp
* NAME
* osm_port_add_new_physp
Index: opensm/osm_port.c
===================================================================
--- opensm/osm_port.c (revision 8108)
+++ opensm/osm_port.c (working copy)
@@ -266,6 +266,44 @@ osm_port_get_lid_range_ho(
/**********************************************************************
**********************************************************************/
+ib_api_status_t
+osm_get_port_by_base_lid(
+ IN const osm_subn_t* const p_subn,
+ IN const ib_net16_t lid,
+ IN OUT const osm_port_t** const pp_port )
+{
+ ib_api_status_t status;
+ uint16_t base_lid;
+ uint8_t lmc;
+
+ *pp_port = NULL;
+
+ /* Loop on lmc from 0 up through max LMC */
+ for (lmc = 0; lmc <= IB_PORT_LMC_MAX; lmc++)
+ {
+ /* Calculate a base LID assuming this is the real LMC */
+ base_lid = (cl_ntoh16(lid) & ~(1 << lmc));
+
+ /* Look for a match */
+ status = cl_ptr_vector_at( &p_subn->port_lid_tbl,
+ base_lid,
+ (void**)pp_port );
+ if ((status == CL_SUCCESS) && (*pp_port != NULL))
+ {
+ /* Determine if base LID "tested" is the real base LID */
+ /* This is true if the LMC "tested" is the port's actual LMC */
+ if (lmc == osm_port_get_lmc( *pp_port ) )
+ goto Found;
+ }
+ }
+ status = IB_NOT_FOUND;
+
+ Found:
+ return status;
+}
+
+/**********************************************************************
+ **********************************************************************/
void
osm_port_add_new_physp(
IN osm_port_t* const p_port,
Index: opensm/osm_sa_link_record.c
===================================================================
--- opensm/osm_sa_link_record.c (revision 8108)
+++ opensm/osm_sa_link_record.c (working copy)
@@ -209,7 +209,6 @@ __osm_lr_rcv_get_physp_link(
ib_net16_t from_max_lid_ho;
ib_net16_t to_max_lid_ho;
ib_net16_t to_base_lid_ho;
- uint16_t i, j;
OSM_LOG_ENTER( p_rcv->p_log, __osm_lr_rcv_get_physp_link );
@@ -313,30 +312,12 @@ __osm_lr_rcv_get_physp_link(
dest_port_num );
}
- if( comp_mask & IB_LR_COMPMASK_FROM_LID )
- {
- from_max_lid_ho = from_base_lid_ho = cl_ntoh16(p_lr->from_lid);
- }
- else
- {
- __get_lid_range(p_src_physp, &from_base_lid_ho, &from_max_lid_ho);
- }
+ __get_lid_range(p_src_physp, &from_base_lid_ho, &from_max_lid_ho);
+ __get_lid_range(p_dest_physp, &to_base_lid_ho, &to_max_lid_ho);
- if( comp_mask & IB_LR_COMPMASK_TO_LID )
- {
- to_max_lid_ho = to_base_lid_ho = cl_ntoh16(p_lr->to_lid);
- }
- else
- {
- __get_lid_range(p_dest_physp, &to_base_lid_ho, &to_max_lid_ho);
- }
-
- for (i = from_base_lid_ho; i <= from_max_lid_ho; i++)
- {
- for(j = to_base_lid_ho; j <= to_max_lid_ho; j++)
- __osm_lr_rcv_build_physp_link(p_rcv, cl_ntoh16(i), cl_ntoh16(j),
- src_port_num, dest_port_num, p_list);
- }
+ __osm_lr_rcv_build_physp_link(p_rcv, cl_ntoh16(from_base_lid_ho),
+ cl_ntoh16(to_base_lid_ho),
+ src_port_num, dest_port_num, p_list);
Exit:
OSM_LOG_EXIT( p_rcv->p_log );
@@ -515,12 +496,11 @@ __osm_lr_rcv_get_end_points(
if( p_sa_mad->comp_mask & IB_LR_COMPMASK_FROM_LID )
{
- status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
- cl_ntoh16(p_lr->from_lid),
- (void**)pp_src_port );
+ status = osm_get_port_by_base_lid( p_rcv->p_subn,
+ p_lr->from_lid,
+ pp_src_port );
- if( ( (status != CL_SUCCESS) || (*pp_src_port == NULL) ) &&
- (p_sa_mad->method == IB_MAD_METHOD_GET) )
+ if( (status != CL_SUCCESS) || (*pp_src_port == NULL) )
{
/*
This 'error' is the client's fault (bad lid) so
@@ -539,12 +519,11 @@ __osm_lr_rcv_get_end_points(
if( p_sa_mad->comp_mask & IB_LR_COMPMASK_TO_LID )
{
- status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
- cl_ntoh16(p_lr->to_lid),
- (void**)pp_dest_port );
+ status = osm_get_port_by_base_lid( p_rcv->p_subn,
+ p_lr->to_lid,
+ pp_dest_port );
- if( ( (status != CL_SUCCESS) || (*pp_dest_port == NULL) ) &&
- (p_sa_mad->method == IB_MAD_METHOD_GET) )
+ if( (status != CL_SUCCESS) || (*pp_dest_port == NULL) )
{
/*
This 'error' is the client's fault (bad lid) so
@@ -732,8 +711,8 @@ osm_lr_rcv_process(
{
const ib_link_record_t* p_lr;
const ib_sa_mad_t* p_sa_mad;
- const osm_port_t* p_src_port = NULL;
- const osm_port_t* p_dest_port = NULL;
+ const osm_port_t* p_src_port;
+ const osm_port_t* p_dest_port;
cl_qlist_t lr_list;
ib_net16_t sa_status;
osm_physp_t* p_req_physp;
@@ -784,16 +763,12 @@ osm_lr_rcv_process(
sa_status = __osm_lr_rcv_get_end_points( p_rcv, p_madw,
&p_src_port, &p_dest_port );
- if( sa_status != IB_SA_MAD_STATUS_SUCCESS )
+ if( sa_status == IB_SA_MAD_STATUS_SUCCESS )
{
- cl_plock_release( p_rcv->p_lock );
- osm_sa_send_error( p_rcv->p_resp, p_madw, sa_status );
- goto Exit;
+ __osm_lr_rcv_get_port_links( p_rcv, p_lr, p_src_port, p_dest_port,
+ p_sa_mad->comp_mask, &lr_list, p_req_physp );
}
- __osm_lr_rcv_get_port_links( p_rcv, p_lr, p_src_port, p_dest_port,
- p_sa_mad->comp_mask, &lr_list, p_req_physp );
-
cl_plock_release( p_rcv->p_lock );
if( (cl_qlist_count( &lr_list ) == 0) &&
Index: osmtest/osmtest.c
===================================================================
--- osmtest/osmtest.c (revision 8109)
+++ osmtest/osmtest.c (working copy)
@@ -4309,6 +4309,99 @@ osmtest_validate_all_path_recs( IN osmte
OSM_LOG_EXIT( &p_osmt->log );
return ( status );
}
+
+/**********************************************************************
+ * Get link record by LID
+ **********************************************************************/
+ib_api_status_t
+osmtest_get_link_rec_by_lid( IN osmtest_t * const p_osmt,
+ IN ib_net16_t const from_lid,
+ IN ib_net16_t const to_lid,
+ IN OUT osmtest_req_context_t * const p_context )
+{
+ ib_api_status_t status = IB_SUCCESS;
+ osmv_user_query_t user;
+ osmv_query_req_t req;
+ ib_link_record_t record;
+ ib_mad_t *p_mad;
+
+ OSM_LOG_ENTER( &p_osmt->log, osmtest_get_link_rec_by_lid );
+
+ if( osm_log_is_active( &p_osmt->log, OSM_LOG_VERBOSE ) )
+ {
+ osm_log( &p_osmt->log, OSM_LOG_VERBOSE,
+ "osmtest_get_link_rec_by_lid: "
+ "Getting link record from LID 0x%02X to LID 0x%02X\n",
+ cl_ntoh16( from_lid ), cl_ntoh16( to_lid ) );
+ }
+
+ /*
+ * Do a blocking query for this record in the subnet.
+ * The result is returned in the result field of the caller's
+ * context structure.
+ *
+ * The query structures are locals.
+ */
+ memset( &req, 0, sizeof( req ) );
+ memset( &user, 0, sizeof( user ) );
+ memset( &record, 0, sizeof( record ) );
+
+ record.from_lid = from_lid;
+ record.to_lid = to_lid;
+ p_context->p_osmt = p_osmt;
+ if (from_lid)
+ user.comp_mask |= IB_LR_COMPMASK_FROM_LID;
+ if (to_lid)
+ user.comp_mask |= IB_LR_COMPMASK_TO_LID;
+ user.attr_id = IB_MAD_ATTR_LINK_RECORD;
+ user.attr_offset = cl_ntoh16( ( uint16_t ) ( sizeof( record ) >> 3 ) );
+ user.p_attr = &record;
+
+ req.query_type = OSMV_QUERY_USER_DEFINED;
+ req.timeout_ms = p_osmt->opt.transaction_timeout;
+ req.retry_cnt = p_osmt->opt.retry_count;
+ req.flags = OSM_SA_FLAGS_SYNC;
+ req.query_context = p_context;
+ req.pfn_query_cb = osmtest_query_res_cb;
+ req.p_query_input = &user;
+ req.sm_key = 0;
+
+ status = osmv_query_sa( p_osmt->h_bind, &req );
+ if( status != IB_SUCCESS )
+ {
+ osm_log( &p_osmt->log, OSM_LOG_ERROR,
+ "osmtest_get_link_rec_by_lid: ERR 007A: "
+ "ib_query failed (%s)\n", ib_get_err_str( status ) );
+ goto Exit;
+ }
+
+ status = p_context->result.status;
+
+ if( status != IB_SUCCESS )
+ {
+ if (status != IB_INVALID_PARAMETER)
+ {
+ osm_log( &p_osmt->log, OSM_LOG_ERROR,
+ "osmtest_get_link_rec_by_lid: ERR 007B: "
+ "ib_query failed (%s)\n", ib_get_err_str( status ) );
+ }
+ if( status == IB_REMOTE_ERROR )
+ {
+ p_mad = osm_madw_get_mad_ptr( p_context->result.p_result_madw );
+ osm_log( &p_osmt->log, OSM_LOG_ERROR,
+ "osmtest_get_link_rec_by_lid: "
+ "Remote error = %s\n",
+ ib_get_mad_status_str( p_mad ));
+
+ status = (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK );
+ }
+ goto Exit;
+ }
+
+ Exit:
+ OSM_LOG_EXIT( &p_osmt->log );
+ return ( status );
+}
#endif
/**********************************************************************
@@ -4891,9 +4984,10 @@ osmtest_validate_against_db( IN osmtest_
{
ib_api_status_t status = IB_SUCCESS;
#ifdef VENDOR_RMPP_SUPPORT
+ ib_net16_t test_lid;
uint8_t lmc;
-#ifdef DUAL_SIDED_RMPP
osmtest_req_context_t context;
+#ifdef DUAL_SIDED_RMPP
osmv_multipath_req_t request;
#endif
#endif
@@ -5003,6 +5097,7 @@ osmtest_validate_against_db( IN osmtest_
#endif
#ifdef VENDOR_RMPP_SUPPORT
+ /* GUIDInfoRecords */
status = osmtest_validate_all_guidinfo_recs( p_osmt );
if( status != IB_SUCCESS )
goto Exit;
@@ -5019,6 +5114,43 @@ osmtest_validate_against_db( IN osmtest_
goto Exit;
}
+ /* Some LinkRecord tests */
+ test_lid = cl_ntoh16( p_osmt->local_port.lid );
+ /* FromLID */
+ memset( &context, 0, sizeof( context ) );
+ status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, 0, &context );
+ if ( status != IB_SUCCESS )
+ goto Exit;
+
+ /* ToLID */
+ memset( &context, 0, sizeof( context ) );
+ status = osmtest_get_link_rec_by_lid( p_osmt, 0, test_lid, &context );
+ if ( status != IB_SUCCESS )
+ goto Exit;
+
+ /* FromLID & ToLID */
+ memset( &context, 0, sizeof( context ) );
+ status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, test_lid, &context );
+ if ( status != IB_SUCCESS )
+ goto Exit;
+
+ if (lmc != 0)
+ {
+ test_lid = cl_ntoh16( p_osmt->local_port.lid + 1 );
+ /* FromLID */
+ memset( &context, 0, sizeof( context ) );
+ status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, 0, &context );
+ if ( status != IB_SUCCESS )
+ goto Exit;
+
+ /* ToLID */
+ memset( &context, 0, sizeof( context ) );
+ status = osmtest_get_link_rec_by_lid( p_osmt, 0, test_lid, &context );
+ if ( status != IB_SUCCESS )
+ goto Exit;
+ }
+
+ /* PathRecords */
if (! p_osmt->opt.ignore_path_records)
{
status = osmtest_validate_all_path_recs( p_osmt );
More information about the general
mailing list