[Pvfs2-cvs] commit by kunkel in pvfs2/src/apps/admin:
pvfs2-validate.c module.mk.in pvfs2-genconfig
CVS commit program
cvs at parl.clemson.edu
Sat Jan 13 05:16:40 EST 2007
Update of /projects/cvsroot/pvfs2/src/apps/admin
In directory parlweb1:/tmp/cvs-serv19417/src/apps/admin
Modified Files:
Tag: kunkel-hint-branch
module.mk.in pvfs2-genconfig
Added Files:
Tag: kunkel-hint-branch
pvfs2-validate.c
Log Message:
Synchronization with HEAD
--- /dev/null 2004-06-24 14:04:38.000000000 -0400
+++ pvfs2-validate.c 2007-01-13 05:16:40.000000000 -0500
@@ -0,0 +1,437 @@
+/*
+ * Copyright © Acxiom Corporation, 2006
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "pvfs2.h"
+#include "pvfs2-internal.h"
+
+
+#include "fsck-utils.h"
+
+#define VERSION "0.1"
+/** \defgroup pvfs2validate PVFS2 Validate
+ *
+ * The pvfs2-validate implementation provides a client side utility to find and
+ * repair PVFS2 file system problems.
+ *
+ * @see fsckutils
+ *
+ * Before running pvfs2-validate, the following requirements must be met:
+ * - The PVFS2 servers must be running
+ * - No clients should be accssing the file system
+ * .
+ *
+ * TODO:
+ * - Need to design a way to kick off process on the pvfs2-server to check
+ * for orphaned bstreams (bstreams with no attributes and/or dfiles)
+ * - Needs to enter admin mode in beginning if needed, and leave at end.
+ * Shouldn't leave admin mode during operation.
+ * - Add ability to run pvfs2-validate on an unmounted filesytem, and on a system
+ * with no entries in tabfiles (pvfs2tab, /etc/mtab, /etc/fstab)
+ * - Force a sync on filesystem before beginning fsck
+ * .
+ *
+ * QUESTIONS:
+ * - Does the underlying filesystem fsck interfere with pvfs2-validate?
+ * - Should the underlying filesytem fsck be run in any conditions?
+ * - How/When to clean up lost+found directory?
+ * - What happens when lost+found directory has errors?
+ * - Can anyone with root access run pvfs2-validate? Do we need some sort of authorization?
+ * - Any known limits? (memory usage in pvfs2-validate, number of files)?
+ * - Should we enter admin mode if there is no chance of repairs on found objects?
+ * - Can pvfs2-validate be initiated automatically in some cases?
+ * - When pvfs2-validate runs, how does is affect performance (readonly/repair)?
+ * - Can the this be parallelized?
+ * - Can we have a "conditional admin mode", where admin mode only entered after
+ * a certain time condition where no file system activity takes place? This
+ * would keep servers from entering admin mode in the middle of operations.
+ * .
+ *
+ * @{
+ */
+
+/** \file
+ * Implementation of PVFS2 FSCK tool.
+ */
+
+/* Function Prototypes */
+static void usage(
+ int,
+ char **);
+
+int validate_pvfs_object(
+ const struct PINT_fsck_options *fsck_options,
+ const PVFS_object_ref * pref,
+ const PVFS_credentials * creds,
+ int *cur_fs,
+ char *current_path);
+
+static struct PINT_fsck_options *parse_args(
+ int argc,
+ char **argv);
+
+int main(int argc, char **argv)
+{
+ int ret = 0;
+ int cur_fs = 0;
+ char pvfs_path[PVFS_NAME_MAX] = { 0 };
+ PVFS_credentials creds;
+ PVFS_sysresp_lookup lookup_resp;
+ struct PINT_fsck_options *fsck_options = NULL;
+
+ memset(&creds, 0, sizeof(creds));
+ memset(&lookup_resp, 0, sizeof(lookup_resp));
+
+ fsck_options = parse_args(argc, argv);
+ if(!fsck_options)
+ {
+ fprintf(stderr, "Error: failed to parse arguments.\n");
+ usage(argc, argv);
+ return -1;
+ }
+
+ if (!fsck_options->start_path)
+ {
+ fprintf(stderr, "Error: no starting path specified (See -d option below).\n");
+ usage(argc, argv);
+ free(fsck_options);
+ return -1;
+ }
+
+ ret = PVFS_util_init_defaults();
+ if (ret != 0)
+ {
+ PVFS_perror("PVFS_util_init_defaults", ret);
+ free(fsck_options);
+ return -1;
+ }
+
+ /* translate local path into pvfs2 relative path */
+ ret = PVFS_util_resolve(
+ fsck_options->start_path,
+ &cur_fs, pvfs_path,
+ sizeof(pvfs_path));
+
+ if (ret != 0)
+ {
+ PVFS_perror("PVFS_util_resolve", ret);
+ PVFS_sys_finalize();
+ free(fsck_options);
+ return -1;
+ }
+
+ if (fsck_options->check_stranded_objects && (strcmp(pvfs_path, "/") != 0))
+ {
+ fprintf(stderr, "Error: -d must specify the pvfs2 root directory when utilizing the -c option.\n");
+ usage(argc, argv);
+ PVFS_sys_finalize();
+ free(fsck_options);
+ return -1;
+ }
+
+ PVFS_util_gen_credentials(&creds);
+
+ ret = PVFS_sys_lookup(
+ cur_fs, pvfs_path,
+ &creds,
+ &lookup_resp,
+ PVFS2_LOOKUP_LINK_NO_FOLLOW, NULL);
+
+ if (ret != 0)
+ {
+ fprintf(stderr, "Error: failed lookup on [%s]\n", pvfs_path);
+ PVFS_perror("PVFS_sys_lookup", ret);
+ PVFS_sys_finalize();
+ free(fsck_options);
+ return -1;
+ }
+
+ ret = PVFS_fsck_initialize(fsck_options, &creds, &cur_fs);
+ if (ret < 0)
+ {
+ PVFS_perror("PVFS_fsck_initialize", ret);
+ PVFS_sys_finalize();
+ free(fsck_options);
+ return(-1);
+ }
+
+ ret = PVFS_fsck_check_server_configs(fsck_options, &creds, &cur_fs);
+ if (ret < 0)
+ {
+ fprintf(stderr, "Error: a difference was detected while validating the server fs configs.\n");
+ PVFS_perror("PVFS_fsck_check_server_configs", ret);
+ PVFS_sys_finalize();
+ free(fsck_options);
+ return(-1);
+ }
+
+ /* stop right here if check_fs_configs option is enabled */
+ if (fsck_options->check_fs_configs)
+ {
+ printf("All PVFS2 servers have consistent fs configurations.\n");
+ free(fsck_options);
+ return 0;
+ }
+
+ printf("pvfs2-validate starting validation at object [%s]\n",
+ fsck_options->start_path);
+
+ /* validate the object */
+ ret = validate_pvfs_object(
+ fsck_options,
+ &lookup_resp.ref,
+ &creds,
+ &cur_fs,
+ fsck_options->start_path);
+
+ if (ret != 0)
+ {
+ printf("failed to validate object tree starting at [%s]. rc=[%d]\n",
+ fsck_options->start_path, ret);
+ }
+ else
+ {
+ printf("pvfs2-validate done validating object tree at [%s]\n",
+ fsck_options->start_path);
+ }
+
+ PVFS_fsck_finalize(fsck_options, &cur_fs, &creds);
+ PVFS_sys_finalize();
+ free(fsck_options);
+
+ return 0;
+}
+
+/**
+ * Validate a PVFS2 file, directory or symlink. Operates recursively to
+ * descend into directories.
+ *
+ * \retval 0 on success
+ * \retval -PVFS_EWARNING for non critical warnings
+ * \retval -PVFS_error on failure
+ */
+int validate_pvfs_object(
+ const struct PINT_fsck_options *fsck_options, /**< fsck options */
+ const PVFS_object_ref * pref, /**< object to validate */
+ const PVFS_credentials * creds, /**< caller's credentials */
+ int *cur_fs, /**< file system */
+ char *current_path) /**< path to object */
+{
+ int ret = 0;
+ int j = 0;
+ PVFS_sysresp_getattr attributes;
+ PVFS_dirent *directory_entries = NULL;
+ char* err_string = NULL;
+
+ memset(&attributes, 0, sizeof(attributes));
+
+ /* get this objects attributes */
+ ret = PVFS_fsck_get_attributes(fsck_options, pref, creds, &attributes);
+ if(ret < 0)
+ {
+ fprintf(stderr, "Error: [%s] cannot retrieve attributes.\n", current_path);
+ }
+ else if (attributes.attr.objtype == PVFS_TYPE_METAFILE)
+ {
+ /* metadata file */
+ ret = PVFS_fsck_validate_metafile(fsck_options, pref,
+ &attributes, creds);
+ }
+ else if (attributes.attr.objtype == PVFS_TYPE_DIRECTORY)
+ {
+ /* directory */
+ directory_entries = calloc(attributes.attr.dirent_count, sizeof(PVFS_dirent));
+ if (directory_entries == NULL)
+ {
+ perror("calloc");
+ return -PVFS_ENOMEM;
+ }
+
+ ret = PVFS_fsck_validate_dir(fsck_options, pref, &attributes, creds,
+ directory_entries);
+
+ if(ret == 0)
+ {
+ /* validate all directory entries recursively */
+ for (j = 0; j < attributes.attr.dirent_count; j++)
+ {
+ PVFS_object_ref obj_ref;
+ char new_path[PVFS_SEGMENT_MAX];
+
+ obj_ref.handle = directory_entries[j].handle;
+ obj_ref.fs_id = *cur_fs;
+
+ /* build full path name of the next object */
+ strcpy(new_path, current_path);
+ strcat(new_path, "/");
+ strcat(new_path, directory_entries[j].d_name);
+
+ /* recurse */
+ ret = validate_pvfs_object(fsck_options, &obj_ref, creds,
+ cur_fs, new_path);
+ }
+ }
+
+ free(directory_entries);
+ }
+ else if (attributes.attr.objtype == PVFS_TYPE_SYMLINK)
+ {
+ /* symbolic link */
+ ret = PVFS_fsck_validate_symlink(fsck_options, pref,
+ &attributes);
+ free(attributes.attr.link_target);
+ }
+ else
+ {
+ fprintf(stderr, "Error: [%s] is of an unknown object type: [%d]\n",
+ current_path, attributes.attr.objtype);
+ ret = -PVFS_EINVAL;
+ }
+
+ if (ret == 0)
+ {
+ if (fsck_options->verbose)
+ {
+ printf("validated [%s] object ret=[%d]\n", current_path, ret);
+ }
+ }
+ else
+ {
+ err_string = (char*)malloc(128*sizeof(char));
+ if(err_string)
+ {
+ PVFS_strerror_r(ret, err_string, 128);
+ fprintf(stderr, "Error: [%s] object is invalid (%s)\n",
+ current_path, err_string);
+ free(err_string);
+ }
+ else
+ {
+ fprintf(stderr, "Error: [%s] object is invalid (%d)\n",
+ current_path, ret);
+ }
+ }
+
+ /* Return 0, rather than "ret", too keep from propogating errors
+ * all the way back to the root object. We want to continue and show all
+ * problem rather than stopping on the first
+ */
+ return 0;
+}
+
+static void usage(
+ int argc,
+ char **argv)
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Usage : %s [-Vvharsfc] -d pvfs2_directory\n", argv[0]);
+ fprintf(stderr, "Recursively checks a PVFS2 directory or file for problems.\n");
+ fprintf(stderr, " -h \t print this help screen\n");
+ fprintf(stderr, " -d \t path to a PVFS2 directory/file\n");
+ fprintf(stderr, " \t (specify mount point to check entire file system)\n");
+ fprintf(stderr, " -c \t check for stranded objects\n");
+ fprintf(stderr, " \t (requires that -d refer to the PVFS2 root directory)\n");
+ fprintf(stderr, " -s \t check for bad practice in symbolic links\n");
+ fprintf(stderr, " -f \t check for bad practice in directory/file names\n");
+ fprintf(stderr,
+ " -F \t stop after confirming consistent configuration of all servers\n");
+ fprintf(stderr, " -V \t run in verbose mode\n");
+ fprintf(stderr, " -v \t print version and exit\n");
+ fprintf(stderr, " -a \t fix all problems found (NOT IMPLEMENTED)\n");
+ fprintf(stderr, " -r \t run in interactive mode (NOT IMPLEMENTED)\n");
+ fprintf(stderr, "\n\n");
+ fprintf(stderr, " Return Codes:\n");
+ fprintf(stderr,
+ " \tThe exit code returned by %s is the sum of the following conditions:\n", argv[0]);
+ fprintf(stderr, " \t\t 0 - No errors\n");
+ fprintf(stderr, " \t\t 1 - File system errors corrected\n");
+ fprintf(stderr, " \t\t 2 - System should be rebooted\n");
+ fprintf(stderr, " \t\t 4 - File system errors left uncorrected\n\n");
+
+ fprintf(stderr, " Example: %s -d /mnt/pvfs2\n", argv[0]);
+}
+
+static struct PINT_fsck_options *parse_args(int argc, char **argv)
+{
+ int opt = 0;
+ int path_length = 0;
+
+ struct PINT_fsck_options *opts;
+ opts = calloc(1, sizeof(struct PINT_fsck_options));
+ if (opts == NULL)
+ {
+ return NULL;
+ }
+
+ while ((opt = getopt(argc, argv, "d:VvharsfcF")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'd':
+ opts->start_path = optarg;
+ path_length = strlen(optarg);
+ /* remove trailing extraneous */
+ if (optarg[path_length - 1] == '/' && path_length > 1)
+ {
+ optarg[path_length - 1] = '\0';
+ }
+ break;
+ case 'V':
+ opts->verbose = 1;
+ break;
+ case 'v':
+ printf("pvfs2-fsck version %s\n", VERSION);
+ exit(0);
+ break;
+ case 'c':
+ opts->check_stranded_objects = 1;
+ break;
+ case 'a':
+ opts->fix_errors = 1;
+ printf("Error: file system repair not implemented\n");
+ usage(argc, argv);
+ exit(-PVFS_ENOSYS);
+ break;
+ case 'r':
+ printf("Error: interactive mode not implemented\n");
+ usage(argc, argv);
+ exit(-PVFS_ENOSYS);
+ break;
+ case 's':
+ opts->check_symlink_target = 1;
+ break;
+ case 'F':
+ opts->check_fs_configs = 1;
+ break;
+ case 'f':
+ opts->check_dir_entry_names = 1;
+ break;
+ case 'h':
+ usage(argc, argv);
+ exit(0);
+ break;
+ case '?':
+ usage(argc, argv); /* unknown option */
+ exit(3);
+ }
+ }
+
+ return opts;
+}
+
+/* @} */
+
+/*
+ * 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/apps/admin/module.mk.in,v
diff -p -u -r1.39.14.2 -r1.39.14.3
--- module.mk.in 2 Dec 2006 11:22:21 -0000 1.39.14.2
+++ module.mk.in 13 Jan 2007 10:16:40 -0000 1.39.14.3
@@ -19,6 +19,7 @@ ADMINSRC := \
$(DIR)/pvfs2-chown.c \
$(DIR)/pvfs2-fs-dump.c\
$(DIR)/pvfs2-fsck.c\
+ $(DIR)/pvfs2-validate.c\
$(DIR)/pvfs2-cp.c \
$(DIR)/pvfs2-viewdist.c \
$(DIR)/pvfs2-xattr.c \
Index: pvfs2-genconfig
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/apps/admin/pvfs2-genconfig,v
diff -p -u -r1.61.6.2 -r1.61.6.3
--- pvfs2-genconfig 2 Dec 2006 11:22:21 -0000 1.61.6.2
+++ pvfs2-genconfig 13 Jan 2007 10:16:40 -0000 1.61.6.3
@@ -176,18 +176,6 @@ sub emit_defaults
print $target "<Defaults>\n";
print $target "\tUnexpectedRequests $num_unexp\n";
-
- if(defined($logfile))
- {
- # remove quotes from logfile if any
- if ($logfile =~ /\".*\"/)
- {
- $logfile =~ s/\"//g;
- }
-
- print $target "\tLogFile $logfile\n";
- }
-
print $target "\tEventLogging $logging\n";
print $target "\tLogStamp $logstamp\n";
print $target "\tBMIModules $bmi_module\n";
@@ -1319,7 +1307,7 @@ if ($opt_security == 1)
}
emit_aliases($output_target);
emit_filesystem($output_target, "pvfs2-fs", $fsid, $root_handle,
- $last_handle, $first_handle, $count, $default_num_dfiles);
+ $last_handle, $first_handle, $meta_count + $io_count, $default_num_dfiles);
# close fs.conf
if ($using_stdout == 0)
More information about the Pvfs2-cvs
mailing list