home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / test / io / bmi / test-bmi-client.c < prev    next >
C/C++ Source or Header  |  2008-11-26  |  8KB  |  382 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7.  
  8.  
  9.  
  10. /*
  11.  * This is an example of a client program that uses the BMI library
  12.  * for communications.
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #include "pvfs2.h"
  22. #include "bmi.h"
  23. #include "test-bmi.h"
  24. #include "gossip.h"
  25.  
  26. /**************************************************************
  27.  * Data structures 
  28.  */
  29.  
  30. /* A little structure to hold program options, either defaults or
  31.  * specified on the command line 
  32.  */
  33. struct options
  34. {
  35.     char *hostid;        /* host identifier */
  36.     int message_size;        /* message size */
  37. };
  38.  
  39.  
  40. /**************************************************************
  41.  * Internal utility functions
  42.  */
  43.  
  44. static struct options *parse_args(
  45.     int argc,
  46.     char *argv[]);
  47.  
  48.  
  49. /**************************************************************/
  50.  
  51. int main(
  52.     int argc,
  53.     char **argv)
  54. {
  55.  
  56.     struct options *user_opts = NULL;
  57.     struct server_request *my_req = NULL;
  58.     struct server_ack *my_ack = NULL;
  59.     int ret = -1;
  60.     PVFS_BMI_addr_t server_addr;
  61.     void *send_buffer = NULL;
  62.     bmi_op_id_t client_ops[2];
  63.     int outcount = 0;
  64.     bmi_error_code_t error_code;
  65.     void *in_test_user_ptr = &server_addr;
  66.     void *out_test_user_ptr = NULL;
  67.     bmi_size_t actual_size;
  68.     bmi_context_id context;
  69.     char method[24], *cp;
  70.     int len;
  71.  
  72.     /* grab any command line options */
  73.     user_opts = parse_args(argc, argv);
  74.     if (!user_opts)
  75.     {
  76.     return (-1);
  77.     }
  78.  
  79.     /* set debugging stuff */
  80.     gossip_enable_stderr();
  81.     gossip_set_debug_mask(1, GOSSIP_BMI_DEBUG_ALL);
  82.  
  83.     /* convert address to bmi method type by prefixing bmi_ */
  84.     cp = strchr(user_opts->hostid, ':');
  85.     if (!cp)
  86.         return 1;
  87.     len = cp - user_opts->hostid;
  88.     strcpy(method, "bmi_");
  89.     strncpy(method + 4, user_opts->hostid, len);
  90.     method[4+len] = '\0';
  91.  
  92.     /* initialize local interface */
  93.     ret = BMI_initialize(NULL, NULL, 0);
  94.     if (ret < 0)
  95.     {
  96.     errno = -ret;
  97.     perror("BMI_initialize");
  98.     return (-1);
  99.     }
  100.  
  101.     ret = BMI_open_context(&context);
  102.     if (ret < 0)
  103.     {
  104.     errno = -ret;
  105.     perror("BMI_open_context()");
  106.     return (-1);
  107.     }
  108.  
  109.     /* get a bmi_addr for the server */
  110.     ret = BMI_addr_lookup(&server_addr, user_opts->hostid);
  111.     if (ret < 0)
  112.     {
  113.     errno = -ret;
  114.     perror("BMI_addr_lookup");
  115.     return (-1);
  116.     }
  117.  
  118.     /* allocate a buffer for the initial request and ack */
  119.     my_req = (struct server_request *) BMI_memalloc(server_addr,
  120.                             sizeof(struct
  121.                                server_request),
  122.                             BMI_SEND);
  123.     my_ack =
  124.     (struct server_ack *) BMI_memalloc(server_addr,
  125.                        sizeof(struct server_ack), BMI_RECV);
  126.     if (!my_req || !my_ack)
  127.     {
  128.     fprintf(stderr, "BMI_memalloc failed.\n");
  129.     return (-1);
  130.     }
  131.  
  132.     my_req->size = user_opts->message_size;
  133.  
  134.     /* send the initial request on its way */
  135.     ret = BMI_post_sendunexpected(&(client_ops[1]), server_addr, my_req,
  136.                   sizeof(struct server_request), BMI_PRE_ALLOC,
  137.                   0, in_test_user_ptr, context, NULL);
  138.     if (ret < 0)
  139.     {
  140.     errno = -ret;
  141.     perror("BMI_post_send");
  142.     return (-1);
  143.     }
  144.     if (ret == 0)
  145.     {
  146.     /* turning this into a blocking call for testing :) */
  147.     /* check for completion of request */
  148.     do
  149.     {
  150.         ret = BMI_test(client_ops[1], &outcount, &error_code, &actual_size,
  151.                &out_test_user_ptr, 10, context);
  152.     } while (ret == 0 && outcount == 0);
  153.  
  154.     if (ret < 0 || error_code != 0)
  155.     {
  156.         fprintf(stderr, "Request send failed.\n");
  157.         if (ret < 0)
  158.         {
  159.         errno = -ret;
  160.         perror("BMI_test");
  161.         }
  162.         return (-1);
  163.     }
  164.  
  165.     if (in_test_user_ptr != out_test_user_ptr)
  166.     {
  167.         fprintf(stderr, "1st ptr failure.\n");
  168.     }
  169.     else
  170.     {
  171.         fprintf(stderr, "1st ptr success.\n");
  172.     }
  173.     out_test_user_ptr = NULL;
  174.     }
  175.  
  176.     /* post a recv for the server acknowledgement */
  177.     ret = BMI_post_recv(&(client_ops[0]), server_addr, my_ack,
  178.             sizeof(struct server_ack), &actual_size, BMI_PRE_ALLOC,
  179.             0, in_test_user_ptr, context, NULL);
  180.     if (ret < 0)
  181.     {
  182.     errno = -ret;
  183.     perror("BMI_post_recv");
  184.     return (-1);
  185.     }
  186.     if (ret == 0)
  187.     {
  188.     /* turning this into a blocking call for testing :) */
  189.     /* check for completion of ack recv */
  190.     do
  191.     {
  192.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  193.                &actual_size, &out_test_user_ptr, 10, context);
  194.     } while (ret == 0 && outcount == 0);
  195.  
  196.     if (ret < 0 || error_code != 0)
  197.     {
  198.         fprintf(stderr, "Ack recv failed.\n");
  199.         return (-1);
  200.     }
  201.     if (in_test_user_ptr != out_test_user_ptr)
  202.     {
  203.         fprintf(stderr, "2nd ptr failure.\n");
  204.     }
  205.     else
  206.     {
  207.         fprintf(stderr, "2nd ptr success.\n");
  208.     }
  209.     out_test_user_ptr = NULL;
  210.     }
  211.     else
  212.     {
  213.     if (actual_size != sizeof(struct server_ack))
  214.     {
  215.         printf("Short recv.\n");
  216.         return (-1);
  217.     }
  218.     }
  219.  
  220.     /* look at the ack */
  221.     if (my_ack->status != 0)
  222.     {
  223.     fprintf(stderr, "Request denied.\n");
  224.     return (-1);
  225.     }
  226.  
  227.     /* create a buffer to send */
  228.     send_buffer = BMI_memalloc(server_addr, user_opts->message_size, BMI_SEND);
  229.     if (!send_buffer)
  230.     {
  231.     fprintf(stderr, "BMI_memalloc.\n");
  232.     return (-1);
  233.     }
  234.  
  235.     /* send the data payload on its way */
  236.     /* NOTE: intentionally sending short message here, testing
  237.      * ability to match eager send with rend. receive
  238.      */
  239.     ret = BMI_post_send(&(client_ops[0]), server_addr, send_buffer,
  240.             15000, BMI_PRE_ALLOC, 0, in_test_user_ptr, context, NULL);
  241.     if (ret < 0)
  242.     {
  243.     errno = -ret;
  244.     perror("BMI_post_send");
  245.     return (-1);
  246.     }
  247.     if (ret == 0)
  248.     {
  249.     /* turning this into a blocking call for testing :) */
  250.     /* check for completion of data payload send */
  251.     do
  252.     {
  253.         ret = BMI_test(client_ops[0], &outcount, &error_code,
  254.                &actual_size, &out_test_user_ptr, 10, context);
  255.     } while (ret == 0 && outcount == 0);
  256.  
  257.     if (ret < 0 || error_code != 0)
  258.     {
  259.         fprintf(stderr, "Data payload send failed.\n");
  260.         return (-1);
  261.     }
  262.     if (in_test_user_ptr != out_test_user_ptr)
  263.     {
  264.         fprintf(stderr, "3rd ptr failure.\n");
  265.     }
  266.     else
  267.     {
  268.         fprintf(stderr, "3rd ptr success.\n");
  269.     }
  270.     out_test_user_ptr = NULL;
  271.     }
  272.  
  273.     /* free up the message buffers */
  274.     BMI_memfree(server_addr, send_buffer, user_opts->message_size, BMI_SEND);
  275.     BMI_memfree(server_addr, my_req, sizeof(struct server_request), BMI_SEND);
  276.     BMI_memfree(server_addr, my_ack, sizeof(struct server_ack), BMI_RECV);
  277.  
  278.     /* try out rev lookup */
  279.     printf("rev_lookup() output: %s\n", BMI_addr_rev_lookup(server_addr));
  280.  
  281.     /* shutdown the local interface */
  282.     BMI_close_context(context);
  283.     ret = BMI_finalize();
  284.     if (ret < 0)
  285.     {
  286.     errno = -ret;
  287.     perror("BMI_finalize");
  288.     return (-1);
  289.     }
  290.  
  291.     /* turn off debugging stuff */
  292.     gossip_disable();
  293.  
  294.     free(user_opts->hostid);
  295.     free(user_opts);
  296.  
  297.     return (0);
  298. }
  299.  
  300.  
  301. static struct options *parse_args(
  302.     int argc,
  303.     char *argv[])
  304. {
  305.     const char flags[] = "h:s:";
  306.     int one_opt = 0;
  307.  
  308.     struct options *tmp_opts = NULL;
  309.     int len = -1;
  310.     int ret = -1;
  311.  
  312.     /* create storage for the command line options */
  313.     tmp_opts = malloc(sizeof(struct options));
  314.     if (!tmp_opts)
  315.     {
  316.     goto parse_args_error;
  317.     }
  318.  
  319.     /* fill in defaults (except for hostid) */
  320.     tmp_opts->hostid = NULL;
  321.     tmp_opts->message_size = 32000;
  322.  
  323.     /* look at command line arguments */
  324.     while ((one_opt = getopt(argc, argv, flags)) != EOF)
  325.     {
  326.     switch (one_opt)
  327.     {
  328.     case ('h'):
  329.         len = (strlen(optarg)) + 1;
  330.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  331.         {
  332.         goto parse_args_error;
  333.         }
  334.         memcpy(tmp_opts->hostid, optarg, len);
  335.         break;
  336.     case ('s'):
  337.         ret = sscanf(optarg, "%d", &tmp_opts->message_size);
  338.         if (ret < 1)
  339.         {
  340.         goto parse_args_error;
  341.         }
  342.         break;
  343.     default:
  344.         break;
  345.     }
  346.     }
  347.  
  348.     /* if we didn't get a host argument, fill in a default: */
  349.     if (tmp_opts->hostid == NULL) {
  350.         len = (strlen(DEFAULT_HOSTID)) + 1;
  351.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  352.         {
  353.             goto parse_args_error;
  354.         }
  355.         memcpy(tmp_opts->hostid, DEFAULT_HOSTID, len);
  356.     }
  357.  
  358.     return (tmp_opts);
  359.  
  360.   parse_args_error:
  361.  
  362.     /* if an error occurs, just free everything and return NULL */
  363.     if (tmp_opts)
  364.     {
  365.     if (tmp_opts->hostid)
  366.     {
  367.         free(tmp_opts->hostid);
  368.     }
  369.     free(tmp_opts);
  370.     }
  371.     return (NULL);
  372. }
  373.  
  374. /*
  375.  * Local variables:
  376.  *  c-indent-level: 4
  377.  *  c-basic-offset: 4
  378.  * End:
  379.  *
  380.  * vim: ts=8 sts=4 sw=4 expandtab
  381.  */
  382.