[openib-general] [PATCH] OpenSM/SA:

Hal Rosenstock halr at voltaire.com
Tue Jun 20 09:44:34 PDT 2006


OpenSM/SA: Properly handle non base LID requests per C15-0.1.11 on
remaining SA records where this hasn't been fixed already.

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.

Also, fixed some error handling for SA GetTable requests in these SA
records.

Signed-off-by: Hal Rosenstock <halr at voltaire.com>

Index: opensm/osm_sa_guidinfo_record.c
===================================================================
--- opensm/osm_sa_guidinfo_record.c	(revision 8140)
+++ opensm/osm_sa_guidinfo_record.c	(working copy)
@@ -201,12 +201,10 @@ __osm_sa_gir_create_gir(
   uint8_t                  port_num;
   uint8_t                  num_ports;
   uint16_t                 match_lid_ho;
-  uint16_t                 lid_ho;
   ib_net16_t               base_lid_ho;
   ib_net16_t               max_lid_ho;
   uint8_t                  lmc;
   ib_net64_t               port_guid;
-  ib_api_status_t          status;
   const ib_port_info_t*    p_pi;
   uint8_t                  block_num, start_block_num, end_block_num, num_blocks;
 
@@ -276,11 +274,12 @@ __osm_sa_gir_create_gir(
     }
 
     base_lid_ho = cl_ntoh16( osm_physp_get_base_lid( p_physp ) );
-    lmc = osm_physp_get_lmc( p_physp );
-    max_lid_ho = (uint16_t)( base_lid_ho + (1 << lmc) - 1 );
     match_lid_ho = cl_ntoh16( match_lid );
     if( match_lid_ho )
     {
+      lmc = osm_physp_get_lmc( p_physp );
+      max_lid_ho = (uint16_t)( base_lid_ho + (1 << lmc) - 1 );
+
       /*
         We validate that the lid belongs to this node.
       */
@@ -295,34 +294,15 @@ __osm_sa_gir_create_gir(
                  );
       }
 
-      if( match_lid_ho <= max_lid_ho && match_lid_ho >= base_lid_ho )
-      {
-        /*
-          Ignore return code for now.
-        */
-       for (block_num = start_block_num; block_num <= end_block_num; block_num++)
-          __osm_gir_rcv_new_gir( p_rcv, p_node, p_list,
-                                 port_guid, match_lid,
-                                 p_physp, block_num );
-      }
-    }
-    else
-    {
-      /*
-        For every lid value create the GUIDInfo record(s).
-      */
-      for( lid_ho = base_lid_ho; lid_ho <= max_lid_ho; lid_ho++ )
-      {
-        for (block_num = start_block_num; block_num <= end_block_num; block_num++)
-        {
-          status = __osm_gir_rcv_new_gir( p_rcv, p_node, p_list,
-                                          port_guid, cl_hton16( lid_ho ),
-                                          p_physp, block_num );
-          if( status != IB_SUCCESS )
-            break;
-        }
-      }
+      if ( match_lid_ho < base_lid_ho || match_lid_ho > max_lid_ho )
+        continue;
     }
+
+    for (block_num = start_block_num; block_num <= end_block_num; block_num++)
+      __osm_gir_rcv_new_gir( p_rcv, p_node, p_list,
+                             port_guid, cl_ntoh16(base_lid_ho),
+                             p_physp, block_num );
+
   }
 
   OSM_LOG_EXIT( p_rcv->p_log );
@@ -496,24 +476,32 @@ osm_gir_rcv_process(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "osm_gir_rcv_process: ERR 5103: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
-
-    /* need to set the mem free ... */
-    p_rec_item = (osm_gir_item_t*)cl_qlist_remove_head( &rec_list );
-    while( p_rec_item != (osm_gir_item_t*)cl_qlist_end( &rec_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
-      p_rec_item = (osm_gir_item_t*)cl_qlist_remove_head( &rec_list );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
     }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "osm_gir_rcv_process: ERR 5103: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
 
-    goto Exit;
+      /* need to set the mem free ... */
+      p_rec_item = (osm_gir_item_t*)cl_qlist_remove_head( &rec_list );
+      while( p_rec_item != (osm_gir_item_t*)cl_qlist_end( &rec_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+        p_rec_item = (osm_gir_item_t*)cl_qlist_remove_head( &rec_list );
+      }
+
+      goto Exit;
+    }
   }
 
   pre_trim_num_rec = num_rec;
Index: opensm/osm_sa_lft_record.c
===================================================================
--- opensm/osm_sa_lft_record.c	(revision 8140)
+++ opensm/osm_sa_lft_record.c	(working copy)
@@ -199,7 +199,6 @@ __osm_lftr_get_port_by_guid(
 
   p_port = (osm_port_t *)cl_qmap_get(&p_rcv->p_subn->port_guid_tbl,
                                      port_guid);
-
   if(p_port == (osm_port_t *)cl_qmap_end(&p_rcv->p_subn->port_guid_tbl))
   {
     osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
@@ -249,9 +248,6 @@ __osm_lftr_rcv_by_comp_mask(
     return;
   }
 
-  /* get the port 0 of the switch */
-  osm_port_get_lid_range_ho( p_port, &min_lid_ho, &max_lid_ho );
-
   /* check that the requester physp and the current physp are under
      the same partition. */
   p_physp = osm_port_get_default_phys_ptr( p_port );
@@ -268,6 +264,9 @@ __osm_lftr_rcv_by_comp_mask(
   if (! osm_physp_share_pkey( p_rcv->p_log, p_req_physp, p_physp ))
     return;
 
+  /* get the port 0 of the switch */
+  osm_port_get_lid_range_ho( p_port, &min_lid_ho, &max_lid_ho );
+
   /* compare the lids - if required */
   if( comp_mask & IB_LFTR_COMPMASK_LID )
   {
@@ -277,8 +276,8 @@ __osm_lftr_rcv_by_comp_mask(
              cl_ntoh16( p_rcvd_rec->lid ), min_lid_ho, max_lid_ho
              );
     /* ok we are ready for range check */
-    if ((min_lid_ho > cl_ntoh16(p_rcvd_rec->lid)) ||
-        (max_lid_ho < cl_ntoh16(p_rcvd_rec->lid)))
+    if (min_lid_ho > cl_ntoh16(p_rcvd_rec->lid) ||
+        max_lid_ho < cl_ntoh16(p_rcvd_rec->lid))
       return;
   }
 
@@ -323,7 +322,7 @@ osm_lftr_rcv_process(
   uint32_t                  i;
   osm_lftr_search_ctxt_t    context;
   osm_lftr_item_t*          p_rec_item;
-  ib_api_status_t           status;
+  ib_api_status_t           status = IB_SUCCESS;
   osm_physp_t*              p_req_physp;
 
   CL_ASSERT( p_rcv );
@@ -382,24 +381,32 @@ osm_lftr_rcv_process(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "osm_lftr_rcv_process: ERR 4409: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-    /* need to set the mem free ... */
-    p_rec_item = (osm_lftr_item_t*)cl_qlist_remove_head( &rec_list );
-    while( p_rec_item != (osm_lftr_item_t*)cl_qlist_end( &rec_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
-      p_rec_item = (osm_lftr_item_t*)cl_qlist_remove_head( &rec_list );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
     }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "osm_lftr_rcv_process: ERR 4409: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
 
-    goto Exit;
+      /* need to set the mem free ... */
+      p_rec_item = (osm_lftr_item_t*)cl_qlist_remove_head( &rec_list );
+      while( p_rec_item != (osm_lftr_item_t*)cl_qlist_end( &rec_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+        p_rec_item = (osm_lftr_item_t*)cl_qlist_remove_head( &rec_list );
+      }
+
+      goto Exit;
+    }
   }
 
   pre_trim_num_rec = num_rec;
Index: opensm/osm_sa_node_record.c
===================================================================
--- opensm/osm_sa_node_record.c	(revision 8140)
+++ opensm/osm_sa_node_record.c	(working copy)
@@ -264,15 +264,12 @@ __osm_nr_rcv_create_nr(
                  );
       }
 
-      if( (match_lid_ho <= max_lid_ho) && (match_lid_ho >= base_lid_ho) )
-      {
-        __osm_nr_rcv_new_nr( p_rcv, p_node, p_list, port_guid, base_lid );
-      }
-    }
-    else
-    {
-      __osm_nr_rcv_new_nr( p_rcv, p_node, p_list, port_guid, base_lid );
+      if ( match_lid_ho < base_lid_ho || match_lid_ho > max_lid_ho )
+        continue;
     }
+
+    __osm_nr_rcv_new_nr( p_rcv, p_node, p_list, port_guid, base_lid );
+
   }
 
   OSM_LOG_EXIT( p_rcv->p_log );
Index: opensm/osm_sa_path_record.c
===================================================================
--- opensm/osm_sa_path_record.c	(revision 8140)
+++ opensm/osm_sa_path_record.c	(working copy)
@@ -1027,8 +1027,7 @@ __osm_pr_rcv_get_end_points(
       status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
                                  cl_ntoh16(p_pr->slid), (void**)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
@@ -1077,8 +1076,7 @@ __osm_pr_rcv_get_end_points(
       status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
                                  cl_ntoh16(p_pr->dlid),  (void**)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
@@ -1521,22 +1519,30 @@ __osm_pr_rcv_respond(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "__osm_pr_rcv_respond: ERR 1F13: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
-    /* need to set the mem free ... */
-    p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
-    while( p_pr_item != (osm_pr_item_t*)cl_qlist_end( p_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pr_pool, &p_pr_item->pool_item );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
+    }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "__osm_pr_rcv_respond: ERR 1F13: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
+      /* need to set the mem free ... */
       p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
+      while( p_pr_item != (osm_pr_item_t*)cl_qlist_end( p_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pr_pool, &p_pr_item->pool_item );
+        p_pr_item = (osm_pr_item_t*)cl_qlist_remove_head( p_list );
+      }
+      goto Exit;
     }
-    goto Exit;
   }
 
   pre_trim_num_rec = num_rec;
@@ -1704,40 +1710,36 @@ osm_pr_rcv_process(
   sa_status = __osm_pr_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;
-  }
-
-  /*
-    What happens next depends on the type of endpoint information
-    that was specified....
-  */
-  if( p_src_port )
-  {
-    if( p_dest_port )
-      __osm_pr_rcv_process_pair( p_rcv, p_madw, requester_port,
-                                 p_src_port, p_dest_port,
-                                 p_sa_mad->comp_mask, &pr_list );
-    else
-      __osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
-                                 p_src_port, NULL,
-                                 p_sa_mad->comp_mask, &pr_list );
-  }
-  else
-  {
-    if( p_dest_port )
-      __osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
-                                 NULL, p_dest_port,
-                                 p_sa_mad->comp_mask, &pr_list );
+    /*
+      What happens next depends on the type of endpoint information
+      that was specified....
+    */
+    if( p_src_port )
+    {
+      if( p_dest_port )
+        __osm_pr_rcv_process_pair( p_rcv, p_madw, requester_port,
+                                   p_src_port, p_dest_port,
+                                   p_sa_mad->comp_mask, &pr_list );
+      else
+        __osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
+                                   p_src_port, NULL,
+                                   p_sa_mad->comp_mask, &pr_list );
+    }
     else
-      /*
-        Katie, bar the door!
-      */
-      __osm_pr_rcv_process_world( p_rcv, p_madw, requester_port,
-                                  p_sa_mad->comp_mask, &pr_list );
+    {
+      if( p_dest_port )
+        __osm_pr_rcv_process_half( p_rcv, p_madw, requester_port,
+                                   NULL, p_dest_port,
+                                   p_sa_mad->comp_mask, &pr_list );
+      else
+        /*
+          Katie, bar the door!
+        */
+        __osm_pr_rcv_process_world( p_rcv, p_madw, requester_port,
+                                    p_sa_mad->comp_mask, &pr_list );
+    }
   }
   goto Unlock;
 
Index: opensm/osm_sa_pkey_record.c
===================================================================
--- opensm/osm_sa_pkey_record.c	(revision 8140)
+++ opensm/osm_sa_pkey_record.c	(working copy)
@@ -332,7 +332,7 @@ osm_pkey_rec_rcv_process(
   uint32_t                 i;
   osm_pkey_search_ctxt_t   context;
   osm_pkey_item_t*         p_rec_item;
-  ib_api_status_t          status;
+  ib_api_status_t          status = IB_SUCCESS;
   ib_net64_t               comp_mask;
   osm_physp_t*             p_req_physp;
 
@@ -421,30 +421,38 @@ osm_pkey_rec_rcv_process(
 
     if ((uint16_t)cl_ptr_vector_get_size(p_tbl) > cl_ntoh16(p_rcvd_rec->lid))
     {
-      p_port = cl_ptr_vector_get( p_tbl, cl_ntoh16(p_rcvd_rec->lid) );
+      status = osm_get_port_by_base_lid( p_rcv->p_subn, p_rcvd_rec->lid, &p_port );
+      if ( ( status != IB_SUCCESS ) || ( p_port == NULL ) )
+      {
+        status = IB_NOT_FOUND;
+        osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+                 "osm_pkey_rec_rcv_process: ERR 460B: "
+                 "No port found with LID 0x%x\n",
+                 cl_ntoh16(p_rcvd_rec->lid) );
+      }
     }
     else
     { /* port out of range */
-      cl_plock_release( p_rcv->p_lock );
-
+      status = IB_NOT_FOUND;
       osm_log( p_rcv->p_log, OSM_LOG_ERROR,
                "osm_pkey_rec_rcv_process: ERR 4609: "
                "Given LID (0x%X) is out of range:0x%X\n",
                cl_ntoh16(p_rcvd_rec->lid), cl_ptr_vector_get_size(p_tbl) );
-      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_REQ_INVALID );
-      goto Exit;
     }
   }
 
-  /* 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( p_rcv, p_port, &context );
-  else
-  {
-    cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
-                        __osm_sa_pkey_by_comp_mask_cb,
-                        &context );
+  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( p_rcv, p_port, &context );
+    else
+    {
+      cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
+                          __osm_sa_pkey_by_comp_mask_cb,
+                          &context );
+    }
   }
 
   cl_plock_release( p_rcv->p_lock );
@@ -455,24 +463,32 @@ osm_pkey_rec_rcv_process(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "osm_pkey_rec_rcv_process: ERR 460A: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
-
-    /* need to set the mem free ... */
-    p_rec_item = (osm_pkey_item_t*)cl_qlist_remove_head( &rec_list );
-    while( p_rec_item != (osm_pkey_item_t*)cl_qlist_end( &rec_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
-      p_rec_item = (osm_pkey_item_t*)cl_qlist_remove_head( &rec_list );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
     }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "osm_pkey_rec_rcv_process: ERR 460A: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
 
-    goto Exit;
+      /* need to set the mem free ... */
+      p_rec_item = (osm_pkey_item_t*)cl_qlist_remove_head( &rec_list );
+      while( p_rec_item != (osm_pkey_item_t*)cl_qlist_end( &rec_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+        p_rec_item = (osm_pkey_item_t*)cl_qlist_remove_head( &rec_list );
+      }
+
+      goto Exit;
+    }
   }
 
   pre_trim_num_rec = num_rec;
Index: opensm/osm_sa_slvl_record.c
===================================================================
--- opensm/osm_sa_slvl_record.c	(revision 8140)
+++ opensm/osm_sa_slvl_record.c	(working copy)
@@ -317,7 +317,7 @@ osm_slvl_rec_rcv_process(
   uint32_t                       i;
   osm_slvl_search_ctxt_t         context;
   osm_slvl_item_t*               p_rec_item;
-  ib_api_status_t                status;
+  ib_api_status_t                status = IB_SUCCESS;
   ib_net64_t                     comp_mask;
   osm_physp_t*                   p_req_physp;
 
@@ -389,30 +389,38 @@ osm_slvl_rec_rcv_process(
 
     if ((uint16_t)cl_ptr_vector_get_size(p_tbl) > cl_ntoh16(p_rcvd_rec->lid))
     {
-      p_port = cl_ptr_vector_get( p_tbl, cl_ntoh16(p_rcvd_rec->lid) );
+      status = osm_get_port_by_base_lid( p_rcv->p_subn, p_rcvd_rec->lid, &p_port );
+      if ( ( status != IB_SUCCESS ) || ( p_port == NULL ) )
+      {
+        status = IB_NOT_FOUND;
+        osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+                 "osm_slvl_rec_rcv_process: ERR 2608: "
+                 "No port found with LID 0x%x\n",
+                 cl_ntoh16(p_rcvd_rec->lid) );
+      }
     }
     else
     { /*  port out of range */
-      cl_plock_release( p_rcv->p_lock );
-
+      status = IB_NOT_FOUND;
       osm_log( p_rcv->p_log, OSM_LOG_ERROR,
                "osm_slvl_rec_rcv_process: ERR 2601: "
                "Given LID (0x%X) is out of range:0x%X\n",
                cl_ntoh16(p_rcvd_rec->lid), cl_ptr_vector_get_size(p_tbl));
-      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_REQ_INVALID );
-      goto Exit;
     }
   }
 
-  /* 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( p_rcv, p_port, &context );
-  else
-  {
-    cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
-                        __osm_sa_slvl_by_comp_mask_cb,
-                        &context );
+  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( p_rcv, p_port, &context );
+    else
+    {
+      cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
+                          __osm_sa_slvl_by_comp_mask_cb,
+                          &context );
+    }
   }
 
   cl_plock_release( p_rcv->p_lock );
@@ -423,24 +431,32 @@ osm_slvl_rec_rcv_process(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "osm_slvl_rec_rcv_process: ERR 2607: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
-
-    /* need to set the mem free ... */
-    p_rec_item = (osm_slvl_item_t*)cl_qlist_remove_head( &rec_list );
-    while( p_rec_item != (osm_slvl_item_t*)cl_qlist_end( &rec_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
-      p_rec_item = (osm_slvl_item_t*)cl_qlist_remove_head( &rec_list );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
     }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "osm_slvl_rec_rcv_process: ERR 2607: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
 
-    goto Exit;
+      /* need to set the mem free ... */
+      p_rec_item = (osm_slvl_item_t*)cl_qlist_remove_head( &rec_list );
+      while( p_rec_item != (osm_slvl_item_t*)cl_qlist_end( &rec_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+        p_rec_item = (osm_slvl_item_t*)cl_qlist_remove_head( &rec_list );
+      }
+
+      goto Exit;
+    }
   }
 
   pre_trim_num_rec = num_rec;
Index: opensm/osm_sa_vlarb_record.c
===================================================================
--- opensm/osm_sa_vlarb_record.c	(revision 8140)
+++ opensm/osm_sa_vlarb_record.c	(working copy)
@@ -337,7 +337,7 @@ osm_vlarb_rec_rcv_process(
   uint32_t                 i;
   osm_vl_arb_search_ctxt_t context;
   osm_vl_arb_item_t*       p_rec_item;
-  ib_api_status_t          status;
+  ib_api_status_t          status = IB_SUCCESS;
   ib_net64_t               comp_mask;
   osm_physp_t*             p_req_physp;
 
@@ -409,30 +409,38 @@ osm_vlarb_rec_rcv_process(
 
     if ((uint16_t)cl_ptr_vector_get_size(p_tbl) > cl_ntoh16(p_rcvd_rec->lid))
     {
-      p_port = cl_ptr_vector_get( p_tbl, cl_ntoh16(p_rcvd_rec->lid) );
+      status = osm_get_port_by_base_lid( p_rcv->p_subn, p_rcvd_rec->lid, &p_port );
+      if ( ( status != IB_SUCCESS ) || ( p_port == NULL ) )
+      {
+        status = IB_NOT_FOUND;
+        osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+                 "osm_vlarb_rec_rcv_process: ERR 2A09: "
+                 "No port found with LID 0x%x\n",
+                 cl_ntoh16(p_rcvd_rec->lid) );
+      }
     }
     else
     { /*  port out of range */
-      cl_plock_release( p_rcv->p_lock );
-
+      status = IB_NOT_FOUND;
       osm_log( p_rcv->p_log, OSM_LOG_ERROR,
                "osm_vlarb_rec_rcv_process: ERR 2A01: "
                "Given LID (0x%X) is out of range:0x%X\n",
                cl_ntoh16(p_rcvd_rec->lid), cl_ptr_vector_get_size(p_tbl) );
-      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_REQ_INVALID );
-      goto Exit;
     }
   }
 
-  /* 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_vl_arb_by_comp_mask( p_rcv, p_port, &context );
-  else
-  {
-    cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
-                        __osm_sa_vl_arb_by_comp_mask_cb,
-                        &context );
+  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_vl_arb_by_comp_mask( p_rcv, p_port, &context );
+    else
+    {
+      cl_qmap_apply_func( &p_rcv->p_subn->port_guid_tbl,
+                          __osm_sa_vl_arb_by_comp_mask_cb,
+                          &context );
+    }
   }
 
   cl_plock_release( p_rcv->p_lock );
@@ -443,24 +451,32 @@ osm_vlarb_rec_rcv_process(
    * C15-0.1.30:
    * If we do a SubnAdmGet and got more than one record it is an error !
    */
-  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) &&
-       (num_rec > 1)) {
-    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
-             "osm_vlarb_rec_rcv_process:  ERR 2A08: "
-             "Got more than one record for SubnAdmGet (%u)\n",
-             num_rec );
-    osm_sa_send_error( p_rcv->p_resp, p_madw,
-                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
-
-    /* need to set the mem free ... */
-    p_rec_item = (osm_vl_arb_item_t*)cl_qlist_remove_head( &rec_list );
-    while( p_rec_item != (osm_vl_arb_item_t*)cl_qlist_end( &rec_list ) )
+  if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+  {
+    if (num_rec == 0)
     {
-      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
-      p_rec_item = (osm_vl_arb_item_t*)cl_qlist_remove_head( &rec_list );
+      osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+      goto Exit;
     }
+    if (num_rec > 1)
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+               "osm_vlarb_rec_rcv_process:  ERR 2A08: "
+               "Got more than one record for SubnAdmGet (%u)\n",
+               num_rec );
+      osm_sa_send_error( p_rcv->p_resp, p_madw,
+                         IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
 
-    goto Exit;
+      /* need to set the mem free ... */
+      p_rec_item = (osm_vl_arb_item_t*)cl_qlist_remove_head( &rec_list );
+      while( p_rec_item != (osm_vl_arb_item_t*)cl_qlist_end( &rec_list ) )
+      {
+        cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+        p_rec_item = (osm_vl_arb_item_t*)cl_qlist_remove_head( &rec_list );
+      }
+
+      goto Exit;
+    }
   }
 
   pre_trim_num_rec = num_rec;







More information about the general mailing list