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 / sys-get-eattr.sm < prev    next >
Text File  |  2008-11-19  |  10KB  |  345 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. #include "pint-eattr.h"
  20.  
  21. extern job_context_id pint_client_sm_context;
  22.  
  23. static int get_eattr_comp_fn(
  24.     void *v_p,
  25.     struct PVFS_server_resp *resp_p,
  26.     int i);
  27.  
  28. %%
  29.  
  30. machine pvfs2_client_get_eattr_sm
  31. {
  32.     state setup_msgpair
  33.     {
  34.         run get_eattr_setup_msgpair;
  35.         success => xfer_msgpair;
  36.         default => cleanup;
  37.     }
  38.  
  39.     state xfer_msgpair
  40.     {
  41.         jump pvfs2_msgpairarray_sm;
  42.         default => cleanup;
  43.     }
  44.  
  45.     state cleanup
  46.     {
  47.         run get_eattr_cleanup;
  48.         default => terminate;
  49.     }
  50. }
  51.  
  52. %%
  53.  
  54. PVFS_error PVFS_isys_geteattr_list(
  55.         PVFS_object_ref ref,
  56.         const PVFS_credentials *credentials,
  57.         int32_t nkey,
  58.         PVFS_ds_keyval *key_array,
  59.         PVFS_sysresp_geteattr *resp_p,
  60.         PVFS_sys_op_id *op_id,
  61.         PVFS_hint hints,
  62.         void *user_ptr)
  63. {
  64.     int ret = -PVFS_EINVAL;
  65.     PINT_smcb *smcb = NULL;
  66.     PINT_client_sm *sm_p = NULL;
  67.  
  68.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  69.                  "PINT_isys_geteattr entered\n");
  70.  
  71.     if ((ref.handle == PVFS_HANDLE_NULL) ||
  72.        (ref.fs_id == PVFS_FS_ID_NULL) || (resp_p == NULL))
  73.     {
  74.         gossip_err("invalid (NULL) required argument\n");
  75.     return ret;
  76.     }
  77.  
  78.     PINT_smcb_alloc(&smcb, PVFS_SYS_GETEATTR,
  79.              sizeof(struct PINT_client_sm),
  80.              client_op_state_get_machine,
  81.              client_state_machine_terminate,
  82.              pint_client_sm_context);
  83.     if (smcb == NULL)
  84.     {
  85.         return -PVFS_ENOMEM;
  86.     }
  87.     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  88.  
  89.     PINT_init_msgarray_params(sm_p, ref.fs_id);
  90.     PINT_init_sysint_credentials(sm_p->cred_p, credentials);
  91.     sm_p->u.geteattr.nkey = nkey;
  92.     sm_p->u.geteattr.key_array = key_array;
  93.     sm_p->u.geteattr.resp_p = resp_p;
  94.     sm_p->error_code = 0;
  95.     sm_p->object_ref = ref;
  96.     PVFS_hint_copy(hints, &sm_p->hints);
  97.  
  98.     return PINT_client_state_machine_post(
  99.             smcb,  op_id, user_ptr);
  100. }
  101.  
  102. PVFS_error PVFS_sys_geteattr_list(
  103.         PVFS_object_ref ref,
  104.         const PVFS_credentials *credentials,
  105.         int32_t nkey,
  106.         PVFS_ds_keyval *key_array,
  107.         PVFS_sysresp_geteattr *resp_p,
  108.         PVFS_hint hints)
  109. {
  110.     PVFS_error ret = -PVFS_EINVAL, error = 0;
  111.     PVFS_sys_op_id op_id;
  112.  
  113.     gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_sys_geteattr entered\n");
  114.  
  115.     ret = PVFS_isys_geteattr_list(ref, credentials,
  116.             nkey, key_array, resp_p, &op_id, hints, NULL);
  117.  
  118.     if (ret)
  119.     {
  120.         PVFS_perror_gossip("PVFS_isys_geteattr call", ret);
  121.         error = ret;
  122.     }
  123.     else
  124.     {
  125.         ret = PVFS_sys_wait(op_id, "geteattr", &error);
  126.         if (ret)
  127.         {
  128.              PVFS_perror_gossip("PVFS_sys_wait call", ret);
  129.              error = ret;
  130.         }
  131.     }
  132.  
  133.     PINT_sys_release(op_id);
  134.     return error;
  135. }
  136.  
  137. PVFS_error PVFS_sys_geteattr(
  138.         PVFS_object_ref ref,
  139.         const PVFS_credentials *credentials,
  140.         PVFS_ds_keyval *key_p,
  141.         PVFS_ds_keyval *val_p,
  142.         PVFS_hint hints)
  143. {
  144.     PVFS_sysresp_geteattr resp_p;
  145.     PVFS_error tmp_err;
  146.     resp_p.val_array = val_p;
  147.     resp_p.err_array = &tmp_err;
  148.     return PVFS_sys_geteattr_list(ref, credentials, 1, key_p, &resp_p, hints);
  149. }
  150.  
  151. static PINT_sm_action get_eattr_setup_msgpair(
  152.         struct PINT_smcb *smcb, job_status_s *js_p)
  153. {
  154.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  155.     int ret = -PVFS_EINVAL;
  156.     int i;
  157.     PINT_sm_msgpair_state *msg_p;
  158.  
  159.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  160.         "get_eattr state: get_eattr_setup_msgpair\n");
  161.  
  162.     /* this will be the array of value buffer sizes */
  163.     sm_p->u.geteattr.size_array =
  164.              (PVFS_size *)malloc(sm_p->u.geteattr.nkey *
  165.                                  sizeof (PVFS_size));
  166.  
  167.     /* fill the array pulling out of the value array */
  168.     /* we don't want to send the unused fields in this array */
  169.     for (i = 0; i < sm_p->u.geteattr.nkey; i++)
  170.         sm_p->u.geteattr.size_array[i] =
  171.             sm_p->u.geteattr.resp_p->val_array[i].buffer_sz;
  172.  
  173.     PINT_msgpair_init(&sm_p->msgarray_op);
  174.     msg_p = &sm_p->msgarray_op.msgpair;
  175.  
  176.     PINT_SERVREQ_GETEATTR_FILL(
  177.         msg_p->req,
  178.         (*sm_p->cred_p),
  179.         sm_p->object_ref.fs_id,
  180.         sm_p->object_ref.handle,
  181.         sm_p->u.geteattr.nkey,
  182.         sm_p->u.geteattr.key_array,
  183.         sm_p->u.geteattr.size_array,
  184.         sm_p->hints);
  185.  
  186.     msg_p->fs_id = sm_p->object_ref.fs_id;
  187.     msg_p->handle = sm_p->object_ref.handle;
  188.     msg_p->retry_flag = PVFS_MSGPAIR_RETRY;
  189.     msg_p->comp_fn = get_eattr_comp_fn;
  190.  
  191.     ret = PINT_cached_config_map_to_server(
  192.             &msg_p->svr_addr,
  193.             msg_p->handle,
  194.             msg_p->fs_id);
  195.  
  196.     if (ret)
  197.     {
  198.         gossip_err("Failed to map meta server address\n");
  199.         js_p->error_code = 0;
  200.     }
  201.  
  202.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  203.     return SM_ACTION_COMPLETE;
  204. }
  205.  
  206. static PINT_sm_action get_eattr_cleanup(
  207.         struct PINT_smcb *smcb, job_status_s *js_p)
  208. {
  209.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  210.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  211.         "get_eattr state: get_eattr_cleanup\n");
  212.     /* free the array malloc'd above */
  213.     free(sm_p->u.geteattr.size_array);
  214.     sm_p->error_code  = js_p->error_code;
  215.     if(sm_p->error_code != 0)
  216.     {
  217.         PINT_acache_invalidate(sm_p->object_ref);
  218.     }
  219.  
  220.     PINT_SET_OP_COMPLETE;
  221.     return SM_ACTION_TERMINATE;
  222. }
  223.  
  224. static int get_eattr_comp_fn(
  225.     void *v_p,
  226.     struct PVFS_server_resp *resp_p,
  227.     int i)
  228. {
  229.     int j = 0;
  230.     int ret = 0;
  231.     int decode_ret;
  232.     PINT_smcb *smcb = v_p;
  233.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  234.  
  235.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  236.         "get_eattr completion fn: get_eattr_comp_fn\n");
  237.  
  238.     /* only posted one msgpair */
  239.     assert(i==0);
  240.  
  241.     /* if this particular request was successful, then store the server
  242.      * response and let the caller sort it out */
  243.  
  244.     /* recall that the returned val only has buffer and buffer_sz
  245.      * encoded across the wire ... so the buffer_sz is actually the
  246.      * read_sz ... the original buffer_sz is still in the original
  247.      * val struct the user passed in
  248.      */
  249.  
  250.     if (sm_p->msgarray_op.msgarray[i].op_status == 0)
  251.     {
  252.         int k, mink;
  253.         mink = sm_p->u.geteattr.nkey;
  254.         if (resp_p->u.geteattr.nkey < mink)
  255.         {
  256.             mink = resp_p->u.geteattr.nkey;
  257.             gossip_err("Successful call returned fewer values than requested\n");
  258.         }
  259.         if (!resp_p->u.geteattr.val)
  260.         {
  261.             gossip_err("Successful call returned NULL value list\n");
  262.             return -1;
  263.         }
  264.         gossip_debug(GOSSIP_GETEATTR_DEBUG,"returned %d values\n",
  265.                 sm_p->u.geteattr.nkey);
  266.         for (k = 0; k < sm_p->u.geteattr.nkey; k++)
  267.         {
  268.             gossip_debug(GOSSIP_GETEATTR_DEBUG,"resp_read_sz = %d\n",
  269.                     resp_p->u.geteattr.val[k].read_sz);
  270.             gossip_debug(GOSSIP_GETEATTR_DEBUG,"resp_buff_sz = %d\n",
  271.                     resp_p->u.geteattr.val[k].buffer_sz);
  272.             gossip_debug(GOSSIP_GETEATTR_DEBUG,"sm_buff_sz = %d\n",
  273.                     sm_p->u.geteattr.resp_p->val_array[k].buffer_sz);
  274.             gossip_debug(GOSSIP_GETEATTR_DEBUG,"resp_buff_ = %s\n",
  275.                     (char *)resp_p->u.geteattr.val[k].buffer);
  276.             /* out the actual read_sz in its place */
  277.             sm_p->u.geteattr.resp_p->val_array[k].read_sz =
  278.                     resp_p->u.geteattr.val[k].buffer_sz;
  279.             sm_p->u.geteattr.resp_p->err_array[k] =
  280.                     resp_p->u.geteattr.err[k];
  281.             /* check for too big a return message */
  282.             if(resp_p->u.geteattr.err[k] == 0)
  283.             {
  284.                 if (sm_p->u.geteattr.resp_p->val_array[k].read_sz <=
  285.                         sm_p->u.geteattr.resp_p->val_array[k].buffer_sz)
  286.                 {
  287.                     gossip_debug(GOSSIP_GETEATTR_DEBUG,"copying\n");
  288.                     memcpy(sm_p->u.geteattr.resp_p->val_array[k].buffer,
  289.                             resp_p->u.geteattr.val[k].buffer,
  290.                             sm_p->u.geteattr.resp_p->val_array[k].read_sz);
  291.                 }
  292.                 else /* oops, error! returned too much data */
  293.                 {
  294.                     gossip_debug(GOSSIP_GETEATTR_DEBUG,"clearing on error\n");
  295.                     memset(sm_p->u.geteattr.resp_p->val_array[k].buffer,0,
  296.                             sm_p->u.geteattr.resp_p->val_array[k].buffer_sz);
  297.                     /* record an error, but keep going */
  298.                     ret = -PVFS_EMSGSIZE;
  299.                 }
  300.  
  301.                 /* seems ok - decode the eattrs we know about */
  302.                 decode_ret = PINT_eattr_decode(
  303.                     &sm_p->u.geteattr.key_array[k],
  304.                     &sm_p->u.geteattr.resp_p->val_array[k]);
  305.                 if(decode_ret != 0)
  306.                 {
  307.                     gossip_debug(GOSSIP_GETATTR_DEBUG, 
  308.                                  "failed decode of eattr: %s\n",
  309.                                  (char *)sm_p->u.geteattr.key_array[k].buffer);
  310.                     return decode_ret;
  311.                 }
  312.             }
  313.         }
  314.     }
  315.     else
  316.     {
  317.         ret = sm_p->msgarray_op.msgarray[i].op_status;
  318.     }
  319.  
  320.     /* if this is the last response, check all of the status values
  321.      * and return error code if any requests failed
  322.      */
  323.     if (i == (sm_p->msgarray_op.count -1))
  324.     {
  325.     for (j=0; j < sm_p->msgarray_op.count; j++)
  326.     {
  327.         if (sm_p->msgarray_op.msgarray[j].op_status != 0)
  328.         {
  329.         return(sm_p->msgarray_op.msgarray[j].op_status);
  330.         }
  331.     }
  332.     }
  333.     return ret;
  334. }
  335.  
  336. /*
  337.  * Local variables:
  338.  *  mode: c
  339.  *  c-indent-level: 4
  340.  *  c-basic-offset: 4
  341.  * End:
  342.  *
  343.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  344.  */
  345.