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 / fs-add.sm < prev    next >
Text File  |  2010-04-30  |  22KB  |  719 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  *
  4.  * Changes by Acxiom Corporation to add support for nonblocking fs addition
  5.  * Copyright ⌐ Acxiom Corporation, 2006.
  6.  *
  7.  * See COPYING in top-level directory.
  8.  */
  9.  
  10. /** \file
  11.  *  \ingroup sysint
  12.  *
  13.  *  PVFS2 system interface bootstrapping routine to tell the interface
  14.  *  about available file systems.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #ifdef HAVE_MALLOC_H
  20. #include <malloc.h>
  21. #endif
  22. #include <errno.h>
  23. #include <assert.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26.  
  27. #include "acache.h"
  28. #include "ncache.h"
  29. #include "pint-cached-config.h"
  30. #include "pvfs2-sysint.h"
  31. #include "pvfs2-util.h"
  32. #include "pint-sysint-utils.h"
  33. #include "gen-locks.h"
  34. #include "PINT-reqproto-encode.h"
  35. #include "trove.h"
  36. #include "server-config-mgr.h"
  37. #include "client-state-machine.h"
  38. #include "pint-util.h"
  39.  
  40. enum {
  41.     SKIP_INTEGRITY_CHECK = 1
  42. };
  43.  
  44. gen_mutex_t mt_config = GEN_MUTEX_INITIALIZER;
  45. extern job_context_id pint_client_sm_context;
  46.  
  47. static int server_fetch_config_comp_fn(
  48.     void *v_p, struct PVFS_server_resp *resp_p, int i);
  49.  
  50. %%
  51.  
  52. machine pvfs2_fs_add_sm
  53. {
  54.     state run_nested 
  55.     {
  56.         jump pvfs2_server_get_config_nested_sm;
  57.         default => parent_cleanup;
  58.     }
  59.  
  60.     state parent_cleanup
  61.     {
  62.         run fs_add_parent_cleanup;
  63.         SKIP_INTEGRITY_CHECK => final_cleanup;
  64.         success => config_integrity_checks;
  65.         default => final_cleanup;
  66.     }
  67.  
  68.     state config_integrity_checks
  69.     {
  70.         run pvfs2_server_prepare_fetch_config;
  71.         SKIP_INTEGRITY_CHECK => final_cleanup;
  72.         success => do_config_integrity_checks;
  73.         default => final_cleanup;
  74.     }
  75.  
  76.     state do_config_integrity_checks
  77.     {
  78.         jump pvfs2_server_fetch_config_nested_sm;
  79.         default => compare_hashes;
  80.     }
  81.  
  82.     state compare_hashes
  83.     {
  84.         run fs_add_compare_hashes;
  85.         default => final_cleanup;
  86.     }
  87.  
  88.     state final_cleanup
  89.     {
  90.         run fs_add_final_cleanup;
  91.         default => terminate;
  92.     }
  93. }
  94.  
  95. nested machine pvfs2_server_fetch_config_nested_sm
  96. {
  97.     state fetch_setup_msgpair
  98.     {
  99.         run server_fetch_config_setup_msgpair;
  100.         success => fetch_xfer_msgpair;
  101.         default => fetch_cleanup;
  102.     }
  103.  
  104.     state fetch_xfer_msgpair
  105.     {
  106.         jump pvfs2_msgpairarray_sm;
  107.         default => fetch_cleanup;
  108.     }
  109.  
  110.     state fetch_cleanup
  111.     {
  112.         run server_fetch_config_cleanup;
  113.         default => return;
  114.     }
  115. }
  116.  
  117. %%
  118.  
  119. /** Tell the system interface about the location of a PVFS2 file system.
  120.  *
  121.  * \return 0 on success, -PVFS_error on failure.
  122.  */
  123. PVFS_error PVFS_isys_fs_add(
  124.     struct PVFS_sys_mntent *mntent,
  125.     PVFS_sys_op_id *op_id,
  126.     void* user_ptr)
  127. {
  128.     int ret = -PVFS_EINVAL;
  129.     int i;
  130.     struct server_configuration_s *new_server_config = NULL;
  131.     PVFS_BMI_addr_t test_addr;
  132.     PINT_smcb *smcb = NULL;
  133.     PINT_client_sm *sm_p = NULL;
  134.     PVFS_credentials creds;
  135.  
  136.     PVFS_util_gen_credentials(&creds);
  137.  
  138.     gen_mutex_lock(&mt_config);
  139.  
  140.     /* Normally the fs_id value has not been resolved yet at this point, and
  141.      * will be zero.  If it is a non-zero value (and this get_config call
  142.      * succeeds) then it indicates someone has already added this mntent
  143.      * instance.  It is ok to add the same _file system_ twice, but not the
  144.      * same mntent instance.
  145.      */
  146.     new_server_config = PINT_server_config_mgr_get_config(mntent->fs_id);
  147.     if (new_server_config)
  148.     {
  149.         PINT_server_config_mgr_put_config(new_server_config);
  150.         PVFS_perror_gossip("Attempted duplicate mntent addition", ret);
  151.         gen_mutex_unlock(&mt_config);
  152.         return -PVFS_EEXIST;
  153.     }
  154.  
  155.     /* make sure BMI knows how to handle this method, else fail quietly */
  156.     for(i = 0; i < mntent->num_pvfs_config_servers; i++)
  157.     {
  158.         ret = BMI_addr_lookup(&test_addr, mntent->pvfs_config_servers[i]);
  159.         if (ret == 0)
  160.         {
  161.             break;
  162.         }
  163.     }
  164.  
  165.     if (i == mntent->num_pvfs_config_servers)
  166.     {
  167.         gossip_err("%s: Failed to initialize any appropriate "
  168.                    "BMI methods for addresses:\n", __func__);
  169.         for(i = 0; i < mntent->num_pvfs_config_servers; ++i)
  170.         {
  171.             gossip_err("\t%s\n", mntent->pvfs_config_servers[i]);
  172.         }
  173.         gen_mutex_unlock(&mt_config);
  174.         return(ret);
  175.     }
  176.     mntent->the_pvfs_config_server = mntent->pvfs_config_servers[i];
  177.  
  178.     PINT_smcb_alloc(&smcb, PVFS_SYS_FS_ADD,
  179.              sizeof(struct PINT_client_sm),
  180.              client_op_state_get_machine,
  181.              client_state_machine_terminate,
  182.              pint_client_sm_context);
  183.     if (smcb == NULL)
  184.     {
  185.         return -PVFS_ENOMEM;
  186.     }
  187.     sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  188.  
  189.     sm_p->u.get_config.mntent = mntent;
  190.     sm_p->u.get_config.config = 
  191.         (struct server_configuration_s *)malloc(
  192.         sizeof(struct server_configuration_s));
  193.     if (!sm_p->u.get_config.config)
  194.     {
  195.         ret = -PVFS_ENOMEM;
  196.         PVFS_perror_gossip("Failed to allocate configuration object", ret);
  197.         gen_mutex_unlock(&mt_config);
  198.         return(ret);
  199.     }
  200.     memset(sm_p->u.get_config.config, 0, sizeof(struct server_configuration_s));
  201.  
  202.     /* NOTE: we set these fields manually here rather than use
  203.      * PINT_init_msgarray_params(), because we don't yet have a server
  204.      * configuration file to override default parameters.
  205.      */
  206.     sm_p->msgarray_op.params.job_context = pint_client_sm_context;
  207.     sm_p->msgarray_op.params.job_timeout = 30;   /* 30 second job timeout */
  208.     sm_p->msgarray_op.params.retry_delay = 2000; /* 2 second retry delay */
  209.     sm_p->msgarray_op.params.retry_limit = 5;    /* retry up to 5 times */
  210.  
  211.     PINT_msgpair_init(&sm_p->msgarray_op);
  212.     PINT_init_sysint_credentials(sm_p->cred_p, &creds);
  213.  
  214.     return PINT_client_state_machine_post(
  215.         smcb,  op_id, user_ptr);
  216. }
  217.  
  218. int PVFS_sys_fs_add(struct PVFS_sys_mntent *mntent)
  219. {
  220.     int ret = -PVFS_EINVAL, error = 0;
  221.     PVFS_sys_op_id op_id;
  222.  
  223.     ret = PVFS_isys_fs_add(mntent, &op_id, NULL);
  224.     if (ret)
  225.     {
  226.         PVFS_perror_gossip("PVFS_isys_fs_add call", ret);
  227.         error = ret;
  228.     }
  229.     else
  230.     {
  231.         ret = PVFS_sys_wait(op_id, "fs_add", &error);
  232.         if (ret)
  233.         {
  234.             PVFS_perror_gossip("PVFS_sys_wait call", ret);
  235.             error = ret;
  236.         }
  237.     }
  238.  
  239.     PINT_sys_release(op_id);
  240.     return error;
  241. }
  242.  
  243. /* PVFS_sys_fs_remove()
  244.  *
  245.  * tells the system interface to dynamically "unmount" a mounted file
  246.  * system by removing the configuration info and reloading the cached
  247.  * configuration interface
  248.  *
  249.  * returns 0 on success, -PVFS_error on failure
  250.  */
  251. int PVFS_sys_fs_remove(struct PVFS_sys_mntent *mntent)
  252. {
  253.     int ret = -PVFS_EINVAL;
  254.  
  255.     if (mntent)
  256.     {
  257.         gen_mutex_lock(&mt_config);
  258.         ret = PVFS_util_remove_internal_mntent(mntent);
  259.         if (ret == 0)
  260.         {
  261.             ret = PINT_server_config_mgr_remove_config(mntent->fs_id);
  262.             if (ret < 0)
  263.             {
  264.                 PVFS_perror_gossip("PINT_server_config_mgr_remove_config "
  265.                             "failed", ret);
  266.             }
  267.  
  268.             /*
  269.               reload all handle mappings as well as the interface with
  270.               the new configuration information
  271.             */
  272.             PINT_server_config_mgr_reload_cached_config_interface();
  273.         }
  274.         gen_mutex_unlock(&mt_config);
  275.     }
  276.     return ret;
  277. }
  278.  
  279. static PINT_sm_action pvfs2_server_prepare_fetch_config(
  280.     struct PINT_smcb *smcb, job_status_s *js_p)
  281. {
  282.     PVFS_fs_id fsid;
  283.     int count, ret;
  284.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  285.  
  286.     assert(js_p->error_code == 0);
  287.     fsid = sm_p->u.get_config.mntent->fs_id;
  288.     ret = PVFS_mgmt_count_servers(
  289.         fsid, sm_p->cred_p, PVFS_MGMT_IO_SERVER | PVFS_MGMT_META_SERVER, &count);
  290.     if (ret < 0)
  291.     {
  292.     PVFS_perror("PVFS_mgmt_count_servers()", ret);
  293.         js_p->error_code = ret;
  294.     return SM_ACTION_COMPLETE;
  295.     }
  296.     if (count == 1)
  297.     {
  298.         js_p->error_code = SKIP_INTEGRITY_CHECK;
  299.     return SM_ACTION_COMPLETE;
  300.     }
  301.     sm_p->fetch_config.nservers = count;
  302.     sm_p->fetch_config.addr_array = (PVFS_BMI_addr_t *) malloc(count * sizeof(PVFS_BMI_addr_t));
  303.     if (sm_p->fetch_config.addr_array == NULL)
  304.     {
  305.     perror("malloc");
  306.     js_p->error_code = -PVFS_ENOMEM;
  307.         return SM_ACTION_COMPLETE;
  308.     }
  309.  
  310.     ret = PVFS_mgmt_get_server_array(fsid, sm_p->cred_p, 
  311.             PVFS_MGMT_IO_SERVER | PVFS_MGMT_META_SERVER, sm_p->fetch_config.addr_array, &count);
  312.     if (ret < 0)
  313.     {
  314.     PVFS_perror("PVFS_mgmt_get_server_array()", ret);
  315.         free(sm_p->fetch_config.addr_array);
  316.         sm_p->fetch_config.addr_array = NULL;
  317.     js_p->error_code = ret;
  318.         return SM_ACTION_COMPLETE;
  319.     }
  320.     sm_p->fetch_config.fs_config_bufs = (char **) calloc(count, sizeof(char *));
  321.     if (sm_p->fetch_config.fs_config_bufs == NULL)
  322.     {
  323.         fprintf(stderr, "Could not allocate fs_configs\n");
  324.         free(sm_p->fetch_config.addr_array);
  325.         sm_p->fetch_config.addr_array = NULL;
  326.         js_p->error_code = -PVFS_ENOMEM;
  327.         return SM_ACTION_COMPLETE;
  328.     }
  329.     sm_p->fetch_config.fs_config_buf_size = (int *) calloc(count, sizeof(int));
  330.     if (sm_p->fetch_config.fs_config_buf_size == NULL)
  331.     {
  332.         fprintf(stderr, "Could not allocate fs_sizes\n");
  333.         free(sm_p->fetch_config.addr_array);
  334.         sm_p->fetch_config.addr_array = NULL;
  335.         free(sm_p->fetch_config.fs_config_bufs);
  336.         sm_p->fetch_config.fs_config_bufs = NULL;
  337.         js_p->error_code = -PVFS_ENOMEM;
  338.         return SM_ACTION_COMPLETE;
  339.     }
  340.  
  341.     ret = PINT_msgpairarray_init(&sm_p->msgarray_op, count);
  342.     if (ret != 0)
  343.     {
  344.         fprintf(stderr, "Could not allocate msgarray for fetch_config\n");
  345.         free(sm_p->fetch_config.addr_array);
  346.         sm_p->fetch_config.addr_array = NULL;
  347.         free(sm_p->fetch_config.fs_config_bufs);
  348.         sm_p->fetch_config.fs_config_bufs = NULL;
  349.         free(sm_p->fetch_config.fs_config_buf_size);
  350.         sm_p->fetch_config.fs_config_buf_size = NULL;
  351.         js_p->error_code = ret;
  352.         return SM_ACTION_COMPLETE;
  353.     }
  354.  
  355.     sm_p->fetch_config.result_indexes = (int*)calloc(count,
  356.         sizeof(int));
  357.     if(sm_p->fetch_config.result_indexes == NULL)
  358.     {
  359.         free(sm_p->fetch_config.addr_array);
  360.         sm_p->fetch_config.addr_array = NULL;
  361.         free(sm_p->fetch_config.fs_config_bufs);
  362.         sm_p->fetch_config.fs_config_bufs = NULL;
  363.         free(sm_p->fetch_config.fs_config_buf_size);
  364.         sm_p->fetch_config.fs_config_buf_size = NULL;
  365.         free(sm_p->fetch_config.result_indexes);
  366.         sm_p->fetch_config.result_indexes = NULL;
  367.         js_p->error_code = -PVFS_ENOMEM;
  368.         return SM_ACTION_COMPLETE;
  369.     }
  370.  
  371.     js_p->error_code = 0;
  372.     return SM_ACTION_COMPLETE;
  373. }
  374.  
  375. static void hash2str(unsigned char *hash, int hash_length, unsigned char *str)
  376. {
  377.     int i, count = 0;
  378.  
  379.     if (!str || !hash || hash_length < 0) 
  380.     {
  381.         return;
  382.     }
  383.     for (i = 0; i < hash_length; i++) 
  384.     {
  385.         int cnt;
  386.         cnt = sprintf((char *)str + count, "%02x", hash[i]);
  387.         count += cnt;
  388.     }
  389.     return;
  390. }
  391.  
  392. static int compare_hashes(PINT_client_sm *sm_p, job_status_s *js_p)
  393. {
  394.     int i, count, ret = 0, fs_conf_failed = 0, fs_conf_size_mismatch = 0, tmp;
  395.     char **sha1_fs_digests = NULL;
  396.     size_t digest_len;
  397.     PVFS_fs_id fsid;
  398.     int* indexes = sm_p->fetch_config.result_indexes;
  399.  
  400.     count = sm_p->fetch_config.result_count;
  401.     if(count < 2)
  402.     {
  403.         /* nothing to compare */
  404.         goto out;
  405.     }
  406.  
  407.     fsid = sm_p->u.get_config.mntent->fs_id;
  408.     sha1_fs_digests = (char **) calloc(count, sizeof(char *));
  409.     if (sha1_fs_digests == NULL)
  410.     {
  411.         ret = -PVFS_ENOMEM;
  412.         goto out;
  413.     }
  414.     for (i = 1; i < count; i++)
  415.     {
  416.         if (sm_p->fetch_config.fs_config_buf_size[indexes[0]] !=
  417.             sm_p->fetch_config.fs_config_buf_size[indexes[i]])
  418.         {
  419.             fs_conf_size_mismatch = 1;
  420.         }
  421.     }
  422.     if (fs_conf_size_mismatch)
  423.     {
  424.         gossip_err("      FS config file integrity checks failed;\n");
  425.         for (i = 0; i < count; i++)
  426.         {
  427.             gossip_err("     FS config file on %s -> (size) %d\n", 
  428.                    PVFS_mgmt_map_addr(fsid, sm_p->cred_p,
  429.                    sm_p->fetch_config.addr_array[indexes[i]], &tmp),
  430.                    sm_p->fetch_config.fs_config_buf_size[indexes[i]] - 1);
  431.             ret = -PVFS_EINVAL;
  432.         }
  433.         goto out;
  434.     }
  435.     for (i = 0; i < count; i++)
  436.     {
  437.         ret =
  438.         PINT_util_digest_sha1(sm_p->fetch_config.fs_config_bufs[indexes[i]], 
  439.                                     sm_p->fetch_config.fs_config_buf_size[indexes[i]],
  440.                                     &sha1_fs_digests[i], &digest_len);
  441.         if (ret < 0)
  442.             goto out;
  443.     }
  444.     ret = 0;
  445.     for (i = 1; i < count; i++) 
  446.     {
  447.         if (memcmp(sha1_fs_digests[0], sha1_fs_digests[i], digest_len))
  448.         {
  449.             fs_conf_failed = 1;
  450.         }
  451.     }
  452.     if (fs_conf_failed)
  453.     {
  454.         gossip_err("    FS config file integrity checks failed;\n");
  455.         for (i = 0; i < count; i++)
  456.         {
  457.             unsigned char str[256];
  458.             hash2str((unsigned char *) sha1_fs_digests[i], digest_len, str);
  459.             gossip_err("     FS config file on %s -> (SHA1) %s\n", 
  460.                    PVFS_mgmt_map_addr(fsid, sm_p->cred_p,
  461.                    sm_p->fetch_config.addr_array[indexes[i]], &tmp), str);
  462.         }
  463.         ret = -PVFS_EINVAL;
  464.         goto out;
  465.     }
  466. out:
  467.     for (i = 0; i < count; i++)
  468.     {
  469.         if (sm_p->fetch_config.fs_config_bufs && sm_p->fetch_config.fs_config_bufs[i])
  470.             free(sm_p->fetch_config.fs_config_bufs[i]);
  471.         if (sha1_fs_digests && sha1_fs_digests[i])
  472.             free(sha1_fs_digests[i]);
  473.     }
  474.     free(sha1_fs_digests);
  475.     free(sm_p->fetch_config.addr_array);
  476.     sm_p->fetch_config.addr_array = NULL;
  477.     free(sm_p->fetch_config.fs_config_bufs);
  478.     sm_p->fetch_config.fs_config_bufs = NULL;
  479.     free(sm_p->fetch_config.result_indexes);
  480.     sm_p->fetch_config.result_indexes = NULL;
  481.     free(sm_p->fetch_config.fs_config_buf_size);
  482.     sm_p->fetch_config.fs_config_buf_size = NULL;
  483.     js_p->error_code = (ret == -PVFS_EOPNOTSUPP) ? 0 : ret;
  484.     return 1;
  485. }
  486.  
  487. static PINT_sm_action fs_add_parent_cleanup(struct PINT_smcb *smcb, job_status_s *js_p)
  488. {
  489.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  490.     int ret = -PVFS_EINVAL;
  491.     PVFS_BMI_addr_t addr;
  492.  
  493.  
  494.     if(js_p->error_code != 0)
  495.     {
  496.         gen_mutex_unlock(&mt_config);
  497.         PINT_config_release(sm_p->u.get_config.config);
  498.         free(sm_p->u.get_config.config);
  499.         return SM_ACTION_COMPLETE;
  500.     }
  501.  
  502. #ifdef USE_TRUSTED
  503.     /* once we know about the server configuration, we need to tell BMI */
  504.     BMI_set_info(0, BMI_TRUSTED_CONNECTION, (void *)sm_p->u.get_config.config);
  505.     gossip_debug(GOSSIP_SERVER_DEBUG, "Enabling trusted connections!\n");
  506. #endif
  507.     /* Set the buffer size according to configuration file */
  508.     BMI_set_info(0, BMI_TCP_BUFFER_SEND_SIZE, 
  509.                  (void *)&sm_p->u.get_config.config->tcp_buffer_size_send);
  510.     BMI_set_info(0, BMI_TCP_BUFFER_RECEIVE_SIZE, 
  511.                  (void *)&sm_p->u.get_config.config->tcp_buffer_size_receive);
  512.     /*
  513.      * Force the connection to the config server down so future transfers
  514.      * will get the new buffer size.
  515.      */
  516.     ret = BMI_addr_lookup(&addr,
  517.                           sm_p->u.get_config.mntent->the_pvfs_config_server);
  518.     if (ret == 0 && 
  519.         sm_p->u.get_config.config->tcp_buffer_size_send != 0 &&
  520.         sm_p->u.get_config.config->tcp_buffer_size_receive != 0)
  521.         BMI_set_info(addr, BMI_TCP_CLOSE_SOCKET, NULL);
  522.  
  523.     /* 
  524.       clear out all configuration information about file systems that
  525.       aren't matching the one being added now.  this ensures no
  526.       erroneous handle mappings are added next
  527.     */
  528.     ret = PINT_config_trim_filesystems_except(
  529.         sm_p->u.get_config.config, sm_p->u.get_config.mntent->fs_id);
  530.     if (ret < 0)
  531.     {
  532.         PVFS_perror_gossip(
  533.             "PINT_config_trim_filesystems_except failed", ret);
  534.         gen_mutex_unlock(&mt_config);
  535.         PINT_config_release(sm_p->u.get_config.config);
  536.         free(sm_p->u.get_config.config);
  537.         js_p->error_code  = ret;
  538.         return SM_ACTION_COMPLETE;
  539.     }
  540.  
  541.     /*
  542.       add the mntent to the internal mount tables; it's okay if it's
  543.       already there, as the return value will tell us and we can
  544.       ignore it.  in short, if the mntent was from a pvfstab file, it
  545.       should already exist in the tables.  in any other case, it needs
  546.       to be added properly.
  547.     */
  548.     ret = PVFS_util_add_dynamic_mntent(sm_p->u.get_config.mntent);
  549.     if (ret < 0)
  550.     {
  551.         PVFS_perror_gossip("PVFS_util_add_mnt failed", ret);
  552.         gen_mutex_unlock(&mt_config);
  553.         PINT_config_release(sm_p->u.get_config.config);
  554.         free(sm_p->u.get_config.config);
  555.         js_p->error_code  = ret;
  556.         return SM_ACTION_COMPLETE;
  557.     }
  558.  
  559.     /* finally, try to add the new config to the server config manager */
  560.     ret = PINT_server_config_mgr_add_config(
  561.         sm_p->u.get_config.config, sm_p->u.get_config.mntent->fs_id,
  562.         &sm_p->u.get_config.free_config_flag);
  563.     if (ret < 0)
  564.     {
  565.         PVFS_perror_gossip("PINT_server_config_mgr_add_config failed", ret);
  566.         gen_mutex_unlock(&mt_config);
  567.         PINT_config_release(sm_p->u.get_config.config);
  568.         free(sm_p->u.get_config.config);
  569.         js_p->error_code  = ret;
  570.         return SM_ACTION_COMPLETE;
  571.     }
  572.  
  573.     /*
  574.       reload all handle mappings as well as the interface with the new
  575.       configuration information
  576.     */
  577.     PINT_server_config_mgr_reload_cached_config_interface();
  578.  
  579.     gen_mutex_unlock(&mt_config);
  580.  
  581.     /* If fs_add indicates a need for checking integrity of config
  582.        files do so, else skip 
  583.      */
  584.     js_p->error_code = (sm_p->u.get_config.mntent->integrity_check == 0)
  585.                         ? SKIP_INTEGRITY_CHECK : 0;
  586.     return SM_ACTION_COMPLETE;
  587. }
  588.  
  589. static PINT_sm_action fs_add_compare_hashes(
  590.     struct PINT_smcb *smcb, job_status_s *js_p)
  591. {
  592.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  593.  
  594.     if (js_p->error_code == SKIP_INTEGRITY_CHECK)
  595.         js_p->error_code = 0;
  596.     else
  597.     {
  598.         compare_hashes(sm_p, js_p);
  599.     }
  600.  
  601.     return SM_ACTION_COMPLETE;
  602. }
  603.  
  604. static PINT_sm_action fs_add_final_cleanup(
  605.     struct PINT_smcb *smcb, job_status_s *js_p)
  606. {
  607.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  608.     if(sm_p->u.get_config.free_config_flag)
  609.     {
  610.         PINT_config_release(sm_p->u.get_config.config);
  611.         free(sm_p->u.get_config.config);
  612.     }
  613.     if (js_p->error_code == SKIP_INTEGRITY_CHECK)
  614.         js_p->error_code = 0;
  615.     sm_p->error_code = js_p->error_code;
  616.     PINT_SET_OP_COMPLETE;
  617.     return SM_ACTION_TERMINATE;
  618. }
  619.  
  620. static PINT_sm_action server_fetch_config_setup_msgpair(struct PINT_smcb *smcb,
  621.                                            job_status_s *js_p)
  622. {
  623.     int i;
  624.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  625.     PINT_sm_msgpair_state *msg_p = NULL;
  626.  
  627.     gossip_debug(GOSSIP_CLIENT_DEBUG,
  628.         "fetch_config state: server_fetch_config_setup_msgpair\n");
  629.  
  630.     foreach_msgpair(&sm_p->msgarray_op, msg_p, i)
  631.     {
  632.         sm_p->msgarray_op.msgarray[i].enc_type = sm_p->msgarray_op.msgpair.enc_type;
  633.         PINT_SERVREQ_GETCONFIG_FILL(msg_p->req, *sm_p->cred_p, sm_p->hints);
  634.  
  635.         msg_p->fs_id = PVFS_FS_ID_NULL;
  636.         msg_p->handle = PVFS_HANDLE_NULL;
  637.         /* only try once to retrieve a config file from each server */
  638.         msg_p->retry_flag = PVFS_MSGPAIR_NO_RETRY;
  639.         msg_p->comp_fn = server_fetch_config_comp_fn;
  640.         msg_p->svr_addr = sm_p->fetch_config.addr_array[i];
  641.     }
  642.     /* don't complain so much about servers we can't reach yet */
  643.     sm_p->msgarray_op.params.quiet_flag = 1; 
  644.  
  645.     js_p->error_code = 0;
  646.  
  647.     PINT_sm_push_frame(smcb, 0, &sm_p->msgarray_op);
  648.     return SM_ACTION_COMPLETE;
  649. }
  650.  
  651. static PINT_sm_action server_fetch_config_cleanup(struct PINT_smcb *smcb,
  652.                                     job_status_s *js_p)
  653. {
  654.     struct PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
  655.     PINT_msgpairarray_destroy(&sm_p->msgarray_op);
  656.     /* preserve js_p->error_code */
  657.  
  658.     return SM_ACTION_COMPLETE;
  659. }
  660.  
  661. static int server_fetch_config_comp_fn(
  662.     void *v_p,
  663.     struct PVFS_server_resp *resp_p,
  664.     int i)
  665. {
  666.     PINT_smcb *smcb = v_p;
  667.     PINT_client_sm *sm_p = PINT_sm_frame(smcb, PINT_MSGPAIR_PARENT_SM);
  668.     int j;
  669.  
  670.     /* if this particular request was successful, then store the server
  671.      * response and let the caller sort it out */
  672.  
  673.     if (sm_p->msgarray_op.msgarray[i].op_status == 0)
  674.     {
  675.     sm_p->fetch_config.fs_config_bufs[i] = 
  676.         strdup(resp_p->u.getconfig.fs_config_buf);
  677.     sm_p->fetch_config.fs_config_buf_size[i] = 
  678.         resp_p->u.getconfig.fs_config_buf_size;
  679.     }
  680.  
  681.     /* is this this last response? */
  682.     if (i == (sm_p->msgarray_op.count -1))
  683.     {
  684.         /* look through responses, count the number of valid responses we
  685.          * received, and mark where they are in the array
  686.          */
  687.         sm_p->fetch_config.result_count = 0;
  688.         for(j=0; j<sm_p->msgarray_op.count; j++)
  689.         {
  690.             if(sm_p->msgarray_op.msgarray[j].op_status == 0)
  691.             {
  692.                 sm_p->fetch_config.result_indexes[sm_p->fetch_config.result_count]
  693.                     = j;
  694.                 sm_p->fetch_config.result_count++;
  695.             }
  696.         }
  697.         if(sm_p->fetch_config.result_count > 0)
  698.         {
  699.             /* we got at least one config file */
  700.             return(0);
  701.         }
  702.         else
  703.         {
  704.             /* pick an error code */
  705.             return PINT_msgarray_status(&sm_p->msgarray_op);
  706.         }
  707.     }
  708.     return 0;
  709. }
  710.  
  711. /*
  712.  * Local variables:
  713.  *  c-indent-level: 4
  714.  *  c-basic-offset: 4
  715.  * End:
  716.  *
  717.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  718.  */
  719.