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-eagerbug.c < prev    next >
C/C++ Source or Header  |  2008-11-26  |  9KB  |  411 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_op_id_t server_ops_list[2];
  63.     bmi_error_code_t error_code;
  64.     int outcount = 0;
  65.     struct BMI_unexpected_info request_info;
  66.     bmi_size_t actual_size;
  67.     bmi_context_id context;
  68.     char method[24], *cp;
  69.     int len;
  70.     char testeagerbuf1[] = "bbbbbbbbb";
  71.     bmi_size_t size_list1[2];
  72.     void *buffer_list1[2];
  73.     bmi_op_id_t out_id;
  74.  
  75.     /* grab any command line options */
  76.     user_opts = parse_args(argc, argv);
  77.     if (!user_opts)
  78.     {
  79.     return (-1);
  80.     }
  81.  
  82.     /* set debugging stuff */
  83.     gossip_enable_stderr();
  84.     /* gossip_set_debug_mask(1, GOSSIP_BMI_DEBUG_ALL); */
  85.  
  86.     /* convert address to bmi method type by prefixing bmi_ */
  87.     cp = strchr(user_opts->hostid, ':');
  88.     if (!cp)
  89.         return 1;
  90.     len = cp - user_opts->hostid;
  91.     strcpy(method, "bmi_");
  92.     strncpy(method + 4, user_opts->hostid, len);
  93.     method[4+len] = '\0';
  94.  
  95.     /* initialize local interface (default options) */
  96.     ret = BMI_initialize(method, user_opts->hostid, BMI_INIT_SERVER);
  97.     if (ret < 0)
  98.     {
  99.     errno = -ret;
  100.     perror("BMI_initialize");
  101.     return (-1);
  102.     }
  103.  
  104.     ret = BMI_open_context(&context);
  105.     if (ret < 0)
  106.     {
  107.     errno = -ret;
  108.     perror("BMI_open_context()");
  109.     return (-1);
  110.     }
  111.  
  112.     /* wait for an initial request  */
  113.     do
  114.     {
  115.     ret = BMI_testunexpected(1, &outcount, &request_info, 10);
  116.     } while (ret == 0 && outcount == 0);
  117.     if (ret < 0)
  118.     {
  119.     fprintf(stderr, "Request recv failure (bad state).\n");
  120.     errno = -ret;
  121.     perror("BMI_testunexpected");
  122.     return (-1);
  123.     }
  124.     if (request_info.error_code != 0)
  125.     {
  126.     fprintf(stderr, "Request recv failure (bad state).\n");
  127.     return (-1);
  128.     }
  129.  
  130.     if (request_info.size != sizeof(struct server_request))
  131.     {
  132.     fprintf(stderr, "Bad Request!\n");
  133.     exit(-1);
  134.     }
  135.  
  136.     my_req = (struct server_request *) request_info.buffer;
  137.     client_addr = request_info.addr;
  138.  
  139.     /* create an ack */
  140.     my_ack = (struct server_ack *) BMI_memalloc(client_addr,
  141.                         sizeof(struct server_ack),
  142.                         BMI_SEND);
  143.     if (!my_ack)
  144.     {
  145.     fprintf(stderr, "BMI_memalloc failed.\n");
  146.     return (-1);
  147.     }
  148.     memset(my_ack, 0, sizeof(struct server_ack));
  149.  
  150.     /* create a buffer to recv into */
  151.     recv_buffer = BMI_memalloc(client_addr, my_req->size, BMI_RECV);
  152.     if (!recv_buffer)
  153.     {
  154.     fprintf(stderr, "BMI_memalloc failed.\n");
  155.     return (-1);
  156.     }
  157.     /* post the ack */
  158.     ret = BMI_post_send(&(server_ops[1]), client_addr, my_ack,
  159.             sizeof(struct server_ack), BMI_PRE_ALLOC, 0, NULL,
  160.             context, NULL);
  161.     if (ret < 0)
  162.     {
  163.     fprintf(stderr, "BMI_post_send_failure.\n");
  164.     return (-1);
  165.     }
  166.     if (ret == 0)
  167.     {
  168.     /* turning this into a blocking call for testing :) */
  169.     /* check for completion of ack send */
  170.     do
  171.     {
  172.         ret = BMI_test(server_ops[1], &outcount, &error_code,
  173.                &actual_size, NULL, 10, context);
  174.     } while (ret == 0 && outcount == 0);
  175.  
  176.     if (ret < 0 || error_code != 0)
  177.     {
  178.         fprintf(stderr, "ack send failed.\n");
  179.         return (-1);
  180.     }
  181.     }
  182.  
  183.     /* post the recv */
  184.     ret = BMI_post_recv(&(server_ops[0]), client_addr, recv_buffer,
  185.             my_req->size, &actual_size, BMI_PRE_ALLOC, 0, NULL,
  186.             context, NULL);
  187.     if (ret < 0)
  188.     {
  189.     fprintf(stderr, "BMI_post_recv_failure.\n");
  190.     return (-1);
  191.     }
  192.     if (ret == 0)
  193.     {
  194.     /* turning this into a blocking call for testing :) */
  195.     /* check for completion of data payload recv */
  196.     do
  197.     {
  198.         ret = BMI_test(server_ops[0], &outcount, &error_code,
  199.                &actual_size, NULL, 10, context);
  200.     } while (ret == 0 && outcount == 0);
  201.  
  202.     if (ret < 0 || error_code != 0)
  203.     {
  204.         fprintf(stderr, "data recv failed.\n");
  205.         return (-1);
  206.     }
  207.     }
  208.  
  209.     if (actual_size != 15000)
  210.     {
  211.     printf("Didn't get short recv when expected.\n");
  212.     printf("actual_size: %d\n", (int) actual_size);
  213.     return (0);
  214.     }
  215.  
  216.     /* sleep a bit to let client get ahead of us */
  217.     sleep(3);
  218.  
  219.     /* poke at BMI to make it buffer the eager message */
  220.     ret = BMI_testcontext(1, &out_id, &outcount, &error_code,
  221.                &actual_size, NULL, 10, context);
  222.     if(ret != 0 || outcount != 0)
  223.     {
  224.         fprintf(stderr, "Error: testcontext found something that it shouldn't have.\n");
  225.         return(-1);
  226.     }
  227.  
  228.     size_list1[0] = 3;
  229.     size_list1[1] = 3;
  230.     buffer_list1[0] = &testeagerbuf1[0];
  231.     buffer_list1[1] = &testeagerbuf1[6];
  232.     
  233.     ret = BMI_post_recv_list(&(server_ops_list[0]), client_addr, buffer_list1,
  234.             size_list1, 2, 6, &actual_size, BMI_EXT_ALLOC, 1, NULL,
  235.             context, NULL);
  236.     if (ret < 0)
  237.     {
  238.     fprintf(stderr, "BMI_post_recv_failure.\n");
  239.     return (-1);
  240.     }
  241.     if (ret == 0)
  242.     {
  243.     /* turning this into a blocking call for testing :) */
  244.     /* check for completion of data payload recv */
  245.     do
  246.     {
  247.         ret = BMI_test(server_ops_list[0], &outcount, &error_code,
  248.                &actual_size, NULL, 10, context);
  249.     } while (ret == 0 && outcount == 0);
  250.  
  251.     if (ret < 0 || error_code != 0)
  252.     {
  253.         fprintf(stderr, "data recv failed.\n");
  254.         return (-1);
  255.     }
  256.     }
  257.  
  258.     printf("Recv 1 (recv posted after msg arrival)\n");
  259.     printf("   Expected: \"aaabbbccc\"\n");
  260.     printf("   Got: \"%s\"\n", testeagerbuf1);
  261.     if(strcmp(testeagerbuf1, "aaabbbccc") != 0)
  262.     {
  263.         fprintf(stderr, "   FAILURE!\n");
  264.     }
  265.     else
  266.     {
  267.         printf("   SUCCESS!\n");
  268.     }
  269.  
  270.     sprintf(testeagerbuf1, "bbbbbbbbb");
  271.     size_list1[0] = 3;
  272.     size_list1[1] = 3;
  273.     buffer_list1[0] = &testeagerbuf1[0];
  274.     buffer_list1[1] = &testeagerbuf1[6];
  275.     
  276.     ret = BMI_post_recv_list(&(server_ops_list[0]), client_addr, buffer_list1,
  277.             size_list1, 2, 6, &actual_size, BMI_EXT_ALLOC, 1, NULL,
  278.             context, NULL);
  279.     if (ret < 0)
  280.     {
  281.     fprintf(stderr, "BMI_post_recv_failure.\n");
  282.     return (-1);
  283.     }
  284.     if (ret == 0)
  285.     {
  286.     /* turning this into a blocking call for testing :) */
  287.     /* check for completion of data payload recv */
  288.     do
  289.     {
  290.         ret = BMI_test(server_ops_list[0], &outcount, &error_code,
  291.                &actual_size, NULL, 10, context);
  292.     } while (ret == 0 && outcount == 0);
  293.  
  294.     if (ret < 0 || error_code != 0)
  295.     {
  296.         fprintf(stderr, "data recv failed.\n");
  297.         return (-1);
  298.     }
  299.     }
  300.  
  301.     printf("Recv 2 (recv posted before msg arrival)\n");
  302.     printf("   Expected: \"aaabbbccc\"\n");
  303.     printf("   Got: \"%s\"\n", testeagerbuf1);
  304.     if(strcmp(testeagerbuf1, "aaabbbccc") != 0)
  305.     {
  306.         fprintf(stderr, "   FAILURE!\n");
  307.     }
  308.     else
  309.     {
  310.         printf("   SUCCESS!\n");
  311.     }
  312.  
  313.     /* free up the message buffers */
  314.     BMI_memfree(client_addr, recv_buffer, my_req->size, BMI_RECV);
  315.     BMI_memfree(client_addr, my_ack, sizeof(struct server_ack), BMI_SEND);
  316.     BMI_unexpected_free(client_addr, my_req);
  317.  
  318.     /* try out rev lookup */
  319.     /* printf("rev_lookup() output: %s\n", BMI_addr_rev_lookup(client_addr)); */
  320.  
  321.     /* shutdown the local interface */
  322.     BMI_close_context(context);
  323.     ret = BMI_finalize();
  324.     if (ret < 0)
  325.     {
  326.     errno = -ret;
  327.     perror("BMI_finalize");
  328.     return (-1);
  329.     }
  330.  
  331.     /* turn off debugging stuff */
  332.     gossip_disable();
  333.  
  334.     free(user_opts->hostid);
  335.     free(user_opts);
  336.  
  337.     return (0);
  338. }
  339.  
  340.  
  341. static struct options *parse_args(
  342.     int argc,
  343.     char *argv[])
  344. {
  345.     const char flags[] = "h:";
  346.     int one_opt = 0;
  347.  
  348.     struct options *tmp_opts = NULL;
  349.     int len = -1;
  350.  
  351.     /* create storage for the command line options */
  352.     tmp_opts = malloc(sizeof(struct options));
  353.     if (!tmp_opts)
  354.     {
  355.     goto parse_args_error;
  356.     }
  357.     tmp_opts->hostid = NULL;
  358.  
  359.     /* look at command line arguments */
  360.     while ((one_opt = getopt(argc, argv, flags)) != EOF)
  361.     {
  362.     switch (one_opt)
  363.     {
  364.     case ('h'):
  365.         len = (strlen(optarg)) + 1;
  366.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  367.         {
  368.         goto parse_args_error;
  369.         }
  370.         memcpy(tmp_opts->hostid, optarg, len);
  371.         break;
  372.     default:
  373.         break;
  374.     }
  375.     }
  376.  
  377.     /* if we didn't get a host argument, fill in a default: */
  378.     if (tmp_opts->hostid == NULL) {
  379.         len = (strlen(DEFAULT_SERVERID)) + 1;
  380.         if ((tmp_opts->hostid = malloc(len)) == NULL)
  381.         {
  382.             goto parse_args_error;
  383.         }
  384.         memcpy(tmp_opts->hostid, DEFAULT_SERVERID, len);
  385.     }
  386.  
  387.     return (tmp_opts);
  388.  
  389.   parse_args_error:
  390.  
  391.     /* if an error occurs, just free everything and return NULL */
  392.     if (tmp_opts)
  393.     {
  394.     if (tmp_opts->hostid)
  395.     {
  396.         free(tmp_opts->hostid);
  397.     }
  398.     free(tmp_opts);
  399.     }
  400.     return (NULL);
  401. }
  402.  
  403. /*
  404.  * Local variables:
  405.  *  c-indent-level: 4
  406.  *  c-basic-offset: 4
  407.  * End:
  408.  *
  409.  * vim: ts=8 sts=4 sw=4 expandtab
  410.  */
  411.