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-server.c < prev    next >
C/C++ Source or Header  |  2008-11-26  |  7KB  |  312 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 server program that uses the BMI 
  12.  * library 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 "gossip.h"
  24. #include "test-bmi.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. };
  37.  
  38.  
  39. /**************************************************************
  40.  * Internal utility functions
  41.  */
  42.  
  43. static struct options *parse_args(
  44.     int argc,
  45.     char *argv[]);
  46.  
  47.  
  48. /**************************************************************/
  49.  
  50. int main(
  51.     int argc,
  52.     char **argv)
  53. {
  54.  
  55.     struct options *user_opts = NULL;
  56.     struct server_request *my_req = NULL;
  57.     struct server_ack *my_ack = NULL;
  58.     int ret = -1;
  59.     PVFS_BMI_addr_t client_addr;
  60.     void *recv_buffer = NULL;
  61.     bmi_op_id_t server_ops[2];
  62.     bmi_error_code_t error_code;
  63.     int outcount = 0;
  64.     struct BMI_unexpected_info request_info;
  65.     bmi_size_t actual_size;
  66.     bmi_context_id context;
  67.     char method[24], *cp;
  68.     int len;
  69.  
  70.     /* grab any command line options */
  71.     user_opts = parse_args(argc, argv);
  72.     if (!user_opts)
  73.     {
  74.     return (-1);
  75.     }
  76.  
  77.     /* set debugging stuff */
  78.     gossip_enable_stderr();
  79.     gossip_set_debug_mask(1, GOSSIP_BMI_DEBUG_ALL);
  80.  
  81.     /* convert address to bmi method type by prefixing bmi_ */
  82.     cp = strchr(user_opts->hostid, ':');
  83.     if (!cp)
  84.         return 1;
  85.     len = cp - user_opts->hostid;
  86.     strcpy(method, "bmi_");
  87.     strncpy(method + 4, user_opts->hostid, len);
  88.     method[4+len] = '\0';
  89.  
  90.     /* initialize local interface (default options) */
  91.     ret = BMI_initialize(method, user_opts->hostid, BMI_INIT_SERVER);
  92.     if (ret < 0)
  93.     {
  94.     errno = -ret;
  95.     perror("BMI_initialize");
  96.     return (-1);
  97.     }
  98.  
  99.     ret = BMI_open_context(&context);
  100.     if (ret < 0)
  101.     {
  102.     errno = -ret;
  103.     perror("BMI_open_context()");
  104.     return (-1);
  105.     }
  106.  
  107.     /* wait for an initial request  */
  108.     do
  109.     {
  110.     ret = BMI_testunexpected(1, &outcount, &request_info, 10);
  111.     } while (ret == 0 && outcount == 0);
  112.     if (ret < 0)
  113.     {
  114.     fprintf(stderr, "Request recv failure (bad state).\n");
  115.     errno = -ret;
  116.     perror("BMI_testunexpected");
  117.     return (-1);
  118.     }
  119.     if (request_info.error_code != 0)
  120.     {
  121.     fprintf(stderr, "Request recv failure (bad state).\n");
  122.     return (-1);
  123.     }
  124.  
  125.     printf("Received a new request.\n");
  126.  
  127.     if (request_info.size != sizeof(struct server_request))
  128.     {
  129.     fprintf(stderr, "Bad Request!\n");
  130.     exit(-1);
  131.     }
  132.  
  133.     my_req = (struct server_request *) request_info.buffer;
  134.     client_addr = request_info.addr;
  135.  
  136.     /* create an ack */
  137.     my_ack = (struct server_ack *) BMI_memalloc(client_addr,
  138.                         sizeof(struct server_ack),
  139.                         BMI_SEND);
  140.     if (!my_ack)
  141.     {
  142.     fprintf(stderr, "BMI_memalloc failed.\n");
  143.     return (-1);
  144.     }
  145.     memset(my_ack, 0, sizeof(struct server_ack));
  146.  
  147.     /* create a buffer to recv into */
  148.     recv_buffer = BMI_memalloc(client_addr, my_req->size, BMI_RECV);
  149.     if (!recv_buffer)
  150.     {
  151.     fprintf(stderr, "BMI_memalloc failed.\n");
  152.     return (-1);
  153.     }
  154.  
  155.     /* post the ack */
  156.     ret = BMI_post_send(&(server_ops[1]), client_addr, my_ack,
  157.             sizeof(struct server_ack), BMI_PRE_ALLOC, 0, NULL,
  158.             context, NULL);
  159.     if (ret < 0)
  160.     {
  161.     fprintf(stderr, "BMI_post_send_failure.\n");
  162.     return (-1);
  163.     }
  164.     if (ret == 0)
  165.     {
  166.     /* turning this into a blocking call for testing :) */
  167.     /* check for completion of ack send */
  168.     do
  169.     {
  170.         ret = BMI_test(server_ops[1], &outcount, &error_code,
  171.                &actual_size, NULL, 10, context);
  172.     } while (ret == 0 && outcount == 0);
  173.  
  174.     if (ret < 0 || error_code != 0)
  175.     {
  176.         fprintf(stderr, "ack send failed.\n");
  177.         return (-1);
  178.     }
  179.     }
  180.  
  181.     /* post the recv */
  182.     ret = BMI_post_recv(&(server_ops[0]), client_addr, recv_buffer,
  183.             my_req->size, &actual_size, BMI_PRE_ALLOC, 0, NULL,
  184.             context, NULL);
  185.     if (ret < 0)
  186.     {
  187.     fprintf(stderr, "BMI_post_recv_failure.\n");
  188.     return (-1);
  189.     }
  190.     if (ret == 0)
  191.     {
  192.     /* turning this into a blocking call for testing :) */
  193.     /* check for completion of data payload recv */
  194.     do
  195.     {
  196.         ret = BMI_test(server_ops[0], &outcount, &error_code,
  197.                &actual_size, NULL, 10, context);
  198.     } while (ret == 0 && outcount == 0);
  199.  
  200.     if (ret < 0 || error_code != 0)
  201.     {
  202.         fprintf(stderr, "data recv failed.\n");
  203.         return (-1);
  204.     }
  205.     }
  206.  
  207.     if (actual_size != 15000)
  208.     {
  209.     printf("Didn't get short recv when expected.\n");
  210.     printf("actual_size: %d\n", (int) actual_size);
  211.     return (0);
  212.     }
  213.  
  214.     /* free up the message buffers */
  215.     BMI_memfree(client_addr, recv_buffer, my_req->size, BMI_RECV);
  216.     BMI_memfree(client_addr, my_ack, sizeof(struct server_ack), BMI_SEND);
  217.     BMI_unexpected_free(client_addr, my_req);
  218.  
  219.     /* try out rev lookup */
  220.     printf("rev_lookup() output: %s\n", BMI_addr_rev_lookup(client_addr));
  221.  
  222.     /* shutdown the local interface */
  223.     BMI_close_context(context);
  224.     ret = BMI_finalize();
  225.     if (ret < 0)
  226.     {
  227.     errno = -ret;
  228.     perror("BMI_finalize");
  229.     return (-1);
  230.     }
  231.  
  232.     /* turn off debugging stuff */
  233.     gossip_disable();
  234.  
  235.     free(user_opts->hostid);
  236.     free(user_opts);
  237.  
  238.     return (0);
  239. }
  240.  
  241.  
  242. static struct options *parse_args(
  243.     int argc,
  244.     char *argv[])
  245. {
  246.     const char flags[] = "h:";
  247.     int one_opt = 0;
  248.  
  249.     struct options *tmp_opts = NULL;
  250.     int len = -1;
  251.  
  252.     /* create storage for the command line options */
  253.     tmp_opts = malloc(sizeof(struct options));
  254.     if (!tmp_opts)
  255.     {
  256.     goto parse_args_error;
  257.     }
  258.     tmp_opts->hostid = NULL;
  259.  
  260.     /* look at command line arguments */
  261.     while ((one_opt = getopt(argc, argv, flags)) != EOF)
  262.     {
  263.     switch (one_opt)
  264.     {
  265.     case ('h'):
  266.         len = (strlen(optarg)) + 1;
  267.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  268.         {
  269.         goto parse_args_error;
  270.         }
  271.         memcpy(tmp_opts->hostid, optarg, len);
  272.         break;
  273.     default:
  274.         break;
  275.     }
  276.     }
  277.  
  278.     /* if we didn't get a host argument, fill in a default: */
  279.     if (tmp_opts->hostid == NULL) {
  280.         len = (strlen(DEFAULT_SERVERID)) + 1;
  281.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  282.         {
  283.             goto parse_args_error;
  284.         }
  285.         memcpy(tmp_opts->hostid, DEFAULT_SERVERID, len);
  286.     }
  287.  
  288.     return (tmp_opts);
  289.  
  290.   parse_args_error:
  291.  
  292.     /* if an error occurs, just free everything and return NULL */
  293.     if (tmp_opts)
  294.     {
  295.     if (tmp_opts->hostid)
  296.     {
  297.         free(tmp_opts->hostid);
  298.     }
  299.     free(tmp_opts);
  300.     }
  301.     return (NULL);
  302. }
  303.  
  304. /*
  305.  * Local variables:
  306.  *  c-indent-level: 4
  307.  *  c-basic-offset: 4
  308.  * End:
  309.  *
  310.  * vim: ts=8 sts=4 sw=4 expandtab
  311.  */
  312.