[PVFS2-CVS] commit by pcarns in pvfs2/src/common/misc: pint-cached-config.c pint-cached-config.h module.mk.in server-config-mgr.c

CVS commit program cvs at parl.clemson.edu
Thu Jul 8 17:06:52 EDT 2004


Update of /projects/cvsroot/pvfs2/src/common/misc
In directory parlweb:/tmp/cvs-serv13399/src/common/misc

Modified Files:
	module.mk.in server-config-mgr.c 
Added Files:
	pint-cached-config.c pint-cached-config.h 
Log Message:
move pint-bucket.[ch] to common subdir and rename to
pint-cached-config.[ch]; still need to rename api


--- /dev/null	2003-01-30 05:24:37.000000000 -0500
+++ pint-cached-config.c	2004-07-08 16:06:52.000000000 -0400
@@ -0,0 +1,1096 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "pvfs2-types.h"
+#include "pvfs2-attr.h"
+#include "pint-sysint-utils.h"
+#include "bmi.h"
+#include "dotconf.h"
+#include "trove.h"
+#include "server-config.h"
+#include "llist.h"
+#include "quickhash.h"
+#include "extent-utils.h"
+#include "pint-cached-config.h"
+
+struct qhash_table *PINT_fsid_config_cache_table = NULL;
+
+/* these are based on code from src/server/request-scheduler.c */
+static int hash_fsid(
+    void *fsid, int table_size);
+static int hash_fsid_compare(
+    void *key, struct qlist_head *link);
+
+static void free_host_extent_table(void *ptr);
+static int cache_server_array(
+    struct server_configuration_s *config, PVFS_fs_id fsid);
+
+
+/* PINT_bucket_initialize()
+ *
+ * initializes the bucket interface
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_initialize(void)
+{
+    if (!PINT_fsid_config_cache_table)
+    {
+        PINT_fsid_config_cache_table =
+            qhash_init(hash_fsid_compare,hash_fsid,11);
+    }
+    srand((unsigned int)time(NULL));
+    return (PINT_fsid_config_cache_table ? 0 : -PVFS_ENOMEM);
+}
+
+/* PINT_bucket_finalize()
+ *
+ * shuts down the bucket interface and releases any resources
+ * associated with it.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_finalize(void)
+{
+    int i = 0;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    /* if we haven't been initialized yet, just return success */
+    if (!PINT_fsid_config_cache_table)
+    {
+        return 0;
+    }
+
+    /*
+      this is an exhaustive and slow iterate.  speed this up if
+      'finalize' is something that will be done frequently.
+    */
+    for (i = 0; i < PINT_fsid_config_cache_table->table_size; i++)
+    {
+        do
+        {
+            hash_link = qhash_search_and_remove_at_index(
+                PINT_fsid_config_cache_table, i);
+            if (hash_link)
+            {
+                cur_config_cache = qlist_entry(
+                    hash_link, struct config_fs_cache_s, hash_link);
+
+                assert(cur_config_cache);
+                assert(cur_config_cache->fs);
+                assert(cur_config_cache->bmi_host_extent_tables);
+
+                /* fs object is freed by PINT_config_release */
+                cur_config_cache->fs = NULL;
+                PINT_llist_free(cur_config_cache->bmi_host_extent_tables,
+                                free_host_extent_table);
+
+                /* if the 'cached server arrays' are used, free them */
+                if (cur_config_cache->io_server_count &&
+                    cur_config_cache->io_server_array)
+                {
+                    free(cur_config_cache->io_server_array);
+                    cur_config_cache->io_server_array = NULL;
+                }
+
+                if (cur_config_cache->meta_server_count &&
+                    cur_config_cache->meta_server_array)
+                {
+                    free(cur_config_cache->meta_server_array);
+                    cur_config_cache->meta_server_array = NULL;
+                }
+
+                if (cur_config_cache->server_count &&
+                    cur_config_cache->server_array)
+                {
+                    free(cur_config_cache->server_array);
+                    cur_config_cache->server_array = NULL;
+                }
+
+                free(cur_config_cache);
+            }
+        } while(hash_link);
+    }
+    qhash_finalize(PINT_fsid_config_cache_table);
+    PINT_fsid_config_cache_table = NULL;
+
+    return 0;
+}
+
+int PINT_bucket_reinitialize(struct server_configuration_s *config)
+{
+    int ret = -PVFS_EINVAL;
+    PINT_llist *cur = NULL;
+    struct filesystem_configuration_s *cur_fs = NULL;
+
+    PINT_bucket_finalize();
+
+    ret = PINT_bucket_initialize();
+    if (ret == 0)
+    {
+        cur = config->file_systems;
+        while(cur)
+        {
+            cur_fs = PINT_llist_head(cur);
+            if (!cur_fs)
+            {
+                break;
+            }
+
+            ret = PINT_handle_load_mapping(config, cur_fs);
+            if (ret)
+            {
+                break;
+            }
+            cur = PINT_llist_next(cur);
+        }
+    }
+    return 0;
+}
+
+/* PINT_handle_load_mapping()
+ *
+ * loads a new mapping of servers to handle into this interface.  This
+ * function may be called multiple times in order to add new file
+ * system information at run time.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_handle_load_mapping(
+    struct server_configuration_s *config,
+    struct filesystem_configuration_s *fs)
+{
+    int ret = -PVFS_EINVAL;
+    PINT_llist *cur = NULL;
+    struct host_handle_mapping_s *cur_mapping = NULL;
+    struct config_fs_cache_s *cur_config_fs_cache = NULL;
+    struct bmi_host_extent_table_s *cur_host_extent_table = NULL;
+
+    if (config && fs)
+    {
+        cur_config_fs_cache = (struct config_fs_cache_s *)
+            malloc(sizeof(struct config_fs_cache_s));
+        assert(cur_config_fs_cache);
+        memset(cur_config_fs_cache, 0, sizeof(struct config_fs_cache_s));
+
+        cur_config_fs_cache->fs = (struct filesystem_configuration_s *)fs;
+        cur_config_fs_cache->meta_server_cursor = NULL;
+        cur_config_fs_cache->data_server_cursor = NULL;
+        cur_config_fs_cache->bmi_host_extent_tables = PINT_llist_new();
+        assert(cur_config_fs_cache->bmi_host_extent_tables);
+
+        /*
+          map all meta and data handle ranges to the extent list, if any.
+          map_handle_range_to_extent_list is a macro defined in
+          pint-cached-config.h for convenience only.
+        */
+        assert(cur_config_fs_cache->fs->meta_handle_ranges);
+        map_handle_range_to_extent_list(
+            cur_config_fs_cache->fs->meta_handle_ranges);
+
+        assert(cur_config_fs_cache->fs->data_handle_ranges);
+        map_handle_range_to_extent_list(
+            cur_config_fs_cache->fs->data_handle_ranges);
+
+        /*
+          add config cache object to the hash table that maps fsid to
+          a config_fs_cache_s.  NOTE: the
+          'map_handle_range_to_extent_list' can set ret to -ENOMEM, so
+          check for that here.
+        */
+        if (ret != -ENOMEM)
+        {
+            cur_config_fs_cache->meta_server_cursor =
+                cur_config_fs_cache->fs->meta_handle_ranges;
+            cur_config_fs_cache->data_server_cursor =
+                cur_config_fs_cache->fs->data_handle_ranges;
+
+            qhash_add(PINT_fsid_config_cache_table,
+                      &(cur_config_fs_cache->fs->coll_id),
+                      &(cur_config_fs_cache->hash_link));
+
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_next_meta()
+ *
+ * returns the bmi address of a random server that should be used to
+ * store a new piece of metadata.  This function is responsible for
+ * fairly distributing the metadata storage responsibility to all
+ * servers.
+ *
+ * in addition, a handle range is returned as an array of extents that
+ * match the meta handle range configured for the returned meta
+ * server.  This array MUST NOT be freed by the caller, nor cached for
+ * later use.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_next_meta(
+    struct server_configuration_s *config,
+    PVFS_fs_id fsid,
+    PVFS_BMI_addr_t *meta_addr,
+    PVFS_handle_extent_array *ext_array)
+{
+    int ret = -PVFS_EINVAL, jitter = 0, num_meta_servers = 0;
+    char *meta_server_bmi_str = NULL;
+    struct host_handle_mapping_s *cur_mapping = NULL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (config && meta_addr && ext_array)
+    {
+        hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+        if (hash_link)
+        {
+            cur_config_cache = qlist_entry(
+                hash_link, struct config_fs_cache_s, hash_link);
+
+            assert(cur_config_cache);
+            assert(cur_config_cache->fs);
+            assert(cur_config_cache->meta_server_cursor);
+
+            num_meta_servers = PINT_llist_count(
+                cur_config_cache->fs->meta_handle_ranges);
+
+            jitter = (rand() % num_meta_servers);
+            while(jitter-- > -1)
+            {
+                cur_mapping = PINT_llist_head(
+                    cur_config_cache->meta_server_cursor);
+                if (!cur_mapping)
+                {
+                    cur_config_cache->meta_server_cursor =
+                        cur_config_cache->fs->meta_handle_ranges;
+                    cur_mapping = PINT_llist_head(
+                        cur_config_cache->meta_server_cursor);
+                    assert(cur_mapping);
+                }
+                cur_config_cache->meta_server_cursor = PINT_llist_next(
+                    cur_config_cache->meta_server_cursor);
+            }
+            meta_server_bmi_str = PINT_config_get_host_addr_ptr(
+                config,cur_mapping->alias_mapping->host_alias);
+
+            ext_array->extent_count =
+                cur_mapping->handle_extent_array.extent_count;
+            ext_array->extent_array =
+                cur_mapping->handle_extent_array.extent_array;
+
+            ret = BMI_addr_lookup(meta_addr,meta_server_bmi_str);
+        }
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_next_io()
+ *
+ * returns the address of a set of servers that should be used to
+ * store new pieces of file data.  This function is responsible for
+ * evenly distributing the file data storage load to all servers.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_next_io(
+    struct server_configuration_s *config,
+    PVFS_fs_id fsid,
+    int num_servers,
+    PVFS_BMI_addr_t *io_addr_array,
+    PVFS_handle_extent_array *io_handle_extent_array)
+{
+    int ret = -PVFS_EINVAL, i = 0;
+    char *data_server_bmi_str = (char *)0;
+    struct host_handle_mapping_s *cur_mapping = NULL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (config && num_servers && io_addr_array && io_handle_extent_array)
+    {
+        hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+        if (hash_link)
+        {
+            cur_config_cache = qlist_entry(
+                hash_link, struct config_fs_cache_s, hash_link);
+
+            assert(cur_config_cache);
+            assert(cur_config_cache->fs);
+
+            while(num_servers)
+            {
+                assert(cur_config_cache->data_server_cursor);
+
+                cur_mapping = PINT_llist_head(
+                    cur_config_cache->data_server_cursor);
+                if (!cur_mapping)
+                {
+                    cur_config_cache->data_server_cursor =
+                        cur_config_cache->fs->data_handle_ranges;
+                    continue;
+                }
+                cur_config_cache->data_server_cursor = PINT_llist_next(
+                    cur_config_cache->data_server_cursor);
+
+                data_server_bmi_str = PINT_config_get_host_addr_ptr(
+                    config,cur_mapping->alias_mapping->host_alias);
+
+                ret = BMI_addr_lookup(io_addr_array,data_server_bmi_str);
+                if (ret)
+                {
+                    break;
+                }
+
+                io_handle_extent_array[i].extent_count =
+                    cur_mapping->handle_extent_array.extent_count;
+                io_handle_extent_array[i].extent_array =
+                    cur_mapping->handle_extent_array.extent_array;
+
+                i++;
+                io_addr_array++;
+                num_servers--;
+            }
+            ret = ((num_servers == 0) ? 0 : ret);
+        }
+    }
+    return ret;
+}
+
+
+/* PINT_bucket_map_addr()
+ *
+ * takes an opaque server address and returns the server type and
+ * address string for that server
+ *
+ * returns pointer to string on success, NULL on failure
+ */
+const char *PINT_bucket_map_addr(
+    struct server_configuration_s *config,
+    PVFS_fs_id fsid, 
+    PVFS_BMI_addr_t addr,
+    int *server_type)
+{
+    int ret = -PVFS_EINVAL, i = 0;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (!(config && server_type))
+    {
+        return NULL;
+    }
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+    if (!hash_link)
+    {
+        return NULL;
+    }
+    cur_config_cache = qlist_entry(
+        hash_link, struct config_fs_cache_s, hash_link);
+    assert(cur_config_cache);
+    assert(cur_config_cache->fs);
+
+    ret = cache_server_array(config, fsid);
+    if (ret < 0)
+    {
+        return NULL;
+    }
+
+    /* run through general server list for a match */
+    for(i = 0; i < cur_config_cache->server_count; i++)
+    {
+        if (cur_config_cache->server_array[i].addr == addr)
+        {
+            *server_type = cur_config_cache->server_array[i].server_type;
+            return (cur_config_cache->server_array[i].addr_string);
+        }
+    }
+    return NULL;
+}
+
+/* PINT_bucket_count_servers()
+ *
+ * counts the number of physical servers of the specified type
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_count_servers(struct server_configuration_s *config,
+                              PVFS_fs_id fsid, 
+                              int server_type,
+                              int *count)
+{
+    int ret = -PVFS_EINVAL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (!config || !server_type)
+    {
+        return ret;
+    }
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+    if (!hash_link)
+    {
+        return ret;
+    }
+    cur_config_cache = qlist_entry(
+        hash_link, struct config_fs_cache_s, hash_link);
+
+    assert(cur_config_cache);
+    assert(cur_config_cache->fs);
+
+    ret = cache_server_array(config, fsid);
+    if (ret == 0)
+    {
+        if (server_type == PINT_BUCKET_META)
+        {
+            *count = cur_config_cache->meta_server_count;
+            ret = 0;
+        }
+        else if (server_type == PINT_BUCKET_IO)
+        {
+            *count = cur_config_cache->io_server_count;
+            ret = 0;
+        }
+        else if (server_type == (PINT_BUCKET_META|PINT_BUCKET_IO))
+        {
+            *count = cur_config_cache->server_count;
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_server_array()
+ *
+ * fills in an array of addresses corresponding to each server of the
+ * type specified by "server_type" (meta,io,or both).  If
+ * inout_count_p is not large enough to accomodate array, then an
+ * error is returned.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_server_array(
+    struct server_configuration_s *config,
+    PVFS_fs_id fsid,
+    int server_type,
+    PVFS_BMI_addr_t *addr_array,
+    int *inout_count_p)
+{
+    int ret = -PVFS_EINVAL, i = 0;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (!config || !*inout_count_p || !addr_array || !server_type)
+    {
+        return ret;
+    }
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+    if (!hash_link)
+    {
+        return ret;
+    }
+    cur_config_cache = qlist_entry(
+        hash_link, struct config_fs_cache_s, hash_link);
+
+    assert(cur_config_cache);
+    assert(cur_config_cache->fs);
+
+    ret = cache_server_array(config, fsid);
+    if (ret < 0)
+    {
+        return ret;
+    }
+
+    /* at this point, we should have the data that we need cached up,
+     * just copy out
+     */
+    if (server_type == PINT_BUCKET_META)
+    {
+        if (*inout_count_p < cur_config_cache->meta_server_count)
+        {
+            return -PVFS_EMSGSIZE;
+        }
+
+        for(i = 0; i < cur_config_cache->meta_server_count; i++)
+        {
+            addr_array[i] = cur_config_cache->meta_server_array[i].addr;
+        }
+
+        *inout_count_p = cur_config_cache->meta_server_count;
+        return 0;
+    }
+    else if (server_type == PINT_BUCKET_IO)
+    {
+        if (*inout_count_p < cur_config_cache->io_server_count)
+        {
+            return -PVFS_EMSGSIZE;
+        }
+
+        for(i = 0; i < cur_config_cache->io_server_count; i++)
+        {
+            addr_array[i] = cur_config_cache->io_server_array[i].addr;
+        }
+
+        *inout_count_p = cur_config_cache->io_server_count;
+        return 0;
+    }
+    else if (server_type == (PINT_BUCKET_META | PINT_BUCKET_IO))
+    {
+        if (*inout_count_p < cur_config_cache->server_count)
+        {
+            return -PVFS_EMSGSIZE;
+        }
+
+        for(i = 0; i < cur_config_cache->server_count; i++)
+        {
+            addr_array[i] =
+                cur_config_cache->server_array[i].addr;
+        }
+
+        *inout_count_p = cur_config_cache->server_count;
+        return 0;
+    }
+    return ret;
+}
+
+/* PINT_bucket_map_to_server()
+ *
+ * maps from a handle and fsid to a server address
+ *
+ * returns 0 on success to -errno on failure
+ */
+int PINT_bucket_map_to_server(
+    PVFS_BMI_addr_t *server_addr,
+    PVFS_handle handle,
+    PVFS_fs_id fs_id)
+{
+    int ret = -PVFS_EINVAL;
+    char bmi_server_addr[PVFS_MAX_SERVER_ADDR_LEN] = {0};
+
+    ret = PINT_bucket_get_server_name(
+        bmi_server_addr, PVFS_MAX_SERVER_ADDR_LEN, handle, fs_id);
+    if (ret)
+    {
+        PVFS_perror_gossip("PINT_bucket_get_server_name failed", ret);
+    }
+    return (!ret ? BMI_addr_lookup(server_addr, bmi_server_addr) : ret);
+}
+
+/** PINT_bucker_get_num_dfiles()
+ *
+ * Return the number of dfiles to use for files with this combination of
+ * fs id, distribution, and attributes.  If the distribution and attributes
+ * do not specify a number of dfiles, the number of io servers will be used.
+ */
+int PINT_bucket_get_num_dfiles(PVFS_fs_id fsid,
+                               PINT_dist* dist,
+                               PVFS_sys_attr attr,
+                               int* num_dfiles)
+{
+    int num_dfiles_req;
+    int num_servers_req;
+    int ret;
+
+    /* Get the user's dfile count request (it may be ignored by dist) */
+    if (attr.mask & PVFS_ATTR_SYS_DFILE_COUNT)
+    {
+        num_dfiles_req = attr.dfile_count;
+    }
+    else
+    {
+        num_dfiles_req = 0;
+    }
+
+    /* Get the number of available servers */
+    ret = PINT_bucket_get_num_io(fsid, &num_servers_req);
+    if (0 == ret)
+    {
+        /* Let the distribution determine the number of dfiles to use */
+        *num_dfiles = dist->methods->get_num_dfiles(dist->params,
+                                                    num_servers_req,
+                                                    num_dfiles_req);
+    }
+    else
+    {
+        ret = -PVFS_EINVAL;
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_num_meta()
+ *
+ * discovers the number of metadata servers available for a given file
+ * system
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_num_meta(PVFS_fs_id fsid, int *num_meta)
+{
+    int ret = -PVFS_EINVAL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (num_meta)
+    {
+        hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+        if (hash_link)
+        {
+            cur_config_cache = qlist_entry(
+                hash_link, struct config_fs_cache_s, hash_link);
+
+            assert(cur_config_cache);
+            assert(cur_config_cache->fs);
+            assert(cur_config_cache->fs->meta_handle_ranges);
+
+            *num_meta = PINT_llist_count(
+                cur_config_cache->fs->meta_handle_ranges);
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_num_io()
+ *
+ * discovers the number of io servers available for a given file
+ * system
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_num_io(PVFS_fs_id fsid, int *num_io)
+{
+    int ret = -PVFS_EINVAL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (num_io)
+    {
+        hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+        if (hash_link)
+        {
+            cur_config_cache = qlist_entry(
+                hash_link, struct config_fs_cache_s, hash_link);
+
+            assert(cur_config_cache);
+            assert(cur_config_cache->fs);
+            assert(cur_config_cache->fs->data_handle_ranges);
+
+            *num_io = PINT_llist_count(
+                cur_config_cache->fs->data_handle_ranges);
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_server_handle_count()
+ *
+ * counts the number of handles associated with a given server
+ *
+ * returns 0 on success, -PVFS_error on failure
+ */
+int PINT_bucket_get_server_handle_count(
+    const char* server_addr_str,
+    PVFS_fs_id fs_id,
+    uint64_t* handle_count)
+{
+    int ret = -PVFS_EINVAL;
+    PINT_llist *cur = NULL;
+    struct bmi_host_extent_table_s *cur_host_extent_table = NULL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+    uint64_t tmp_count;
+
+    *handle_count = 0;
+
+    assert(PINT_fsid_config_cache_table);
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fs_id));
+    if (hash_link)
+    {
+        cur_config_cache = qlist_entry(
+            hash_link, struct config_fs_cache_s, hash_link);
+
+        assert(cur_config_cache);
+        assert(cur_config_cache->fs);
+        assert(cur_config_cache->bmi_host_extent_tables);
+
+        cur = cur_config_cache->bmi_host_extent_tables;
+        while (cur)
+        {
+            cur_host_extent_table = PINT_llist_head(cur);
+            if (!cur_host_extent_table)
+            {
+                break;
+            }
+            assert(cur_host_extent_table->bmi_address);
+            assert(cur_host_extent_table->extent_list);
+
+            if (!strcmp(cur_host_extent_table->bmi_address, server_addr_str))
+            {
+                PINT_extent_list_count_total(
+                    cur_host_extent_table->extent_list, &tmp_count);
+                *handle_count += tmp_count;
+            }
+            cur = PINT_llist_next(cur);
+        }
+        return 0;
+    }
+    return ret;
+}
+
+/* PINT_bucket_get_server_name()
+ *
+ * discovers the string (BMI url) name of a server that controls the
+ * specified bucket.
+ *
+ * returns 0 on success, -errno on failure
+ */
+int PINT_bucket_get_server_name(
+    char *server_name,
+    int max_server_name_len,
+    PVFS_handle handle,
+    PVFS_fs_id fsid)
+{
+    int ret = -PVFS_EINVAL;
+    PINT_llist *cur = NULL;
+    struct bmi_host_extent_table_s *cur_host_extent_table = NULL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    assert(PINT_fsid_config_cache_table);
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+    if (hash_link)
+    {
+        cur_config_cache = qlist_entry(
+            hash_link, struct config_fs_cache_s, hash_link);
+
+        assert(cur_config_cache);
+        assert(cur_config_cache->fs);
+        assert(cur_config_cache->bmi_host_extent_tables);
+
+        cur = cur_config_cache->bmi_host_extent_tables;
+        while (cur)
+        {
+            cur_host_extent_table = PINT_llist_head(cur);
+            if (!cur_host_extent_table)
+            {
+                break;
+            }
+            assert(cur_host_extent_table->bmi_address);
+            assert(cur_host_extent_table->extent_list);
+
+            if (PINT_handle_in_extent_list(
+                    cur_host_extent_table->extent_list, handle))
+            {
+                strncpy(server_name,cur_host_extent_table->bmi_address,
+                        max_server_name_len);
+                ret = 0;
+                break;
+            }
+            cur = PINT_llist_next(cur);
+        }
+    }
+
+    return ret;
+}
+
+/* PINT_bucket_get_root_handle()
+ *
+ * return the root handle of any valid filesystem
+ *
+ * returns 0 on success -errno on failure
+ *
+ */
+int PINT_bucket_get_root_handle(
+    PVFS_fs_id fsid,
+    PVFS_handle *fh_root)
+{
+    int ret = -PVFS_EINVAL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+
+    if (fh_root)
+    {
+        hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+        if (hash_link)
+        {
+            cur_config_cache = qlist_entry(
+                hash_link, struct config_fs_cache_s, hash_link);
+
+            assert(cur_config_cache);
+            assert(cur_config_cache->fs);
+
+            *fh_root = (PVFS_handle)cur_config_cache->fs->root_handle;
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+
+/* cache_server_array()
+ *
+ * verifies that the arrays of physical server addresses have been
+ * cached in the configuration structs
+ *
+ * returns 0 on success, -errno on failure
+ */
+static int cache_server_array(struct server_configuration_s* config,
+                              PVFS_fs_id fsid)
+{
+    int ret = -PVFS_EINVAL, i = 0, j = 0;
+    char *server_bmi_str = NULL;
+    struct host_handle_mapping_s *cur_mapping = NULL;
+    struct qlist_head *hash_link = NULL;
+    struct config_fs_cache_s *cur_config_cache = NULL;
+    PINT_llist* tmp_server = NULL;
+    PVFS_BMI_addr_t tmp_bmi_addr;
+    int dup_flag = 0;
+    int current = 0;
+    int array_index = 0, array_index2 = 0;
+
+    if (!config)
+    {
+        return ret;
+    }
+
+    hash_link = qhash_search(PINT_fsid_config_cache_table,&(fsid));
+    if (!hash_link)
+    {
+        return ret;
+    }
+    cur_config_cache = qlist_entry(
+        hash_link, struct config_fs_cache_s, hash_link);
+
+    assert(cur_config_cache);
+    assert(cur_config_cache->fs);
+
+    /* first check to see if we have the array information cached */
+    if (cur_config_cache->server_count < 1)
+    {
+        /* we need to fill in this stuff in our config cache */
+        cur_config_cache->server_count = 0;
+        cur_config_cache->meta_server_count = 0;
+        cur_config_cache->io_server_count = 0;
+        
+        /* iterate through lists to come up with an upper bound for
+         * the size of the arrays that we need
+         */
+        tmp_server = cur_config_cache->fs->meta_handle_ranges;
+        while ((cur_mapping = PINT_llist_head(tmp_server)))
+        {
+            tmp_server = PINT_llist_next(tmp_server);
+            cur_config_cache->meta_server_count++;
+            cur_config_cache->server_count++;
+        }
+        tmp_server = cur_config_cache->fs->data_handle_ranges;
+        while ((cur_mapping = PINT_llist_head(tmp_server)))
+        {
+            tmp_server = PINT_llist_next(tmp_server);
+            cur_config_cache->io_server_count++;
+            cur_config_cache->server_count++;
+        }
+
+        cur_config_cache->meta_server_array = (phys_server_desc_s*)malloc(
+            (cur_config_cache->meta_server_count *
+             sizeof(phys_server_desc_s)));
+        cur_config_cache->io_server_array = (phys_server_desc_s*)malloc(
+            (cur_config_cache->io_server_count*
+             sizeof(phys_server_desc_s)));
+        cur_config_cache->server_array = (phys_server_desc_s*)malloc(
+            (cur_config_cache->server_count*
+             sizeof(phys_server_desc_s)));
+
+        if ((cur_config_cache->meta_server_array == NULL) ||
+            (cur_config_cache->io_server_array == NULL) ||
+            (cur_config_cache->server_array == NULL))
+        {
+            ret = -PVFS_ENOMEM;
+            goto cleanup_allocations;
+        }
+        memset(cur_config_cache->server_array, 0, 
+               (cur_config_cache->server_count *
+                sizeof(phys_server_desc_s)));
+
+        /* reset counts until we find out how many physical servers
+         * are actually present
+         */
+        cur_config_cache->server_count = 0;
+        cur_config_cache->meta_server_count = 0;
+        cur_config_cache->io_server_count = 0;
+
+        for(i = 0; i < 2; i++)
+        {
+            if (i == 0)
+            {
+                tmp_server = cur_config_cache->fs->meta_handle_ranges;
+                current = PINT_BUCKET_META;
+            }
+            else
+            {
+                tmp_server = cur_config_cache->fs->data_handle_ranges;
+                current = PINT_BUCKET_IO;
+            }
+            while ((cur_mapping = PINT_llist_head(tmp_server)))
+            {
+                tmp_server = PINT_llist_next(tmp_server);
+                server_bmi_str = PINT_config_get_host_addr_ptr(
+                    config,cur_mapping->alias_mapping->host_alias);
+
+                ret = BMI_addr_lookup(&tmp_bmi_addr,server_bmi_str);
+                if (ret < 0)
+                {
+                    return(ret);
+                }
+
+                /* see if we have already listed this BMI address */
+                dup_flag = 0;
+                for (j=0; j < array_index; j++)
+                {
+                    if (cur_config_cache->server_array[j].addr ==
+                        tmp_bmi_addr)
+                    {
+                        cur_config_cache->server_array[j].server_type 
+                            |= current;
+                        dup_flag = 1;
+                        break;
+                    }
+                }
+                
+                if (!dup_flag)
+                {
+                    cur_config_cache->server_array[array_index].addr =
+                        tmp_bmi_addr;
+                    cur_config_cache->server_array[
+                        array_index].addr_string = server_bmi_str;
+                    cur_config_cache->server_array[
+                        array_index].server_type = current;
+                    array_index++;
+                    cur_config_cache->server_count = array_index;
+                }
+            }
+        }
+
+        /* now build meta and I/O arrays based on generic server list */
+        array_index = 0;
+        array_index2 = 0;
+        for(i = 0; i < cur_config_cache->server_count; i++)
+        {
+            if (cur_config_cache->server_array[i].server_type &
+                PINT_BUCKET_META)
+            {
+                cur_config_cache->meta_server_array[array_index] = 
+                    cur_config_cache->server_array[i];
+                array_index++;
+            }
+            if (cur_config_cache->server_array[i].server_type &
+                PINT_BUCKET_IO)
+            {
+                cur_config_cache->io_server_array[array_index2] = 
+                    cur_config_cache->server_array[i];
+                array_index2++;
+            }
+        }
+        cur_config_cache->meta_server_count = array_index;
+        cur_config_cache->io_server_count = array_index2;
+    }
+    return 0;
+
+  cleanup_allocations:
+    if (cur_config_cache->meta_server_array)
+    {
+        free(cur_config_cache->meta_server_array);
+    }
+    if (cur_config_cache->io_server_array)
+    {
+        free(cur_config_cache->io_server_array);
+    }
+    if (cur_config_cache->server_array)
+    {
+        free(cur_config_cache->server_array);
+    }
+    return ret;
+}
+
+/* hash_fsid()
+ *
+ * hash function for fsids added to table
+ *
+ * returns integer offset into table
+ */
+static int hash_fsid(void *fsid, int table_size)
+{
+    unsigned long tmp = 0;
+    PVFS_fs_id *real_fsid = (PVFS_fs_id *)fsid;
+
+    assert(PINT_fsid_config_cache_table);
+
+    tmp += (*(real_fsid));
+    tmp = tmp%table_size;
+
+    return ((int) tmp);
+}
+
+/* hash_fsid_compare()
+ *
+ * performs a comparison of a hash table entro to a given key (used
+ * for searching)
+ *
+ * returns 1 if match found, 0 otherwise
+ */
+static int hash_fsid_compare(void *key, struct qlist_head *link)
+{
+    config_fs_cache_s *fs_info = NULL;
+    PVFS_fs_id *real_fsid = (PVFS_fs_id *)key;
+
+    assert(PINT_fsid_config_cache_table);
+
+    fs_info = qlist_entry(link, config_fs_cache_s, hash_link);
+    if ((PVFS_fs_id)fs_info->fs->coll_id == *real_fsid)
+    {
+        return 1;
+    }
+    return 0;
+}
+
+static void free_host_extent_table(void *ptr)
+{
+    struct bmi_host_extent_table_s *cur_host_extent_table =
+        (struct bmi_host_extent_table_s *)ptr;
+
+    assert(cur_host_extent_table);
+    assert(cur_host_extent_table->bmi_address);
+    assert(cur_host_extent_table->extent_list);
+
+    /*
+      NOTE: cur_host_extent_table->bmi_address is a ptr
+      into a server_configuration_s->host_aliases object.
+      it is properly freed by PINT_config_release
+    */
+    cur_host_extent_table->bmi_address = (char *)0;
+    PINT_release_extent_list(cur_host_extent_table->extent_list);
+    free(cur_host_extent_table);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 noexpandtab
+ */

--- /dev/null	2003-01-30 05:24:37.000000000 -0500
+++ pint-cached-config.h	2004-07-08 16:06:52.000000000 -0400
@@ -0,0 +1,124 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#ifndef __PINT_CACHED_CONFIG_H
+#define __PINT_CACHED_CONFIG_H
+
+#include "pvfs2-types.h"
+#include "pvfs2-storage.h"
+#include "pvfs2-mgmt.h"
+#include "bmi.h"
+#include "dotconf.h"
+#include "trove.h"
+#include "server-config.h"
+
+/* This is the interface to the bucket management component of the
+ * system interface.  It is responsible for managing the list of meta
+ * and data servers and mapping between handle ranges and servers.
+ */
+int PINT_bucket_initialize(void);
+
+int PINT_bucket_finalize(void);
+
+int PINT_handle_load_mapping(struct server_configuration_s *config,
+			     struct filesystem_configuration_s *fs);
+
+int PINT_bucket_get_next_meta(struct server_configuration_s *config,
+			      PVFS_fs_id fsid,
+			      PVFS_BMI_addr_t *meta_addr,
+			      PVFS_handle_extent_array *meta_extent_array);
+
+int PINT_bucket_get_next_io(struct server_configuration_s *config,
+			    PVFS_fs_id fsid,
+			    int num_servers,
+			    PVFS_BMI_addr_t *io_addr_array,
+			    PVFS_handle_extent_array *io_handle_extent_array);
+
+#define PINT_BUCKET_IO PVFS_MGMT_IO_SERVER
+#define PINT_BUCKET_META PVFS_MGMT_META_SERVER
+#define PINT_BUCKET_ALL (PINT_BUCKET_META|PINT_BUCKET_IO)
+
+const char* PINT_bucket_map_addr(struct server_configuration_s* config,
+				 PVFS_fs_id fsid,
+				 PVFS_BMI_addr_t addr,
+				 int* server_type);
+
+int PINT_bucket_get_server_array(struct server_configuration_s* config,
+				 PVFS_fs_id fsid,
+				 int server_type,
+				 PVFS_BMI_addr_t *addr_array,
+				 int* inout_count_p);
+
+int PINT_bucket_count_servers(struct server_configuration_s* config,
+			      PVFS_fs_id fsid,
+			      int server_type,
+			      int* count);
+
+int PINT_bucket_map_to_server(PVFS_BMI_addr_t *server_addr,
+			      PVFS_handle handle,
+			      PVFS_fs_id fsid);
+
+int PINT_bucket_get_num_dfiles(PVFS_fs_id fsid,
+                               PINT_dist* dist,
+                               PVFS_sys_attr attr,
+                               int* num_dfiles);
+
+int PINT_bucket_get_num_meta(PVFS_fs_id fsid,
+			     int *num_meta);
+
+int PINT_bucket_get_num_io(PVFS_fs_id fsid,
+			   int *num_io);
+
+int PINT_bucket_get_server_name(char *server_name,
+				int max_server_name_len,
+				PVFS_handle handle,
+				PVFS_fs_id fsid);
+
+int PINT_bucket_get_server_handle_count(const char* server_addr_str,
+					PVFS_fs_id fs_id,
+					uint64_t* handle_count);
+    
+int PINT_bucket_get_root_handle(PVFS_fs_id fsid,
+				PVFS_handle *fh_root);
+
+#define map_handle_range_to_extent_list(hrange_list)             \
+do { cur = hrange_list;                                          \
+ while(cur) {                                                    \
+     cur_mapping = PINT_llist_head(cur);                         \
+     if (!cur_mapping) break;                                    \
+     assert(cur_mapping->alias_mapping);                         \
+     assert(cur_mapping->alias_mapping->host_alias);             \
+     assert(cur_mapping->handle_range);                          \
+     cur_host_extent_table = (bmi_host_extent_table_s *)malloc(  \
+         sizeof(bmi_host_extent_table_s));                       \
+     if (!cur_host_extent_table) {                               \
+         ret = -ENOMEM;                                          \
+         break;                                                  \
+     }                                                           \
+     cur_host_extent_table->bmi_address =                        \
+         PINT_config_get_host_addr_ptr(                          \
+             config,cur_mapping->alias_mapping->host_alias);     \
+     assert(cur_host_extent_table->bmi_address);                 \
+     cur_host_extent_table->extent_list =                        \
+         PINT_create_extent_list(cur_mapping->handle_range);     \
+     if (!cur_host_extent_table->extent_list) {                  \
+         free(cur_host_extent_table);                            \
+         ret = -ENOMEM;                                          \
+         break;                                                  \
+     }                                                           \
+     /*                                                          \
+       add this host to extent list mapping to                   \
+       config cache object's host extent table                   \
+     */                                                          \
+     ret = PINT_llist_add_to_tail(                               \
+         cur_config_fs_cache->bmi_host_extent_tables,            \
+         cur_host_extent_table);                                 \
+     assert(ret == 0);                                           \
+     cur = PINT_llist_next(cur);                                 \
+ } } while(0)
+
+
+#endif /* __PINT_CACHED_CONFIG_H */

Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/module.mk.in,v
diff -p -u -r1.15 -r1.16
--- module.mk.in	15 Apr 2004 00:41:27 -0000	1.15
+++ module.mk.in	8 Jul 2004 20:06:50 -0000	1.16
@@ -8,7 +8,8 @@ LIBSRC += $(DIR)/server-config.c \
 	  $(DIR)/pvfs2-util.c \
           $(DIR)/pvfs2-debug.c \
 	  $(DIR)/pint-perf-counter.c \
-	  $(DIR)/pint-event.c
+	  $(DIR)/pint-event.c \
+	  $(DIR)/pint-cached-config.c
 SERVERSRC += $(DIR)/server-config.c \
              $(DIR)/server-config-mgr.c \
              $(DIR)/str-utils.c \

Index: server-config-mgr.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/server-config-mgr.c,v
diff -p -u -r1.5 -r1.6
--- server-config-mgr.c	8 Jul 2004 16:17:09 -0000	1.5
+++ server-config-mgr.c	8 Jul 2004 20:06:50 -0000	1.6
@@ -19,7 +19,7 @@
 #include "quickhash.h"
 #include "gen-locks.h"
 #include "gossip.h"
-#include "pint-bucket.h"
+#include "pint-cached-config.h"
 
 /*
   this is an internal structure and shouldn't be used by anyone except



More information about the PVFS2-CVS mailing list