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 / server / final-response.sm < prev    next >
Text File  |  2008-11-19  |  8KB  |  254 lines

  1. /* 
  2.  * (C) 2001 Clemson University and The University of Chicago 
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7.  
  8. #include <string.h>
  9. #include <assert.h>
  10.  
  11. #include "server-config.h"
  12. #include "pvfs2-server.h"
  13. #include "pvfs2-attr.h"
  14. #include "pvfs2-internal.h"
  15. #include "pint-perf-counter.h"
  16.  
  17. /* final-response state machine:
  18.  * This is used as a nested state machine to perform two primary tasks:
  19.  * - release the operation from the request scheduler
  20.  * - send a response to the client
  21.  */
  22.  
  23. /* PRECONDITIONS:
  24.  * - the s_op->resp struct must be filled in with the response that
  25.  *   needs to be sent (not yet encoded), with one exception:
  26.  * - js_p->error_code must indicate the status value that you wish 
  27.  *   to have set in the response structure
  28.  * - if the operation has been scheduled, then the scheduled id must be
  29.  *   stored in s_op->scheduled_id
  30.  */
  31.  
  32. static void PINT_gossip_err_server_resp(
  33.     struct PVFS_server_resp *resp);
  34.  
  35. %%
  36.  
  37. nested machine pvfs2_final_response_sm
  38. {
  39.     state release
  40.     {
  41.         run final_response_release;
  42.         default => send_resp;
  43.     }
  44.  
  45.     state send_resp
  46.     {
  47.         run final_response_send_resp;
  48.         default => cleanup;
  49.     }
  50.  
  51.     state cleanup
  52.     {
  53.         run final_response_cleanup;
  54.         default => return;
  55.     }
  56. }
  57.  
  58. %%
  59.  
  60. /* final_response_release()
  61.  *
  62.  * releases the operation from the request scheduler
  63.  */
  64. static PINT_sm_action final_response_release(
  65.         struct PINT_smcb *smcb, job_status_s *js_p)
  66. {
  67.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  68.     int ret = -1;
  69.     job_id_t tmp_id;
  70.  
  71.     gossip_debug(GOSSIP_SERVER_DEBUG, 
  72.                  "(s_op %p) %s (FR sm) state: release: (error_code = %d)\n",
  73.                  s_op, PINT_map_server_op_to_string(s_op->req->op),
  74.                  js_p->error_code);
  75.  
  76.     /* this seems a little odd, but since this is the first state of the
  77.      * nested machine, now is the time to grab the error code if we
  78.      * are going to use it
  79.      */
  80.     /* NOTE: we filter out any subsystem mask and make sure that this
  81.      * shows up as a generic pvfs error on the client side
  82.      */
  83.     s_op->resp.status = -PVFS_ERROR_CODE(-js_p->error_code);
  84.  
  85.     /* catch cases in which the operation has not been scheduled */
  86.     if (!s_op->scheduled_id)
  87.     {
  88.         js_p->error_code = 0;
  89.         return SM_ACTION_COMPLETE;
  90.     }
  91.  
  92.     ret = job_req_sched_release(
  93.         s_op->scheduled_id, smcb, 0, js_p, &tmp_id, server_job_context);
  94.  
  95.     PINT_perf_count(PINT_server_pc, PINT_PERF_REQSCHED, 1, PINT_PERF_SUB);
  96.  
  97.     return ret;
  98. }
  99.  
  100. /* final_response_send_resp()
  101.  *
  102.  * encodes and sends a response to the client
  103.  */
  104. static PINT_sm_action final_response_send_resp(
  105.         struct PINT_smcb *smcb, job_status_s *js_p)
  106. {
  107.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  108.     int ret = -1;
  109.     job_id_t tmp_id;
  110.     struct server_configuration_s *user_opts = get_server_config_struct();
  111.     
  112.     gossip_debug(
  113.         GOSSIP_SERVER_DEBUG, 
  114.     "(s_op %p) %s (FR sm) state: send_resp (status = %d)\n",
  115.     s_op, PINT_map_server_op_to_string(s_op->req->op),
  116.     s_op->resp.status);
  117.  
  118.     if (js_p->error_code != 0)
  119.     {
  120.         gossip_lerr("Error: req_sched_release() failure; continuing...\n");
  121.     }
  122.  
  123.     ret = PINT_encode(&s_op->resp, PINT_ENCODE_RESP, &(s_op->encoded),
  124.                       s_op->addr, s_op->decoded.enc_type);
  125.     if (ret < 0)
  126.     {
  127.         gossip_lerr("Error: PINT_encode() failure.\n");
  128.         PINT_gossip_err_server_resp(&s_op->resp);
  129.  
  130.         js_p->error_code = ret;
  131.         return 1;
  132.     }
  133.  
  134.     /* send the response */
  135.     ret = job_bmi_send_list(
  136.         s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
  137.         s_op->encoded.list_count, s_op->encoded.total_size, s_op->tag,
  138.         s_op->encoded.buffer_type, 0, smcb, 0, js_p, &tmp_id,
  139.         server_job_context, user_opts->server_job_bmi_timeout,
  140.         s_op->req->hints);
  141.  
  142.     return ret;
  143. }
  144.  
  145.  
  146. /* final_response_cleanup()
  147.  *
  148.  * cleans up resources allocated while in this nested machine.  Right now 
  149.  * that just means releasing the encoding of the response
  150.  */
  151. static PINT_sm_action final_response_cleanup(
  152.         struct PINT_smcb *smcb, job_status_s *js_p)
  153. {
  154.     struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  155.     char status_string[64] = {0};
  156.  
  157.     gossip_debug(GOSSIP_SERVER_DEBUG, 
  158.                  "(s_op %p) %s (FR sm) state: cleanup\n",
  159.                  s_op, PINT_map_server_op_to_string(s_op->req->op));
  160.  
  161.     PVFS_strerror_r(s_op->resp.status, status_string, 64);
  162.     PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, "finish (%s)\n", status_string);
  163.  
  164.     PINT_encode_release(&s_op->encoded, PINT_ENCODE_RESP);
  165.  
  166.     js_p->error_code = 0;
  167.     return SM_ACTION_COMPLETE;
  168. }
  169.  
  170. static void PINT_gossip_err_server_resp(
  171.     struct PVFS_server_resp *resp)
  172. {
  173.     if (resp)
  174.     {
  175.         if (resp->op >= 0 && resp->op < PVFS_SERV_NUM_OPS)
  176.         {
  177.             gossip_err("Server Response %p is of type: %s\n",
  178.                        resp, PINT_map_server_op_to_string(resp->op));
  179.         }
  180.         else
  181.         {
  182.             gossip_err("Server Response %p is of type: UNKNOWN (op %d)\n",
  183.                        resp, resp->op);
  184.         }
  185.  
  186.         switch(resp->op)
  187.         {
  188.             case PVFS_SERV_GETATTR:
  189.             {
  190.                 PVFS_object_attr *attr = &resp->u.getattr.attr;
  191.                 switch(attr->objtype)
  192.                 {
  193.                     case PVFS_TYPE_METAFILE:
  194.                     {
  195.                         int i = 0;
  196.                         gossip_err(
  197.                             "METAFILE [ dist is %p, dist_size is %d,\n\t"
  198.                             "   dfile_array is %p, dfile_count is %d ]\n",
  199.                             attr->u.meta.dist, attr->u.meta.dist_size,
  200.                             attr->u.meta.dfile_array, 
  201.                             attr->u.meta.dfile_count);
  202.  
  203.                         if (attr->u.meta.dfile_array)
  204.                         {
  205.                             for(i = 0; i < attr->u.meta.dfile_count; i++)
  206.                             {
  207.                                 gossip_err("   DATA HANDLE[%d] is %llu\n", i,
  208.                                            llu(attr->u.meta.dfile_array[i]));
  209.                             }
  210.                         }
  211.                     }
  212.                     break;
  213.                     case PVFS_TYPE_DATAFILE:
  214.                         gossip_err("DATAFILE [ size is %lld ]\n",
  215.                                    lld(attr->u.data.size));
  216.                         break;
  217.                     case PVFS_TYPE_SYMLINK:
  218.                         gossip_err(
  219.                             "SYMLINK [ target is %s ; len is %d ]\n",
  220.                             attr->u.sym.target_path,
  221.                             attr->u.sym.target_path_len);
  222.                         break;
  223.                     case PVFS_TYPE_DIRECTORY:
  224.                         gossip_err("DIRECTORY [ n/a ]\n");
  225.                         break;
  226.                     case PVFS_TYPE_DIRDATA:
  227.                         gossip_err("DIRDATA [ n/a ]\n");
  228.                         break;
  229.                     case PVFS_TYPE_INTERNAL:
  230.                         gossip_err("INTERNAL [ n/a ]\n");
  231.                         break;
  232.                     case PVFS_TYPE_NONE:
  233.                         gossip_err("NONE [ n/a ]\n");
  234.                         break;
  235.                 }
  236.             }
  237.             break;
  238.             default:
  239.                 gossip_err("FIXME: unimplemented resp type to print\n");
  240.                 break;
  241.         }
  242.     }
  243. }
  244.  
  245. /*
  246.  * Local variables:
  247.  *  mode: c
  248.  *  c-indent-level: 4
  249.  *  c-basic-offset: 4
  250.  * End:
  251.  *
  252.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  253.  */
  254.