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