[Pvfs2-cvs] commit by slang in pvfs2/src/apps/admin:
pvfs2-change-fsid.c module.mk.in
CVS commit program
cvs at parl.clemson.edu
Wed Nov 7 16:39:55 EST 2007
Update of /projects/cvsroot/pvfs2/src/apps/admin
In directory parlweb1:/tmp/cvs-serv20918/src/apps/admin
Modified Files:
module.mk.in
Added Files:
pvfs2-change-fsid.c
Log Message:
[on behalf of Phil]:
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.
--- /dev/null 2004-06-24 14:04:38.000000000 -0400
+++ pvfs2-change-fsid.c 2007-11-07 16:39:55.000000000 -0500
@@ -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
+ */
+
Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/apps/admin/module.mk.in,v
diff -p -u -r1.44 -r1.45
--- module.mk.in 6 Dec 2006 16:06:09 -0000 1.44
+++ module.mk.in 7 Nov 2007 21:39:55 -0000 1.45
@@ -31,4 +31,5 @@ ADMINSRC := \
ADMINSRC_SERVER := \
$(DIR)/pvfs2-mkspace.c \
$(DIR)/pvfs2-migrate-collection.c \
+ $(DIR)/pvfs2-change-fsid.c \
$(DIR)/pvfs2-showcoll.c
More information about the Pvfs2-cvs
mailing list