[Pvfs2-developers] patches: admin utilities
Sam Lang
slang at mcs.anl.gov
Wed Nov 7 16:51:54 EST 2007
Hi Phil,
First off, thanks for the patches. They'll be useful for debugging
stuff, and setting up failover deployments. I committed the first two.
I've attached an updated patch for the validate repair patch with
some changes to get stuff working with MAIN. The conflicts were with
the new state machine code. You're calling the create state actions
from multiple state machines, which we've never done before.
I had added some code to statecomp to auto-generate the declarations
for state actions based on the "run <action>" directive it finds in
the state machines, but the declarations were static functions, which
doesn't work with your patch, since the state actions in that case
have to be public. The patch adds a 'rung' directive to the state
machine code, which is pretty much the same as run, but it just skips
the function declaration (rung == run global). It feels like a
kludge at this point -- I don't want to add another state machine
directive if I can avoid it, but I can't think of a better way.
-sam
-------------- next part --------------
A non-text attachment was scrubbed...
Name: phil-validate-repair-update.patch
Type: application/octet-stream
Size: 38342 bytes
Desc: not available
Url : http://www.beowulf-underground.org/pipermail/pvfs2-developers/attachments/20071107/2701c4fc/phil-validate-repair-update-0001.obj
-------------- next part --------------
On Oct 12, 2007, at 3:34 PM, Phil Carns wrote:
> These are a few patches that either add new admin utilities or
> modify existing ones:
>
> pvfs2-check-server-gen-mntent.patch
> -----------------------------------
> This patch does two things. First, it adds a utilty function
> called PVFS_util_gen_mntent() that can be used to create a mntent
> structure in memory without parsing a tabfile. Previously there
> wasn't any clean way to construct this on the fly. Secondly, it
> adds a utility (using the gen_mntent() function) called pvfs2-check-
> server. pvfs2-check-server can be used to probe a specific pvfs2
> server to see if it is running and responding to protocol
> requests. Since it does not rely on a tab file, it can talk
> directly to one specific server without having to retrieve
> configuration information from the primary server listed in the tab
> file. This utility is useful for watchdog purposes when you want
> to find out if one specific server is working properly.
>
> pvfs2-change-fsid.patch
> -----------------------
> This patch adds a new admin utility called pvfs2-change-fsid. It
> can be used to modify the fsid on an existing file system. This is
> helpful if you duplicate a file system (from backup, clone, etc.)
> and want to make sure that the new one does not conflict with the
> old one.
>
> pvfs2-validate-repair.patch
> ---------------------------
> This patch fills in some repair functionality that was missing from
> pvfs2-validate. Specifically, it adds the ability to move stranded
> files or datafiles into the lost+found directory. This patch is
> rather old, and I think pvfs2-fsck has had some substantial fixes
> since then, so this may be duplicating some functionality at this
> point.
>
> -Phil
> diff -Naur pvfs2/src/apps/admin/module.mk.in pvfs2-patched/src/apps/
> admin/module.mk.in
> --- pvfs2/src/apps/admin/module.mk.in 2006-12-06 11:06:09.000000000
> -0500
> +++ pvfs2-patched/src/apps/admin/module.mk.in 2007-05-02
> 14:48:44.000000000 -0400
> @@ -31,4 +31,5 @@
> ADMINSRC_SERVER := \
> $(DIR)/pvfs2-mkspace.c \
> $(DIR)/pvfs2-migrate-collection.c \
> + $(DIR)/pvfs2-change-fsid.c \
> $(DIR)/pvfs2-showcoll.c
> diff -Naur pvfs2/src/apps/admin/pvfs2-change-fsid.c pvfs2-patched/
> src/apps/admin/pvfs2-change-fsid.c
> --- pvfs2/src/apps/admin/pvfs2-change-fsid.c 1969-12-31
> 19:00:00.000000000 -0500
> +++ pvfs2-patched/src/apps/admin/pvfs2-change-fsid.c 2007-05-02
> 14:48:44.000000000 -0400
> @@ -0,0 +1,637 @@
> +/*
> + * (C) 2001 Clemson University and The University of Chicago
> + *
> + * See COPYING in top-level directory.
> + */
> +
> +/** \file
> + * Update utility for updating fsid in PVFS2 collections
> + */
> +
> +#include <unistd.h>
> +#include <string.h>
> +#include <stdio.h>
> +#include <getopt.h>
> +#include <limits.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <limits.h>
> +#include <inttypes.h>
> +#include <time.h>
> +
> +#include <db.h>
> +
> +#include "pvfs2-config.h"
> +#include "pvfs2.h"
> +#include "pvfs2-internal.h"
> +#include "trove.h"
> +#include "mkspace.h"
> +#include "pint-distribution.h"
> +#include "pint-dist-utils.h"
> +
> +
> +typedef struct
> +{
> + char db_path[PATH_MAX];
> + char fs_conf[PATH_MAX];
> + char fs_name[PATH_MAX];
> + char storage_path[PATH_MAX];
> + int32_t old_fsid;
> + int32_t new_fsid;
> + char old_fsid_hex[9];
> + char new_fsid_hex[9];
> + int verbose;
> + int view_only;
> + int hex_dir_exists;
> +} options_t;
> +
> +
> +int update_fs_conf(void);
> +int update_fsid_in_collections_db(void);
> +int get_old_fsid_from_conf(void);
> +int move_hex_dir(void);
> +int process_args(int argc, char ** argv);
> +int setup(int argc, char ** argv);
> +void print_help(char * progname);
> +
> +static options_t opts;
> +
> +int main(int argc, char ** argv)
> +{
> + int ret = 0;
> +
> + ret = setup( argc, argv);
> + if(ret)
> + {
> + printf("Error in setup function\n");
> + return -1;
> + }
> +
> + if(opts.old_fsid == opts.new_fsid)
> + {
> + if(opts.verbose)
> + {
> + printf("Nothing to do. Old/New fsids are the same.\n");
> + }
> + return 0;
> + }
> +
> + /* Fix up the pvfs2-fs.conf file */
> + if(!opts.view_only)
> + {
> + ret = update_fs_conf();
> + if(ret)
> + {
> + fprintf(stderr,"Error updating %s\n", opts.fs_conf);
> + return -1;
> + }
> +
> + if(opts.verbose)
> + {
> + printf("Successfully changed ID in [%s] from [%"
> PRId32 "] " \
> + "to [%" PRId32 "]\n",
> + opts.fs_conf,
> + opts.old_fsid,
> + opts.new_fsid);
> + }
> + }
> +
> + /* Move the hex dir in the storage space */
> + ret = move_hex_dir();
> + if(ret)
> + {
> + fprintf(stderr,"Error moving hex directory in storage
> space.\n");
> + return -1;
> + }
> +
> + if(opts.view_only)
> + {
> + printf("ID field in [%s] is dec=[%" PRId32 "] hex=[%s]\n",
> + opts.fs_conf,
> + opts.old_fsid,
> + opts.old_fsid_hex);
> + if(opts.hex_dir_exists)
> + {
> + printf("Found directory [%s] in storage space.\n",
> + opts.old_fsid_hex);
> + }
> + else
> + {
> + printf("Directory [%s] was NOT found in storage space.
> \n",
> + opts.old_fsid_hex);
> + }
> + }
> +
> + /* Fix up the collections.db file */
> + ret = update_fsid_in_collections_db();
> + if(ret)
> + {
> + fprintf(stderr,"Error updating collections.db file\n");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +int setup( int argc, char ** argv)
> +{
> + int ret = 0;
> +
> + /* Process command line args */
> + ret = process_args( argc, argv);
> + if(ret)
> + {
> + fprintf(stderr,"Error processing arguments\n");
> + return -1;
> + }
> +
> +
> + /* If no old_fsid provided, look it up in the conf file */
> + /* OR if view_only is specified, look it up */
> + if(!opts.old_fsid || opts.view_only)
> + {
> + ret = get_old_fsid_from_conf();
> + if(ret)
> + {
> + fprintf(stderr,"Error getting fsid.\n");
> + return -1;
> + }
> + }
> +
> + /* If no new_fsid provided, generate one */
> + if(!opts.new_fsid && !opts.view_only)
> + {
> + srand( time(NULL) );
> + /* This number came from genconfig */
> + opts.new_fsid = (int32_t)abs(rand() * 2147483647);
> + sprintf(opts.new_fsid_hex,"%08" PRIx32, opts.new_fsid);
> + if(opts.verbose)
> + {
> + printf("Generated new fsid of %" PRId32 "\n",
> opts.new_fsid);
> + }
> + }
> +
> + if(opts.verbose)
> + {
> + printf("Moving from fsid dec=[%" PRId32 "] hex=[%s] " \
> + "to fsid dec=[%" PRId32 "] hex=[%s]\n",
> + opts.old_fsid,
> + opts.old_fsid_hex,
> + opts.new_fsid,
> + opts.new_fsid_hex);
> + }
> +
> + return 0;
> +}
> +
> +int update_fs_conf(void)
> +{
> + FILE * fptr = NULL;
> + char command[PATH_MAX];
> + char output[PATH_MAX];
> + char file[512][512];
> + struct stat buf;
> + int ret = 0, i = 0, j = 0;
> +
> + /* See if fs_conf file exists */
> + ret = stat(opts.fs_conf, &buf);
> + if(ret)
> + {
> + fprintf(stderr,
> + "Error checking for file's existance. [%s]",
> + opts.fs_conf);
> + return -1;
> + }
> +
> + memset(command,0,sizeof(command));
> + memset(output,0,sizeof(output));
> +
> + /* See if old_fsid is in the file provided */
> + sprintf(command,
> + "grep ID %s | grep %" PRId32,
> + opts.fs_conf,
> + opts.old_fsid);
> + fptr = popen(command, "r");
> + if(fptr == NULL)
> + {
> + fprintf(stderr,"Error opening pipe. errno=%d",errno);
> + exit(-1);
> + }
> + fscanf(fptr, "%s", output);
> + if(!strncmp(output,"",PATH_MAX))
> + {
> + printf("fsid [%" PRId32 "] not found in file
> \n",opts.old_fsid);
> + return -1;
> + }
> + pclose(fptr);
> +
> + memset(output,0,sizeof(output));
> +
> + /* Replace old_fsid with new_fsid and write file back out */
> + sprintf(command,
> + "sed s/%" PRId32 "/%" PRId32 "/ %s",
> + opts.old_fsid,
> + opts.new_fsid,
> + opts.fs_conf);
> + fptr = popen(command, "r");
> + if(fptr == NULL)
> + {
> + fprintf(stderr,"Error opening pipe. errno=%d",errno);
> + exit(-1);
> + }
> +
> + i = 0;
> + while( fgets(output, sizeof(output), fptr) )
> + {
> + strncpy(file[i],output,512);
> + i++;
> + }
> + pclose(fptr);
> +
> + fptr = fopen(opts.fs_conf,"w");
> + for(j = 0; j < i; j++)
> + {
> + fprintf(fptr,"%s",file[j]);
> + }
> + fclose(fptr);
> +
> + return 0;
> +}
> +
> +int get_old_fsid_from_conf(void)
> +{
> + FILE * fptr = NULL;
> + int i = 0;
> + char buffer[512][512];
> + int32_t read_fsid = 0;
> +
> + memset(buffer, 0, sizeof(buffer));
> +
> + fptr = fopen(opts.fs_conf,"r+");
> + if(fptr == NULL)
> + {
> + fprintf(stderr,"Error opening %s\n",opts.fs_conf);
> + return -1;
> + }
> +
> + /* Read in file */
> + while(!feof(fptr))
> + {
> + fscanf(fptr,"%s",buffer[i]);
> + i++;
> + }
> + fclose(fptr);
> +
> + /* Search for ID field */
> + i = 0;
> + while(strncmp(buffer[i],"ID",2))
> + {
> + i++;
> + }
> +
> + /* Read in ID */
> + sscanf(buffer[++i],"%" SCNd32, &read_fsid);
> + if(!read_fsid)
> + {
> + fprintf(stderr,"Error: fsid not found.\n");
> + return -1;
> + }
> +
> + opts.old_fsid = read_fsid;
> + sprintf(opts.old_fsid_hex,"%08" PRIx32,opts.old_fsid);
> +
> + return 0;
> +}
> +
> +int move_hex_dir(void)
> +{
> + FILE * fptr = NULL;
> + char command[PATH_MAX];
> + char output[PATH_MAX];
> + struct stat buf;
> + char path[PATH_MAX];
> + char new_path[PATH_MAX];
> + int ret = 0;
> +
> + memset(path,0,sizeof(path));
> + sprintf(path,"%s/%s", opts.storage_path, opts.old_fsid_hex);
> +
> + /* See if directory exists */
> + ret = stat(path, &buf);
> + if(ret)
> + {
> + fprintf(stderr,
> + "Error checking for directory's existance. [%s]\n",
> + path);
> + return -1;
> + }
> +
> + opts.hex_dir_exists = 1;
> +
> + if(opts.view_only)
> + {
> + return 0;
> + }
> +
> + memset(command,0,sizeof(command));
> + memset(output,0,sizeof(output));
> + memset(new_path,0,sizeof(new_path));
> +
> + /* Move the directory */
> + sprintf(new_path, "%s/%s", opts.storage_path, opts.new_fsid_hex);
> + sprintf(command, "mv %s %s", path, new_path);
> +
> + fptr = popen(command, "r");
> + if(fptr == NULL)
> + {
> + fprintf(stderr,"Error opening pipe. errno=%d",errno);
> + exit(-1);
> + }
> + fscanf(fptr, "%s", output);
> + if(strncmp(output,"",PATH_MAX))
> + {
> + printf("mv from [%s] to [%s] failed.\n", path, new_path);
> + return -1;
> + }
> + pclose(fptr);
> +
> + if(opts.verbose)
> + {
> + printf("Successful dir move from [%s] to [%s]\n", path,
> new_path);
> + }
> +
> + return 0;
> +}
> +
> +int update_fsid_in_collections_db(void)
> +{
> + int ret = -1;
> + DB * dbp;
> + DBT key, data;
> + DBC * dbc_p = NULL;
> + TROVE_coll_id coll_id;
> +
> + ret = db_create(&dbp, NULL, 0);
> + if(ret != 0)
> + {
> + fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
> + return(-1);
> + }
> +
> + /* open collections.db */
> + ret = dbp->open(dbp,
> + #ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
> + NULL,
> + #endif
> + opts.db_path,
> + NULL,
> + DB_UNKNOWN,
> + 0,
> + 0);
> + if(ret != 0)
> + {
> + fprintf(stderr,"Error:dbp->open:%s.\n", db_strerror(ret));
> + return(-1);
> + }
> +
> + ret = dbp->cursor(dbp, NULL, &dbc_p, 0);
> + if (ret != 0)
> + {
> + fprintf(stderr, "Error: dbp->cursor: %s.\n", db_strerror
> (ret));
> + dbp->close(dbp, 0);
> + return(-1);
> + }
> +
> + memset(&key, 0, sizeof(key));
> + memset(&data, 0, sizeof(data));
> +
> + key.data = opts.fs_name;
> + key.size = strlen(opts.fs_name) + 1;
> + data.data = &coll_id;
> + data.ulen = sizeof(coll_id);
> + data.flags = DB_DBT_USERMEM;
> +
> + ret = dbp->get(dbp, NULL, &key, &data, 0);
> + if (ret != 0)
> + {
> + fprintf(stderr, "Error: dbp->get: %s\n", db_strerror(ret));
> + return -1;
> + }
> +
> + if(opts.view_only)
> + {
> + printf("DB entry in [%s] for key [%s] is dec=[%" PRId32 "]
> " \
> + "hex=[%08" PRIx32 "]\n",
> + opts.db_path,
> + opts.fs_name,
> + (int32_t)coll_id,
> + (int32_t)coll_id);
> + return 0;
> + }
> +
> + if(opts.verbose)
> + {
> + printf("Retrieved key [%s] from db. Old value is [%"
> PRId32 "]\n",
> + (char *)key.data,
> + (int32_t)coll_id);
> + }
> +
> + if(coll_id != opts.old_fsid)
> + {
> + fprintf(stderr, "Error: fsid retrieved does not equal old " \
> + "fsid provided! Found:[%" PRId32 "] " \
> + "Provided:[%" PRId32 "]\n",
> + (int32_t)coll_id,
> + opts.old_fsid);
> + return -1;
> + }
> +
> + /* At this point the fsid (or coll_id) has been retrieved and
> checked */
> + /* against the user provided fsid (old) */
> + /* Replace old fsid with new fsid */
> +
> + data.data = &(opts.new_fsid);
> + data.ulen = sizeof(opts.new_fsid);
> + data.flags = DB_DBT_USERMEM;
> +
> + ret = dbp->put(dbp, NULL, &key, &data, 0);
> + if (ret != 0)
> + {
> + fprintf(stderr, "Error: dbp->get: %s\n", db_strerror(ret));
> + return -1;
> + }
> +
> + /* At this point the new fsid should be properly inserted into
> the db */
> + /* Sanity check by retrieving again, and comparing to the new
> fsid */
> +
> + data.data = &coll_id;
> + data.ulen = sizeof(coll_id);
> + data.flags = DB_DBT_USERMEM;
> +
> + ret = dbp->get(dbp, NULL, &key, &data, 0);
> + if (ret != 0)
> + {
> + fprintf(stderr, "Error: dbp->get: %s\n", db_strerror(ret));
> + return -1;
> + }
> +
> + if(coll_id != opts.new_fsid)
> + {
> + fprintf(stderr, "Error: fsid retrieved after the replace
> finished " \
> + "does not equal old fsid provided! "\
> + "Found:[%" PRId32 "] Provided:[%" PRId32 "]
> \n",
> + (int32_t)coll_id,
> + (int32_t)opts.old_fsid);
> + return -1;
> + }
> +
> + if(opts.verbose)
> + {
> + printf("Retrieved key [%s] from db. New value is [%"
> PRId32 "]\n",
> + (char *)key.data, (int32_t)coll_id);
> + }
> +
> + dbc_p->c_close(dbc_p);
> + dbp->close(dbp, 0);
> + return 0;
> +}
> +
> +int process_args(int argc, char ** argv)
> +{
> + int tmp_fsid = 0;
> + int ret = 0, option_index = 0;
> + static struct option long_opts[] =
> + {
> + {"help",0,0,0},
> + {"verbose",0,0,0},
> + {"oldfsid",1,0,0},
> + {"newfsid",1,0,0},
> + {"fsname",1,0,0},
> + {"dbpath",1,0,0},
> + {"fsconf",1,0,0},
> + {"storage",1,0,0},
> + {"view",0,0,0},
> + {0,0,0,0}
> + };
> +
> + memset(&opts, 0, sizeof(options_t));
> + sprintf(opts.fs_name, "pvfs2-fs");
> +
> + while ((ret = getopt_long(argc, argv, "",
> + long_opts, &option_index)) != -1)
> + {
> + switch (option_index)
> + {
> + case 0: /* help */
> + print_help(argv[0]);
> + exit(0);
> +
> + case 1: /* verbose */
> + opts.verbose = 1;
> + break;
> +
> + case 2: /* oldfsid */
> + tmp_fsid = atoi(optarg);
> + opts.old_fsid = (int32_t) tmp_fsid;
> + sprintf(opts.old_fsid_hex,"%08"
> PRIx32,opts.old_fsid);
> + break;
> +
> + case 3: /* newfsid */
> + tmp_fsid = atoi(optarg);
> + opts.new_fsid = (int32_t) tmp_fsid;
> + sprintf(opts.new_fsid_hex,"%08"
> PRIx32,opts.new_fsid);
> + break;
> +
> + case 4: /* fsname */
> + strncpy(opts.fs_name, optarg, PATH_MAX);
> + break;
> +
> + case 5: /* dbpath */
> + strncpy(opts.db_path, optarg, PATH_MAX);
> + break;
> +
> + case 6: /* fsconf */
> + strncpy(opts.fs_conf, optarg, PATH_MAX);
> + break;
> +
> + case 7: /* storage */
> + strncpy(opts.storage_path, optarg, PATH_MAX);
> + break;
> +
> + case 8: /* view */
> + opts.view_only = 1;
> + break;
> +
> + default:
> + print_help(argv[0]);
> + return(-1);
> + }
> + option_index = 0;
> + }
> +
> + /* db_path must be set */
> + if(!strncmp(opts.db_path,"",PATH_MAX))
> + {
> + fprintf(stderr,"Error: --dbpath option must be given.\n");
> + print_help(argv[0]);
> + return(-1);
> + }
> +
> + /* fs_conf must be set */
> + if(!strncmp(opts.fs_conf,"",PATH_MAX))
> + {
> + fprintf(stderr,"Error: --fsconf option must be given.\n");
> + print_help(argv[0]);
> + return(-1);
> + }
> +
> + /* storage_path must be set */
> + if(!strncmp(opts.storage_path,"",PATH_MAX))
> + {
> + fprintf(stderr,"Error: --storage option must be given.\n");
> + print_help(argv[0]);
> + return(-1);
> + }
> +
> + return 0;
> +}
> +
> +void print_help(char * progname)
> +{
> + fprintf(stderr,"\nThis utility will update the fsid for a
> filesystem.\n");
> + fprintf(stderr,"The following arguments are required:\n");
> + fprintf(stderr,"--------------\n");
> + fprintf(stderr," --dbpath=</path/to/collections.db> "
> + "The current file system ID.\n");
> + fprintf(stderr," --fsconf=</path/to/pvfs2-fs.conf> "
> + "Fs config file for the the file system being modified.
> \n");
> + fprintf(stderr," --storage=</path/to/pvfs2-storage-space> "
> + "Local storage space for the the file system being
> modified.\n");
> + fprintf(stderr, "\n");
> + fprintf(stderr,"The following arguments are optional:\n");
> + fprintf(stderr,"--------------\n");
> + fprintf(stderr," --oldfsid=<fs_id> "
> + "The current file system ID. Else looked up from fs
> conf.\n");
> + fprintf(stderr," --newfsid=<fs_id> "
> + "The desired file system ID. Else generated as in
> genconfig.\n");
> + fprintf(stderr," --verbose "
> + "Print verbose messages during execution.\n");
> + fprintf(stderr," --help "
> + "Show this help listing.\n");
> + fprintf(stderr, "\n");
> + return;
> +}
> +
> +
> +/*
> + * Local variables:
> + * c-indent-level: 4
> + * c-basic-offset: 4
> + * End:
> + *
> + * vim: ts=8 sts=4 sw=4 expandtab
> + */
> +
> diff -Naur pvfs2/include/pvfs2-util.h pvfs2-patched/include/pvfs2-
> util.h
> --- pvfs2/include/pvfs2-util.h 2006-09-16 17:13:14.000000000 -0400
> +++ pvfs2-patched/include/pvfs2-util.h 2007-05-02
> 10:44:10.000000000 -0400
> @@ -47,6 +47,12 @@
> PVFS_credentials *PVFS_util_dup_credentials(
> const PVFS_credentials *credentials);
>
> +struct PVFS_sys_mntent* PVFS_util_gen_mntent(
> + char* config_server,
> + char* fs_name);
> +
> +void PVFS_util_gen_mntent_release(struct PVFS_sys_mntent* mntent);
> +
> void PVFS_util_release_credentials(
> PVFS_credentials *credentials);
>
> diff -Naur pvfs2/src/apps/admin/module.mk.in pvfs2-patched/src/apps/
> admin/module.mk.in
> --- pvfs2/src/apps/admin/module.mk.in 2006-12-06 11:06:09.000000000
> -0500
> +++ pvfs2-patched/src/apps/admin/module.mk.in 2007-05-02
> 10:44:52.000000000 -0400
> @@ -26,7 +26,8 @@
> $(DIR)/pvfs2-touch.c \
> $(DIR)/pvfs2-remove-object.c \
> $(DIR)/pvfs2-ln.c \
> - $(DIR)/pvfs2-perror.c
> + $(DIR)/pvfs2-perror.c \
> + $(DIR)/pvfs2-check-server.c
>
> ADMINSRC_SERVER := \
> $(DIR)/pvfs2-mkspace.c \
> diff -Naur pvfs2/src/apps/admin/pvfs2-check-server.c pvfs2-patched/
> src/apps/admin/pvfs2-check-server.c
> --- pvfs2/src/apps/admin/pvfs2-check-server.c 1969-12-31
> 19:00:00.000000000 -0500
> +++ pvfs2-patched/src/apps/admin/pvfs2-check-server.c 2007-05-02
> 10:50:56.000000000 -0400
> @@ -0,0 +1,221 @@
> +/*
> + * (C) 2001 Clemson University and The University of Chicago
> + *
> + * See COPYING in top-level directory.
> + */
> +
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <sys/time.h>
> +#include <time.h>
> +#include <stdlib.h>
> +
> +#include "pvfs2.h"
> +#include "pvfs2-mgmt.h"
> +
> +#ifndef PVFS2_VERSION
> +#define PVFS2_VERSION "Unknown"
> +#endif
> +
> +struct options
> +{
> + char* hostname;
> + char* fsname;
> + int port;
> + char* network_proto;
> +};
> +
> +static struct options* parse_args(int argc, char* argv[]);
> +static void usage(int argc, char** argv);
> +
> +int main(int argc, char **argv)
> +{
> + int ret = -1;
> + struct options* user_opts = NULL;
> + struct PVFS_sys_mntent* tmp_ent = NULL;
> + char config_server[256];
> +
> + /* look at command line arguments */
> + user_opts = parse_args(argc, argv);
> + if(!user_opts)
> + {
> + fprintf(stderr, "Error: failed to parse command "
> + "line arguments.\n");
> + usage(argc, argv);
> + return(-1);
> + }
> +
> + sprintf(config_server, "%.50s://%.150s:%d", user_opts-
> >network_proto,
> + user_opts->hostname, user_opts->port);
> +
> + /* build mnt entry */
> + tmp_ent = PVFS_util_gen_mntent(config_server, user_opts->fsname);
> + if(!tmp_ent)
> + {
> + fprintf(stderr, "Error: failed to build mnt entry.\n");
> + return(-1);
> + }
> +
> + ret = PVFS_sys_initialize(GOSSIP_NO_DEBUG);
> + if(ret < 0)
> + {
> + fprintf(stderr, "Error: failed to initialize PVFS2 library.
> \n");
> + return(-1);
> + }
> +
> + ret = PVFS_sys_fs_add(tmp_ent);
> + if(ret < 0)
> + {
> + PVFS_perror("Error: could not retrieve configuration from
> server", ret);
> + return(-1);
> + }
> +
> + PVFS_sys_finalize();
> +
> + PVFS_util_gen_mntent_release(tmp_ent);
> +
> + return(ret);
> +}
> +
> +
> +/* parse_args()
> + *
> + * parses command line arguments
> + *
> + * returns pointer to options structure on success, NULL on failure
> + */
> +static struct options* parse_args(int argc, char* argv[])
> +{
> + /* getopt stuff */
> + extern char* optarg;
> + extern int optind, opterr, optopt;
> + char flags[] = "h:f:n:p:";
> + int one_opt = 0;
> + int len = 0;
> +
> + struct options* tmp_opts = NULL;
> + int ret = -1;
> +
> + /* create storage for the command line options */
> + tmp_opts = (struct options*)malloc(sizeof(struct options));
> + if(!tmp_opts){
> + return(NULL);
> + }
> + memset(tmp_opts, 0, sizeof(struct options));
> +
> + /* look at command line arguments */
> + while((one_opt = getopt(argc, argv, flags)) != EOF){
> + switch(one_opt)
> + {
> + case('h'):
> + len = strlen(optarg)+1;
> + tmp_opts->hostname = (char*)malloc(len+1);
> + if(!tmp_opts->hostname)
> + {
> + free(tmp_opts);
> + return(NULL);
> + }
> + memset(tmp_opts->hostname, 0, len+1);
> + ret = sscanf(optarg, "%s", tmp_opts->hostname);
> + if(ret < 1){
> + free(tmp_opts);
> + return(NULL);
> + }
> + break;
> + case('f'):
> + len = strlen(optarg)+1;
> + tmp_opts->fsname = (char*)malloc(len+1);
> + if(!tmp_opts->fsname)
> + {
> + free(tmp_opts);
> + return(NULL);
> + }
> + memset(tmp_opts->fsname, 0, len+1);
> + ret = sscanf(optarg, "%s", tmp_opts->fsname);
> + if(ret < 1){
> + free(tmp_opts);
> + return(NULL);
> + }
> + break;
> + case('n'):
> + len = strlen(optarg)+1;
> + tmp_opts->network_proto = (char*)malloc(len+1);
> + if(!tmp_opts->network_proto)
> + {
> + free(tmp_opts);
> + return(NULL);
> + }
> + memset(tmp_opts->network_proto, 0, len+1);
> + ret = sscanf(optarg, "%s", tmp_opts->network_proto);
> + if(ret < 1){
> + free(tmp_opts);
> + return(NULL);
> + }
> + break;
> + case('p'):
> + ret = sscanf(optarg, "%d", &tmp_opts->port);
> + if(ret < 1){
> + free(tmp_opts);
> + return(NULL);
> + }
> + break;
> + case('?'):
> + usage(argc, argv);
> + exit(EXIT_FAILURE);
> + }
> + }
> +
> + if(!tmp_opts->hostname || !tmp_opts->fsname ||
> + !tmp_opts->network_proto || !tmp_opts->port)
> + {
> + if(tmp_opts->hostname)
> + free(tmp_opts->hostname);
> +
> + if(tmp_opts->fsname)
> + free(tmp_opts->fsname);
> +
> + if(tmp_opts->network_proto)
> + free(tmp_opts->network_proto);
> +
> + free(tmp_opts);
> + return(NULL);
> + }
> +
> + return(tmp_opts);
> +}
> +
> +static void usage(int argc, char** argv)
> +{
> + fprintf(stderr, "\n");
> + fprintf(stderr, "Usage : %s -h <server> "
> + "-f <fsname> -n <proto> -p <port>\n", argv[0]);
> +
> + fprintf(stderr, "Check to see if a server is responding.\n\n");
> +
> + fprintf(stderr," -h <server> name of the server
> \n");
> + fprintf(stderr," -f <fsname> name of the
> exported"
> + " file system\n");
> + fprintf(stderr," -n <proto> name of the network"
> + " protocol to use\n");
> + fprintf(stderr," -p <port> port number on
> which"
> + " the pvfs2 server is listening\n");
> +
> + fprintf(stderr, "Example: %s -h localhost -f pvfs2-fs -n tcp -
> p 7500\n",
> + argv[0]);
> + return;
> +}
> +
> +/*
> + * Local variables:
> + * c-indent-level: 4
> + * c-basic-offset: 4
> + * End:
> + *
> + * vim: ts=8 sts=4 sw=4 expandtab
> + */
> +
> diff -Naur pvfs2/src/common/misc/pvfs2-util.c pvfs2-patched/src/
> common/misc/pvfs2-util.c
> --- pvfs2/src/common/misc/pvfs2-util.c 2007-03-20
> 15:01:36.000000000 -0500
> +++ pvfs2-patched/src/common/misc/pvfs2-util.c 2007-05-02
> 10:44:10.000000000 -0400
> @@ -100,6 +100,60 @@
> char* out_fs_path,
> int out_fs_path_max);
>
> +struct PVFS_sys_mntent* PVFS_util_gen_mntent(
> + char* config_server,
> + char* fs_name)
> +{
> + struct PVFS_sys_mntent* tmp_ent = NULL;
> +
> + tmp_ent = (struct PVFS_sys_mntent*)malloc(sizeof(struct
> + PVFS_sys_mntent));
> + if(!tmp_ent)
> + {
> + return(NULL);
> + }
> + memset(tmp_ent, 0, sizeof(struct PVFS_sys_mntent));
> +
> + tmp_ent->num_pvfs_config_servers = 1;
> + tmp_ent->pvfs_config_servers = (char**)malloc(sizeof(char*));
> + if(!tmp_ent->pvfs_config_servers)
> + {
> + free(tmp_ent);
> + return(NULL);
> + }
> +
> + tmp_ent->pvfs_config_servers[0] = strdup(config_server);
> + if(!tmp_ent->pvfs_config_servers[0])
> + {
> + free(tmp_ent->pvfs_config_servers);
> + free(tmp_ent);
> + return(NULL);
> + }
> +
> + tmp_ent->pvfs_fs_name = strdup(fs_name);
> + if(!tmp_ent->pvfs_fs_name)
> + {
> + free(tmp_ent->pvfs_config_servers[0]);
> + free(tmp_ent->pvfs_config_servers);
> + free(tmp_ent);
> + return(NULL);
> + }
> +
> + tmp_ent->flowproto = FLOWPROTO_DEFAULT;
> + tmp_ent->encoding = ENCODING_DEFAULT;
> +
> + return(tmp_ent);
> +}
> +
> +void PVFS_util_gen_mntent_release(struct PVFS_sys_mntent* mntent)
> +{
> + free(mntent->pvfs_config_servers[0]);
> + free(mntent->pvfs_config_servers);
> + free(mntent->pvfs_fs_name);
> + free(mntent);
> + return;
> +}
> +
> void PVFS_util_gen_credentials(
> PVFS_credentials *credentials)
> {
> Index: include/pvfs2-mgmt.h
> ===================================================================
> --- include/pvfs2-mgmt.h (.../vendor/pvfs2/current) (revision 3373)
> +++ include/pvfs2-mgmt.h (.../trunk/pvfs2_src) (revision 3373)
> @@ -23,6 +23,7 @@
> #ifndef __PVFS2_MGMT_H
> #define __PVFS2_MGMT_H
>
> +#include "pvfs2-sysint.h"
> #include "pvfs2-types.h"
>
> /* non-blocking mgmt operation handle */
> @@ -361,6 +362,24 @@
>
> void PVFS_mgmt_release(PVFS_mgmt_op_id op_id);
>
> +PVFS_error PVFS_imgmt_repair_file(
> + char *object_name,
> + PVFS_object_ref parent_ref,
> + PVFS_sys_attr attr,
> + PVFS_credentials *credentials,
> + PVFS_handle handle,
> + PVFS_sysresp_create *resp,
> + PVFS_sys_op_id *op_id,
> + void *user_ptr);
> +
> +PVFS_error PVFS_mgmt_repair_file(
> + char *object_name,
> + PVFS_object_ref parent_ref,
> + PVFS_sys_attr attr,
> + PVFS_credentials *credentials,
> + PVFS_handle handle,
> + PVFS_sysresp_create *resp);
> +
> int PVFS_mgmt_get_config(
> const PVFS_fs_id* fsid,
> PVFS_BMI_addr_t* addr,
> Index: src/apps/admin/pvfs2-validate.c
> ===================================================================
> --- src/apps/admin/pvfs2-validate.c (.../vendor/pvfs2/current)
> (revision 3373)
> +++ src/apps/admin/pvfs2-validate.c (.../trunk/pvfs2_src) (revision
> 3373)
> @@ -104,6 +104,16 @@
> return -1;
> }
>
> + if (fsck_options->repair_stranded_objects &&
> + !fsck_options->check_stranded_objects)
> + {
> + fprintf(stderr, "Error: option to check for stranded
> objects (-c) ");
> + fprintf(stderr, "required with repair option (See -R
> option below).\n");
> + usage(argc, argv);
> + free(fsck_options);
> + return -1;
> + }
> +
> ret = PVFS_util_init_defaults();
> if (ret != 0)
> {
> @@ -235,7 +245,10 @@
> ret = PVFS_fsck_get_attributes(fsck_options, pref, creds,
> &attributes);
> if(ret < 0)
> {
> - fprintf(stderr, "Error: [%s] cannot retrieve attributes.
> \n", current_path);
> + fprintf(stderr,
> + "Error: [%s] cannot retrieve attributes for object: "
> + "handle=[%llu] fsid=[%d]\n",
> + current_path, llu(pref->handle), pref->fs_id);
> }
> else if (attributes.attr.objtype == PVFS_TYPE_METAFILE)
> {
> @@ -345,6 +358,8 @@
> 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, " -R \t repair stranded objects (requires -c)
> \n");
> + fprintf(stderr, " \t (requires that -d refer to the PVFS2
> root directory)\n");
> fprintf(stderr, "\n\n");
> fprintf(stderr, " Return Codes:\n");
> fprintf(stderr,
> @@ -359,6 +374,10 @@
>
> static struct PINT_fsck_options *parse_args(int argc, char **argv)
> {
> + /* getopt variables */
> + extern char *optarg;
> + extern int optind, opterr, optopt;
> +
> int opt = 0;
> int path_length = 0;
>
> @@ -369,7 +388,7 @@
> return NULL;
> }
>
> - while ((opt = getopt(argc, argv, "d:VvharsfcF")) != EOF)
> + while ((opt = getopt(argc, argv, "d:VvharsfcFR")) != EOF)
> {
> switch (opt)
> {
> @@ -392,6 +411,9 @@
> case 'c':
> opts->check_stranded_objects = 1;
> break;
> + case 'R':
> + opts->repair_stranded_objects = 1;
> + break;
> case 'a':
> opts->fix_errors = 1;
> printf("Error: file system repair not implemented\n");
>
> Property changes on: src/apps/admin/pvfs2-validate.c
> ___________________________________________________________________
> Name: svn:executable
> - *
>
> Index: src/common/misc/fsck-utils.c
> ===================================================================
> --- src/common/misc/fsck-utils.c (.../vendor/pvfs2/current)
> (revision 3373)
> +++ src/common/misc/fsck-utils.c (.../trunk/pvfs2_src) (revision 3373)
> @@ -11,6 +11,7 @@
> #include <assert.h>
>
> #include "fsck-utils.h"
> +#include "client-state-machine.h"
>
> #define HANDLE_BATCH 1000
> #define MAX_DIR_ENTS 64
> @@ -62,14 +63,16 @@
> PVFS_BMI_addr_t *addr_array;
> } PINT_handle_wrangler_handlelist;
>
> -#if 0
> -/* not used yet */
> static int PINT_handle_wrangler_get_stranded_handles(
> const PVFS_fs_id * cur_fs,
> int *num_stranded_handles,
> PVFS_handle ** stranded_handles);
> -#endif
>
> +static int PINT_handle_wrangler_repair_stranded_handles(
> + const struct PINT_fsck_options *fsck_options,
> + const PVFS_fs_id * cur_fs,
> + const PVFS_credentials * creds);
> +
> static int PINT_handle_wrangler_display_stranded_handles(
> const struct PINT_fsck_options *fsck_options,
> const PVFS_fs_id * cur_fs,
> @@ -1059,6 +1062,13 @@
> creds);
> }
>
> + /* repair leftover handles */
> + if (fsck_options->repair_stranded_objects)
> + {
> + PINT_handle_wrangler_repair_stranded_handles(fsck_options,
> cur_fs,
> + creds);
> + }
> +
> return(0);
> }
>
> @@ -1426,14 +1436,14 @@
> return ret;
> }
>
> -#if 0
> /**
> * Returns the handles left over from the fsck
> */
> static int PINT_handle_wrangler_get_stranded_handles(
> const PVFS_fs_id * cur_fs, /**< filesystem id */
> int *num_stranded_handles, /**< number of
> handles in array of handles returned */
> - PVFS_handle ** stranded_handles) /**< array of
> stranded handles on fs cur_fs */
> + PVFS_handle ** stranded_handles) /**< array of
> stranded handles on fs cur_fs,
> + allocated
> here. Must be freed by the caller. */
> {
> int ret = 0;
> int i = 0;
> @@ -1469,9 +1479,179 @@
>
> return ret;
> }
> -#endif
>
> /**
> + * Repairs the handles left over from the fsck
> + *
> + * \retval 0 on success
> + * \retval -PVFS_error on failure
> + */
> +static int PINT_handle_wrangler_repair_stranded_handles(
> + const struct PINT_fsck_options *fsck_options, /**< populated
> fsck options */
> + const PVFS_fs_id * cur_fs, /**<
> filesystem id */
> + const PVFS_credentials * creds) /**< populated
> credentials structure */
> +{
> + int i = 0;
> + int ret = 0;
> + int num_stranded_handles = 0;
> + PVFS_handle * stranded_handles = NULL;
> + PVFS_credentials credentials;
> + PVFS_sys_attr attr;
> + PVFS_sysresp_getattr attributes;
> + PVFS_sysresp_mkdir mkdir_resp;
> + PVFS_sysresp_create repair_resp;
> + PVFS_sysresp_lookup lookup_resp;
> + PVFS_object_ref parent_ref;
> +
> + memset(&credentials, 0, sizeof(credentials));
> + memset(&attr, 0, sizeof(attr));
> + memset(&attributes, 0, sizeof(attributes));
> + memset(&mkdir_resp, 0, sizeof(mkdir_resp));
> + memset(&repair_resp, 0, sizeof(repair_resp));
> + memset(&lookup_resp, 0, sizeof(lookup_resp));
> + memset(&parent_ref, 0, sizeof(parent_ref));
> +
> + char cur_time[20];
> + size_t num_chars;
> + struct tm cur_time_s;
> + time_t now;
> + now = time(NULL);
> + cur_time_s = *(localtime(&now));
> + num_chars = strftime(cur_time,20,"%Y.%m.%d_%H.%M.%
> S",&cur_time_s);
> + if(num_chars == 0)
> + {
> + gossip_err("Error: could not get current time.\n");
> + return(-PVFS_EINVAL);
> + }
> +
> + PVFS_util_gen_credentials(&credentials);
> + attr.owner = credentials.uid;
> + attr.group = credentials.gid;
> + attr.perms = 0700; /*owner (root) only*/
> + attr.atime = attr.mtime = attr.ctime = 0; /*Set to "now"*/
> + attr.mask = PVFS_ATTR_SYS_ALL_SETABLE; /*requires 'at
> lest' this*/
> +
> + /*Set to dir in lost+found.*/
> + /*look up the handle for lost+found*/
> + char * parent_name = "/lost+found";
> + ret = PVFS_sys_lookup(*cur_fs, parent_name, &credentials,
> &lookup_resp,
> + PVFS2_LOOKUP_LINK_NO_FOLLOW);
> + if (ret < 0)
> + {
> + gossip_err(" *** lookup failed on [%s] directory
> \n",parent_name);
> + return ret;
> + }
> +
> + ret = PVFS_sys_mkdir(cur_time, lookup_resp.ref, attr,
> &credentials,
> + &mkdir_resp);
> + if (ret < 0 && ret != -PVFS_EEXIST)
> + {
> + gossip_err(" *** mkdir failed on directory [/lost+found/%s]
> \n",cur_time);
> + return ret;
> + }
> +
> + parent_ref = mkdir_resp.ref;
> +
> + PINT_handle_wrangler_get_stranded_handles(cur_fs,
> + &num_stranded_handles,
> + &stranded_handles);
> + if(num_stranded_handles > 0)
> + {
> + printf("Repaired Objects:\n");
> + printf("[ Handle ] [ FSID ] [ Size ] ");
> + printf("[ PVFS2 Server ] [ Filename ]\n");
> + }
> + for(i = 0;i < num_stranded_handles; i++)
> + {
> + char name[PATH_MAX] = "";
> + PVFS_object_ref dfile;
> + sprintf(name,"%d.dfile",i);
> +
> + /* get this objects attributes */
> + dfile.handle = stranded_handles[i];
> + dfile.fs_id = parent_ref.fs_id;
> + ret = PVFS_fsck_get_attributes(fsck_options, &dfile,
> + creds, &attributes);
> +
> + /* If get attributes fails skip to next, Only try to
> rescue dfiles */
> + if(ret || attributes.attr.objtype != PVFS_TYPE_DATAFILE)
> + {
> + continue;
> + }
> +
> + ret = PVFS_mgmt_repair_file
> (name,parent_ref,attr,&credentials,
> + stranded_handles
> [i],&repair_resp);
> + if(ret < 0)
> + {
> + gossip_err("Unable to repair stranded handle [%llu]",
> + llu(stranded_handles[i]));
> + }
> + else
> + {
> + const char * server_name = NULL;
> + int j = 0;
> + int server_type = 0;
> + struct server_configuration_s *config;
> + PVFS_BMI_addr_t server_addr;
> +
> + /* get this objects attributes */
> + ret = PVFS_fsck_get_attributes(fsck_options, &dfile,
> + creds, &attributes);
> + if(ret < 0)
> + {
> + PVFS_perror_gossip("PVFS_fsck_get_attributes", ret);
> + gossip_err("Error: unable to retrieve attributes
> for handle ");
> + gossip_err("[%llu]\n", llu(repair_resp.ref.handle));
> + return(ret);
> + }
> +
> + /*Get the pretty server name */
> + config = PINT_get_server_config_struct(*cur_fs);
> + /* find which server the handle is on */
> + ret = PINT_cached_config_map_to_server(&server_addr,
> + stranded_handles
> [i],
> + *cur_fs);
> + if(ret < 0)
> + {
> + PVFS_perror_gossip
> ("PINT_cached_config_map_to_server", ret);
> + gossip_err("Error: could not resolve handle [%llu]
> to server\n",
> + llu(stranded_handles[i]));
> + /* release mutex on server config */
> + PINT_put_server_config_struct(config);
> + return(ret);
> + }
> + /* get the index of the server this handle is located
> on */
> + for(j = 0; j <
> PINT_handle_wrangler_handlelist.num_servers; j++)
> + {
> + if(PINT_handle_wrangler_handlelist.addr_array[j]
> == server_addr)
> + {
> + /* retrieve the server name */
> + server_name = PINT_cached_config_map_addr(
> + config,
> + *cur_fs,
> + PINT_handle_wrangler_handlelist.
> + addr_array[j],
> + &server_type);
> + break;
> + }
> + }
> +
> + /* release mutex on server config */
> + PINT_put_server_config_struct(config);
> +
> + printf("%12llu %10d ",llu(stranded_handles
> [i]),repair_resp.ref.fs_id);
> + printf("%13lld ", lld(attributes.attr.size));
> + printf(" %10s ", server_name);
> + printf(" %10s\n", name);
> + }
> + }
> +
> + free(stranded_handles);
> +
> + return ret;
> +}
> +
> +/**
> * Displays the handles left over from the fsck
> *
> * \retval 0 on success
> Index: src/common/misc/fsck-utils.h
> ===================================================================
> --- src/common/misc/fsck-utils.h (.../vendor/pvfs2/current)
> (revision 3373)
> +++ src/common/misc/fsck-utils.h (.../trunk/pvfs2_src) (revision 3373)
> @@ -45,6 +45,7 @@
> struct PINT_fsck_options
> {
> unsigned int fix_errors; /**< fix errors found */
> + unsigned int repair_stranded_objects; /**< check for stranded
> objects */
> unsigned int check_stranded_objects; /**< check for stranded
> objects */
> unsigned int check_symlink_target; /**< checks symlink
> target for bad practice */
> unsigned int check_dir_entry_names; /**< checks dirent names
> for bad practice */
> Index: src/client/sysint/mgmt-repair-file.sm
> ===================================================================
> --- src/client/sysint/mgmt-repair-file.sm (.../vendor/pvfs2/
> current) (revision 0)
> +++ src/client/sysint/mgmt-repair-file.sm (.../trunk/pvfs2_src)
> (revision 3373)
> @@ -0,0 +1,303 @@
> +/*
> + * (C) 2001 Clemson University and The University of Chicago
> + *
> + * See COPYING in top-level directory.
> + */
> +
> +/** \file
> + * \ingroup sysint
> + *
> + * PVFS2 system interface routines for repairing files.
> + */
> +
> +#include <string.h>
> +#include <assert.h>
> +
> +#include "client-state-machine.h"
> +#include "pvfs2-debug.h"
> +#include "pvfs2-dist-simple-stripe.h"
> +#include "job.h"
> +#include "gossip.h"
> +#include "str-utils.h"
> +#include "pint-cached-config.h"
> +#include "pint-distribution.h"
> +#include "PINT-reqproto-encode.h"
> +#include "pint-util.h"
> +#include "pint-dist-utils.h"
> +#include "ncache.h"
> +#include "pvfs2-internal.h"
> +#include "sys-create.h"
> +
> +extern job_context_id pint_client_sm_context;
> +
> +static int create_dspace_create_failure(PINT_client_sm *sm_p,
> job_status_s *js_p);
> +
> +%%
> +
> +machine pvfs2_client_mgmt_repair_file_sm
> +{
> + state init
> + {
> + run create_init;
> + default => parent_getattr;
> + }
> +
> + state parent_getattr
> + {
> + jump pvfs2_client_getattr_sm;
> + success => parent_getattr_inspect;
> + default => cleanup;
> + }
> +
> + state parent_getattr_inspect
> + {
> + run create_parent_getattr_inspect;
> + success => dspace_create_setup_msgpair;
> + default => cleanup;
> + }
> +
> + state dspace_create_setup_msgpair
> + {
> + run create_dspace_create_setup_msgpair;
> + success => dspace_create_xfer_msgpair;
> + default => dspace_create_failure;
> + }
> +
> + state dspace_create_xfer_msgpair
> + {
> + jump pvfs2_msgpairarray_sm;
> + success => create_setattr_setup_msgpair;
> + default => dspace_create_failure;
> + }
> +
> + state dspace_create_failure
> + {
> + run create_dspace_create_failure;
> + default => cleanup;
> + }
> +
> + state create_setattr_setup_msgpair
> + {
> + run create_setattr_setup_msgpair;
> + success => create_setattr_xfer_msgpair;
> + default => cleanup;
> + }
> +
> + state create_setattr_xfer_msgpair
> + {
> + jump pvfs2_msgpairarray_sm;
> + success => crdirent_setup_msgpair;
> + default => create_setattr_failure;
> + }
> +
> + state create_setattr_failure
> + {
> + run create_setattr_failure;
> + default => delete_handles_setup_msgpair_array;
> + }
> +
> + state crdirent_setup_msgpair
> + {
> + run create_crdirent_setup_msgpair;
> + success => crdirent_xfer_msgpair;
> + default => crdirent_failure;
> + }
> +
> + state crdirent_xfer_msgpair
> + {
> + jump pvfs2_msgpairarray_sm;
> + success => cleanup;
> + default => crdirent_failure;
> + }
> +
> + state crdirent_failure
> + {
> + run create_crdirent_failure;
> + default => delete_handles_setup_msgpair_array;
> + }
> +
> + state delete_handles_setup_msgpair_array
> + {
> + run create_delete_handles_setup_msgpair_array;
> + success => delete_handles_xfer_msgpair_array;
> + default => cleanup;
> + }
> +
> + state delete_handles_xfer_msgpair_array
> + {
> + jump pvfs2_msgpairarray_sm;
> + default => cleanup;
> + }
> +
> + state cleanup
> + {
> + run create_cleanup;
> + CREATE_RETRY => init;
> + default => terminate;
> + }
> +}
> +
> +%%
> +
> +/** Initiate creation of a file with a specified distribution.
> + */
> +PVFS_error PVFS_imgmt_repair_file(
> + char *object_name,
> + PVFS_object_ref parent_ref,
> + PVFS_sys_attr attr,
> + PVFS_credentials *credentials,
> + PVFS_handle handle, /*Pull in handle of dfile to create*/
> + PVFS_sysresp_create *resp,
> + PVFS_sys_op_id *op_id,
> + void *user_ptr)
> +{
> + int num_dfiles_req = 0;
> + PVFS_error ret = -PVFS_EINVAL;
> + PINT_client_sm *sm_p = NULL;
> +
> + gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_imgmt_repair_file
> entered\n");
> +
> + if ((parent_ref.handle == PVFS_HANDLE_NULL) ||
> + (parent_ref.fs_id == PVFS_FS_ID_NULL) ||
> + (object_name == NULL) || (resp == NULL))
> + {
> + gossip_err("invalid (NULL) required argument\n");
> + return ret;
> + }
> +
> + if ((attr.mask & PVFS_ATTR_SYS_ALL_SETABLE) !=
> + PVFS_ATTR_SYS_ALL_SETABLE)
> + {
> + gossip_lerr("PVFS_imgmt_repair_file() failure: invalid
> attributes "
> + "specified\n");
> + return ret;
> + }
> +
> + if ((attr.mask & PVFS_ATTR_SYS_DFILE_COUNT) &&
> + ((attr.dfile_count < 1) ||
> + (attr.dfile_count > PVFS_REQ_LIMIT_DFILE_COUNT)))
> + {
> + gossip_err("Error: invalid number of datafiles (%d) specified "
> + "in PVFS_mgmt_repair_file().\n", (int)
> attr.dfile_count);
> + return ret;
> + }
> +
> + if ((strlen(object_name) + 1) > PVFS_REQ_LIMIT_SEGMENT_BYTES)
> + {
> + return -PVFS_ENAMETOOLONG;
> + }
> +
> + sm_p = (PINT_client_sm *)malloc(sizeof(*sm_p));
> + if (sm_p == NULL)
> + {
> + return -PVFS_ENOMEM;
> + }
> + memset(sm_p, 0, sizeof(*sm_p));
> +
> + sm_p->u.create.datafile_handles = (PVFS_handle *)malloc(
> + sizeof(PVFS_handle));
> + if (sm_p->u.create.datafile_handles == NULL)
> + {
> + gossip_err("create: Failed to allocate data handle array\n");
> + return -PVFS_ENOMEM;
> + }
> + memset(sm_p->u.create.datafile_handles, 0,sizeof(PVFS_handle));
> +
> + PINT_init_msgarray_params(&sm_p->msgarray_params,
> parent_ref.fs_id);
> + PINT_init_sysint_credentials(sm_p->cred_p, credentials);
> + sm_p->u.create.object_name = object_name;
> + sm_p->u.create.create_resp = resp;
> + sm_p->u.create.datafile_handles[0] = handle; /*Assign handle
> pulled in here*/
> + PVFS_util_copy_sys_attr(&sm_p->u.create.sys_attr, &attr);
> + sm_p->u.create.stored_error_code = 0;
> + sm_p->u.create.retry_count = 0;
> +
> + sm_p->object_ref = parent_ref;
> +
> + /* use the basic_dist distribution to keep all on one server */
> + sm_p->u.create.dist = PINT_dist_create("basic_dist");
> + if (!sm_p->u.create.dist)
> + {
> + free(sm_p);
> + return -PVFS_ENOMEM;
> + }
> +
> + /*Set requested number of dfiles to 1*/
> + num_dfiles_req = 1;
> +
> + /* Determine the number of dfiles, passing in desired value of
> 1 */
> + ret = PINT_cached_config_get_num_dfiles(sm_p->object_ref.fs_id,
> + sm_p->u.create.dist,
> + num_dfiles_req,
> + &sm_p-
> >u.create.num_data_files);
> + if (ret < 0)
> + {
> + gossip_err("Failed to get number of data servers\n");
> + free(sm_p);
> + return ret;
> + }
> +
> + gossip_debug(
> + GOSSIP_CLIENT_DEBUG, "Creating file %s under %llu, %d\n",
> + object_name, llu(parent_ref.handle), parent_ref.fs_id);
> +
> + return PINT_client_state_machine_post(
> + sm_p, PVFS_MGMT_REPAIR_FILE, op_id, user_ptr);
> +}
> +
> +/** Create a file with a specified distribution.
> + */
> +PVFS_error PVFS_mgmt_repair_file(
> + char *object_name,
> + PVFS_object_ref parent_ref,
> + PVFS_sys_attr attr,
> + PVFS_credentials *credentials,
> + PVFS_handle handle,
> + PVFS_sysresp_create *resp)
> +{
> + PVFS_error ret = -PVFS_EINVAL, error = 0;
> + PVFS_sys_op_id op_id;
> +
> + gossip_debug(GOSSIP_CLIENT_DEBUG, "PVFS_mgmt_repair_file
> entered\n");
> +
> + ret = PVFS_imgmt_repair_file(object_name, parent_ref, attr,
> credentials,
> + handle, resp, &op_id, NULL);
> + if (ret)
> + {
> + PVFS_perror_gossip("PVFS_imgmt_repair_file call", ret);
> + error = ret;
> + }
> + else
> + {
> + ret = PVFS_sys_wait(op_id, "create", &error);
> + if (ret)
> + {
> + PVFS_perror_gossip("PVFS_sys_wait call", ret);
> + error = ret;
> + }
> + }
> +
> + PVFS_sys_release(op_id);
> + return error;
> +}
> +
> +static int create_dspace_create_failure(PINT_client_sm *sm_p,
> + job_status_s *js_p)
> +{
> + sm_p->u.create.stored_error_code = js_p->error_code;
> +
> + gossip_debug(GOSSIP_CLIENT_DEBUG,
> + "create state: dspace_create_failure\n");
> + return 1;
> +}
> +
> +
> +/*
> + * Local variables:
> + * mode: c
> + * c-indent-level: 4
> + * c-basic-offset: 4
> + * End:
> + *
> + * vim: ft=c ts=8 sts=4 sw=4 expandtab
> + */
> Index: src/client/sysint/client-state-machine.c
> ===================================================================
> --- src/client/sysint/client-state-machine.c (.../vendor/pvfs2/
> current) (revision 3373)
> +++ src/client/sysint/client-state-machine.c (.../trunk/pvfs2_src)
> (revision 3373)
> @@ -222,7 +222,8 @@
> {&pvfs2_client_mgmt_remove_object_sm},
> {&pvfs2_client_mgmt_remove_dirent_sm},
> {&pvfs2_client_mgmt_create_dirent_sm},
> - {&pvfs2_client_mgmt_get_dirdata_handle_sm}
> + {&pvfs2_client_mgmt_get_dirdata_handle_sm},
> + {&pvfs2_client_mgmt_repair_file_sm}
> };
>
> /*
> @@ -816,6 +817,7 @@
> { PVFS_MGMT_REMOVE_OBJECT, "PVFS_MGMT_REMOVE_OBJECT" },
> { PVFS_MGMT_REMOVE_DIRENT, "PVFS_MGMT_REMOVE_DIRENT" },
> { PVFS_MGMT_CREATE_DIRENT, "PVFS_MGMT_CREATE_DIRENT" },
> + { PVFS_MGMT_REPAIR_FILE, "PVFS_MGMT_REPAIR_FILE" },
> { PVFS_MGMT_GET_DIRDATA_HANDLE,
> "PVFS_MGMT_GET_DIRDATA_HANDLE" },
> { PVFS_SYS_GETEATTR, "PVFS_SYS_GETEATTR" },
> Index: src/client/sysint/client-state-machine.h
> ===================================================================
> --- src/client/sysint/client-state-machine.h (.../vendor/pvfs2/
> current) (revision 3373)
> +++ src/client/sysint/client-state-machine.h (.../trunk/pvfs2_src)
> (revision 3373)
> @@ -658,6 +658,7 @@
> PVFS_MGMT_REMOVE_DIRENT = 78,
> PVFS_MGMT_CREATE_DIRENT = 79,
> PVFS_MGMT_GET_DIRDATA_HANDLE = 80,
> + PVFS_MGMT_REPAIR_FILE = 81,
> PVFS_SERVER_GET_CONFIG = 200,
> PVFS_SERVER_FETCH_CONFIG = 201,
> PVFS_CLIENT_JOB_TIMER = 300,
> @@ -790,6 +791,7 @@
> extern struct PINT_state_machine_s
> pvfs2_client_mgmt_remove_dirent_sm;
> extern struct PINT_state_machine_s
> pvfs2_client_mgmt_create_dirent_sm;
> extern struct PINT_state_machine_s
> pvfs2_client_mgmt_get_dirdata_handle_sm;
> +extern struct PINT_state_machine_s pvfs2_client_mgmt_repair_file_sm;
> extern struct PINT_state_machine_s pvfs2_client_get_eattr_sm;
> extern struct PINT_state_machine_s pvfs2_client_set_eattr_sm;
> extern struct PINT_state_machine_s pvfs2_client_del_eattr_sm;
> Index: src/client/sysint/sys-create.h
> ===================================================================
> --- src/client/sysint/sys-create.h (.../vendor/pvfs2/current)
> (revision 0)
> +++ src/client/sysint/sys-create.h (.../trunk/pvfs2_src) (revision
> 3373)
> @@ -0,0 +1,43 @@
> +/*
> + * (C) 2001 Clemson University and The University of Chicago
> + *
> + * See COPYING in top-level directory.
> + */
> +
> +enum
> +{
> + CREATE_RETRY = 170
> +};
> +
> +/* state function prototypes */
> +int create_init(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_dspace_create_setup_msgpair(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_datafiles_setup_msgpair_array(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_datafiles_failure(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_setattr_setup_msgpair(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_setattr_failure(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_crdirent_setup_msgpair(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_crdirent_failure(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_delete_handles_setup_msgpair_array(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_cleanup(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +int create_parent_getattr_inspect(
> + PINT_client_sm *sm_p, job_status_s *js_p);
> +/*
> + * Local variables:
> + * c-indent-level: 4
> + * c-basic-offset: 4
> + * End:
> + *
> + * vim: ts=8 sts=4 sw=4 expandtab
> + */
> +
>
> Property changes on: src/client/sysint/fs-add.sm
> ___________________________________________________________________
> Name: svn:keywords
> + Author Date Id Revision
>
> Index: src/client/sysint/sys-create.sm
> ===================================================================
> --- src/client/sysint/sys-create.sm (.../vendor/pvfs2/current)
> (revision 3373)
> +++ src/client/sysint/sys-create.sm (.../trunk/pvfs2_src) (revision
> 3373)
> @@ -26,38 +26,8 @@
> #include "pint-dist-utils.h"
> #include "ncache.h"
> #include "pvfs2-internal.h"
> +#include "sys-create.h"
>
> -extern job_context_id pint_client_sm_context;
> -
> -enum
> -{
> - CREATE_RETRY = 170
> -};
> -
> -/* state function prototypes */
> -static int create_init(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_dspace_create_setup_msgpair(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_datafiles_setup_msgpair_array(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_datafiles_failure(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_setattr_setup_msgpair(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_setattr_failure(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_crdirent_setup_msgpair(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_crdirent_failure(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_delete_handles_setup_msgpair_array(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_cleanup(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -static int create_parent_getattr_inspect(
> - PINT_client_sm *sm_p, job_status_s *js_p);
> -
> /* completion function prototypes */
> static int create_create_comp_fn(
> void *v_p, struct PVFS_server_resp *resp_p, int index);
> @@ -73,6 +43,8 @@
> /* misc helper functions */
> static PINT_dist* get_default_distribution(PVFS_fs_id fs_id);
>
> +extern job_context_id pint_client_sm_context;
> +
> %%
>
> machine pvfs2_client_create_sm
> @@ -369,7 +341,7 @@
>
> /****************************************************************/
>
> -static int create_init(PINT_client_sm *sm_p,
> +int create_init(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> job_id_t tmp_id;
> @@ -519,7 +491,7 @@
> return resp_p->status;
> }
>
> -static int create_dspace_create_setup_msgpair(PINT_client_sm *sm_p,
> +int create_dspace_create_setup_msgpair(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> int ret = -PVFS_EINVAL;
> @@ -577,7 +549,7 @@
> return 1;
> }
>
> -static int create_datafiles_setup_msgpair_array(PINT_client_sm *sm_p,
> +int create_datafiles_setup_msgpair_array(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> int ret = -PVFS_EINVAL, i = 0;
> @@ -686,7 +658,7 @@
> return 1;
> }
>
> -static int create_datafiles_failure(PINT_client_sm *sm_p,
> +int create_datafiles_failure(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> sm_p->u.create.stored_error_code = js_p->error_code;
> @@ -696,7 +668,7 @@
> return 1;
> }
>
> -static int create_setattr_setup_msgpair(PINT_client_sm *sm_p,
> +int create_setattr_setup_msgpair(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> int ret = -PVFS_EINVAL;
> @@ -745,7 +717,7 @@
> return 1;
> }
>
> -static int create_setattr_failure(PINT_client_sm *sm_p,
> +int create_setattr_failure(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> sm_p->u.create.stored_error_code = js_p->error_code;
> @@ -755,7 +727,7 @@
> return 1;
> }
>
> -static int create_crdirent_setup_msgpair(PINT_client_sm *sm_p,
> +int create_crdirent_setup_msgpair(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> int ret = -1;
> @@ -800,7 +772,7 @@
> return 1;
> }
>
> -static int create_crdirent_failure(PINT_client_sm *sm_p,
> +int create_crdirent_failure(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> gossip_debug(GOSSIP_CLIENT_DEBUG, "create state:
> crdirent_failure\n");
> @@ -816,7 +788,7 @@
> }
>
> /* delete the newly created meta and data handles */
> -static int create_delete_handles_setup_msgpair_array(
> +int create_delete_handles_setup_msgpair_array(
> PINT_client_sm *sm_p, job_status_s *js_p)
> {
> int ret = -PVFS_EINVAL, i = 0, actual_count = 0;
> @@ -923,7 +895,7 @@
> return 1;
> }
>
> -static int create_cleanup(PINT_client_sm *sm_p,
> +int create_cleanup(PINT_client_sm *sm_p,
> job_status_s *js_p)
> {
> PVFS_object_ref metafile_ref;
> @@ -1015,7 +987,7 @@
> /** looks at the attributes of the parent directory and decides if
> it impacts
> * the file creation in any way
> */
> -static int create_parent_getattr_inspect(
> +int create_parent_getattr_inspect(
> PINT_client_sm *sm_p, job_status_s *js_p)
> {
> PVFS_object_attr *attr = NULL;
>
> Property changes on: src/client/sysint/sys-statfs.sm
> ___________________________________________________________________
> Name: svn:keywords
> + Author Date Id Revision
>
> Index: src/client/sysint/module.mk.in
> ===================================================================
> --- src/client/sysint/module.mk.in (.../vendor/pvfs2/current)
> (revision 3373)
> +++ src/client/sysint/module.mk.in (.../trunk/pvfs2_src) (revision
> 3373)
> @@ -49,6 +49,7 @@
> $(DIR)/mgmt-remove-object.c \
> $(DIR)/mgmt-remove-dirent.c \
> $(DIR)/mgmt-create-dirent.c \
> + $(DIR)/mgmt-repair-file.c \
> $(DIR)/mgmt-get-dirdata-handle.c
>
> # track generated .c files that need to be removed during dist
> clean, etc.
> _______________________________________________
> Pvfs2-developers mailing list
> Pvfs2-developers at beowulf-underground.org
> http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers
More information about the Pvfs2-developers
mailing list