On 7/5/2011 3:08 PM, Ira Weiny wrote:
> 
> While this is sub-optimal it is the easiest way to get saquery support to the
> other diags.

Just some nits below...

> Signed-off-by: Ira Weiny <[email protected]>
> ---
>  include/ibdiag_common.h |   45 +++++++++++
>  src/ibdiag_common.c     |  172 ++++++++++++++++++++++++++++++++++++++++
>  src/saquery.c           |  198 
> ++---------------------------------------------
>  3 files changed, 224 insertions(+), 191 deletions(-)
> 
> diff --git a/include/ibdiag_common.h b/include/ibdiag_common.h
> index b113cfe..69cddfb 100644
> --- a/include/ibdiag_common.h
> +++ b/include/ibdiag_common.h

Merge saquery.c copyrights into here...

> @@ -81,4 +81,49 @@ extern int ibdiag_process_opts(int argc, char *const 
> argv[], void *context,
>  extern void ibdiag_show_usage();
>  extern void iberror(const char *fn, char *msg, ...);
>  
> +/* define an SA query structure to be common
> + * This is by no means optimal but it moves the saquery functionality out of
> + * the saquery tool and provides it to other utilities.
> + */
> +struct bind_handle {
> +     int fd, agent;
> +     ib_portid_t dport;
> +     struct ibmad_port *srcport;
> +};
> +typedef struct bind_handle * bind_handle_t;
> +bind_handle_t sa_get_bind_handle(void);
> +void sa_free_bind_handle(bind_handle_t h);
> +
> +struct sa_query_result {
> +     uint32_t status;
> +     unsigned result_cnt;
> +     void *p_result_madw;
> +};
> +int sa_query(struct bind_handle *h, uint8_t method,
> +          uint16_t attr, uint32_t mod, uint64_t comp_mask, uint64_t sm_key,
> +          void *data, struct sa_query_result *result);
> +void sa_free_result_mad(struct sa_query_result *result);
> +void *sa_get_query_rec(void *mad, unsigned i);
> +void sa_report_err(int status);
> +
> +#define cl_hton8(x) (x)
> +#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
> +     if ((int##size##_t) val != (int##size##_t) comp_with) { \
> +             target = cl_hton##size((uint##size##_t) val); \
> +             comp_mask |= IB_##name##_COMPMASK_##mask; \
> +     }
> +
> +#define CHECK_AND_SET_GID(val, target, name, mask) \
> +     if (valid_gid(&(val))) { \
> +             memcpy(&(target), &(val), sizeof(val)); \
> +             comp_mask |= IB_##name##_COMPMASK_##mask; \
> +     }
> +
> +#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
> +     if (val) { \
> +             target = val; \
> +             comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
> +             comp_mask |= IB_##name##_COMPMASK_##mask; \
> +     }
> +
>  #endif                               /* _IBDIAG_COMMON_H_ */
> diff --git a/src/ibdiag_common.c b/src/ibdiag_common.c
> index 82f72af..6d03a43 100644
> --- a/src/ibdiag_common.c
> +++ b/src/ibdiag_common.c

Merge saquery.c copyrights into here...

> @@ -337,3 +337,175 @@ void iberror(const char *fn, char *msg, ...)
>  
>       exit(-1);
>  }
> +
> +/* define an SA query structure to be common
> + * This is by no means optimal but it moves the saquery functionality out of
> + * the saquery tool and provides it to other utilities.
> + */
> +bind_handle_t sa_get_bind_handle(void)
> +{
> +     struct ibmad_port * srcport;
> +     bind_handle_t handle;
> +     int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
> +
> +     srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
> +     if (!srcport) {
> +             IBWARN("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
> +             return (NULL);
> +     }
> +
> +     handle = calloc(1, sizeof(*handle));
> +     if (!handle)
> +             IBPANIC("calloc failed");

Should we IBPANIC in a library or IBWARN and return NULL here or some
other way to get the app to exit ?

> +
> +     ib_resolve_smlid_via(&handle->dport, ibd_timeout, srcport);
> +     if (!handle->dport.lid) {
> +             IBWARN("No SM found.");
> +             free(handle);
> +             return (NULL);
> +     }
> +
> +     handle->dport.qp = 1;
> +     if (!handle->dport.qkey)
> +             handle->dport.qkey = IB_DEFAULT_QP1_QKEY;
> +
> +     handle->srcport = srcport;
> +     handle->fd = mad_rpc_portid(srcport);
> +     handle->agent = umad_register(handle->fd, IB_SA_CLASS, 2, 1, NULL);
> +
> +     return handle;
> +}
> +
> +void sa_free_bind_handle(bind_handle_t h)
> +{
> +     umad_unregister(h->fd, h->agent);
> +     mad_rpc_close_port(h->srcport);
> +     free(h);
> +}
> +
> +int sa_query(bind_handle_t h, uint8_t method,
> +                 uint16_t attr, uint32_t mod, uint64_t comp_mask,
> +                 uint64_t sm_key, void *data, struct sa_query_result *result)
> +{
> +     ib_rpc_t rpc;
> +     void *umad, *mad;
> +     int ret, offset, len = 256;
> +
> +     memset(&rpc, 0, sizeof(rpc));
> +     rpc.mgtclass = IB_SA_CLASS;
> +     rpc.method = method;
> +     rpc.attr.id = attr;
> +     rpc.attr.mod = mod;
> +     rpc.mask = comp_mask;
> +     rpc.datasz = IB_SA_DATA_SIZE;
> +     rpc.dataoffs = IB_SA_DATA_OFFS;
> +
> +     umad = calloc(1, len + umad_size());
> +     if (!umad)
> +             IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));

Should we IBPANIC in a library or IBWARN and return IB_ERROR here or
some other way to get the app to exit ?

-- Hal

> +
> +     mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
> +
> +     mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
> +
> +     if (ibdebug > 1)
> +             xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
> +
> +     ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
> +     if (ret < 0) {
> +             IBWARN("umad_send failed: attr %u: %s\n",
> +                     attr, strerror(errno));
> +             free(umad);
> +             return (IB_ERROR);
> +     }
> +
> +recv_mad:
> +     ret = umad_recv(h->fd, umad, &len, ibd_timeout);
> +     if (ret < 0) {
> +             if (errno == ENOSPC) {
> +                     umad = realloc(umad, umad_size() + len);
> +                     goto recv_mad;
> +             }
> +             IBWARN("umad_recv failed: attr 0x%x: %s\n", attr,
> +                     strerror(errno));
> +             free(umad);
> +             return (IB_ERROR);
> +     }
> +
> +     if ((ret = umad_status(umad)))
> +             return ret;
> +
> +     mad = umad_get_mad(umad);
> +
> +     if (ibdebug > 1)
> +             xdump(stdout, "SA Response:\n", mad, len);
> +
> +     method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
> +     offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
> +     result->status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
> +     result->p_result_madw = mad;
> +     if (result->status != IB_SA_MAD_STATUS_SUCCESS)
> +             result->result_cnt = 0;
> +     else if (method != IB_MAD_METHOD_GET_TABLE)
> +             result->result_cnt = 1;
> +     else if (!offset)
> +             result->result_cnt = 0;
> +     else
> +             result->result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
> +
> +     return 0;
> +}
> +
> +void sa_free_result_mad(struct sa_query_result *result)
> +{
> +     if (result->p_result_madw) {
> +             free((uint8_t *) result->p_result_madw - umad_size());
> +             result->p_result_madw = NULL;
> +     }
> +}
> +
> +void *sa_get_query_rec(void *mad, unsigned i)
> +{
> +     int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
> +     return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
> +}
> +
> +static const char *ib_sa_error_str[] = {
> +     "SA_NO_ERROR",
> +     "SA_ERR_NO_RESOURCES",
> +     "SA_ERR_REQ_INVALID",
> +     "SA_ERR_NO_RECORDS",
> +     "SA_ERR_TOO_MANY_RECORDS",
> +     "SA_ERR_REQ_INVALID_GID",
> +     "SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
> +     "SA_ERR_REQ_DENIED",
> +     "SA_ERR_STATUS_PRIO_SUGGESTED",
> +     "SA_ERR_UNKNOWN"
> +};
> +
> +#define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
> +#define SA_ERR_UNKNOWN (ARR_SIZE(ib_sa_error_str) - 1)
> +
> +static inline const char *ib_sa_err_str(IN uint8_t status)
> +{
> +     if (status > SA_ERR_UNKNOWN)
> +             status = SA_ERR_UNKNOWN;
> +     return (ib_sa_error_str[status]);
> +}
> +
> +void sa_report_err(int status)
> +{
> +     int st = status & 0xff;
> +     char sm_err_str[64] = { 0 };
> +     char sa_err_str[64] = { 0 };
> +
> +     if (st)
> +             sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
> +
> +     st = status >> 8;
> +     if (st)
> +             sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
> +
> +     fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
> +             status, sm_err_str, sa_err_str);
> +}
> diff --git a/src/saquery.c b/src/saquery.c
> index 73acea5..95f7e6e 100644
> --- a/src/saquery.c
> +++ b/src/saquery.c
> @@ -59,19 +59,6 @@
>  
>  #include "ibdiag_common.h"
>  
> -struct bind_handle {
> -     int fd, agent;
> -     ib_portid_t dport;
> -};
> -
> -struct sa_query_result {
> -     uint32_t status;
> -     unsigned result_cnt;
> -     void *p_result_madw;
> -};
> -
> -typedef struct bind_handle *bind_handle_t;
> -
>  struct query_params {
>       ib_gid_t sgid, dgid, gid, mgid;
>       uint16_t slid, dlid, mlid;
> @@ -122,121 +109,6 @@ int requested_lid_flag = 0;
>  uint64_t requested_guid = 0;
>  int requested_guid_flag = 0;
>  
> -#define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
> -
> -static const char *ib_sa_error_str[] = {
> -     "SA_NO_ERROR",
> -     "SA_ERR_NO_RESOURCES",
> -     "SA_ERR_REQ_INVALID",
> -     "SA_ERR_NO_RECORDS",
> -     "SA_ERR_TOO_MANY_RECORDS",
> -     "SA_ERR_REQ_INVALID_GID",
> -     "SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
> -     "SA_ERR_REQ_DENIED",
> -     "SA_ERR_STATUS_PRIO_SUGGESTED",
> -     "SA_ERR_UNKNOWN"
> -};
> -
> -#define SA_ERR_UNKNOWN (ARR_SIZE(ib_sa_error_str) - 1)
> -
> -static inline const char *ib_sa_err_str(IN uint8_t status)
> -{
> -     if (status > SA_ERR_UNKNOWN)
> -             status = SA_ERR_UNKNOWN;
> -     return (ib_sa_error_str[status]);
> -}
> -
> -static inline void report_err(int status)
> -{
> -     int st = status & 0xff;
> -     char sm_err_str[64] = { 0 };
> -     char sa_err_str[64] = { 0 };
> -
> -     if (st)
> -             sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
> -
> -     st = status >> 8;
> -     if (st)
> -             sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
> -
> -     fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
> -             status, sm_err_str, sa_err_str);
> -}
> -
> -static int sa_query(struct bind_handle *h, uint8_t method,
> -                 uint16_t attr, uint32_t mod, uint64_t comp_mask,
> -                 uint64_t sm_key, void *data, struct sa_query_result *result)
> -{
> -     ib_rpc_t rpc;
> -     void *umad, *mad;
> -     int ret, offset, len = 256;
> -
> -     memset(&rpc, 0, sizeof(rpc));
> -     rpc.mgtclass = IB_SA_CLASS;
> -     rpc.method = method;
> -     rpc.attr.id = attr;
> -     rpc.attr.mod = mod;
> -     rpc.mask = comp_mask;
> -     rpc.datasz = IB_SA_DATA_SIZE;
> -     rpc.dataoffs = IB_SA_DATA_OFFS;
> -
> -     umad = calloc(1, len + umad_size());
> -     if (!umad)
> -             IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
> -
> -     mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
> -
> -     mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
> -
> -     if (ibdebug > 1)
> -             xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
> -
> -     ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
> -     if (ret < 0)
> -             IBPANIC("umad_send failed: attr %u: %s\n",
> -                     attr, strerror(errno));
> -
> -recv_mad:
> -     ret = umad_recv(h->fd, umad, &len, ibd_timeout);
> -     if (ret < 0) {
> -             if (errno == ENOSPC) {
> -                     umad = realloc(umad, umad_size() + len);
> -                     goto recv_mad;
> -             }
> -             IBPANIC("umad_recv failed: attr 0x%x: %s\n", attr,
> -                     strerror(errno));
> -     }
> -
> -     if ((ret = umad_status(umad)))
> -             return ret;
> -
> -     mad = umad_get_mad(umad);
> -
> -     if (ibdebug > 1)
> -             xdump(stdout, "SA Response:\n", mad, len);
> -
> -     method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
> -     offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
> -     result->status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
> -     result->p_result_madw = mad;
> -     if (result->status != IB_SA_MAD_STATUS_SUCCESS)
> -             result->result_cnt = 0;
> -     else if (method != IB_MAD_METHOD_GET_TABLE)
> -             result->result_cnt = 1;
> -     else if (!offset)
> -             result->result_cnt = 0;
> -     else
> -             result->result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
> -
> -     return 0;
> -}
> -
> -static void *sa_get_query_rec(void *mad, unsigned i)
> -{
> -     int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
> -     return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
> -}
> -
>  static unsigned valid_gid(ib_gid_t * gid)
>  {
>       ib_gid_t zero_gid;
> @@ -837,14 +709,6 @@ static void dump_results(struct sa_query_result *r, void 
> (*dump_func) (void *))
>       }
>  }
>  
> -static void sa_free_result_mad(struct sa_query_result *result)
> -{
> -     if (result->p_result_madw) {
> -             free((uint8_t *) result->p_result_madw - umad_size());
> -             result->p_result_madw = NULL;
> -     }
> -}
> -
>  /**
>   * Get any record(s)
>   */
> @@ -861,7 +725,7 @@ static int get_any_records(bind_handle_t h,
>       }
>  
>       if (result->status != IB_SA_MAD_STATUS_SUCCESS) {
> -             report_err(result->status);
> +             sa_report_err(result->status);
>               return EIO;
>       }
>  
> @@ -1004,26 +868,6 @@ static int parse_lid_and_ports(bind_handle_t h,
>       return 0;
>  }
>  
> -#define cl_hton8(x) (x)
> -#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
> -     if ((int##size##_t) val != (int##size##_t) comp_with) { \
> -             target = cl_hton##size((uint##size##_t) val); \
> -             comp_mask |= IB_##name##_COMPMASK_##mask; \
> -     }
> -
> -#define CHECK_AND_SET_GID(val, target, name, mask) \
> -     if (valid_gid(&(val))) { \
> -             memcpy(&(target), &(val), sizeof(val)); \
> -             comp_mask |= IB_##name##_COMPMASK_##mask; \
> -     }
> -
> -#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
> -     if (val) { \
> -             target = val; \
> -             comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
> -             comp_mask |= IB_##name##_COMPMASK_##mask; \
> -     }
> -
>  /*
>   * Get the portinfo records available with IsSM or IsSMdisabled 
> CapabilityMask bit on.
>   */
> @@ -1095,7 +939,7 @@ static int get_print_class_port_info(bind_handle_t h)
>               return ret;
>       }
>       if (result.status != IB_SA_MAD_STATUS_SUCCESS) {
> -             report_err(result.status);
> +             sa_report_err(result.status);
>               ret = EIO;
>               goto Exit;
>       }
> @@ -1434,37 +1278,6 @@ static int query_mft_records(const struct query_cmd 
> *q, bind_handle_t h,
>                                       &mftr, 0, dump_one_mft_record);
>  }
>  
> -static bind_handle_t get_bind_handle(void)
> -{
> -     static struct ibmad_port *srcport;
> -     static struct bind_handle handle;
> -     int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
> -
> -     srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
> -     if (!srcport)
> -             IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
> -
> -     ib_resolve_smlid_via(&handle.dport, ibd_timeout, srcport);
> -     if (!handle.dport.lid)
> -             IBPANIC("No SM found.");
> -
> -     handle.dport.qp = 1;
> -     if (!handle.dport.qkey)
> -             handle.dport.qkey = IB_DEFAULT_QP1_QKEY;
> -
> -     handle.fd = mad_rpc_portid(srcport);
> -     handle.agent = umad_register(handle.fd, IB_SA_CLASS, 2, 1, NULL);
> -
> -     return &handle;
> -}
> -
> -static void clean_up(struct bind_handle *h)
> -{
> -     umad_unregister(h->fd, h->agent);
> -     umad_close_port(h->fd);
> -     umad_done();
> -}
> -
>  static const struct query_cmd query_cmds[] = {
>       {"ClassPortInfo", "CPI", CLASS_PORT_INFO,
>        NULL, query_class_port_info},
> @@ -1861,7 +1674,10 @@ int main(int argc, char **argv)
>               ibdiag_show_usage();
>       }
>  
> -     h = get_bind_handle();
> +     h = sa_get_bind_handle();
> +     if (!h)
> +             IBPANIC("Failed to bind to the SA");
> +
>       node_name_map = open_node_name_map(node_name_map_file);
>  
>       if (src_lid && *src_lid)
> @@ -1898,7 +1714,7 @@ int main(int argc, char **argv)
>  
>       if (src_lid)
>               free(src_lid);
> -     clean_up(h);
> +     sa_free_bind_handle(h);
>       close_node_name_map(node_name_map);
>       return (status);
>  }

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to