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 / src / client / sysint / server-get-config.sm < prev    next >
Text File  |  2010-04-30  |  10KB  |  379 lines

  1. /* 
  2.  * (C) 2003 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. #include <string.h>
  8. #include <assert.h>
  9. #include <unistd.h>
  10.  
  11. #include "client-state-machine.h"
  12. #include "pvfs2-debug.h"
  13. #include "pvfs2-util.h"
  14. #include "job.h"
  15. #include "gossip.h"
  16. #include "str-utils.h"
  17. #include "pint-cached-config.h"
  18. #include "PINT-reqproto-encode.h"
  19.  
  20. extern job_context_id pint_client_sm_context;
  21.  
  22. static int server_parse_config(
  23.     struct server_configuration_s *config,
  24.     char *fs_config_buf,
  25.     uint32_t fs_config_buf_size);
  26.  
  27. static int server_get_config_comp_fn(
  28.     void *v_p, struct PVFS_server_resp *resp_p, int i);
  29.  
  30. %%
  31.  
  32. nested machine pvfs2_server_get_config_nested_sm
  33. {
  34.     state setup_msgpair
  35.     {
  36.         run server_get_config_setup_msgpair;
  37.         success => xfer_msgpair;
  38.         default => cleanup;
  39.     }
  40.  
  41.     state xfer_msgpair
  42.     {
  43.         jump pvfs2_msgpairarray_sm;
  44.         success => parse;
  45.         default => cleanup;
  46.     }
  47.  
  48.     state parse
  49.     {
  50.         run server_get_config_parse;
  51.         default => cleanup;
  52.     }
  53.  
  54.     state cleanup
  55.     {
  56.         run server_get_config_cleanup;
  57.         default => return;
  58.     }
  59. }
  60.  
  61. machine pvfs2_server_get_config_sm
  62. {
  63.     state run_nested 
  64.     {
  65.         jump pvfs2_server_get_config_nested_sm;
  66.         default => parent_cleanup;
  67.     }
  68.  
  69.     state parent_cleanup
  70.     {
  71.         run server_get_config_parent_cleanup;
  72.         default => terminate;
  73.     }
  74. }
  75.  
  76. %%
  77.  
  78. /*
  79.   given mount information, retrieve the server's configuration by
  80.   issuing a getconfig operation.  on successful response, we parse the
  81.   configuration and fill in the config object specified.
  82.  
  83.   returns 0 on success, -errno on error
  84. */
  85. int PINT_server_get_config(
  86.     struct server_configuration_s *config,
  87.     struct PVFS_sys_mntent* mntent_p,
  88.     PVFS_hint hints)
  89. {
  90.     int ret = -PVFS_EINVAL;
  91.     PINT_smcb *smcb = NULL;
  92.     PINT_client_sm *sm_p = NULL;
  93.     PVFS_error error = 0;
  94.     PVFS_credentials creds;
  95.     PVFS_sys_op_id op_id;
  96.  
  97.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  98.                  "PINT_server_get_config entered\n");
  99.  
  100.     if (!config || !mntent_p)
  101.     {
  102.     return ret;
  103.     }
  104.  
  105.     PVFS_util_gen_credentials(&creds);
  106.  
  107.     gossip_debug(GOSSIP_CLIENT_DEBUG, "asked for fs name = %s\n",
  108.                  mntent_p->pvfs_fs_name);
  109.  
  110.     PINT_smcb_alloc(&smcb, PVFS_SERVER_GET_CONFIG,
  111.              sizeof(struct PINT_client_sm),
  112.              client_op_state_get_machine,
  113.              client_state_machine_terminate,
  114.              pint_client_sm_context);
  115.     if (smcb == NULL)
  116.     {
  117.         return -PVFS_ENOMEM;
  118.     }
  119.     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  120.  
  121.     /* NOTE: we set these fields manually here rather than use
  122.      * PINT_init_msgarray_params(), because we don't yet have a server
  123.      * configuration file to override default parameters.
  124.      */
  125.     sm_p->msgarray_op.params.job_context = pint_client_sm_context;
  126.     sm_p->msgarray_op.params.job_timeout = 30;   /* 30 second job timeout */
  127.     sm_p->msgarray_op.params.retry_delay = 2000; /* 2 second retry delay */
  128.     sm_p->msgarray_op.params.retry_limit = 5;    /* retry up to 5 times */
  129.  
  130.     PINT_msgpair_init(&sm_p->msgarray_op);
  131.     PINT_init_sysint_credentials(sm_p->cred_p, &creds);
  132.     sm_p->u.get_config.mntent = mntent_p;
  133.     sm_p->u.get_config.config = config;
  134.     
  135.     PVFS_hint_copy(hints, &sm_p->hints);
  136.  
  137.     ret = PINT_client_state_machine_post(smcb, &op_id, NULL);
  138.     if (ret)
  139.     {
  140.         PVFS_perror_gossip("PINT_client_state_machine_post call", ret);
  141.         error = ret;
  142.     }
  143.     else
  144.     {
  145.         ret = PVFS_sys_wait(op_id, "X-get_config", &error);
  146.         if (ret)
  147.         {
  148.             PVFS_perror_gossip("PVFS_sys_wait call", ret);
  149.             error = ret;
  150.         }
  151.     }
  152.  
  153.     PINT_sys_release(op_id);
  154.     return(error);
  155. }
  156.  
  157. static int server_parse_config(
  158.     struct server_configuration_s *config,
  159.     char *fs_config_buf,
  160.     uint32_t fs_config_buf_size)
  161. {
  162.     int ret = 1, template_index = 1;
  163.     int fs_fd = 0;
  164.     char fs_template_array[2][64] =
  165.     {
  166.         ".__pvfs_fs_configXXXXXX",
  167.         "/tmp/.__pvfs_fs_configXXXXXX"
  168.     };
  169.     char *fs_template = NULL;
  170.  
  171.     if (config)
  172.     {
  173.         assert(fs_config_buf);
  174.  
  175.         while(1)
  176.         {
  177.             assert(template_index > -1);
  178.             fs_template = fs_template_array[template_index];
  179.  
  180.             fs_fd = mkstemp(fs_template);
  181.             if (fs_fd != -1)
  182.             {
  183.                 break;
  184.             }
  185.             else if ((--template_index) < 0)
  186.             {
  187.                 gossip_err("Error: Cannot create temporary "
  188.                            "configuration files!\n");
  189.                 return ret;
  190.             }
  191.         }
  192.  
  193.         assert(!fs_config_buf[fs_config_buf_size - 1]);
  194.  
  195.         if (write(fs_fd,fs_config_buf, 
  196.             (fs_config_buf_size - 1)) == (fs_config_buf_size - 1))
  197.         {
  198.             ret = PINT_parse_config(config, fs_template, NULL);
  199.         }
  200.         else
  201.         {
  202.             gossip_err("Failed to write fs.conf buffer to temp file: %s: %s\n",
  203.                        fs_template, strerror(errno));
  204.         }
  205.     
  206.         close(fs_fd);
  207.  
  208.         remove(fs_template);
  209.     }
  210.     return ret;
  211. }
  212.  
  213. static PINT_sm_action server_get_config_setup_msgpair(
  214.         struct PINT_smcb *smcb, job_status_s *js_p)
  215. {
  216.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  217.     int ret = -PVFS_EINVAL;
  218.     PINT_sm_msgpair_state *msg_p = NULL;
  219.     PVFS_BMI_addr_t serv_addr;
  220.  
  221.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  222.                  "get_config state: server_get_config_setup_msgpair\n");
  223.  
  224.     PINT_msgpair_init(&sm_p->msgarray_op);
  225.     msg_p = &sm_p->msgarray_op.msgpair;
  226.  
  227.     if (ENCODING_IS_VALID(sm_p->u.get_config.mntent->encoding))
  228.     {
  229.         msg_p->enc_type = sm_p->u.get_config.mntent->encoding;
  230.     }
  231.  
  232.     ret = BMI_addr_lookup(&serv_addr,
  233.                           sm_p->u.get_config.mntent->the_pvfs_config_server);
  234.     if (ret < 0)
  235.     {
  236.         gossip_lerr("Failed to resolve BMI address %s\n",
  237.                     sm_p->u.get_config.mntent->the_pvfs_config_server);
  238.         js_p->error_code = ret;
  239.         return SM_ACTION_COMPLETE;
  240.     }
  241.  
  242.     PINT_SERVREQ_GETCONFIG_FILL(msg_p->req, *sm_p->cred_p, sm_p->hints);
  243.  
  244.     msg_p->fs_id = PVFS_FS_ID_NULL;
  245.     msg_p->handle = PVFS_HANDLE_NULL;
  246.     msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
  247.     msg_p->comp_fn = server_get_config_comp_fn;
  248.     msg_p->svr_addr = serv_addr;
  249.  
  250.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  251.     js_p->error_code = 0;
  252.     return SM_ACTION_COMPLETE;
  253. }
  254.  
  255. static PINT_sm_action server_get_config_cleanup(
  256.         struct PINT_smcb *smcb, job_status_s *js_p)
  257. {
  258.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  259.     if (sm_p && !sm_p->u.get_config.persist_config_buffers)
  260.     {
  261.     free(sm_p->u.get_config.fs_config_buf);
  262.         sm_p->u.get_config.fs_config_buf = NULL;
  263.     }
  264.  
  265.     /* preserve js_p->error_code */
  266.  
  267.     return SM_ACTION_COMPLETE;
  268. }
  269.  
  270. static PINT_sm_action server_get_config_parse(
  271.         struct PINT_smcb *smcb, job_status_s *js_p)
  272. {
  273.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  274.     int ret = -1;
  275.     struct filesystem_configuration_s* cur_fs = NULL;
  276.  
  277.     if(sm_p->u.get_config.config)
  278.     {
  279.         ret = server_parse_config(
  280.             sm_p->u.get_config.config,  sm_p->u.get_config.fs_config_buf,
  281.             sm_p->u.get_config.fs_config_buf_size);
  282.         if (ret)
  283.         {
  284.             gossip_err("Failed to get_config from host %s\n",
  285.                        sm_p->u.get_config.mntent->the_pvfs_config_server); 
  286.             js_p->error_code = ret;
  287.             return SM_ACTION_COMPLETE;
  288.         }
  289.     }
  290.  
  291.     if(sm_p->u.get_config.mntent->fs_id == PVFS_FS_ID_NULL)
  292.     {
  293.         cur_fs = PINT_config_find_fs_name(sm_p->u.get_config.config, 
  294.             sm_p->u.get_config.mntent->pvfs_fs_name);
  295.         if (!cur_fs)
  296.         {
  297.             gossip_err("Warning:\n Cannot retrieve information about "
  298.                     "filesystem %s at tab entry: %s\n",
  299.                     sm_p->u.get_config.mntent->pvfs_fs_name,
  300.                     sm_p->u.get_config.mntent->the_pvfs_config_server);
  301.  
  302.             /*
  303.               if the device has no space left on it, we can't save
  304.               the config file for parsing and get a failure; make
  305.               a note of that possibility here
  306.             */ 
  307.             gossip_err("\nHINTS: If you're sure that your pvfstab file "
  308.                        "contains valid information,\n please make sure "
  309.                        "that you are not out of disk space and that you "
  310.                        "have\n write permissions in the current "
  311.                        "directory or in the /tmp directory\n\n");
  312.  
  313.             js_p->error_code = -PVFS_ENODEV;
  314.             return SM_ACTION_COMPLETE;
  315.         }
  316.  
  317.         sm_p->u.get_config.mntent->fs_id = cur_fs->coll_id;
  318.         cur_fs->flowproto = sm_p->u.get_config.mntent->flowproto;
  319.         cur_fs->encoding = sm_p->u.get_config.mntent->encoding;
  320.     }
  321.  
  322.     js_p->error_code = 0;
  323.     return SM_ACTION_COMPLETE;
  324. }
  325.  
  326.  
  327. static PINT_sm_action server_get_config_parent_cleanup(
  328.         struct PINT_smcb *smcb, job_status_s *js_p)
  329. {
  330.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  331.     sm_p->error_code  = js_p->error_code;
  332.     PINT_SET_OP_COMPLETE;
  333.  
  334.     return SM_ACTION_DEFERRED;
  335. }
  336.  
  337.  
  338. static int server_get_config_comp_fn(
  339.     void *v_p,
  340.     struct PVFS_server_resp *resp_p,
  341.     int i)
  342. {
  343.     PINT_smcb *smcb = v_p;
  344.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  345.  
  346.     /* only posted one msgpair */
  347.     assert(i==0);
  348.  
  349.     /* if this particular request was successful, then store the server
  350.      * response and let the caller sort it out */
  351.  
  352.     if (sm_p->msgarray_op.msgarray[i].op_status == 0)
  353.     {
  354.     sm_p->u.get_config.fs_config_buf = 
  355.         strdup(resp_p->u.getconfig.fs_config_buf);
  356.     sm_p->u.get_config.fs_config_buf_size = 
  357.         resp_p->u.getconfig.fs_config_buf_size;
  358.     }
  359.  
  360.     /* if this is the last response, check all of the status values
  361.      * and return error code if any requests failed
  362.      */
  363.     if (i == (sm_p->msgarray_op.count -1))
  364.     {
  365.         return PINT_msgarray_status(&sm_p->msgarray_op);
  366.     }
  367.     return 0;
  368. }
  369.         
  370. /*
  371.  * Local variables:
  372.  *  mode: c
  373.  *  c-indent-level: 4
  374.  *  c-basic-offset: 4
  375.  * End:
  376.  *
  377.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  378.  */
  379.