[PVFS2-CVS]
commit by slang in pvfs2/src/common/misc: realpath.c realpath.h
module.mk.in msgpairarray.sm pint-cached-config.c
pint-cached-config.h pint-event.c pint-event.h pint-textlog.c
pint-util.c pint-util.h pvfs2-debug.c pvfs2-util.c
server-config-mgr.c server-config.c server-config.h
state-machine-fns.h str-utils.c str-utils.h
CVS commit program
cvs at parl.clemson.edu
Thu Aug 25 17:38:18 EDT 2005
Update of /projects/cvsroot/pvfs2/src/common/misc
In directory parlweb:/tmp/cvs-serv7520/src/common/misc
Modified Files:
Tag: slang-event-changes-branch
module.mk.in msgpairarray.sm pint-cached-config.c
pint-cached-config.h pint-event.c pint-event.h pint-textlog.c
pint-util.c pint-util.h pvfs2-debug.c pvfs2-util.c
server-config-mgr.c server-config.c server-config.h
state-machine-fns.h str-utils.c str-utils.h
Added Files:
Tag: slang-event-changes-branch
realpath.c realpath.h
Log Message:
updates to my event changes to bring them inline with trunk
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ realpath.c 2005-08-25 16:38:18.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ * realpath.c -- canonicalize pathname by removing symlinks
+ * Copyright (C) 1993 Rick Sladkey <jrs at world.std.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library Public License for more details.
+ */
+
+#define resolve_symlinks
+
+/*
+ * This routine is part of libc. We include it nevertheless,
+ * since the libc version has some security flaws.
+ */
+
+#include <limits.h> /* for PATH_MAX */
+#ifndef PATH_MAX
+#define PATH_MAX 8192
+#endif
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "realpath.h"
+#include "pvfs2-types.h"
+
+#define MAX_READLINKS 32
+
+/* PINT_realpath()
+ *
+ * canonicalizes path and places the result into resolved_path. Includes
+ * cleaning of symbolic links, trailing slashes, and .. or . components.
+ * maxreslth is the maximum length allowed in resolved_path.
+ *
+ * returns 0 on succes, -PVFS_error on failure.
+ */
+int PINT_realpath(
+ const char *path,
+ char *resolved_path,
+ int maxreslth)
+{
+ int readlinks = 0;
+ char *npath;
+ char link_path[PATH_MAX + 1];
+ int n;
+ char *buf = NULL;
+ int ret;
+
+ npath = resolved_path;
+
+ /* If it's a relative pathname use getcwd for starters. */
+ if (*path != '/')
+ {
+ if (!getcwd(npath, maxreslth - 2))
+ {
+ return(-PVFS_EINVAL);
+ }
+ npath += strlen(npath);
+ if (npath[-1] != '/')
+ *npath++ = '/';
+ }
+ else
+ {
+ *npath++ = '/';
+ path++;
+ }
+
+ /* Expand each slash-separated pathname component. */
+ while (*path != '\0')
+ {
+ /* Ignore stray "/" */
+ if (*path == '/')
+ {
+ path++;
+ continue;
+ }
+ if (*path == '.' && (path[1] == '\0' || path[1] == '/'))
+ {
+ /* Ignore "." */
+ path++;
+ continue;
+ }
+ if (*path == '.' && path[1] == '.' &&
+ (path[2] == '\0' || path[2] == '/'))
+ {
+ /* Backup for ".." */
+ path += 2;
+ while (npath > resolved_path + 1 && (--npath)[-1] != '/')
+ ;
+ continue;
+ }
+ /* Safely copy the next pathname component. */
+ while (*path != '\0' && *path != '/')
+ {
+ if (npath - resolved_path > maxreslth - 2)
+ {
+ ret = -PVFS_ENAMETOOLONG;
+ goto err;
+ }
+ *npath++ = *path++;
+ }
+
+ /* Protect against infinite loops. */
+ if (readlinks++ > MAX_READLINKS)
+ {
+ ret = -PVFS_ELOOP;
+ goto err;
+ }
+
+ /* See if last pathname component is a symlink. */
+ *npath = '\0';
+ n = readlink(resolved_path, link_path, PATH_MAX);
+ if (n < 0)
+ {
+ /* EINVAL means the file exists but isn't a symlink. */
+ if (errno != EINVAL)
+ {
+ ret = -PVFS_EINVAL;
+ goto err;
+ }
+ }
+ else
+ {
+#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */
+ int m;
+
+ /* Note: readlink doesn't add the null byte. */
+ link_path[n] = '\0';
+ if (*link_path == '/')
+ /* Start over for an absolute symlink. */
+ npath = resolved_path;
+ else
+ /* Otherwise back up over this component. */
+ while (*(--npath) != '/')
+ ;
+
+ /* Insert symlink contents into path. */
+ m = strlen(path);
+ if (buf)
+ free(buf);
+ buf = malloc(m + n + 1);
+ if(!buf)
+ {
+ ret = -PVFS_ENOMEM;
+ goto err;
+ }
+ memcpy(buf, link_path, n);
+ memcpy(buf + n, path, m + 1);
+ path = buf;
+#endif
+ }
+ *npath++ = '/';
+ }
+ /* Delete trailing slash but don't whomp a lone slash. */
+ if (npath != resolved_path + 1 && npath[-1] == '/')
+ npath--;
+ /* Make sure it's null terminated. */
+ *npath = '\0';
+
+ if (buf)
+ free(buf);
+ return 0;
+
+ err:
+ if (buf)
+ free(buf);
+ return ret;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ realpath.h 2005-08-25 16:38:18.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+
+
+/*
+ * realpath.c -- canonicalize pathname by removing symlinks
+ * Copyright (C) 1993 Rick Sladkey <jrs at world.std.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library Public License for more details.
+ */
+
+int PINT_realpath(
+ const char *path,
+ char *resolved_path,
+ int m);
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/module.mk.in,v
diff -p -u -r1.21.6.1 -r1.21.6.2
--- module.mk.in 8 Jul 2005 20:58:31 -0000 1.21.6.1
+++ module.mk.in 25 Aug 2005 20:38:17 -0000 1.21.6.2
@@ -12,7 +12,8 @@ LIBSRC += $(DIR)/server-config.c \
$(DIR)/pint-textlog.c \
$(DIR)/pint-cached-config.c \
$(DIR)/msgpairarray.c \
- $(DIR)/pint-util.c
+ $(DIR)/pint-util.c \
+ $(DIR)/realpath.c
SERVERSRC += $(DIR)/server-config.c \
$(DIR)/server-config-mgr.c \
$(DIR)/str-utils.c \
@@ -26,6 +27,9 @@ SERVERSRC += $(DIR)/server-config.c \
$(DIR)/pint-cached-config.c \
$(DIR)/msgpairarray.c \
$(DIR)/pint-util.c
+
+MODCFLAGS_$(DIR)/server-config.c = \
+ -I$(srcdir)/src/server
# autogenerated files
SMCGEN += $(DIR)/msgpairarray.c
Index: msgpairarray.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/msgpairarray.sm,v
diff -p -u -r1.28 -r1.28.2.1
--- msgpairarray.sm 31 Mar 2005 19:12:55 -0000 1.28
+++ msgpairarray.sm 25 Aug 2005 20:38:17 -0000 1.28.2.1
@@ -361,7 +361,7 @@ static int msgpairarray_post(PARENT_SM *
else
{
PVFS_perror_gossip("Send immediately failed",
- msg_p->recv_status.error_code);
+ msg_p->send_status.error_code);
}
gossip_err("Send error: cancelling recv.\n");
Index: pint-cached-config.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-cached-config.c,v
diff -p -u -r1.12 -r1.12.6.1
--- pint-cached-config.c 7 Dec 2004 14:38:55 -0000 1.12
+++ pint-cached-config.c 25 Aug 2005 20:38:17 -0000 1.12.6.1
@@ -626,12 +626,14 @@ int PINT_cached_config_map_to_server(
return (!ret ? BMI_addr_lookup(server_addr, bmi_server_addr) : ret);
}
-/* PINT_bucker_get_num_dfiles()
+/* PINT_cached_config_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.
+ * Returns 0 if the number of dfiles has been successfully set
+ *
+ * Sets the number of dfiles to a distribution approved the value. Clients
+ * may pass in num_dfiles_requested as a hint, if no hint is given, the server
+ * configuration is checked to find a hint there. The distribution will
+ * choose a correct number of dfiles even if no hint is set.
*/
int PINT_cached_config_get_num_dfiles(
PVFS_fs_id fsid,
@@ -639,14 +641,39 @@ int PINT_cached_config_get_num_dfiles(
int num_dfiles_requested,
int *num_dfiles)
{
- int ret = -PVFS_EINVAL, num_servers_requested = 0;
-
- if (PINT_cached_config_get_num_io(fsid, &num_servers_requested) == 0)
+ int ret = -PVFS_EINVAL;
+ int rc;
+ int num_io_servers;
+
+ /* If the dfile request is zero, check to see if the config has that
+ setting */
+ if (0 == num_dfiles_requested)
{
- /* Let the distribution determine the number of dfiles to use */
- *num_dfiles = dist->methods->get_num_dfiles(
- dist->params, num_servers_requested, num_dfiles_requested);
+ struct qlist_head *hash_link = NULL;
+ struct config_fs_cache_s *cur_config_cache = NULL;
+
+ /* Locate the filesystem configuration for this fs id */
+ 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);
+ num_dfiles_requested = cur_config_cache->fs->default_num_dfiles;
+ }
+ }
+ /* Determine the number of I/O servers available */
+ rc = PINT_cached_config_get_num_io(fsid, &num_io_servers);
+
+ if (0 == rc)
+ {
+ /* Allow the distribution to apply its hint to the number of
+ dfiles requested and the number of I/O servers available */
+ *num_dfiles = dist->methods->get_num_dfiles(dist->params,
+ num_io_servers,
+ num_dfiles_requested);
ret = 0;
}
return ret;
@@ -868,6 +895,32 @@ int PINT_cached_config_get_root_handle(
*fh_root = (PVFS_handle)cur_config_cache->fs->root_handle;
ret = 0;
}
+ }
+ return ret;
+}
+
+int PINT_cached_config_get_handle_timeout(
+ PVFS_fs_id fsid,
+ struct timeval *timeout)
+{
+ int ret = -PVFS_EINVAL;
+ struct qlist_head *hash_link = NULL;
+ struct config_fs_cache_s *cur_config_cache = NULL;
+
+ 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);
+
+ timeout->tv_sec =
+ cur_config_cache->fs->handle_recycle_timeout_sec.tv_sec;
+ timeout->tv_usec =
+ cur_config_cache->fs->handle_recycle_timeout_sec.tv_usec;
+ ret = 0;
}
return ret;
}
Index: pint-cached-config.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-cached-config.h,v
diff -p -u -r1.6 -r1.6.6.1
--- pint-cached-config.h 10 Aug 2004 20:30:55 -0000 1.6
+++ pint-cached-config.h 25 Aug 2005 20:38:17 -0000 1.6.6.1
@@ -99,6 +99,13 @@ int PINT_cached_config_get_root_handle(
PVFS_fs_id fsid,
PVFS_handle *fh_root);
+int PINT_cached_config_get_handle_timeout(
+ PVFS_fs_id fsid,
+ struct timeval *timeout);
+
+int PINT_cached_config_reinitialize(
+ struct server_configuration_s *config);
+
#define map_handle_range_to_extent_list(hrange_list) \
do { cur = hrange_list; \
while(cur) { \
Index: pint-event.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-event.c,v
diff -p -u -r1.10.6.2 -r1.10.6.3
--- pint-event.c 7 Jun 2005 21:59:12 -0000 1.10.6.2
+++ pint-event.c 25 Aug 2005 20:38:17 -0000 1.10.6.3
@@ -16,6 +16,7 @@
#include "pvfs2-mgmt.h"
#include "gossip.h"
#include "id-generator.h"
+#include "pint-util.h"
#define PINT_EVENT_DEFAULT_TEXTLOG_FILENAME "/tmp/pvfs2-events-log.txt"
@@ -293,8 +294,11 @@ void __PINT_event_pablo(enum PVFS_event_
case PVFS_EVENT_API_TROVE:
sprintf(description, "trove operation");
break;
- default:
- /* TODO: someone fed us a bad api */
+ case PVFS_EVENT_API_ENCODE_REQ:
+ case PVFS_EVENT_API_ENCODE_RESP:
+ case PVFS_EVENT_API_DECODE_REQ:
+ case PVFS_EVENT_API_DECODE_RESP:
+ case PVFS_EVENT_API_SM:
}
/* PVFS_EVENT_API_BMI, operation(SEND|RECV), value, id, FLAG (start|end) */
@@ -340,10 +344,16 @@ void __PINT_event_mpe(enum PVFS_event_ap
}
case PVFS_EVENT_API_TROVE:
if (flags & PVFS_EVENT_FLAG_START) {
- MPE_Log_event(PINT_event_trove_start, 0, NULL);
+ MPE_Log_event(PINT_event_trove_wr_start, 0, NULL);
} else if (flags & PVFS_EVENT_FLAG_END) {
- MPE_Log_event(PINT_event_trove_stop, value, NULL);
+ MPE_Log_event(PINT_event_trove_wr_stop, value, NULL);
}
+ case PVFS_EVENT_API_ENCODE_REQ:
+ case PVFS_EVENT_API_ENCODE_RESP:
+ case PVFS_EVENT_API_DECODE_REQ:
+ case PVFS_EVENT_API_DECODE_RESP:
+ case PVFS_EVENT_API_SM:
+ ; /* XXX: NEEDS SOMETHING */
}
}
@@ -443,47 +453,98 @@ void PINT_event_log_events(
gen_mutex_unlock(&event_mutex);
}
-const char * PVFS_event_api_names[PVFS_EVENT_API_COUNT] =
+#define API_KEYWORD_ENTRY(__kw) {#__kw, PVFS_EVENT_API_##__kw}
+
+const PINT_keyword_mask_t PINT_event_api_names[] =
{
- "JOB",
- "BMI",
- "TROVE",
- "ENCODE_REQ",
- "ENCODE_RESP",
- "DECODE_REQ",
- "DECODE_RESP",
- "SM",
- "STATES"
+ API_KEYWORD_ENTRY(JOB),
+ API_KEYWORD_ENTRY(BMI),
+ API_KEYWORD_ENTRY(TROVE),
+ API_KEYWORD_ENTRY(ENCODE_REQ),
+ API_KEYWORD_ENTRY(ENCODE_RESP),
+ API_KEYWORD_ENTRY(DECODE_REQ),
+ API_KEYWORD_ENTRY(DECODE_RESP),
+ API_KEYWORD_ENTRY(SM),
+ API_KEYWORD_ENTRY(STATES)
};
-const char * PVFS_event_op_names[PVFS_EVENT_OP_COUNT] =
+uint64_t PVFS_event_api_keyword_to_mask(const char *value)
{
- "BMI_SEND",
- "BMI_RECV",
- "FLOW",
- "TROVE_READ_AT",
- "TROVE_WRITE_AT",
- "TROVE_BSTREAM_FLUSH",
- "TROVE_KEYVAL_FLUSH",
- "TROVE_READ_LIST",
- "TROVE_WRITE_LIST",
- "TROVE_KEYVAL_READ",
- "TROVE_KEYVAL_READ_LIST",
- "TROVE_KEYVAL_WRITE",
- "TROVE_DSPACE_GETATTR",
- "TROVE_DSPACE_SETATTR",
- "TROVE_BSTREAM_RESIZE",
- "TROVE_KEYVAL_REMOVE",
- "TROVE_KEYVAL_ITERATE",
- "TROVE_KEYVAL_ITERATE_KEYS",
- "TROVE_DSPACE_ITERATE_HANDLES",
- "TROVE_DSPACE_CREATE",
- "TROVE_DSPACE_REMOVE",
- "TROVE_DSPACE_VERIFY",
- "TROVE_BSTREAM_VALIDATE",
- "TROVE_KEYVAL_VALIDATE"
+ return PINT_keyword_to_mask(PINT_event_api_names,
+ (sizeof(PINT_event_api_names) /
+ sizeof(PINT_keyword_mask_t)),
+ value);
+}
+
+const char * PINT_event_api_get_keyword(uint64_t mask)
+{
+ return PINT_mask_to_keyword(PINT_event_api_names,
+ (sizeof(PINT_event_api_names) /
+ sizeof(PINT_keyword_mask_t)),
+ mask);
+}
+
+char * PINT_event_api_print_keywords(int columns, const char * sep)
+{
+ return PINT_print_keywords(PINT_event_api_names,
+ sizeof(PINT_event_api_names) /
+ sizeof(PINT_keyword_mask_t),
+ columns, sep);
+}
+
+#define OP_KEYWORD_ENTRY(__kw) {#__kw, PVFS_EVENT_##__kw}
+
+const PINT_keyword_mask_t PINT_event_op_names[] =
+{
+ OP_KEYWORD_ENTRY(BMI_SEND),
+ OP_KEYWORD_ENTRY(BMI_RECV),
+ OP_KEYWORD_ENTRY(FLOW),
+ OP_KEYWORD_ENTRY(TROVE_READ_AT),
+ OP_KEYWORD_ENTRY(TROVE_WRITE_AT),
+ OP_KEYWORD_ENTRY(TROVE_BSTREAM_FLUSH),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_FLUSH),
+ OP_KEYWORD_ENTRY(TROVE_READ_LIST),
+ OP_KEYWORD_ENTRY(TROVE_WRITE_LIST),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_READ),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_READ_LIST),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_WRITE),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_GETATTR),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_SETATTR),
+ OP_KEYWORD_ENTRY(TROVE_BSTREAM_RESIZE),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_REMOVE),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_ITERATE),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_ITERATE_KEYS),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_ITERATE_HANDLES),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_CREATE),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_REMOVE),
+ OP_KEYWORD_ENTRY(TROVE_DSPACE_VERIFY),
+ OP_KEYWORD_ENTRY(TROVE_BSTREAM_VALIDATE),
+ OP_KEYWORD_ENTRY(TROVE_KEYVAL_VALIDATE)
};
+uint64_t PVFS_event_op_keyword_to_mask(const char *value)
+{
+ return PINT_keyword_to_mask(PINT_event_op_names,
+ sizeof(PINT_event_op_names) /
+ sizeof(PINT_keyword_mask_t),
+ value);
+}
+
+const char * PINT_event_op_get_keyword(uint64_t mask)
+{
+ return PINT_mask_to_keyword(PINT_event_op_names,
+ sizeof(PINT_event_op_names) /
+ sizeof(PINT_keyword_mask_t),
+ mask);
+}
+
+char * PINT_event_op_print_keywords(int columns, const char * sep)
+{
+ return PINT_print_keywords(PINT_event_op_names,
+ sizeof(PINT_event_op_names) /
+ sizeof(PINT_keyword_mask_t),
+ columns, sep);
+}
/*
* Local variables:
Index: pint-event.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-event.h,v
diff -p -u -r1.12.6.2 -r1.12.6.3
--- pint-event.h 7 Jun 2005 21:59:12 -0000 1.12.6.2
+++ pint-event.h 25 Aug 2005 20:38:17 -0000 1.12.6.3
@@ -7,6 +7,7 @@
#ifndef __PINT_EVENT_H
#define __PINT_EVENT_H
+#include "pvfs2-config.h"
#include "pvfs2-types.h"
#include "pvfs2-mgmt.h"
#include "gen-locks.h"
@@ -19,6 +20,9 @@
extern int PINT_event_on;
extern int32_t PINT_event_api_mask;
extern int32_t PINT_event_op_mask;
+
+const char * PINT_event_api_get_keyword(uint64_t mask);
+const char * PINT_event_op_get_keyword(uint64_t mask);
int PINT_event_initialize(int ring_size);
void PINT_event_finalize(void);
Index: pint-textlog.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/Attic/pint-textlog.c,v
diff -p -u -r1.1.2.2 -r1.1.2.3
--- pint-textlog.c 7 Jun 2005 21:59:12 -0000 1.1.2.2
+++ pint-textlog.c 25 Aug 2005 20:38:17 -0000 1.1.2.3
@@ -28,6 +28,7 @@
#include "gossip.h"
#include "quickhash.h"
#include "pint-event.h"
+#include "pint-textlog.h"
#define STATE_TABLE_SIZE 503
@@ -64,19 +65,6 @@ static char * PINT_event_server_operatio
"PROTO_ERROR",
};
-static int PINT_event_log2(int _val)
-{
- int res = 0;
- while(!(_val & (1 << res)))
- {
- ++res;
- }
- return res;
-}
-
-#define PINT_event_api_get_name(_api) PVFS_event_api_names[PINT_event_log2(_api)]
-
-#define PINT_event_op_get_name(_op) PVFS_event_op_names[_op - 1]
/* We need to keep track of the start events
* so that we can match them up with the end events
@@ -250,8 +238,8 @@ static inline int PINT_textlog_write_sta
res = fprintf(fp,
"%s:%s topo=State "
"color=(%d,%d,%d,127,true) width=1 ]\n",
- PINT_event_api_get_name(event->api),
- PINT_event_op_get_name(event->operation),
+ PINT_event_api_get_keyword(event->api),
+ PINT_event_op_get_keyword(event->operation),
rand() % 255,
rand() % 255,
rand() % 255);
@@ -278,8 +266,15 @@ static int PINT_textlog_write_event(
float starttime, endtime;
int req_index;
- req_index = (int)id_gen_fast_lookup(estart->req_id);
-
+ /*
+ * req_index = (int)id_gen_fast_lookup(estart->req_id);
+ */
+
+ /* instead of using the request handle, we give each event
+ * a specific horizontal index based on the operation
+ */
+ req_index = estart->operation;
+
starttime = PINT_textlog_timeval_to_secs(epoc, estart);
endtime = PINT_textlog_timeval_to_secs(epoc, eend);
@@ -371,26 +366,26 @@ void PINT_textlog_generate(
FILE * outfp;
struct timeval epoc;
int tr_index;
- struct qhash_table * id_map;
QLIST_HEAD(start_events_list);
int textlog_state_index = 0;
-
+ struct qhash_table * id_map;
+
+ id_map = qhash_init(PINT_textlog_id_compare,
+ PINT_textlog_id_hash,
+ STATE_TABLE_SIZE);
+ if(!id_map)
+ {
+ gossip_err("PINT_generate_textlog: qhash_init failed for state map "
+ "with table size of %d\n", STATE_TABLE_SIZE);
+ goto close_fp;
+ }
+
outfp = fopen(filename, "w");
if(!outfp)
{
gossip_err("PINT_generate_textlog: Failed to open file %s: %s\n",
filename, strerror(errno));
return;
- }
-
- id_map = qhash_init(PINT_textlog_id_compare,
- PINT_textlog_id_hash,
- STATE_TABLE_SIZE);
- if(!id_map)
- {
- gossip_err("PINT_generate_textlog: qhash_init failed for state map "
- "with table size of %d\n", STATE_TABLE_SIZE);
- goto close_fp;
}
for(tr_index = 0; tr_index < count; ++tr_index)
Index: pint-util.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-util.c,v
diff -p -u -r1.6 -r1.6.6.1
--- pint-util.c 4 Oct 2004 21:28:18 -0000 1.6
+++ pint-util.c 25 Aug 2005 20:38:17 -0000 1.6.6.1
@@ -1,6 +1,11 @@
/*
* (C) 2001 Clemson University and The University of Chicago
*
+ * Changes by Acxiom Corporation to add PINT_check_mode() helper function
+ * as a replacement for check_mode() in permission checking, also added
+ * PINT_check_group() for supplimental group support
+ * Copyright © Acxiom Corporation, 2005.
+ *
* See COPYING in top-level directory.
*/
@@ -11,14 +16,27 @@
#include <sys/resource.h>
#include <unistd.h>
#include <assert.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/types.h>
#include "pvfs2-types.h"
#include "pint-util.h"
#include "gen-locks.h"
+#include "gossip.h"
+#include "pvfs2-debug.h"
static int current_tag = 1;
static gen_mutex_t current_tag_lock = GEN_MUTEX_INITIALIZER;
+static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
+static char* check_group_pw_buffer = NULL;
+static long check_group_pw_buffer_size = 0;
+static char* check_group_gr_buffer = NULL;
+static long check_group_gr_buffer_size = 0;
+static int PINT_check_group(uid_t uid, gid_t gid);
+
void PINT_time_mark(PINT_time_marker *out_marker)
{
struct rusage usage;
@@ -110,6 +128,12 @@ int PINT_copy_object_attr(PVFS_object_at
dest->objtype = src->objtype;
}
+ if (src->mask & PVFS_ATTR_DIR_DIRENT_COUNT)
+ {
+ dest->u.dir.dirent_count =
+ src->u.dir.dirent_count;
+ }
+
/*
NOTE:
we only copy the size out if we're actually a
@@ -133,53 +157,53 @@ int PINT_copy_object_attr(PVFS_object_at
}
if ((src->mask & PVFS_ATTR_COMMON_TYPE) &&
- (src->objtype == PVFS_TYPE_METAFILE) &&
- (src->mask & PVFS_ATTR_META_DFILES))
- {
- PVFS_size df_array_size = src->u.meta.dfile_count *
- sizeof(PVFS_handle);
-
- if (df_array_size)
+ (src->objtype == PVFS_TYPE_METAFILE))
+ {
+ if(src->mask & PVFS_ATTR_META_DFILES)
{
- if ((dest->mask & PVFS_ATTR_META_DFILES) &&
- dest->u.meta.dfile_count > 0)
+ PVFS_size df_array_size = src->u.meta.dfile_count *
+ sizeof(PVFS_handle);
+
+ if (df_array_size)
{
- if (dest->u.meta.dfile_array)
+ if ((dest->mask & PVFS_ATTR_META_DFILES) &&
+ dest->u.meta.dfile_count > 0)
+ {
+ if (dest->u.meta.dfile_array)
+ {
+ free(dest->u.meta.dfile_array);
+ }
+ }
+ dest->u.meta.dfile_array = malloc(df_array_size);
+ if (!dest->u.meta.dfile_array)
{
- free(dest->u.meta.dfile_array);
+ return ret;
}
+ memcpy(dest->u.meta.dfile_array,
+ src->u.meta.dfile_array, df_array_size);
}
- dest->u.meta.dfile_array = malloc(df_array_size);
- if (!dest->u.meta.dfile_array)
- {
- return ret;
- }
- memcpy(dest->u.meta.dfile_array,
- src->u.meta.dfile_array, df_array_size);
- }
- else
- {
- dest->u.meta.dfile_array = NULL;
- }
- dest->u.meta.dfile_count = src->u.meta.dfile_count;
- }
-
- if ((src->mask & PVFS_ATTR_COMMON_TYPE) &&
- (src->objtype == PVFS_TYPE_METAFILE) &&
- (src->mask & PVFS_ATTR_META_DIST))
- {
- assert(src->u.meta.dist_size > 0);
-
- if ((dest->mask & PVFS_ATTR_META_DIST))
- {
- PINT_dist_free(dest->u.meta.dist);
+ else
+ {
+ dest->u.meta.dfile_array = NULL;
+ }
+ dest->u.meta.dfile_count = src->u.meta.dfile_count;
}
- dest->u.meta.dist = PINT_dist_copy(src->u.meta.dist);
- if (dest->u.meta.dist == NULL)
+
+ if(src->mask & PVFS_ATTR_META_DIST)
{
- return ret;
+ assert(src->u.meta.dist_size > 0);
+
+ if ((dest->mask & PVFS_ATTR_META_DIST))
+ {
+ PINT_dist_free(dest->u.meta.dist);
+ }
+ dest->u.meta.dist = PINT_dist_copy(src->u.meta.dist);
+ if (dest->u.meta.dist == NULL)
+ {
+ return ret;
+ }
+ dest->u.meta.dist_size = src->u.meta.dist_size;
}
- dest->u.meta.dist_size = src->u.meta.dist_size;
}
if (src->mask & PVFS_ATTR_SYMLNK_TARGET)
@@ -231,6 +255,373 @@ void PINT_free_object_attr(PVFS_object_a
}
}
}
+}
+
+uint64_t PINT_keyword_to_mask(const PINT_keyword_mask_t * keyword_map,
+ size_t length,
+ const char *value)
+{
+ uint64_t mask = -1;
+ char *s = NULL, *t = NULL;
+ const char *toks = ", ";
+ int i = 0, negate = 0;
+
+ if (value)
+ {
+ s = strdup(value);
+ t = strtok(s, toks);
+
+ while(t)
+ {
+ if (*t == '-')
+ {
+ negate = 1;
+ ++t;
+ }
+
+ for(i = 0; i < length; i++)
+ {
+ if (!strcasecmp(t, keyword_map[i].keyword))
+ {
+ if (negate)
+ {
+ mask &= ~keyword_map[i].mask_val;
+ }
+ else
+ {
+ mask |= keyword_map[i].mask_val;
+ }
+ break;
+ }
+ }
+ t = strtok(NULL, toks);
+ }
+ free(s);
+ }
+ return mask;
+}
+
+const char * PINT_mask_to_keyword(const PINT_keyword_mask_t * mask_map,
+ size_t length,
+ uint64_t mask)
+{
+ int i = 0;
+ for(; i < length; ++i)
+ {
+ if(mask_map[i].mask_val & mask)
+ {
+ return mask_map[i].keyword;
+ }
+ }
+ return NULL;
+}
+
+char * PINT_print_keywords(const PINT_keyword_mask_t * keyword_array,
+ size_t arraylen,
+ int columns,
+ const char * sep)
+{
+ int i = 0;
+ char * kstr = NULL;
+ int kstrlen = 0;
+ int lastlinelen = 0;
+ int seplen = strlen(sep);
+ int sprlen = 0;
+
+ while(i < (arraylen-1))
+ {
+ kstr = realloc(kstr,
+ kstrlen +
+ strlen(keyword_array[i].keyword) +
+ seplen + 2);
+ if(!kstr)
+ {
+ return NULL;
+ }
+
+ sprlen = sprintf(kstr + kstrlen, "%s%s",
+ keyword_array[i].keyword,
+ sep);
+ kstrlen += sprlen;
+
+ if((kstrlen - lastlinelen) > columns)
+ {
+ sprintf(kstr + kstrlen, "\n");
+ kstrlen++;
+ lastlinelen = kstrlen;
+ }
+ ++i;
+ }
+
+ kstr = realloc(kstr, kstrlen + strlen(keyword_array[i].keyword) + 1);
+ if(!kstr)
+ {
+ return NULL;
+ }
+
+ sprintf(kstr + kstrlen, "%s", keyword_array[i].keyword);
+
+ return kstr;
+}
+
+
+/* PINT_check_mode()
+ *
+ * checks to see if the type of access described by "access_type" is permitted
+ * for user "uid" of group "gid" on the object with attributes "attr"
+ *
+ * returns 0 on success, -PVFS_EPERM if permission is not granted
+ */
+int PINT_check_mode(
+ PVFS_object_attr *attr,
+ PVFS_uid uid, PVFS_gid gid,
+ enum PINT_access_type access_type)
+{
+ int in_group_flag = 0;
+ int ret = 0;
+ uint32_t perm_mask = (PVFS_ATTR_COMMON_UID |
+ PVFS_ATTR_COMMON_GID |
+ PVFS_ATTR_COMMON_PERM);
+
+ /* if we don't have masks for the permission information that we
+ * need, then the system is broken
+ */
+ assert((attr->mask & perm_mask) == perm_mask);
+
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - check_mode called --- "
+ "(uid=%d,gid=%d,access_type=%d)\n", uid, gid, access_type);
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - object attributes --- "
+ "(uid=%d,gid=%d,mode=%d)\n", attr->owner, attr->group,
+ attr->perms);
+
+ /* give root permission, no matter what */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG,
+ " - checking if uid (%d) is root ...\n", uid);
+ if (uid == 0)
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return 0;
+ }
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+ /* see if uid matches object owner */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if owner (%d) "
+ "matches uid (%d)...\n", attr->owner, uid);
+ if(attr->owner == uid)
+ {
+ /* see if object user permissions match access type */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+ "(%d) allows access type (%d) for user...\n", attr->perms, access_type);
+ if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+ PVFS_U_READ))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+ PVFS_U_WRITE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+ PVFS_U_EXECUTE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+ }
+ else
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+ }
+
+ /* see if other bits allow access */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+ "(%d) allows access type (%d) by others...\n", attr->perms, access_type);
+ if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+ PVFS_O_READ))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+ PVFS_O_WRITE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+ PVFS_O_EXECUTE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+ /* see if gid matches object group */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if group (%d) "
+ "matches gid (%d)...\n", attr->group, gid);
+ if(attr->group == gid)
+ {
+ /* default group match */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ in_group_flag = 1;
+ }
+ else
+ {
+ /* no default group match, check supplementary groups */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking for"
+ " supplementary group match...\n");
+ ret = PINT_check_group(uid, attr->group);
+ if(ret == 0)
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ in_group_flag = 1;
+ }
+ else
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+ if(ret != -PVFS_ENOENT)
+ {
+ /* system error; not just failed match */
+ return(ret);
+ }
+ }
+ }
+
+ if(in_group_flag)
+ {
+ /* see if object group permissions match access type */
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+ "(%d) allows access type (%d) for group...\n", attr->perms, access_type);
+ if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+ PVFS_G_READ))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+ PVFS_G_WRITE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+ PVFS_G_EXECUTE))
+ {
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+ return(0);
+ }
+ gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+ }
+
+ /* default case: access denied */
+ return -PVFS_EPERM;
+}
+
+/* PINT_check_group()
+ *
+ * checks to see if uid is a member of gid
+ *
+ * returns 0 on success, -PVFS_ENOENT if not a member, other PVFS error codes
+ * on system failure
+ */
+static int PINT_check_group(uid_t uid, gid_t gid)
+{
+ struct passwd pwd;
+ struct passwd* pwd_p = NULL;
+ struct group grp;
+ struct group* grp_p = NULL;
+ int i = 0;
+ int ret = -1;
+
+ /* Explanation:
+ *
+ * We use the _r variants of getpwuid and getgrgid in order to insure
+ * thread safety; particularly if this function ever gets called in a
+ * client side situation in which we can't prevent the application from
+ * making conflicting calls.
+ *
+ * These _r functions require that a buffer be supplied for the user and
+ * group information, however. These buffers may be unconfortably large
+ * for the stack, so we malloc them on a static pointer and then mutex
+ * lock this function so that it can still be reentrant.
+ */
+
+ gen_mutex_lock(&check_group_mutex);
+
+ if(!check_group_pw_buffer)
+ {
+ /* need to create a buffer for pw and grp entries */
+#if defined(_SC_GETGR_R_SIZE_MAX) && defined(_SC_GETPW_R_SIZE_MAX)
+ /* newish posix systems can tell us what the max buffer size is */
+ check_group_gr_buffer_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+ check_group_pw_buffer_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+#else
+ /* fall back for older systems */
+ check_group_pw_buffer_size = 1024;
+ check_group_gr_buffer_size = 1024;
+#endif
+ check_group_pw_buffer = (char*)malloc(check_group_pw_buffer_size);
+ check_group_gr_buffer = (char*)malloc(check_group_gr_buffer_size);
+ if(!check_group_pw_buffer || !check_group_gr_buffer)
+ {
+ if(check_group_pw_buffer)
+ {
+ free(check_group_pw_buffer);
+ check_group_pw_buffer = NULL;
+ }
+ if(check_group_gr_buffer)
+ {
+ free(check_group_gr_buffer);
+ check_group_gr_buffer = NULL;
+ }
+ gen_mutex_unlock(&check_group_mutex);
+ return(-PVFS_ENOMEM);
+ }
+ }
+
+ /* get user information */
+ ret = getpwuid_r(uid, &pwd, check_group_pw_buffer,
+ check_group_pw_buffer_size,
+ &pwd_p);
+ if(ret != 0)
+ {
+ gen_mutex_unlock(&check_group_mutex);
+ return(-PVFS_ENOENT);
+ }
+
+ /* check primary group */
+ if(pwd.pw_gid == gid) return 0;
+
+ /* get other group information */
+ ret = getgrgid_r(gid, &grp, check_group_gr_buffer,
+ check_group_gr_buffer_size,
+ &grp_p);
+ if(ret != 0)
+ {
+ gen_mutex_unlock(&check_group_mutex);
+ return(-PVFS_ENOENT);
+ }
+
+ gen_mutex_unlock(&check_group_mutex);
+
+
+ for(i = 0; grp.gr_mem[i] != NULL; i++)
+ {
+ if(0 == strcmp(pwd.pw_name, grp.gr_mem[i]) )
+ {
+ gen_mutex_unlock(&check_group_mutex);
+ return 0;
+ }
+ }
+
+ gen_mutex_unlock(&check_group_mutex);
+ return(-PVFS_ENOENT);
}
/*
Index: pint-util.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pint-util.h,v
diff -p -u -r1.6 -r1.6.6.1
--- pint-util.h 3 Oct 2004 19:00:54 -0000 1.6
+++ pint-util.h 25 Aug 2005 20:38:17 -0000 1.6.6.1
@@ -47,6 +47,39 @@ void PINT_time_diff(PINT_time_marker mar
double* out_utime_sec,
double* out_stime_sec);
+/* allows us to define arrays that map human readable keywords to mask values */
+typedef struct
+{
+ char *keyword;
+ uint64_t mask_val;
+} PINT_keyword_mask_t;
+
+uint64_t PINT_keyword_to_mask(const PINT_keyword_mask_t * keyword_array,
+ size_t length,
+ const char *value);
+
+const char * PINT_mask_to_keyword(const PINT_keyword_mask_t * mask_map,
+ size_t length,
+ uint64_t mask);
+
+char * PINT_print_keywords(const PINT_keyword_mask_t * keyword_array,
+ size_t arraylen,
+ int columns,
+ const char * sep);
+
+enum PINT_access_type
+{
+ PINT_ACCESS_EXECUTABLE = 1,
+ PINT_ACCESS_WRITABLE = 2,
+ PINT_ACCESS_READABLE = 4,
+};
+
+int PINT_check_mode(
+ PVFS_object_attr *attr,
+ PVFS_uid uid, PVFS_gid gid,
+ enum PINT_access_type access_type);
+
+
#endif /* __PINT_UTIL_H */
/*
Index: pvfs2-debug.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pvfs2-debug.c,v
diff -p -u -r1.29 -r1.29.6.1
--- pvfs2-debug.c 27 Oct 2004 19:12:27 -0000 1.29
+++ pvfs2-debug.c 25 Aug 2005 20:38:17 -0000 1.29.6.1
@@ -10,13 +10,7 @@
#include <stdlib.h>
#include "pvfs2-debug.h"
-
-/* a private internal type */
-typedef struct
-{
- char *keyword;
- uint64_t mask_val;
-} __keyword_mask_t;
+#include "pint-util.h"
#define __DEBUG_ALL \
(GOSSIP_TROVE_DEBUG | GOSSIP_BMI_DEBUG_ALL | GOSSIP_SERVER_DEBUG |\
@@ -29,10 +23,12 @@ GOSSIP_REMOVE_DEBUG | GOSSIP_GETATTR_DEB
GOSSIP_IO_DEBUG | GOSSIP_DBPF_OPEN_CACHE_DEBUG | \
GOSSIP_PERMISSIONS_DEBUG | GOSSIP_CANCEL_DEBUG | \
GOSSIP_MSGPAIR_DEBUG | GOSSIP_CLIENTCORE_DEBUG | \
-GOSSIP_SETATTR_DEBUG | GOSSIP_MKDIR_DEBUG)
+GOSSIP_SETATTR_DEBUG | GOSSIP_MKDIR_DEBUG | \
+GOSSIP_SETEATTR_DEBUG | GOSSIP_GETEATTR_DEBUG | \
+GOSSIP_ACCESS_DEBUG | GOSSIP_ACCESS_DETAIL_DEBUG)
/* map all config keywords to pvfs2 debug masks here */
-static __keyword_mask_t s_keyword_mask_map[] =
+static PINT_keyword_mask_t s_keyword_mask_map[] =
{
{ "storage", GOSSIP_TROVE_DEBUG },
{ "trove", GOSSIP_TROVE_DEBUG },
@@ -40,6 +36,7 @@ static __keyword_mask_t s_keyword_mask_m
{ "network", GOSSIP_BMI_DEBUG_ALL },
{ "server", GOSSIP_SERVER_DEBUG },
{ "client", GOSSIP_CLIENT_DEBUG },
+ { "varstrip", GOSSIP_VARSTRIP_DEBUG },
{ "job", GOSSIP_JOB_DEBUG },
{ "request", GOSSIP_REQUEST_DEBUG },
{ "reqsched", GOSSIP_REQ_SCHED_DEBUG },
@@ -54,6 +51,8 @@ static __keyword_mask_t s_keyword_mask_m
{ "remove", GOSSIP_REMOVE_DEBUG },
{ "getattr", GOSSIP_GETATTR_DEBUG },
{ "setattr", GOSSIP_SETATTR_DEBUG },
+ { "geteattr", GOSSIP_GETEATTR_DEBUG },
+ { "seteattr", GOSSIP_SETEATTR_DEBUG },
{ "readdir", GOSSIP_READDIR_DEBUG },
{ "mkdir", GOSSIP_MKDIR_DEBUG },
{ "io", GOSSIP_IO_DEBUG },
@@ -63,6 +62,8 @@ static __keyword_mask_t s_keyword_mask_m
{ "msgpair", GOSSIP_MSGPAIR_DEBUG },
{ "clientcore", GOSSIP_CLIENTCORE_DEBUG },
{ "clientcore_timing", GOSSIP_CLIENTCORE_TIMING_DEBUG },
+ { "access", GOSSIP_ACCESS_DEBUG },
+ { "access_detail", GOSSIP_ACCESS_DETAIL_DEBUG },
{ "verbose", (__DEBUG_ALL & ~GOSSIP_REQ_SCHED_DEBUG)},
{ "none", GOSSIP_NO_DEBUG },
{ "all", __DEBUG_ALL }
@@ -70,7 +71,7 @@ static __keyword_mask_t s_keyword_mask_m
#undef __DEBUG_ALL
static const int num_keyword_mask_map = (int) \
-(sizeof(s_keyword_mask_map) / sizeof(__keyword_mask_t));
+(sizeof(s_keyword_mask_map) / sizeof(PINT_keyword_mask_t));
/*
* Based on human readable keywords, translate them into
@@ -83,44 +84,8 @@ static const int num_keyword_mask_map =
*/
uint64_t PVFS_debug_eventlog_to_mask(const char *event_logging)
{
- uint64_t mask = 0;
- char *s = NULL, *t = NULL;
- const char *toks = ", ";
- int i = 0, negate = 0;
-
- if (event_logging)
- {
- s = strdup(event_logging);
- t = strtok(s, toks);
-
- while(t)
- {
- if (*t == '-')
- {
- negate = 1;
- ++t;
- }
-
- for(i = 0; i < num_keyword_mask_map; i++)
- {
- if (!strcmp(t, s_keyword_mask_map[i].keyword))
- {
- if (negate)
- {
- mask &= ~s_keyword_mask_map[i].mask_val;
- }
- else
- {
- mask |= s_keyword_mask_map[i].mask_val;
- }
- break;
- }
- }
- t = strtok(NULL, toks);
- }
- free(s);
- }
- return mask;
+ return PINT_keyword_to_mask(
+ s_keyword_mask_map, num_keyword_mask_map, event_logging);
}
/*
@@ -133,7 +98,7 @@ uint64_t PVFS_debug_eventlog_to_mask(con
char *PVFS_debug_get_next_debug_keyword(int position)
{
int num_entries = (int)(sizeof(s_keyword_mask_map) /
- sizeof(__keyword_mask_t));
+ sizeof(PINT_keyword_mask_t));
return (((position > -1) && (position < num_entries)) ?
s_keyword_mask_map[position].keyword : NULL);
Index: pvfs2-util.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/pvfs2-util.c,v
diff -p -u -r1.74 -r1.74.6.1
--- pvfs2-util.c 27 Oct 2004 19:12:27 -0000 1.74
+++ pvfs2-util.c 25 Aug 2005 20:38:17 -0000 1.74.6.1
@@ -1,6 +1,10 @@
/*
* (C) 2001 Clemson University and The University of Chicago
*
+ * Changes by Acxiom Corporation to add relative path support to
+ * PVFS_util_resolve(),
+ * Copyright © Acxiom Corporation, 2005
+ *
* See COPYING in top-level directory.
*/
@@ -13,14 +17,18 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
+#include <libgen.h>
#include "pvfs2-config.h"
#include "pvfs2-sysint.h"
#include "pvfs2-util.h"
#include "pvfs2-debug.h"
#include "gossip.h"
+#include "pvfs2-attr.h"
+#include "pvfs2-types-debug.h"
#include "str-utils.h"
#include "gen-locks.h"
+#include "realpath.h"
/* TODO: add replacement functions for systems without getmntent() */
#ifndef HAVE_GETMNTENT
@@ -53,6 +61,14 @@ static int parse_encoding_string(
const char *cp,
enum PVFS_encoding_type *et);
+static int parse_num_dfiles_string(const char* cp, int* num_dfiles);
+
+static int PINT_util_resolve_absolute(
+ const char* local_path,
+ PVFS_fs_id* out_fs_id,
+ char* out_fs_path,
+ int out_fs_path_max);
+
void PVFS_util_gen_credentials(
PVFS_credentials *credentials)
{
@@ -118,17 +134,17 @@ int PVFS_util_copy_sys_attr(
dest_attr->objtype = src_attr->objtype;
dest_attr->mask = src_attr->mask;
- if ((src_attr->mask & PVFS_ATTR_COMMON_TYPE) &&
- (src_attr->objtype == PVFS_TYPE_SYMLINK) &&
+ if((src_attr->mask & PVFS_ATTR_SYS_LNK_TARGET) &&
src_attr->link_target)
{
dest_attr->link_target = strdup(src_attr->link_target);
if (!dest_attr->link_target)
{
ret = -PVFS_ENOMEM;
+ return ret;
}
- ret = 0;
}
+ ret = 0;
}
return ret;
}
@@ -137,7 +153,7 @@ void PVFS_util_release_sys_attr(PVFS_sys
{
if (attr)
{
- if ((attr->mask & PVFS_ATTR_COMMON_TYPE) &&
+ if ((attr->mask & PVFS_ATTR_SYS_TYPE) &&
(attr->objtype == PVFS_TYPE_SYMLINK) && attr->link_target)
{
free(attr->link_target);
@@ -166,9 +182,10 @@ const PVFS_util_tab *PVFS_util_parse_pvf
const char *tabfile)
{
FILE *mnt_fp = NULL;
- int file_count = 4;
- const char *file_list[4] =
- { NULL, "/etc/fstab", "/etc/pvfs2tab", "pvfs2tab" };
+ int file_count = 5;
+ /* NOTE: mtab should be last for clean error logic below */
+ const char *file_list[5] =
+ { NULL, "/etc/fstab", "/etc/pvfs2tab", "pvfs2tab", "/etc/mtab" };
const char *targetfile = NULL;
struct mntent *tmp_ent;
int i, j;
@@ -192,7 +209,6 @@ const PVFS_util_tab *PVFS_util_parse_pvf
first check for environment variable override
*/
file_list[0] = getenv("PVFS2TAB_FILE");
- file_count = 4;
}
gen_mutex_lock(&s_stat_tab_mutex);
@@ -322,9 +338,29 @@ const PVFS_util_tab *PVFS_util_parse_pvf
}
if (slashcount != 3)
{
- gossip_lerr("Error: invalid tab file entry: %s\n",
- tmp_ent->mnt_fsname);
- goto error_exit;
+ /* if we are looking at the mtab, then just silently
+ * treat this error as if we didn't find an entry at
+ * all; they may have mounted using an odd syntax on a
+ * 2.4 kernel system
+ */
+ if(!strcmp(targetfile, "/etc/mtab"))
+ {
+ gossip_err("Error: could not find any pvfs2 tabfile entries.\n");
+ gossip_err("Error: tried the following tabfiles:\n");
+ for (j = 0; j < file_count; j++)
+ {
+ gossip_err(" %s\n", file_list[j]);
+ }
+ goto error_exit;
+ }
+ else
+ {
+ gossip_err("Error: invalid tab file entry: %s\n",
+ tmp_ent->mnt_fsname);
+ gossip_err("Error: offending tab file: %s\n",
+ targetfile);
+ goto error_exit;
+ }
}
/* find a reference point in the string */
@@ -393,6 +429,23 @@ const PVFS_util_tab *PVFS_util_parse_pvf
goto error_exit;
}
}
+
+ /* find out if a particular flow protocol was specified */
+ current_tab->mntent_array[i].default_num_dfiles = 0;
+ cp = hasmntopt(tmp_ent, "num_dfiles");
+ if (cp)
+ {
+ ret = parse_num_dfiles_string(
+ cp,
+ &(current_tab->mntent_array[i].default_num_dfiles));
+
+ if (ret < 0)
+ {
+ goto error_exit;
+ }
+ }
+
+ /* Loop counter increment */
i++;
}
}
@@ -530,6 +583,7 @@ int PVFS_util_add_dynamic_mntent(struct
}
}
+#if 0
/* check the dynamic region if we haven't found a match yet */
for(j = 0; j < s_stat_tab_array[
PVFS2_DYNAMIC_TAB_INDEX].mntent_count; j++)
@@ -537,17 +591,20 @@ int PVFS_util_add_dynamic_mntent(struct
current_mnt = &(s_stat_tab_array[PVFS2_DYNAMIC_TAB_INDEX].
mntent_array[j]);
- if (current_mnt->fs_id == mntent->fs_id)
- {
- gossip_debug(
- GOSSIP_CLIENT_DEBUG, "* File system %d already "
- "mounted on %s already exists [dynamic]\n",
- mntent->fs_id, current_mnt->mnt_dir);
-
+ if ((current_mnt->fs_id == mntent->fs_id) &&
+ (strcmp(current_mnt->pvfs_config_servers[0],
+ mntent->pvfs_config_servers[0]) != 0))
+ {
+ gossip_err("Error: FS with id %d is already mounted using"
+ " a different config server.\n", (int)mntent->fs_id);
+ gossip_err("Error: This could indicate that a duplicate fsid"
+ " is being used.\n");
+ gossip_err("Error: Please check your server configuration.\n");
gen_mutex_unlock(&s_stat_tab_mutex);
- return -PVFS_EEXIST;
+ return -PVFS_ENXIO;
}
}
+#endif
/* copy the mntent to our table in the dynamic tab area */
new_index = s_stat_tab_array[
@@ -639,7 +696,8 @@ int PVFS_util_remove_internal_mntent(
for(j = 0; j < s_stat_tab_array[i].mntent_count; j++)
{
current_mnt = &(s_stat_tab_array[i].mntent_array[j]);
- if (current_mnt->fs_id == mntent->fs_id)
+ if ((current_mnt->fs_id == mntent->fs_id)
+ && (strcmp(current_mnt->mnt_dir, mntent->mnt_dir) == 0))
{
found_index = i;
found = 1;
@@ -700,7 +758,8 @@ int PVFS_util_remove_internal_mntent(
{
current_mnt = &s_stat_tab_array[found_index].mntent_array[i];
- if (current_mnt->fs_id == mntent->fs_id)
+ if ((current_mnt->fs_id == mntent->fs_id)
+ && (strcmp(current_mnt->mnt_dir, mntent->mnt_dir) == 0))
{
PVFS_util_free_mntent(current_mnt);
continue;
@@ -735,10 +794,45 @@ int PVFS_util_remove_internal_mntent(
return ret;
}
+/*
+ * PVFS_util_get_mntent_copy()
+ *
+ * Given a pointer to a valid mount entry, out_mntent, copy the contents of
+ * the mount entry for fs_id into out_mntent.
+ *
+ * returns 0 on success, -PVFS_error on failure
+ */
+int PVFS_util_get_mntent_copy(PVFS_fs_id fs_id,
+ struct PVFS_sys_mntent* out_mntent)
+{
+ int i = 0;
+
+ /* Search for mntent by fsid */
+ gen_mutex_lock(&s_stat_tab_mutex);
+ for(i = 0; i < s_stat_tab_count; i++)
+ {
+ int j;
+ for(j = 0; j < s_stat_tab_array[i].mntent_count; j++)
+ {
+ struct PVFS_sys_mntent* mnt_iter;
+ mnt_iter = &(s_stat_tab_array[i].mntent_array[j]);
+
+ if (mnt_iter->fs_id == fs_id)
+ {
+ PVFS_util_copy_mntent(out_mntent, mnt_iter);
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return 0;
+ }
+ }
+ }
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return -PVFS_EINVAL;
+}
+
/* PVFS_util_resolve()
*
* given a local path of a file that resides on a pvfs2 volume,
- * determine what the fsid and fs relative path is
+ * determine what the fsid and fs relative path is.
*
* returns 0 on succees, -PVFS_error on failure
*/
@@ -748,65 +842,83 @@ int PVFS_util_resolve(
char* out_fs_path,
int out_fs_path_max)
{
- int i = 0, j = 0;
- int ret = -PVFS_EINVAL;
-
- gen_mutex_lock(&s_stat_tab_mutex);
+ int ret = -1;
+ char* tmp_path = NULL;
+ char* parent_path = NULL;
+ int base_len = 0;
- for(i=0; i < s_stat_tab_count; i++)
+ /* the most common case first; just try to resolve the path that we
+ * were given
+ */
+ ret = PINT_util_resolve_absolute(local_path, out_fs_id, out_fs_path,
+ out_fs_path_max);
+ if(ret == 0)
{
- for(j=0; j<s_stat_tab_array[i].mntent_count; j++)
- {
- ret = PINT_remove_dir_prefix(
- local_path, s_stat_tab_array[i].mntent_array[j].mnt_dir,
- out_fs_path, out_fs_path_max);
- if(ret == 0)
- {
- *out_fs_id = s_stat_tab_array[i].mntent_array[j].fs_id;
- if(*out_fs_id == PVFS_FS_ID_NULL)
- {
- gossip_err("Error: %s resides on a PVFS2 file system "
- "that has not yet been initialized.\n", local_path);
-
- gen_mutex_unlock(&s_stat_tab_mutex);
- return(-PVFS_ENXIO);
- }
- gen_mutex_unlock(&s_stat_tab_mutex);
- return(0);
- }
- }
+ /* done */
+ return(0);
}
-
- /* check the dynamic tab area if we haven't resolved anything yet */
- for(j = 0; j < s_stat_tab_array[
- PVFS2_DYNAMIC_TAB_INDEX].mntent_count; j++)
+ if(ret == -PVFS_ENOENT)
{
- ret = PINT_remove_dir_prefix(
- local_path, s_stat_tab_array[
- PVFS2_DYNAMIC_TAB_INDEX].mntent_array[j].mnt_dir,
- out_fs_path, out_fs_path_max);
- if (ret == 0)
+ /* if the path wasn't found, try canonicalizing the path in case it
+ * refers to a relative path on a mounted volume or contains symlinks
+ */
+ tmp_path = (char*)malloc(PVFS_NAME_MAX*sizeof(char));
+ if(!tmp_path)
{
- *out_fs_id = s_stat_tab_array[
- PVFS2_DYNAMIC_TAB_INDEX].mntent_array[j].fs_id;
- if(*out_fs_id == PVFS_FS_ID_NULL)
+ return(-PVFS_ENOMEM);
+ }
+ memset(tmp_path, 0, PVFS_NAME_MAX*sizeof(char));
+ ret = PINT_realpath(local_path, tmp_path, (PVFS_NAME_MAX-1));
+ if(ret == -PVFS_EINVAL)
+ {
+ /* one more try; canonicalize the parent in case this function
+ * is called before object creation; the basename
+ * doesn't yet exist but we still need to find the PVFS volume
+ */
+ parent_path = (char*)malloc(PVFS_NAME_MAX*sizeof(char));
+ if(!parent_path)
{
- gossip_err("Error: %s resides on a PVFS2 file system "
- "that has not yet been initialized.\n",
- local_path);
-
- gen_mutex_unlock(&s_stat_tab_mutex);
- return(-PVFS_ENXIO);
+ free(tmp_path);
+ return(-PVFS_ENOMEM);
}
- gen_mutex_unlock(&s_stat_tab_mutex);
- return(0);
+ /* find size of basename so we can reserve space for it */
+ /* note: basename() and dirname() modifiy args, thus the strcpy */
+ strcpy(parent_path, local_path);
+ base_len = strlen(basename(parent_path));
+ strcpy(parent_path, local_path);
+ ret = PINT_realpath(dirname(parent_path), tmp_path,
+ (PVFS_NAME_MAX-base_len-2));
+ if(ret < 0)
+ {
+ free(tmp_path);
+ free(parent_path);
+ /* last chance failed; this is not a valid pvfs2 path */
+ return(-PVFS_ENOENT);
+ }
+ /* glue the basename back on */
+ strcpy(parent_path, local_path);
+ strcat(tmp_path, "/");
+ strcat(tmp_path, basename(parent_path));
+ free(parent_path);
+ }
+ else if(ret < 0)
+ {
+ /* first canonicalize failed; this is not a valid pvfs2 path */
+ free(tmp_path);
+ return(-PVFS_ENOENT);
}
+
+ ret = PINT_util_resolve_absolute(tmp_path, out_fs_id, out_fs_path,
+ out_fs_path_max);
+ free(tmp_path);
+
+ /* fall through and preserve "ret" to be returned */
}
- gen_mutex_unlock(&s_stat_tab_mutex);
- return(-PVFS_ENOENT);
+ return(ret);
}
+
/* PVFS_util_init_defaults()
*
* performs the standard set of initialization steps for the system
@@ -1015,11 +1127,7 @@ static int parse_flowproto_string(
comma[0] = '\0';
}
- if (!strcmp(flow, "bmi_trove"))
- {
- *flowproto = FLOWPROTO_BMI_TROVE;
- }
- else if (!strcmp(flow, "dump_offsets"))
+ if (!strcmp(flow, "dump_offsets"))
{
*flowproto = FLOWPROTO_DUMP_OFFSETS;
}
@@ -1142,6 +1250,7 @@ int PVFS_util_copy_mntent(
dest_mntent->flowproto = src_mntent->flowproto;
dest_mntent->encoding = src_mntent->encoding;
dest_mntent->fs_id = src_mntent->fs_id;
+ dest_mntent->default_num_dfiles = src_mntent->default_num_dfiles;
}
return 0;
@@ -1288,6 +1397,207 @@ void PINT_release_pvfstab(void)
gen_mutex_unlock(&s_stat_tab_mutex);
}
+inline uint32_t PVFS_util_sys_to_object_attr_mask(
+ uint32_t sys_attrmask)
+{
+
+ /*
+ adjust parameters as necessary; what's happening here
+ is that we're converting sys_attr masks to obj_attr masks
+ before passing the getattr request to the server.
+ */
+ uint32_t attrmask = 0;
+ if (sys_attrmask & PVFS_ATTR_SYS_SIZE)
+ {
+ /* need datafile handles and distribution in order to get
+ * datafile handles and know what function to call to get
+ * the file size.
+ */
+ attrmask |= (PVFS_ATTR_META_ALL | PVFS_ATTR_DATA_SIZE);
+ }
+
+ if (sys_attrmask & PVFS_ATTR_SYS_DFILE_COUNT)
+ {
+ attrmask |= PVFS_ATTR_META_DFILES;
+ }
+
+ if (sys_attrmask & PVFS_ATTR_SYS_LNK_TARGET)
+ {
+ attrmask |= PVFS_ATTR_SYMLNK_TARGET;
+ }
+
+ gossip_debug(GOSSIP_GETATTR_DEBUG,
+ "attrmask being passed to server: ");
+ PINT_attrmask_print(GOSSIP_GETATTR_DEBUG, attrmask);
+
+ return attrmask;
+}
+
+inline uint32_t PVFS_util_object_to_sys_attr_mask(
+ uint32_t obj_mask)
+{
+ int sys_mask = 0;
+
+ if (obj_mask & PVFS_ATTR_COMMON_UID)
+ {
+ sys_mask |= PVFS_ATTR_SYS_UID;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_GID)
+ {
+ sys_mask |= PVFS_ATTR_SYS_GID;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_PERM)
+ {
+ sys_mask |= PVFS_ATTR_SYS_PERM;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_ATIME)
+ {
+ sys_mask |= PVFS_ATTR_SYS_ATIME;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_CTIME)
+ {
+ sys_mask |= PVFS_ATTR_SYS_CTIME;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_MTIME)
+ {
+ sys_mask |= PVFS_ATTR_SYS_MTIME;
+ }
+ if (obj_mask & PVFS_ATTR_COMMON_TYPE)
+ {
+ sys_mask |= PVFS_ATTR_SYS_TYPE;
+ }
+ if (obj_mask & PVFS_ATTR_DATA_SIZE)
+ {
+ sys_mask |= PVFS_ATTR_DATA_SIZE;
+ }
+ if (obj_mask & PVFS_ATTR_SYMLNK_TARGET)
+ {
+ sys_mask |= PVFS_ATTR_SYS_LNK_TARGET;
+ }
+ return sys_mask;
+}
+
+/*
+ * Pull out the wire encoding specified as a mount option in the tab
+ * file.
+ *
+ * Input string is not modified; result goes into et.
+ *
+ * Returns 0 if all okay.
+ */
+static int parse_num_dfiles_string(const char* cp, int* num_dfiles)
+{
+ int parsed_value = 0;
+ char* end_ptr = NULL;
+
+ gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: input is %s\n",
+ __func__, cp);
+
+ cp += strlen("num_dfiles");
+
+ /* Skip optional spacing */
+ for (; isspace(*cp); cp++);
+
+ if (*cp != '=')
+ {
+ gossip_err("Error: %s: malformed num_dfiles option in tab file.\n",
+ __func__);
+ return -PVFS_EINVAL;
+ }
+
+ /* Skip optional spacing */
+ for (++cp; isspace(*cp); cp++);
+
+ parsed_value = strtol(cp, &end_ptr, 10);
+
+ /* If a numerica value was found, continue
+ else, report an error */
+ if (end_ptr != cp)
+ {
+ *num_dfiles = parsed_value;
+ }
+ else
+ {
+ gossip_err("Error: %s: malformed num_dfiles option in tab file.\n",
+ __func__);
+ return -PVFS_EINVAL;
+ }
+
+ return 0;
+}
+
+/* PINT_util_resolve_absolute()
+ *
+ * given a local path of a file that may reside on a pvfs2 volume,
+ * determine what the fsid and fs relative path is. Makes no attempt
+ * to canonicalize the path.
+ *
+ * returns 0 on succees, -PVFS_error on failure
+ */
+static int PINT_util_resolve_absolute(
+ const char* local_path,
+ PVFS_fs_id* out_fs_id,
+ char* out_fs_path,
+ int out_fs_path_max)
+{
+ int i = 0, j = 0;
+ int ret = -PVFS_EINVAL;
+
+ gen_mutex_lock(&s_stat_tab_mutex);
+
+ for(i=0; i < s_stat_tab_count; i++)
+ {
+ for(j=0; j<s_stat_tab_array[i].mntent_count; j++)
+ {
+ ret = PINT_remove_dir_prefix(
+ local_path, s_stat_tab_array[i].mntent_array[j].mnt_dir,
+ out_fs_path, out_fs_path_max);
+ if(ret == 0)
+ {
+ *out_fs_id = s_stat_tab_array[i].mntent_array[j].fs_id;
+ if(*out_fs_id == PVFS_FS_ID_NULL)
+ {
+ gossip_err("Error: %s resides on a PVFS2 file system "
+ "that has not yet been initialized.\n", local_path);
+
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return(-PVFS_ENXIO);
+ }
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return(0);
+ }
+ }
+ }
+
+ /* check the dynamic tab area if we haven't resolved anything yet */
+ for(j = 0; j < s_stat_tab_array[
+ PVFS2_DYNAMIC_TAB_INDEX].mntent_count; j++)
+ {
+ ret = PINT_remove_dir_prefix(
+ local_path, s_stat_tab_array[
+ PVFS2_DYNAMIC_TAB_INDEX].mntent_array[j].mnt_dir,
+ out_fs_path, out_fs_path_max);
+ if (ret == 0)
+ {
+ *out_fs_id = s_stat_tab_array[
+ PVFS2_DYNAMIC_TAB_INDEX].mntent_array[j].fs_id;
+ if(*out_fs_id == PVFS_FS_ID_NULL)
+ {
+ gossip_err("Error: %s resides on a PVFS2 file system "
+ "that has not yet been initialized.\n",
+ local_path);
+
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return(-PVFS_ENXIO);
+ }
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return(0);
+ }
+ }
+
+ gen_mutex_unlock(&s_stat_tab_mutex);
+ return(-PVFS_ENOENT);
+}
/*
* Local variables:
* c-indent-level: 4
Index: server-config-mgr.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/server-config-mgr.c,v
diff -p -u -r1.13 -r1.13.6.1
--- server-config-mgr.c 5 Oct 2004 15:04:17 -0000 1.13
+++ server-config-mgr.c 25 Aug 2005 20:38:18 -0000 1.13.6.1
@@ -33,6 +33,7 @@ typedef struct
gen_mutex_t *server_config_mutex;
struct server_configuration_s *server_config;
+ int ref_count; /* allows same config to be added multiple times */
} server_config_t;
static struct qhash_table *s_fsid_to_config_table = NULL;
@@ -167,9 +168,7 @@ int PINT_server_config_mgr_reload_cached
for (i = 0; i < s_fsid_to_config_table->table_size; i++)
{
- hash_link = qhash_search_at_index(
- s_fsid_to_config_table, i);
- if (hash_link)
+ qhash_for_each(hash_link, &s_fsid_to_config_table->array[i])
{
config = qlist_entry(
hash_link, server_config_t, hash_link);
@@ -238,8 +237,15 @@ int PINT_server_config_mgr_add_config(
hash_link = qhash_search(s_fsid_to_config_table, &fs_id);
if (hash_link)
{
- ret = -PVFS_EEXIST;
- goto add_failure;
+ gossip_debug(GOSSIP_CLIENT_DEBUG, "PINT_server_config_mgr_add_"
+ "config: increasing reference count.\n");
+ /* config is already stored here, increase reference count */
+ config = qlist_entry(hash_link, server_config_t, hash_link);
+ assert(config);
+ assert(config->server_config);
+ config->ref_count++;
+ gen_mutex_unlock(s_server_config_mgr_mutex);
+ return(0);
}
config = (server_config_t *)malloc(sizeof(server_config_t));
@@ -259,6 +265,7 @@ int PINT_server_config_mgr_add_config(
config->server_config = config_s;
config->fs_id = fs_id;
+ config->ref_count = 1;
qhash_add(s_fsid_to_config_table, &fs_id,
&config->hash_link);
@@ -305,7 +312,7 @@ int PINT_server_config_mgr_remove_config
gen_mutex_lock(s_server_config_mgr_mutex);
SC_MGR_ASSERT_OK(ret);
- hash_link = qhash_search_and_remove(
+ hash_link = qhash_search(
s_fsid_to_config_table, &fs_id);
if (hash_link)
{
@@ -314,26 +321,38 @@ int PINT_server_config_mgr_remove_config
assert(config->server_config);
assert(config->fs_id == fs_id);
- gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: "
- "Removed config object %p with fs_id %d\n",
- __func__, config, fs_id);
-
- /*
- config objects are allocated by fs-add.c:PVFS_sys_fs_add
- but we free them here
- */
- PINT_config_release(config->server_config);
- free(config->server_config);
+ config->ref_count--;
- if (gen_mutex_trylock(config->server_config_mutex) == EBUSY)
+ if(config->ref_count == 0)
{
- gossip_err("FIXME: Destroying mutex that is in use!\n");
- }
- gen_mutex_unlock(config->server_config_mutex);
- gen_mutex_destroy(config->server_config_mutex);
+ gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: "
+ "Removed config object %p with fs_id %d\n",
+ __func__, config, fs_id);
+ qhash_del(&config->hash_link);
+
+ /*
+ * config objects are allocated by fs-add.c:PVFS_sys_fs_add
+ * but we free them here
+ */
+ PINT_config_release(config->server_config);
+ free(config->server_config);
- free(config);
- config = NULL;
+ if(gen_mutex_trylock(config->server_config_mutex) == EBUSY)
+ {
+ gossip_err("FIXME: Destroying mutex that is in use!\n");
+ }
+ gen_mutex_unlock(config->server_config_mutex);
+ gen_mutex_destroy(config->server_config_mutex);
+
+ free(config);
+ config = NULL;
+ }
+ else
+ {
+ gossip_debug(GOSSIP_CLIENT_DEBUG, "%s: "
+ "Config object %p with fs_id %d still in use.\n",
+ __func__, config, fs_id);
+ }
ret = 0;
}
Index: server-config.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/server-config.c,v
diff -p -u -r1.67.4.1 -r1.67.4.2
--- server-config.c 7 Jun 2005 21:59:12 -0000 1.67.4.1
+++ server-config.c 25 Aug 2005 20:38:18 -0000 1.67.4.2
@@ -21,7 +21,9 @@
#include "gossip.h"
#include "extent-utils.h"
#include "mkspace.h"
+#include "pint-distribution.h"
#include "pvfs2-config.h"
+#include "pvfs2-server.h"
static DOTCONF_CB(get_pvfs_server_id);
static DOTCONF_CB(get_logstamp);
@@ -38,10 +40,12 @@ static DOTCONF_CB(enter_mhranges_context
static DOTCONF_CB(exit_mhranges_context);
static DOTCONF_CB(enter_dhranges_context);
static DOTCONF_CB(exit_dhranges_context);
+static DOTCONF_CB(enter_distribution_context);
+static DOTCONF_CB(exit_distribution_context);
static DOTCONF_CB(get_unexp_req);
static DOTCONF_CB(get_perf_update_interval);
static DOTCONF_CB(get_root_handle);
-static DOTCONF_CB(get_filesystem_name);
+static DOTCONF_CB(get_name);
static DOTCONF_CB(get_logfile);
static DOTCONF_CB(get_event_logging_list);
static DOTCONF_CB(get_event_log_size);
@@ -56,9 +60,20 @@ static DOTCONF_CB(get_attr_cache_size);
static DOTCONF_CB(get_attr_cache_max_num_elems);
static DOTCONF_CB(get_trove_sync_meta);
static DOTCONF_CB(get_trove_sync_data);
+static DOTCONF_CB(get_param);
+static DOTCONF_CB(get_value);
+static DOTCONF_CB(get_default_num_dfiles);
+static DOTCONF_CB(get_server_job_bmi_timeout);
+static DOTCONF_CB(get_server_job_flow_timeout);
+static DOTCONF_CB(get_client_job_bmi_timeout);
+static DOTCONF_CB(get_client_job_flow_timeout);
+static DOTCONF_CB(get_client_retry_limit);
+static DOTCONF_CB(get_client_retry_delay);
+static FUNC_ERRORHANDLER(errorhandler);
+const char *contextchecker(command_t *cmd, unsigned long mask);
/* internal helper functions */
-static int is_valid_alias(char *str);
+static int is_valid_alias(PINT_llist * host_aliases, char *str);
static int is_valid_handle_range_description(char *h_range);
static void free_host_handle_mapping(void *ptr);
static void free_host_alias(void *ptr);
@@ -67,6 +82,7 @@ static void copy_filesystem(
struct filesystem_configuration_s *dest_fs,
struct filesystem_configuration_s *src_fs);
static int cache_config_files(
+ struct server_configuration_s *config_s,
char *global_config_filename,
char *server_config_filename);
static int is_populated_filesystem_configuration(
@@ -90,50 +106,447 @@ static struct host_handle_mapping_s *get
static int build_extent_array(
char *handle_range_str,
PVFS_handle_extent_array *handle_extent_array);
+
#ifdef __PVFS2_TROVE_SUPPORT__
static int is_root_handle_in_my_range(
struct server_configuration_s *config_s,
struct filesystem_configuration_s *fs);
#endif
-static struct server_configuration_s *config_s = NULL;
-
+/*
+ * NOTE: The documentation for the server config format is generated
+ * from the following static array. The documentation for an option
+ * is taken from the comments found before the beginning of each sub-structure
+ * as shown.
+ */
static const configoption_t options[] =
{
- {"HostID",ARG_STR, get_pvfs_server_id,NULL,CTX_ALL},
- {"StorageSpace",ARG_STR, get_storage_space,NULL,CTX_ALL},
- {"<Defaults>",ARG_NONE, enter_defaults_context,NULL,CTX_ALL},
- {"</Defaults>",ARG_NONE, exit_defaults_context,NULL,CTX_ALL},
- {"<Aliases>",ARG_NONE, enter_aliases_context,NULL,CTX_ALL},
- {"</Aliases>",ARG_NONE, exit_aliases_context,NULL,CTX_ALL},
- {"Alias",ARG_LIST, get_alias_list,NULL,CTX_ALL},
- {"<FileSystem>",ARG_NONE, enter_filesystem_context,NULL,CTX_ALL},
- {"</FileSystem>",ARG_NONE, exit_filesystem_context,NULL,CTX_ALL},
- {"<StorageHints>",ARG_NONE, enter_storage_hints_context,NULL,CTX_ALL},
- {"</StorageHints>",ARG_NONE, exit_storage_hints_context,NULL,CTX_ALL},
- {"<MetaHandleRanges>",ARG_NONE, enter_mhranges_context,NULL,CTX_ALL},
- {"</MetaHandleRanges>",ARG_NONE, exit_mhranges_context,NULL,CTX_ALL},
- {"<DataHandleRanges>",ARG_NONE, enter_dhranges_context,NULL,CTX_ALL},
- {"</DataHandleRanges>",ARG_NONE, exit_dhranges_context,NULL,CTX_ALL},
- {"Range",ARG_LIST, get_range_list,NULL,CTX_ALL},
- {"RootHandle",ARG_STR, get_root_handle,NULL,CTX_ALL},
- {"Name",ARG_STR, get_filesystem_name,NULL,CTX_ALL},
- {"ID",ARG_INT, get_filesystem_collid,NULL,CTX_ALL},
- {"LogFile",ARG_STR, get_logfile,NULL,CTX_ALL},
- {"EventLogging",ARG_LIST, get_event_logging_list,NULL,CTX_ALL},
- {"EventLogSize",ARG_INT, get_event_log_size,NULL,CTX_ALL},
- {"UnexpectedRequests",ARG_INT, get_unexp_req,NULL,CTX_ALL},
- {"PerfUpdateInterval",ARG_INT, get_perf_update_interval,NULL,CTX_ALL},
- {"BMIModules",ARG_LIST, get_bmi_module_list,NULL,CTX_ALL},
- {"FlowModules",ARG_LIST, get_flow_module_list,NULL,CTX_ALL},
+ /*
+ * Specifies a string identifier for the pvfs2 server that is to be
+ * run on this host. The format of this string is:
+ *
+ * {transport}://{hostname}:{port}
+ *
+ * Where {transport} is one of the possible BMI transport modules
+ * (tcp, ib, gm). Example:
+ *
+ * tcp://myhost.mydn:12345
+ *
+ */
+ {"HostID",ARG_STR, get_pvfs_server_id,NULL,CTX_GLOBAL,NULL},
+
+ /* Specifies the local path for the pvfs2 server to use as storage space.
+ * Example:
+ *
+ * /tmp/pvfs.storage
+ */
+ {"StorageSpace",ARG_STR, get_storage_space,NULL,CTX_GLOBAL,NULL},
+
+ /* Specifies the beginning of the Defaults context. Options specified
+ * within the Defaults context are used as default values over all the
+ * pvfs2 server specific config files.
+ */
+ {"<Defaults>",ARG_NONE, enter_defaults_context,NULL,CTX_GLOBAL,NULL},
+
+ /* Specifies the end-tag for the Defaults context.
+ */
+ {"</Defaults>",ARG_NONE, exit_defaults_context,NULL,CTX_DEFAULTS,NULL},
+
+ /* Specifies the beginning of the Aliases context. This groups
+ * the Alias mapping options.
+ *
+ * The Aliases context should be defined before any FileSystem contexts
+ * are defined, as options in the FileSystem context usually need to
+ * reference the aliases defined in this context.
+ */
+ {"<Aliases>",ARG_NONE, enter_aliases_context,NULL,CTX_GLOBAL,NULL},
+
+ /* Specifies the end-tag for the Aliases context.
+ */
+ {"</Aliases>",ARG_NONE, exit_aliases_context,NULL,CTX_ALIASES,NULL},
+
+ /* Specifies an alias in the form of a non-whitespace string that
+ * can be used to reference a BMI server address (a HostID). This
+ * allows us to reference individual servers by an alias instead of their
+ * full HostID. The format of the Alias option is:
+ *
+ * Alias {alias string} {bmi address}
+ *
+ * As an example:
+ *
+ * Alias mynode1 tcp://hostname1.clustername1.domainname:12345
+ */
+ {"Alias",ARG_LIST, get_alias_list,NULL,CTX_ALIASES,NULL},
+
+ /* Specifies the beginning of a Filesystem context. This groups
+ * options specific to a filesystem. A pvfs2 server may manage
+ * more than one filesystem, so a config file may have more than
+ * one Filesystem context, each defining the parameters of a different
+ * Filesystem.
+ */
+ {"<FileSystem>",ARG_NONE, enter_filesystem_context,NULL,CTX_GLOBAL,NULL},
+
+ /* Specifies the end-tag of a Filesystem context.
+ */
+ {"</FileSystem>",ARG_NONE, exit_filesystem_context,NULL,CTX_FILESYSTEM,
+ NULL},
+
+ /* Specifies the beginning of a StorageHints context. This groups
+ * options specific to a filesystem and related to the behavior of the
+ * storage system. Mostly these options are passed directly to the
+ * TROVE storage module which may or may not support them. The
+ * DBPF module (the only TROVE module implemented at present) supports
+ * all of them.
+ */
+ {"<StorageHints>",ARG_NONE, enter_storage_hints_context,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* Specifies the end-tag of the StorageHints context.
+ */
+ {"</StorageHints>",ARG_NONE, exit_storage_hints_context,NULL,
+ CTX_STORAGEHINTS,NULL},
+
+ /* This context groups together the Range options that define valid values
+ * for meta handles on a per-host basis for this filesystem.
+ *
+ * The MetaHandleRanges context is required to be present in a
+ * Filesystem context.
+ */
+ {"<MetaHandleRanges>",ARG_NONE, enter_mhranges_context,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* Specifies the end-tag for the MetaHandleRanges context.
+ */
+ {"</MetaHandleRanges>",ARG_NONE, exit_mhranges_context,NULL,
+ CTX_METAHANDLERANGES,NULL},
+
+ /* This context groups together the Range options that define valid values
+ * for the data handles on a per-host basis for this filesystem.
+ *
+ * A DataHandleRanges context is required to be present in a
+ * Filesystem context.
+ */
+ {"<DataHandleRanges>",ARG_NONE, enter_dhranges_context,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* Specifies the end-tag for the DataHandleRanges context.
+ */
+ {"</DataHandleRanges>",ARG_NONE, exit_dhranges_context,NULL,
+ CTX_DATAHANDLERANGES,NULL},
+
+ /* Provides a context for defining the filesystem's default
+ * distribution to use and the parameters to be set for that distribution.
+ *
+ * Valid options within the Distribution context are Name, Param, and Value.
+ *
+ * This context is an optional context within the Filesystem context. If
+ * not specified, the filesystem defaults to the simple-stripe distribution.
+ */
+ {"<Distribution>",ARG_NONE, enter_distribution_context,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* Specifies the end-tag for the Distribution context.
+ */
+ {"</Distribution>",ARG_NONE, exit_distribution_context,NULL,
+ CTX_DISTRIBUTION,NULL},
+
+ /* As logical files are created in pvfs2, the data files and meta files
+ * that represent them are given filesystem unique handle values. The
+ * user can specify a range of values (or set of ranges)
+ * to be allocated to data files and meta files for a particular server,
+ * using the Range option in the DataHandleRanges and MetaHandleRanges
+ * contexts. Note that in most cases, its easier to let the
+ * pvfs2-genconfig script determine the best ranges to specify.
+ *
+ * This option specifies a range of handle values that can be used for
+ * a particular pvfs2 server in a particular context (meta handles
+ * or data handles). The DataHandleRanges and MetaHandleRanges contexts
+ * should contain one or more Range options. The format is:
+ *
+ * Range {alias} {min value1}-{max value1}[, {min value2}-{max value2},...]
+ *
+ * Where {alias} is one of the alias strings already specified in the
+ * Aliases context.
+ *
+ * {min value} and {max value} are positive integer values that specify
+ * the range of possible handles that can be given out for that particular
+ * host. {max value} must be less than 18446744073709551615 (UINT64_MAX).
+ *
+ * As shown in the specified format, multiple ranges can be specified for
+ * the same alias. The format requires that max value of a given range
+ * is less than the min value of the next one,
+ * i.e. {max value1}<{min value2}
+ *
+ * Example of a Range option for data handles:
+ *
+ * Range mynode1 2147483651-4294967297
+ */
+ {"Range",ARG_LIST, get_range_list,NULL,
+ CTX_METAHANDLERANGES|CTX_DATAHANDLERANGES,NULL},
+
+ /* Specifies the handle value for the root of the Filesystem. This
+ * is a required option in the Filesystem context. The format is:
+ *
+ * RootHandle {handle value}
+ *
+ * Where {handle value} is a positive integer no greater than
+ * 18446744073709551615 (UIN64_MAX).
+ *
+ * In general its best to let the pvfs2-genconfig script specify a
+ * RootHandle value for the filesystem.
+ */
+ {"RootHandle",ARG_STR, get_root_handle,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* This option specifies the name of the particular filesystem or
+ * distribution that its defined in. It is a required option in
+ * Filesystem and Distribution contexts.
+ */
+ {"Name",ARG_STR, get_name,NULL,
+ CTX_FILESYSTEM|CTX_DISTRIBUTION,NULL},
+
+ /* A pvfs2 server may manage more than one filesystem, and so a
+ * unique identifier is used to represent each one.
+ * This option specifies such an ID (sometimes called a 'collection
+ * id') for the filesystem it is defined in.
+ *
+ * The ID value can be any positive integer, no greater than
+ * 2147483647 (INT32_MAX). It is a required option in the Filesystem
+ * context.
+ */
+ {"ID",ARG_INT, get_filesystem_collid,NULL,
+ CTX_FILESYSTEM,NULL},
+
+ /* The gossip interface in pvfs2 allows users to specify different
+ * levels of logging for the pvfs2 server. The output of these
+ * different log levels is written to a file, which is specified in
+ * this option. The value of the option must be the path pointing to a
+ * file with valid write permissions. The Logfile option can be
+ * specified for all the pvfs2 servers in the Defaults context or for
+ * a particular server in the Global context.
+ */
+ {"LogFile",ARG_STR, get_logfile,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"/tmp/pvfs2-server.log"},
+
+ /* The gossip interface in pvfs2 allows users to specify different
+ * levels of logging for the pvfs2 server. This option sets that level for
+ * either all servers (by being defined in the Defaults context) or for
+ * a particular server by defining it in the Global context. Possible
+ * values for event logging are:
+ *
+ * __EVENTLOGGING__
+ *
+ * The value of the EventLogging option can be a comma separated list
+ * of the above values. Individual values can also be negated with
+ * a '-'. Examples of possible values are:
+ *
+ * EventLogging flow,msgpair,io
+ * EventLogging -storage
+ * EventLogging -flow,-flowproto
+ */
+ {"EventLogging",ARG_LIST, get_event_logging_list,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"none,"},
+
+ /* At startup each pvfs2 server allocates space for a set number
+ * of incoming requests to prevent the allocation delay at the beginning
+ * of each unexpected request. This parameter specifies the number
+ * of requests for which to allocate space.
+ *
+ * If set in the Defaults context, its value will be used for all servers.
+ * The default value can also be overwritten by setting a separate value
+ * in the Global context.
+ */
+ {"UnexpectedRequests",ARG_INT, get_unexp_req,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"50"},
+
+ /* Specifies the timeout value in seconds for BMI jobs on the server.
+ */
+ {"ServerJobBMITimeoutSecs",ARG_INT, get_server_job_bmi_timeout,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "30"},
+
+ /* Specifies the timeout value in seconds for TROVE jobs on the server.
+ */
+ {"ServerJobFlowTimeoutSecs",ARG_INT, get_server_job_flow_timeout,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "30"},
+
+ /* Specifies the timeout value in seconds for BMI jobs on the client.
+ */
+ {"ClientJobBMITimeoutSecs",ARG_INT, get_client_job_bmi_timeout,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "300"},
+
+ /* Specifies the timeout value in seconds for FLOW jobs on the client.
+ */
+ {"ClientJobFlowTimeoutSecs",ARG_INT, get_client_job_flow_timeout,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "300"},
+
+ /* Specifies the number of retry attempts for operations (when possible)
+ */
+ {"ClientRetryLimit",ARG_INT, get_client_retry_limit,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "5"},
+
+ /* Specifies the delay in milliseconds to wait between retries.
+ */
+ {"ClientRetryDelayMilliSecs",ARG_INT, get_client_retry_delay,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL, "2000"},
+
+ /* This specifies the frequency (in milliseconds)
+ * that performance monitor should be updated
+ * when the pvfs2 server is running in admin mode.
+ *
+ * Can be set in either Default or Global contexts.
+ */
+ {"PerfUpdateInterval",ARG_INT, get_perf_update_interval,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"1000"},
+
+ /* List the BMI modules to load when the server is started. At present,
+ * only tcp, infiniband, and myrinet are valid BMI modules.
+ * The format of the list is a comma separated list of one of:
+ *
+ * bmi_tcp
+ * bmi_ib
+ * bmi_gm
+ *
+ * For example:
+ *
+ * BMIModules bmi_tcp,bmi_ib
+ *
+ * Note that only the bmi modules compiled into pvfs2 should be
+ * specified in this list. The BMIModules option can be specified
+ * in either the Defaults or Global contexts.
+ */
+ {"BMIModules",ARG_LIST, get_bmi_module_list,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,NULL},
+
+ /* List the flow modules to load when the server is started. The modules
+ * available for loading currently are:
+ *
+ * flowproto_multiqueue - A flow module that handles all the possible flows,
+ * bmi->trove, trove->bmi, mem->bmi, bmi->mem. At present, this is the
+ * default and only available flow for production use.
+ *
+ * flowproto_bmi_cache - A flow module that enables the use of the NCAC
+ * (network-centric adaptive cache) in the pvfs2 server. Since the NCAC
+ * is currently disable and unsupported, this module exists as a proof
+ * of concept only.
+ *
+ * flowproto_dump_offsets - Used for debugging, this module allows the
+ * developer to see what/when flows are being posted, without making
+ * any actual BMI or TROVE requests. This should only be used if you
+ * know what you're doing.
+ *
+ */
+ {"FlowModules",ARG_LIST, get_flow_module_list,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"flowproto_multiqueue,"},
+
+ /* The TROVE storage layer has a management component that deals with
+ * allocating handle values for new metafiles and datafiles. The underlying
+ * trove module can be given a hint to tell it how long to wait before
+ * reusing handle values that have become freed up (only deleting files will
+ * free up a handle). The HandleRecycleTimeoutSecs option specifies
+ * the number of seconds to wait for each filesystem. This is an
+ * optional parameter that can be specified in the StorageHints context.
+ */
{"HandleRecycleTimeoutSecs", ARG_INT,
- get_handle_recycle_timeout_seconds, NULL, CTX_ALL},
- {"AttrCacheKeywords",ARG_LIST, get_attr_cache_keywords_list,NULL,CTX_ALL},
- {"AttrCacheSize",ARG_INT, get_attr_cache_size, NULL,CTX_ALL},
- {"AttrCacheMaxNumElems",ARG_INT,get_attr_cache_max_num_elems,NULL,CTX_ALL},
- {"TroveSyncMeta",ARG_STR, get_trove_sync_meta, NULL, CTX_ALL},
- {"TroveSyncData",ARG_STR, get_trove_sync_data, NULL, CTX_ALL},
- {"LogStamp",ARG_STR, get_logstamp,NULL,CTX_ALL},
+ get_handle_recycle_timeout_seconds, NULL,
+ CTX_STORAGEHINTS,"360"},
+
+ /* The TROVE layer has an attribute caching component that handles
+ * caching of stored attributes. This is used to improve the performance of
+ * metadata accesses. The AttrCacheKeywords option is a list of the
+ * object types that should get cached in the attribute cache.
+ * The possible values for this option are:
+ *
+ * datafile_handles - This will cache the array of datafile handles for
+ * each logical file in this filesystem
+ *
+ * metafile_dist - This will cache (for each logical file)
+ * the file distribution information used to create/manage
+ * the datafiles.
+ *
+ * dir_ent - This will cache the handles of the directory entries in this
+ * filesystem
+ *
+ * symlink_target - This will cache the target path for the symbolic links
+ * in this filesystem
+ *
+ * The format of this option is a comma-separated list of one or more
+ * of the above values. For example:
+ *
+ * AttrCacheKeywords datafile_handles,metafile_dist,dir_ent
+ */
+ {"AttrCacheKeywords",ARG_LIST, get_attr_cache_keywords_list,NULL,
+ CTX_STORAGEHINTS,
+ "datafile_handles,metafile_dist,dir_ent,symlink_target,"},
+
+ /* The attribute cache in the TROVE layer mentioned in the documentation
+ * for the AttrCacheKeywords option is managed as a hashtable. The
+ * AttrCacheSize adjusts the number of buckets that this hashtable contains.
+ * This value can be adjusted for better performance. A good hashtable
+ * size should always be a prime number.
+ */
+ {"AttrCacheSize",ARG_INT, get_attr_cache_size, NULL,
+ CTX_STORAGEHINTS,"511"},
+
+ /* This option specifies the max cache size of the attribute cache
+ * in the TROVE layer mentioned in the documentation
+ * for the AttrCacheKeywords option. This value can be adjusted for
+ * better performance.
+ */
+ {"AttrCacheMaxNumElems",ARG_INT,get_attr_cache_max_num_elems,NULL,
+ CTX_STORAGEHINTS,"1024"},
+
+ /* The TroveSyncMeta option allows users to turn off metadata
+ * synchronization with every metadata write. This can greatly improve
+ * performance. In general, this value should probably be set to yes,
+ * otherwise metadata transaction could be lost in the event of server
+ * failover.
+ */
+ {"TroveSyncMeta",ARG_STR, get_trove_sync_meta, NULL,
+ CTX_STORAGEHINTS,"yes"},
+
+ /* The TroveSyncData option allows users to turn off datafile
+ * synchronization with every write operation. This can greatly improve
+ * performance, but may cause lost data in the event of server failover.
+ */
+ {"TroveSyncData",ARG_STR, get_trove_sync_data, NULL,
+ CTX_STORAGEHINTS,"yes"},
+
+ /* Specifies the format of the date/timestamp that events will have
+ * in the event log. Possible values are:
+ *
+ * usec: [%H:%M:%S
+ *
+ * datetime: [%m/%d %H:%M]
+ *
+ * none
+ *
+ * The format of the option is one of the above values. For example,
+ *
+ * LogStamp datetime
+ */
+ {"LogStamp",ARG_STR, get_logstamp,NULL,
+ CTX_DEFAULTS|CTX_GLOBAL,"usec"},
+
+ /* This option specifies a parameter name to be passed to the
+ * distribution to be used. This option should be immediately
+ * followed by a Value option.
+ */
+ {"Param", ARG_STR, get_param, NULL,
+ CTX_DISTRIBUTION,NULL},
+
+ /* This option specifies the value of the parameter who's name
+ * was specified in the previous option.
+ */
+ {"Value", ARG_INT, get_value, NULL,
+ CTX_DISTRIBUTION,NULL},
+
+ /* This option specifies the default number of datafiles to use
+ * when a new file is created. The value is passed to the distribution
+ * and it determines whether to use that value or not.
+ */
+ {"DefaultNumDFiles", ARG_INT, get_default_num_dfiles, NULL,
+ CTX_FILESYSTEM,"0"},
+
LAST_OPTION
};
@@ -154,6 +567,7 @@ int PINT_parse_config(
char *global_config_filename,
char *server_config_filename)
{
+ struct server_configuration_s *config_s;
configfile_t *configfile = (configfile_t *)0;
if (!config_obj)
@@ -168,8 +582,15 @@ int PINT_parse_config(
/* set some global defaults for optional parameters */
config_s->logstamp_type = GOSSIP_LOGSTAMP_DEFAULT;
+ config_s->server_job_bmi_timeout = PVFS2_SERVER_JOB_BMI_TIMEOUT_DEFAULT;
+ config_s->server_job_flow_timeout = PVFS2_SERVER_JOB_FLOW_TIMEOUT_DEFAULT;
+ config_s->client_job_bmi_timeout = PVFS2_CLIENT_JOB_BMI_TIMEOUT_DEFAULT;
+ config_s->client_job_flow_timeout = PVFS2_CLIENT_JOB_FLOW_TIMEOUT_DEFAULT;
+ config_s->client_retry_limit = PVFS2_CLIENT_RETRY_LIMIT_DEFAULT;
+ config_s->client_retry_delay_ms = PVFS2_CLIENT_RETRY_DELAY_MS_DEFAULT;
- if (cache_config_files(global_config_filename, server_config_filename))
+ if (cache_config_files(
+ config_s, global_config_filename, server_config_filename))
{
return 1;
}
@@ -177,39 +598,42 @@ int PINT_parse_config(
assert(config_s->server_config_buflen && config_s->server_config_buf);
/* first read in the fs.conf defaults config file */
- config_s->configuration_context = GLOBAL_CONFIG;
+ config_s->configuration_context = CTX_GLOBAL;
configfile = PINT_dotconf_create(config_s->fs_config_filename,
- options, NULL, CASE_INSENSITIVE);
+ options, (void *)config_s,
+ CASE_INSENSITIVE);
if (!configfile)
{
gossip_err("Error opening config file %s\n",
config_s->fs_config_filename);
return 1;
}
-
- if (PINT_dotconf_command_loop(configfile) == 0)
+ configfile->errorhandler = (dotconf_errorhandler_t)errorhandler;
+ configfile->contextchecker = (dotconf_contextchecker_t)contextchecker;
+
+ if(PINT_dotconf_command_loop(configfile) == 0)
{
- gossip_err("Error reading config file %s\n",
- config_s->fs_config_filename);
+ /* NOTE: dotconf error handler will log message */
return 1;
}
PINT_dotconf_cleanup(configfile);
/* then read in the server.conf (host specific) config file */
- config_s->configuration_context = GLOBAL_CONFIG;
+ config_s->configuration_context = CTX_GLOBAL;
configfile = PINT_dotconf_create(config_s->server_config_filename,
- options, NULL, CASE_INSENSITIVE);
+ options, (void *)config_s, CASE_INSENSITIVE);
if (!configfile)
{
gossip_err("Error opening config file: %s\n",
config_s->server_config_filename);
return 1;
}
+ configfile->errorhandler = (dotconf_errorhandler_t)errorhandler;
+ configfile->contextchecker = (dotconf_contextchecker_t)contextchecker;
if (PINT_dotconf_command_loop(configfile) == 0)
{
- gossip_err("Error reading config file %s\n",
- config_s->server_config_filename);
+ /* NOTE: dotconf error handler will log message */
return 1;
}
PINT_dotconf_cleanup(configfile);
@@ -235,30 +659,48 @@ int PINT_parse_config(
return 1;
}
+ /* We set to the default flow module since there's only one.
+ */
if (!config_s->flow_modules)
{
- gossip_err("Configuration file error. "
- "No Flow modules specified.\n");
+ gossip_err("Configuration file error. No flow module specified\n");
return 1;
}
-
+
+ /* Users don't need to learn about this unless they want to
+ */
if (!config_s->perf_update_interval)
{
- gossip_err("Configuration file error. "
+ gossip_err("Configuration file error. "
"No PerfUpdateInterval specified.\n");
- return 1;
+ return 1;
}
-
+
return 0;
}
-DOTCONF_CB(get_pvfs_server_id)
+const char *contextchecker(command_t *cmd, unsigned long mask)
{
- if (config_s->configuration_context != GLOBAL_CONFIG)
+ struct server_configuration_s *config_s = cmd->context;
+
+ if(!(mask & config_s->configuration_context))
{
- gossip_err("HostID Tag can only be in the Global context");
- return NULL;
+ return "Option can't be defined in that context";
}
+ return NULL;
+}
+
+FUNC_ERRORHANDLER(errorhandler)
+{
+ gossip_err("Error: %s line %ld: %s", configfile->filename,
+ configfile->line, msg);
+ return(1);
+}
+
+DOTCONF_CB(get_pvfs_server_id)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
if (config_s->host_id)
{
gossip_err("WARNING: HostID value being overwritten (from "
@@ -271,13 +713,8 @@ DOTCONF_CB(get_pvfs_server_id)
DOTCONF_CB(get_logstamp)
{
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("Error: LogStamp tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
if(!strcmp(cmd->data.str, "none"))
{
@@ -293,8 +730,7 @@ DOTCONF_CB(get_logstamp)
}
else
{
- gossip_err("Error: LogStamp tag (if specified) must have one of the following values: none, usec, or datetime.\n");
- return NULL;
+ return("LogStamp tag (if specified) must have one of the following values: none, usec, or datetime.\n");
}
return NULL;
@@ -303,11 +739,8 @@ DOTCONF_CB(get_logstamp)
DOTCONF_CB(get_storage_space)
{
- if (config_s->configuration_context != GLOBAL_CONFIG)
- {
- gossip_err("StorageSpace Tag can only be in the Global context");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
if (config_s->storage_path)
{
gossip_err("WARNING: StorageSpace value being overwritten.\n");
@@ -320,63 +753,48 @@ DOTCONF_CB(get_storage_space)
DOTCONF_CB(enter_defaults_context)
{
- if (config_s->configuration_context != GLOBAL_CONFIG)
- {
- gossip_err("Error in context. Cannot have Defaults tag here\n");
- return NULL;
- }
- config_s->configuration_context = DEFAULTS_CONFIG;
- return NULL;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_DEFAULTS;
+
+ return PINT_dotconf_set_defaults(
+ cmd->configfile, CTX_DEFAULTS);
}
DOTCONF_CB(exit_defaults_context)
{
- if (config_s->configuration_context != DEFAULTS_CONFIG)
- {
- gossip_err("Error in context. Cannot have /Defaults tag here\n");
- return NULL;
- }
- config_s->configuration_context = GLOBAL_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_GLOBAL;
return NULL;
}
DOTCONF_CB(enter_aliases_context)
{
- if (config_s->configuration_context != GLOBAL_CONFIG)
- {
- gossip_err("Error in context. Cannot have Aliases tag here\n");
- return NULL;
- }
- config_s->configuration_context = ALIASES_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_ALIASES;
return NULL;
}
DOTCONF_CB(exit_aliases_context)
{
- if (config_s->configuration_context != ALIASES_CONFIG)
- {
- gossip_err("Error in context. Cannot have /Aliases tag here\n");
- return NULL;
- }
- config_s->configuration_context = GLOBAL_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_GLOBAL;
return NULL;
}
DOTCONF_CB(enter_filesystem_context)
{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
struct filesystem_configuration_s *fs_conf = NULL;
if (config_s->host_aliases == NULL)
{
- gossip_err("Error in context. Filesystem tag cannot "
+ return("Error in context. Filesystem tag cannot "
"be declared before an Aliases tag.\n");
- return NULL;
- }
-
- if (config_s->configuration_context != GLOBAL_CONFIG)
- {
- gossip_err("Error in context. Cannot have Filesystem tag here\n");
- return NULL;
}
fs_conf = (struct filesystem_configuration_s *)
@@ -396,19 +814,18 @@ DOTCONF_CB(enter_filesystem_context)
}
PINT_llist_add_to_head(config_s->file_systems,(void *)fs_conf);
assert(PINT_llist_head(config_s->file_systems) == (void *)fs_conf);
- config_s->configuration_context = FILESYSTEM_CONFIG;
- return NULL;
+ config_s->configuration_context = CTX_FILESYSTEM;
+
+ return PINT_dotconf_set_defaults(
+ cmd->configfile,
+ CTX_FILESYSTEM);
}
DOTCONF_CB(exit_filesystem_context)
{
struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("Error in context. Cannot have /Filesystem tag here\n");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
@@ -421,165 +838,181 @@ DOTCONF_CB(exit_filesystem_context)
if (!is_populated_filesystem_configuration(fs_conf))
{
gossip_err("Error: Filesystem configuration is invalid!\n");
- gossip_err("Possible Error in context. Cannot have /Filesystem "
- "tag before all filesystem attributes are declared\n");
- return NULL;
+ return("Possible Error in context. Cannot have /Filesystem "
+ "tag before all filesystem attributes are declared.\n");
}
- config_s->configuration_context = GLOBAL_CONFIG;
+ config_s->configuration_context = CTX_GLOBAL;
return NULL;
}
DOTCONF_CB(enter_storage_hints_context)
{
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("Error in context. Cannot "
- "have StorageHints tag here\n");
- return NULL;
- }
- config_s->configuration_context = STORAGEHINTS_CONFIG;
- return NULL;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_STORAGEHINTS;
+
+ return PINT_dotconf_set_defaults(
+ cmd->configfile, CTX_STORAGEHINTS);
}
DOTCONF_CB(exit_storage_hints_context)
{
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("Error in context. Cannot "
- "have /StorageHints tag here\n");
- return NULL;
- }
- config_s->configuration_context = FILESYSTEM_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_FILESYSTEM;
return NULL;
}
DOTCONF_CB(enter_mhranges_context)
{
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("Error in context. Cannot have "
- "MetaHandleRanges tag here\n");
- return NULL;
- }
- config_s->configuration_context = META_HANDLERANGES_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_METAHANDLERANGES;
return NULL;
}
DOTCONF_CB(exit_mhranges_context)
{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
struct filesystem_configuration_s *fs_conf = NULL;
- if (config_s->configuration_context != META_HANDLERANGES_CONFIG)
- {
- gossip_err("Error in context. Cannot have "
- "/MetaHandleRanges tag here\n");
- return NULL;
- }
-
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
if (!fs_conf->meta_handle_ranges)
{
- gossip_err("Error! No valid mhandle ranges added to %s\n",
- fs_conf->file_system_name);
+ return("No valid mhandle ranges added to file system.\n");
}
- config_s->configuration_context = FILESYSTEM_CONFIG;
+ config_s->configuration_context = CTX_FILESYSTEM;
return NULL;
}
DOTCONF_CB(enter_dhranges_context)
{
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("Error in context. Cannot have "
- "DataHandleRanges tag here\n");
- return NULL;
- }
- config_s->configuration_context = DATA_HANDLERANGES_CONFIG;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_DATAHANDLERANGES;
return NULL;
}
DOTCONF_CB(exit_dhranges_context)
{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
struct filesystem_configuration_s *fs_conf = NULL;
- if (config_s->configuration_context != DATA_HANDLERANGES_CONFIG)
- {
- gossip_err("Error in context. Cannot have "
- "/DataHandleRanges tag here\n");
- return NULL;
- }
-
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
if (!fs_conf->data_handle_ranges)
{
- gossip_err("Error! No valid dhandle ranges added to %s\n",
- fs_conf->file_system_name);
+ return("No valid dhandle ranges added to file system.\n");
}
- config_s->configuration_context = FILESYSTEM_CONFIG;
+ config_s->configuration_context = CTX_FILESYSTEM;
+ return NULL;
+}
+
+DOTCONF_CB(enter_distribution_context)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_DISTRIBUTION;
+ return NULL;
+}
+
+DOTCONF_CB(exit_distribution_context)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->configuration_context = CTX_GLOBAL;
return NULL;
}
DOTCONF_CB(get_unexp_req)
{
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("UnexpectedRequests Tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
config_s->initial_unexpected_requests = cmd->data.value;
return NULL;
}
+DOTCONF_CB(get_server_job_bmi_timeout)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->server_job_bmi_timeout = cmd->data.value;
+ return NULL;
+}
+
+DOTCONF_CB(get_server_job_flow_timeout)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->server_job_flow_timeout = cmd->data.value;
+ return NULL;
+}
+
+DOTCONF_CB(get_client_job_bmi_timeout)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->client_job_bmi_timeout = cmd->data.value;
+ return NULL;
+}
+
+DOTCONF_CB(get_client_job_flow_timeout)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->client_job_flow_timeout = cmd->data.value;
+ return NULL;
+}
+
+DOTCONF_CB(get_client_retry_limit)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->client_retry_limit = cmd->data.value;
+ return NULL;
+}
+
+DOTCONF_CB(get_client_retry_delay)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ config_s->client_retry_delay_ms = cmd->data.value;
+ return NULL;
+}
+
DOTCONF_CB(get_perf_update_interval)
{
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("PerfUpdateInterval Tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
config_s->perf_update_interval = cmd->data.value;
return NULL;
}
DOTCONF_CB(get_logfile)
{
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("LogFile Tag can only be in a Defaults "
- "or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
config_s->logfile = (cmd->data.str ? strdup(cmd->data.str) : NULL);
return NULL;
}
DOTCONF_CB(get_event_logging_list)
{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
int i = 0, len = 0;
char buf[512] = {0};
char *ptr = buf;
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("EventLogging Tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
-
if (config_s->event_logging != NULL)
{
len = strlen(config_s->event_logging);
@@ -623,13 +1056,8 @@ DOTCONF_CB(get_flow_module_list)
char buf[512] = {0};
char *ptr = buf;
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("FlowModules Tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
if (config_s->flow_modules != NULL)
{
@@ -654,13 +1082,8 @@ DOTCONF_CB(get_bmi_module_list)
char buf[512] = {0};
char *ptr = buf;
- if ((config_s->configuration_context != DEFAULTS_CONFIG) &&
- (config_s->configuration_context != GLOBAL_CONFIG))
- {
- gossip_err("BMIModules Tag can only be in a "
- "Defaults or Global block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
if (config_s->bmi_modules != NULL)
{
@@ -681,24 +1104,13 @@ DOTCONF_CB(get_bmi_module_list)
DOTCONF_CB(get_handle_recycle_timeout_seconds)
{
struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("HandleRecycleTimeoutSecs Tag can only be in a "
- "StorageHints block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
- if (fs_conf->handle_recycle_timeout_sec.tv_sec)
- {
- gossip_err("WARNING: Overwriting %d with %d\n",
- (int)fs_conf->handle_recycle_timeout_sec.tv_sec,
- (int)cmd->data.value);
- }
fs_conf->handle_recycle_timeout_sec.tv_sec = (int)cmd->data.value;
fs_conf->handle_recycle_timeout_sec.tv_usec = 0;
@@ -712,12 +1124,8 @@ DOTCONF_CB(get_attr_cache_keywords_list)
char *ptr = buf;
struct filesystem_configuration_s *fs_conf = NULL;
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("AttrCacheKeywords Tag can only be in a "
- "Filesystem block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
@@ -748,23 +1156,13 @@ DOTCONF_CB(get_attr_cache_size)
{
struct filesystem_configuration_s *fs_conf = NULL;
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("AttrCacheSize Tag can only be in a "
- "StorageHints block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
- if (fs_conf->attr_cache_size)
- {
- gossip_err("WARNING: Overwriting %d with %d\n",
- fs_conf->attr_cache_size,
- (int)cmd->data.value);
- }
fs_conf->attr_cache_size = (int)cmd->data.value;
return NULL;
}
@@ -772,24 +1170,13 @@ DOTCONF_CB(get_attr_cache_size)
DOTCONF_CB(get_attr_cache_max_num_elems)
{
struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("AttrCacheMaxNumElems Tag can only be in a "
- "StorageHints block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
- if (fs_conf->attr_cache_max_num_elems)
- {
- gossip_err("WARNING: Overwriting %d with %d\n",
- fs_conf->attr_cache_max_num_elems,
- (int)cmd->data.value);
- }
fs_conf->attr_cache_max_num_elems = (int)cmd->data.value;
return NULL;
}
@@ -797,108 +1184,125 @@ DOTCONF_CB(get_attr_cache_max_num_elems)
DOTCONF_CB(get_trove_sync_meta)
{
struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("TroveSyncMeta Tag can only be in a "
- "StorageHints block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
+ if(strcasecmp(cmd->data.str, "yes") == 0)
+ {
+ fs_conf->trove_sync_meta = TROVE_SYNC;
+ }
+ else if(strcasecmp(cmd->data.str, "no") == 0)
+ {
+ fs_conf->trove_sync_meta = 0;
+ }
+ else
+ {
+ return("TroveSyncMeta value must be 'yes' or 'no'.\n");
+ }
#ifndef HAVE_DB_DIRTY_READ
- fs_conf->trove_sync_meta = ((strcasecmp(cmd->data.str, "yes") == 0) ?
- TROVE_SYNC : 0);
if (fs_conf->trove_sync_meta != TROVE_SYNC)
{
- gossip_err("Forcing TroveSyncMeta to be yes instead of %s\n",
+ gossip_err("WARNING: Forcing TroveSyncMeta to be yes instead of %s\n",
cmd->data.str);
- gossip_err("Non-sync mode is NOT supported without "
- "DB_DIRTY_READ support\n");
+ gossip_err("WARNING: Non-sync mode is NOT supported without "
+ "DB_DIRTY_READ support.\n");
fs_conf->trove_sync_meta = TROVE_SYNC;
}
-#else
- fs_conf->trove_sync_meta = ((strcasecmp(cmd->data.str, "yes") == 0) ?
- TROVE_SYNC : 0);
#endif
+
return NULL;
}
DOTCONF_CB(get_trove_sync_data)
{
struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != STORAGEHINTS_CONFIG)
- {
- gossip_err("TroveSyncData Tag can only be in a "
- "StorageHints block");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
- fs_conf->trove_sync_data = ((strcasecmp(cmd->data.str, "yes") == 0) ?
- TROVE_SYNC : 0);
+ if(strcasecmp(cmd->data.str, "yes") == 0)
+ {
+ fs_conf->trove_sync_data = TROVE_SYNC;
+ }
+ else if(strcasecmp(cmd->data.str, "no") == 0)
+ {
+ fs_conf->trove_sync_data = 0;
+ }
+ else
+ {
+ return("TroveSyncData value must be 'yes' or 'no'.\n");
+ }
+
return NULL;
}
DOTCONF_CB(get_root_handle)
{
struct filesystem_configuration_s *fs_conf = NULL;
+ unsigned long long int tmp_var;
+ int ret = -1;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("RootHandle Tag can only be in a Filesystem block");
- return NULL;
- }
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
-#ifdef HAVE_STRTOULL
- fs_conf->root_handle = (PVFS_handle)strtoull(
- cmd->data.str, NULL, 10);
-#else
- fs_conf->root_handle = (PVFS_handle)strtoul(
- cmd->data.str, NULL, 10);
-#endif
+ ret = sscanf(cmd->data.str, "%Lu", &tmp_var);
+ if(ret != 1)
+ {
+ return("RootHandle does not have a long long unsigned value.\n");
+ }
+ fs_conf->root_handle = (PVFS_handle)tmp_var;
return NULL;
}
-DOTCONF_CB(get_filesystem_name)
+DOTCONF_CB(get_name)
{
- struct filesystem_configuration_s *fs_conf = NULL;
-
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ if (config_s->configuration_context == CTX_FILESYSTEM)
{
- gossip_err("Name Tags can only be within Filesystem tags");
- return NULL;
+ struct filesystem_configuration_s *fs_conf = NULL;
+
+ fs_conf = (struct filesystem_configuration_s *)
+ PINT_llist_head(config_s->file_systems);
+ if (fs_conf->file_system_name)
+ {
+ gossip_err("WARNING: Overwriting %s with %s\n",
+ fs_conf->file_system_name,cmd->data.str);
+ }
+ fs_conf->file_system_name =
+ (cmd->data.str ? strdup(cmd->data.str) : NULL);
}
- fs_conf = (struct filesystem_configuration_s *)
- PINT_llist_head(config_s->file_systems);
- if (fs_conf->file_system_name)
+ else if (config_s->configuration_context == CTX_DISTRIBUTION)
{
- gossip_err("WARNING: Overwriting %s with %s\n",
- fs_conf->file_system_name,cmd->data.str);
+ if (0 == config_s->default_dist_config.name)
+ {
+ config_s->default_dist_config.name =
+ (cmd->data.str ? strdup(cmd->data.str) : NULL);
+ config_s->default_dist_config.param_list = PINT_llist_new();
+ }
+ else
+ {
+ return "Only one distribution configuration is allowed.\n";
+ }
}
- fs_conf->file_system_name =
- (cmd->data.str ? strdup(cmd->data.str) : NULL);
return NULL;
}
DOTCONF_CB(get_filesystem_collid)
{
struct filesystem_configuration_s *fs_conf = NULL;
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
- if (config_s->configuration_context != FILESYSTEM_CONFIG)
- {
- gossip_err("ID Tags can only be within Filesystem tags");
- return NULL;
- }
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
if (fs_conf->coll_id)
@@ -910,17 +1314,31 @@ DOTCONF_CB(get_filesystem_collid)
return NULL;
}
+static int compare_aliases(void * vkey,
+ void * valias2)
+{
+ char * hostaliaskey1 = (char *)vkey;
+ host_alias_s * alias2 = (host_alias_s *)valias2;
+
+ return strcmp(hostaliaskey1, alias2->host_alias);
+}
+
DOTCONF_CB(get_alias_list)
{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
struct host_alias_s *cur_alias = NULL;
- if (config_s->configuration_context != ALIASES_CONFIG)
+ assert(cmd->arg_count == 2);
+
+ /* prevent users from adding the same alias twice */
+ if(config_s->host_aliases &&
+ PINT_llist_search(config_s->host_aliases,
+ (void *)cmd->data.list[0],
+ compare_aliases))
{
- gossip_err("Error in context. Cannot have Alias "
- "outside of Aliases context\n");
- return NULL;
+ return "Error: alias already defined";
}
- assert(cmd->arg_count == 2);
cur_alias = (host_alias_s *)
malloc(sizeof(host_alias_s));
@@ -931,6 +1349,7 @@ DOTCONF_CB(get_alias_list)
{
config_s->host_aliases = PINT_llist_new();
}
+
PINT_llist_add_to_tail(config_s->host_aliases,(void *)cur_alias);
return NULL;
}
@@ -941,21 +1360,15 @@ DOTCONF_CB(get_range_list)
struct filesystem_configuration_s *fs_conf = NULL;
struct host_handle_mapping_s *handle_mapping = NULL;
PINT_llist **handle_range_list = NULL;
-
- if ((config_s->configuration_context != META_HANDLERANGES_CONFIG) &&
- (config_s->configuration_context != DATA_HANDLERANGES_CONFIG))
- {
- gossip_err("Error in context. Cannot have Range keyword "
- "outside of [Meta|Data]HandleRanges context\n");
- return NULL;
- }
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
fs_conf = (struct filesystem_configuration_s *)
PINT_llist_head(config_s->file_systems);
assert(fs_conf);
handle_range_list = ((config_s->configuration_context ==
- META_HANDLERANGES_CONFIG) ?
+ CTX_METAHANDLERANGES) ?
&fs_conf->meta_handle_ranges :
&fs_conf->data_handle_ranges);
@@ -966,7 +1379,7 @@ DOTCONF_CB(get_range_list)
for(i = 0; i < cmd->arg_count; i += 2)
{
- if (is_valid_alias(cmd->data.list[i]))
+ if (is_valid_alias(config_s->host_aliases, cmd->data.list[i]))
{
i++;
assert(cmd->data.list[i]);
@@ -977,10 +1390,8 @@ DOTCONF_CB(get_range_list)
*handle_range_list, cmd->data.list[i-1]);
if (!handle_mapping)
{
- gossip_err("Error: Alias %s allocation failed; "
- "aborting alias handle range addition!\n",
- cmd->data.list[i-1]);
- return NULL;
+ return("Error: Alias allocation failed; "
+ "aborting alias handle range addition!\n");
}
if (!handle_mapping->alias_mapping)
@@ -1027,19 +1438,61 @@ DOTCONF_CB(get_range_list)
}
else
{
- gossip_err("Error in handle range description.\n %s is "
- "invalid input data!\n",cmd->data.list[i]);
+ return("Error in handle range description.\n");
}
}
else
{
- gossip_err("Error! %s is an unrecognized alias\n",
- cmd->data.list[i]);
+ return("Unrecognized alias.\n");
}
}
return NULL;
}
+DOTCONF_CB(get_param)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ distribution_param_configuration* param =
+ malloc(sizeof(distribution_param_configuration));
+
+ if (NULL != param)
+ {
+ memset(param, 0, sizeof(param));
+ param->name = (cmd->data.str ? strdup(cmd->data.str) : NULL);
+ PINT_llist_add_to_tail(config_s->default_dist_config.param_list,
+ param);
+ }
+ return NULL;
+}
+
+DOTCONF_CB(get_value)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ distribution_param_configuration* param;
+ param = (distribution_param_configuration*)PINT_llist_tail(
+ config_s->default_dist_config.param_list);
+ if (NULL != param)
+ {
+ param->value = (PVFS_size)cmd->data.value;
+ }
+ return NULL;
+}
+
+DOTCONF_CB(get_default_num_dfiles)
+{
+ struct server_configuration_s *config_s =
+ (struct server_configuration_s *)cmd->context;
+ struct filesystem_configuration_s *fs_conf = NULL;
+
+ fs_conf = (struct filesystem_configuration_s *)
+ PINT_llist_head(config_s->file_systems);
+
+ fs_conf->default_num_dfiles = (int)cmd->data.value;
+ return NULL;
+}
+
/*
* Function: PINT_config_release
*
@@ -1125,7 +1578,7 @@ void PINT_config_release(struct server_c
}
}
-static int is_valid_alias(char *str)
+static int is_valid_alias(PINT_llist * host_aliases, char *str)
{
int ret = 0;
PINT_llist *cur = NULL;
@@ -1133,7 +1586,7 @@ static int is_valid_alias(char *str)
if (str)
{
- cur = config_s->host_aliases;
+ cur = host_aliases;
while(cur)
{
cur_alias = PINT_llist_head(cur);
@@ -1190,7 +1643,7 @@ static int is_populated_filesystem_confi
fs->meta_handle_ranges && fs->data_handle_ranges &&
fs->root_handle) ? 1 : 0);
}
-
+
static int is_root_handle_in_a_meta_range(
struct server_configuration_s *config,
struct filesystem_configuration_s *fs)
@@ -1346,6 +1799,7 @@ static void copy_filesystem(
dest_fs->coll_id = src_fs->coll_id;
dest_fs->root_handle = src_fs->root_handle;
+ dest_fs->default_num_dfiles = src_fs->default_num_dfiles;
dest_fs->flowproto = src_fs->flowproto;
dest_fs->encoding = src_fs->encoding;
@@ -1570,7 +2024,6 @@ static int build_extent_array(
return 0;
}
-
/*
* Function: PINT_config_get_host_addr_ptr
*
@@ -1817,6 +2270,7 @@ char *PINT_config_get_merged_handle_rang
call should properly de-alloc all consumed memory.
*/
static int cache_config_files(
+ struct server_configuration_s *config_s,
char *global_config_filename,
char *server_config_filename)
{
@@ -2025,8 +2479,8 @@ int PINT_config_is_valid_configuration(
PINT_llist *cur = NULL;
struct filesystem_configuration_s *cur_fs = NULL;
- if (config_s && config_s->logfile && config_s->event_logging &&
- config_s->bmi_modules)
+ if (config_s && config_s->bmi_modules && config_s->event_logging &&
+ config_s->logfile)
{
cur = config_s->file_systems;
while(cur)
@@ -2442,7 +2896,7 @@ int PINT_config_get_trove_sync_meta(
if (config)
{
- fs_conf = PINT_config_find_fs_id(config_s, fs_id);
+ fs_conf = PINT_config_find_fs_id(config, fs_id);
}
return (fs_conf ? fs_conf->trove_sync_meta : TROVE_SYNC);
}
@@ -2459,7 +2913,7 @@ int PINT_config_get_trove_sync_data(
if (config)
{
- fs_conf = PINT_config_find_fs_id(config_s, fs_id);
+ fs_conf = PINT_config_find_fs_id(config, fs_id);
}
return (fs_conf ? fs_conf->trove_sync_data : TROVE_SYNC);
}
Index: server-config.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/server-config.h,v
diff -p -u -r1.42.4.1 -r1.42.4.2
--- server-config.h 7 Jun 2005 21:59:12 -0000 1.42.4.1
+++ server-config.h 25 Aug 2005 20:38:18 -0000 1.42.4.2
@@ -15,15 +15,16 @@
#include "trove.h"
#endif
-enum
+enum
{
- GLOBAL_CONFIG = 1,
- FILESYSTEM_CONFIG = 2,
- DEFAULTS_CONFIG = 3,
- ALIASES_CONFIG = 4,
- META_HANDLERANGES_CONFIG = 5,
- DATA_HANDLERANGES_CONFIG = 6,
- STORAGEHINTS_CONFIG = 7
+ CTX_GLOBAL = (1 << 1),
+ CTX_DEFAULTS = (1 << 2),
+ CTX_ALIASES = (1 << 3),
+ CTX_FILESYSTEM = (1 << 4),
+ CTX_METAHANDLERANGES = (1 << 5),
+ CTX_DATAHANDLERANGES = (1 << 6),
+ CTX_STORAGEHINTS = (1 << 7),
+ CTX_DISTRIBUTION = (1 << 8)
};
typedef struct phys_server_desc
@@ -58,6 +59,7 @@ typedef struct filesystem_configuration_
char *file_system_name;
PVFS_fs_id coll_id;
PVFS_handle root_handle;
+ int default_num_dfiles;
/* ptrs are type host_handle_mapping_s* */
PINT_llist *meta_handle_ranges;
@@ -81,6 +83,21 @@ typedef struct filesystem_configuration_
} filesystem_configuration_s;
+typedef struct distribution_param_configuration_s
+{
+ char* name;
+ int64_t value; /* Temporarily hard code to 64bit type */
+
+} distribution_param_configuration;
+
+/* Config struct to hold overloaded distribution defaults */
+typedef struct distribution_configuration_s
+{
+ char* name;
+ PINT_llist* param_list;
+
+} distribution_configuration;
+
typedef struct server_configuration_s
{
char *host_id;
@@ -92,6 +109,12 @@ typedef struct server_configuration_s
ssize_t server_config_buflen; /* the server.conf file length */
char *server_config_buf; /* the server.conf file contents */
int initial_unexpected_requests;
+ int server_job_bmi_timeout; /* job timeout values in seconds */
+ int server_job_flow_timeout;
+ int client_job_bmi_timeout;
+ int client_job_flow_timeout;
+ int client_retry_limit; /* how many times to retry client operations */
+ int client_retry_delay_ms; /* delay between retries */
int perf_update_interval; /* how quickly (in msecs) to
update perf monitor */
char *logfile;
@@ -104,6 +127,8 @@ typedef struct server_configuration_s
PINT_llist *host_aliases; /* ptrs are type host_alias_s */
PINT_llist *file_systems; /* ptrs are type
filesystem_configuration_s */
+ distribution_configuration default_dist_config; /* distribution conf */
+
} server_configuration_s;
int PINT_parse_config(
Index: state-machine-fns.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/state-machine-fns.h,v
diff -p -u -r1.15.6.2 -r1.15.6.3
--- state-machine-fns.h 7 Jun 2005 21:59:12 -0000 1.15.6.2
+++ state-machine-fns.h 25 Aug 2005 20:38:18 -0000 1.15.6.3
@@ -25,6 +25,10 @@
* includes state-machine.h, because state-machine.h needs a key #define
* before it can be included.
*
+ * The PINT_OP_STATE_TABLE has been replaced with a macro that must be #defined
+ * instead: PINT_OP_STATE_GET_MACHINE.
+ * This allows the _locate function to be used in the client as well.
+ *
* A good example of this is the pvfs2-server.h in the src/server directory,
* which includes state-machine.h at the bottom, and server-state-machine.c,
* which includes first pvfs2-server.h and then state-machine-fns.h.
@@ -37,10 +41,7 @@
/* Prototypes for functions defined in here */
static inline int PINT_state_machine_halt(void);
static inline int PINT_state_machine_next(struct PINT_OP_STATE *,job_status_s *r);
-static inline int PINT_state_machine_invoke(struct PINT_OP_STATE *,job_status_s *r);
-#ifdef PINT_OP_STATE_TABLE
static union PINT_state_array_values *PINT_state_machine_locate(struct PINT_OP_STATE *);
-#endif
static inline union PINT_state_array_values *PINT_pop_state(struct PINT_OP_STATE *s);
static inline void PINT_push_state(struct PINT_OP_STATE *s, union PINT_state_array_values *p);
@@ -192,25 +193,23 @@ static union PINT_state_array_values *PI
union PINT_state_array_values *current_tmp;
/* check for valid inputs */
- if (!s_op || s_op->op < 0
- || s_op->op > PVFS_MAX_SERVER_OP)
+ if (!s_op || s_op->op < 0)
{
gossip_err("State machine requested not valid\n");
return NULL;
}
- if (PINT_OP_STATE_TABLE[s_op->op].sm->state_machine != NULL)
+ if (PINT_OP_STATE_GET_MACHINE(s_op->op) != NULL)
{
- current_tmp = PINT_OP_STATE_TABLE[s_op->op].sm->state_machine;
+ current_tmp = PINT_OP_STATE_GET_MACHINE(s_op->op)->state_machine;
/* added the state name string as the first entry in the
* state's array values. Skip past it to get to the type
* of action. --slang
*/
current_tmp += 1;
-
- /* handle the case in which the first state points to a nested
- * machine, rather than a simple function
- */
- while(current_tmp->flag == SM_JUMP)
+ /* handle the case in which the first state points to a nested
+ * machine, rather than a simple function
+ */
+ while(current_tmp->flag == SM_JUMP)
{
PINT_push_state(s_op, current_tmp);
current_tmp += 1;
@@ -230,7 +229,6 @@ static union PINT_state_array_values *PI
gossip_err("State machine not found for operation %d\n",s_op->op);
return NULL;
}
-#endif
static inline union PINT_state_array_values *PINT_pop_state(struct PINT_OP_STATE *s)
{
Index: str-utils.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/str-utils.c,v
diff -p -u -r1.16 -r1.16.6.1
--- str-utils.c 2 Aug 2004 17:29:23 -0000 1.16
+++ str-utils.c 25 Aug 2005 20:38:18 -0000 1.16.6.1
@@ -366,7 +366,7 @@ int PINT_split_string_list(char ***token
}
/* allocate pointers for each */
- *tokens = (char **) malloc(sizeof(char **));
+ *tokens = (char **) malloc(sizeof(char *) * tokencount);
if (!(*tokens))
{
return 0;
@@ -375,7 +375,7 @@ int PINT_split_string_list(char ***token
/* copy out all of the tokenized strings */
holder = comma_list;
end = comma_list + strlen(comma_list);
- for (i = 0; i < tokencount; i++)
+ for (i = 0; i < tokencount && holder; i++)
{
holder2 = index(holder, ',');
if (!holder2)
@@ -410,6 +410,27 @@ int PINT_split_string_list(char ***token
free(*tokens);
}
return (0);
+}
+
+/* PINT_free_string_list()
+ *
+ * Free the string list allocated by PINT_split_string_list()
+ */
+void PINT_free_string_list(char ** list, int len)
+{
+ int i = 0;
+
+ if(list)
+ {
+ for(; i < len; ++i)
+ {
+ if(list[i])
+ {
+ free(list[i]);
+ }
+ }
+ free(list);
+ }
}
/* PINT_remove_base_dir()
Index: str-utils.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/str-utils.h,v
diff -p -u -r1.14 -r1.14.6.1
--- str-utils.h 2 Aug 2004 17:29:23 -0000 1.14
+++ str-utils.h 25 Aug 2005 20:38:18 -0000 1.14.6.1
@@ -36,6 +36,9 @@ int PINT_get_next_path(
int PINT_split_string_list(
char ***tokens,
const char *comma_list);
+void PINT_free_string_list(
+ char ** list,
+ int len);
int PINT_remove_base_dir(
char *pathname,
char *out_dir,
More information about the PVFS2-CVS
mailing list