[PVFS2-CVS] commit by robl in pvfs2-1/src/apps/admin: pvfs2-stat.c module.mk.in

CVS commit program cvs at parl.clemson.edu
Mon Jul 11 17:22:40 EDT 2005


Update of /projects/cvsroot/pvfs2-1/src/apps/admin
In directory parlweb:/tmp/cvs-serv18917

Modified Files:
	module.mk.in 
Added Files:
	pvfs2-stat.c 
Log Message:
david metheny contributed the much-requested pvfs2-stat utility


--- /dev/null	2003-01-30 05:24:37.000000000 -0500
+++ pvfs2-stat.c	2005-07-11 16:22:40.000000000 -0400
@@ -0,0 +1,494 @@
+/*
+ * Copyright Acxiom Corporation, 2005
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <pwd.h>
+#include <grp.h>
+#include <assert.h>
+#include <getopt.h>
+
+#include "pvfs2.h"
+
+/* We need to set some limit, I suppose */
+#define MAX_NUM_FILES 100 
+
+#ifndef PVFS2_VERSION
+#define PVFS2_VERSION "Unknown"
+#endif
+
+/* parameters, filled in by parse_args() */
+struct options
+{
+    int     nVerbose;
+    int     nFollowLink;
+    char ** pszFiles;
+    int     nNumFiles;
+};
+
+/* Function Prototypes */
+static void usage(int argc, char** argv);
+static int parse_args(int argc, char** argv, struct options * opts);
+static void enable_verbose(struct options * opts);
+static void enable_dereference(struct options * opts);
+static int do_stat(const char             * pszFile,
+                   const char             * pszRelativeFile, 
+                   const PVFS_fs_id         fs_id, 
+                   const PVFS_credentials * credentials,
+                   const struct options   * opts);
+void print_stats(const PVFS_object_ref * ref,
+                 const char            * pszName,
+                 const char            * pszRelativeName,
+                 const PVFS_sys_attr   * attr);
+
+int main(int argc, char **argv)
+{
+   int               ret          = -1,
+                     i            =  0;
+   char           ** ppszPvfsPath = NULL;
+   PVFS_fs_id     *  pfs_id       = NULL;
+   PVFS_credentials  credentials;
+   struct options    user_opts;
+
+   /* Initialize any memory */
+   memset(&user_opts,   0, sizeof(user_opts));
+   memset(&credentials, 0, sizeof(credentials));
+   
+   ret = parse_args(argc, argv, &user_opts);
+   if(ret < 0)
+   {
+      fprintf(stderr, "Error: failed to parse command line arguments.\n");
+      usage(argc, argv);
+      return(-1);
+   }
+
+   if(user_opts.nVerbose)
+   {
+      fprintf(stdout, "Starting pvfs2-stat\n");
+   }
+   
+   /* Allocate space to hold the relative pvfs2 path & fs_id for each 
+    * requested file 
+    */
+   ppszPvfsPath = (char **)calloc(user_opts.nNumFiles, sizeof(char *));
+   
+   if(ppszPvfsPath == NULL)
+   {
+      fprintf(stderr, "Unable to allocate memory\n");
+      return(-1);
+   }
+   
+    /* Allocate enough space to hold file system id for each directory */
+   pfs_id = (PVFS_fs_id *)calloc(user_opts.nNumFiles, sizeof(PVFS_fs_id));
+   
+   if(pfs_id == NULL)
+   {
+      fprintf(stderr, "Unable to allocate memory\n");
+      return(-1);
+   }
+   
+   
+   for(i = 0; i < user_opts.nNumFiles; i++)
+   {
+      ppszPvfsPath[i] = (char *)calloc(PVFS_NAME_MAX, sizeof(char));
+      if(ppszPvfsPath[i] == NULL)
+      {
+         fprintf(stderr, "Unable to allocate memory\n");
+         return(-1);
+      }
+   }
+
+   ret = PVFS_util_init_defaults();
+   if(ret < 0)
+   {
+      PVFS_perror("PVFS_util_init_defaults", ret);
+      return(-1);
+   }
+   
+   /* Let's verify that all the given files reside on a PVFS2 filesytem */
+   for(i = 0; i < user_opts.nNumFiles; i++)
+   {
+      ret = PVFS_util_resolve(user_opts.pszFiles[i], 
+                              &pfs_id[i], 
+                              ppszPvfsPath[i], 
+                              PVFS_NAME_MAX);
+
+      if (ret < 0)
+      {
+         fprintf(stderr, "Error: could not find file system for %s\n", 
+                 user_opts.pszFiles[i]);
+         return(-1);
+      }
+   }
+
+   /* We will re-use the same credentials for each call */
+   PVFS_util_gen_credentials(&credentials);
+
+   for(i = 0; i < user_opts.nNumFiles; i++)
+   {
+      ret = do_stat(user_opts.pszFiles[i], 
+                    ppszPvfsPath[i], 
+                    pfs_id[i], 
+                    &credentials,
+                    &user_opts);
+      if(ret != 0)
+      {
+         fprintf(stderr, "Error stating [%s]\n", user_opts.pszFiles[i]);
+      }
+   }
+
+   PVFS_sys_finalize();
+
+   /* Deallocate any allocated memory */
+   if(user_opts.pszFiles != NULL)
+   {
+      free(user_opts.pszFiles);
+   }
+   
+   if(ppszPvfsPath != NULL)
+   {
+       for(i=0;i<user_opts.nNumFiles;i++)
+       {
+          if(ppszPvfsPath[i] != NULL)
+          {
+             free(ppszPvfsPath[i]);
+          }
+       }
+   
+      free(ppszPvfsPath);
+   }
+   
+   if(pfs_id != NULL)
+   {
+      free(pfs_id);
+   }
+
+   return(0);
+}
+
+static int do_stat(const char             * pszFile,
+                   const char             * pszRelativeFile, 
+                   const PVFS_fs_id         fs_id, 
+                   const PVFS_credentials * credentials,
+                   const struct options   * opts)
+{
+   int                  ret = 0;
+   PVFS_sysresp_lookup  lk_response;
+   PVFS_object_ref      ref;
+   PVFS_sysresp_getattr getattr_response;
+
+   /* Initialize memory */
+   memset(&lk_response,     0, sizeof(lk_response));
+   memset(&ref,             0, sizeof(ref));
+   memset(&getattr_response,0, sizeof(getattr_response));
+   
+
+   /* Do we want to follow if the file is a symbolic link */
+   if(opts->nFollowLink)
+   {
+      ret = PVFS_sys_lookup(fs_id, 
+                            (char *) pszRelativeFile, 
+                            (PVFS_credentials *) credentials, 
+                            &lk_response, 
+                            PVFS2_LOOKUP_LINK_FOLLOW);
+   }
+   else
+   {
+      ret = PVFS_sys_lookup(fs_id, 
+                            (char *) pszRelativeFile, 
+                            (PVFS_credentials *) credentials, 
+                            &lk_response, 
+                            PVFS2_LOOKUP_LINK_NO_FOLLOW);
+   }
+   
+   if(ret < 0)
+   {
+      if(opts->nVerbose)
+      {
+         fprintf(stderr, "PVFS_sys_lookup call on [%s]\n", pszRelativeFile);
+      }
+      PVFS_perror("PVFS_sys_lookup", ret);
+      return -1;
+   }
+
+   ref.handle = lk_response.ref.handle;
+   ref.fs_id  = fs_id;
+   
+   ret = PVFS_sys_getattr(ref, 
+                          PVFS_ATTR_SYS_ALL,
+                          (PVFS_credentials *) credentials, 
+                          &getattr_response);
+
+   if(ret < 0)
+   {                          
+      PVFS_perror("PVFS_sys_getattr", ret);
+      return -1;
+   }
+
+   /* Display the attributes for the file */
+   print_stats(&ref,
+               pszFile, 
+               pszRelativeFile, 
+               &(getattr_response.attr));
+   
+   return(0);
+}
+
+/* parse_args()
+ *
+ * parses command line arguments
+ *
+ * returns pointer to options structure on success, NULL on failure
+ */
+static int parse_args(int argc, char** argv, struct options * opts)
+{
+    int    i            = 0, 
+           ret          = 0, 
+           option_index = 0;
+    char * cur_option   = NULL;
+
+    static struct option long_opts[] =
+    {
+        {"help",0,0,0},
+        {"version",0,0,0},
+        {"verbose",0,0,0},
+        {"dereference",0,0,0},
+        {0,0,0,0}
+    };
+
+   while((ret = getopt_long_only(argc, argv, "VL", long_opts, &option_index)) != -1)
+   {
+      switch (ret)
+      {
+         case 0:
+               cur_option = (char*)long_opts[option_index].name;
+   
+               if(strcmp("help", cur_option) == 0)
+               {
+                  usage(argc, argv);
+                  exit(0);
+               }
+               else if(strcmp("verbose", cur_option) == 0)
+               {
+                  enable_verbose(opts);
+               }
+               else if(strcmp("dereference", cur_option) == 0)
+               {
+                  enable_dereference(opts);
+               }
+               else if (strcmp("version", cur_option) == 0)
+               {
+                  printf("%s\n", PVFS2_VERSION);
+                  exit(0);
+               }
+               else
+               {
+                  usage(argc, argv);
+                  exit(0);
+               }
+               break;
+
+         case 'V': /* --verbose     */ 
+                  enable_verbose(opts);
+                  break;
+                   
+         case 'L': /* --dereference */
+                  enable_dereference(opts);
+                  break;
+         
+         case '?': 
+                  usage(argc, argv);
+                  exit(0);
+
+         default:
+                  usage(argc, argv);
+                  exit(0);
+      }
+   }
+
+   /* We processed all arguments, so let's figure out how many files the user
+    * wants to stat, and allocate enough space to hold them, barring they haven't
+    * exceeded the limit. 
+    */
+   opts->nNumFiles = argc - optind;
+   
+   /* Validation to make sure we have at least one file to check */
+   if(opts->nNumFiles <= 0)
+   {
+      fprintf(stderr, "No filename(s)\n");
+      usage(argc, argv);
+      exit(0);
+   }
+
+   /* Validation to make sure we haven't exceeded */
+   if(opts->nNumFiles > MAX_NUM_FILES)
+   {
+      fprintf(stderr, "Filename limit of [%d] exceeded. [%d] file entered\n", 
+              MAX_NUM_FILES,
+              opts->nNumFiles);
+      usage(argc, argv);
+      exit(0);
+   }
+   
+   /* Allocate memory to hold the filenames */
+   opts->pszFiles = (char **)calloc(opts->nNumFiles, sizeof(char *));
+   
+   if(opts->pszFiles == NULL)
+   {
+      fprintf(stderr, "Memory allocation failed\n");
+      exit(0);
+   }
+
+   /* Loop through arguments and capture the file names */
+   for(i = optind; i < argc; i++)
+   {
+      opts->pszFiles[i-optind] = argv[i];
+   }
+   
+   return(0);
+}
+
+static void enable_verbose(struct options * opts)
+{
+   opts->nVerbose = 1;  
+}
+
+static void enable_dereference(struct options * opts)
+{
+   opts->nFollowLink = 1;  
+}
+
+void print_stats(const PVFS_object_ref * ref,
+                 const char            * pszName,
+                 const char            * pszRelativeName,
+                 const PVFS_sys_attr   * attr)
+{
+   char a_time[100] = "", 
+        m_time[100] = "",  
+        c_time[100] = "";
+   struct passwd * user;
+   struct group  * group;
+
+   fprintf(stdout, "-------------------------------------------------------\n");
+   fprintf(stdout, "  File Name     : %s\n",  pszName);
+   fprintf(stdout, "  Relative Name : %s\n",  pszRelativeName);
+   fprintf(stdout, "  fs ID         : %d\n",  ref->fs_id);
+   fprintf(stdout, "  Handle        : %Lu\n", Lu(ref->handle));
+   fprintf(stdout, "  Mask          : %o\n",  attr->mask);
+   if(attr->mask & PVFS_ATTR_SYS_PERM)
+   {
+      fprintf(stdout, "  Permissions   : %o\n",  attr->perms);
+   }
+
+   /* Print the type of object */
+   if(attr->mask & PVFS_ATTR_SYS_TYPE)
+   {
+      if(attr->objtype & PVFS_TYPE_METAFILE)
+      {
+         fprintf(stdout, "  Type          : Regular File\n");
+      }
+      else if(attr->objtype & PVFS_TYPE_DIRECTORY)
+      {
+         fprintf(stdout, "  Type          : Directory\n");
+      }
+      else if(attr->objtype & PVFS_TYPE_SYMLINK)
+      {
+         fprintf(stdout, "  Type          : Symbolic Link\n");
+         if(attr->mask &  PVFS_ATTR_SYS_LNK_TARGET)
+         {
+            fprintf(stdout, "  Link Target   : %s\n", attr->link_target);
+         }
+      }
+   }
+
+   if(attr->mask & PVFS_ATTR_SYS_SIZE)
+   {
+      /* If the size of a directory object is zero, let's default the size to 
+       * 4096. This is what the kernel module does, and is the default directory
+       * size on an EXT3 system
+       */
+      if( (attr->size == 0) && 
+          (attr->objtype & PVFS_TYPE_DIRECTORY))
+      {
+         fprintf(stdout, "  Size          : 4096\n");
+      }
+      else
+      {
+         fprintf(stdout, "  Size          : %Ld\n",      Ld(attr->size));
+      }
+
+   }
+   if(attr->mask & PVFS_ATTR_SYS_UID)
+   {
+      user  = getpwuid(attr->owner);
+      fprintf(stdout, "  Owner         : %d (%s)\n",  attr->owner, user->pw_name);
+   }      
+   if(attr->mask & PVFS_ATTR_SYS_GID)
+   {
+      group = getgrgid(attr->group);
+      fprintf(stdout, "  Group         : %d (%s)\n",  attr->group, group->gr_name);
+   }
+   if(attr->mask & PVFS_ATTR_SYS_ATIME)
+   {
+      sprintf(a_time, "%s", ctime((const time_t *)&(attr)->atime));
+      a_time[strlen(a_time)-1] = 0;
+      fprintf(stdout, "  atime         : %Lu (%s)\n", Lu(attr->atime), a_time);
+   }
+   if(attr->mask & PVFS_ATTR_SYS_MTIME)
+   {
+      sprintf(m_time, "%s", ctime((const time_t *)&(attr)->mtime));
+      m_time[strlen(m_time)-1] = 0;
+      fprintf(stdout, "  mtime         : %Lu (%s)\n", Lu(attr->mtime), m_time);
+   }
+   if(attr->mask & PVFS_ATTR_SYS_CTIME)
+   {
+      sprintf(c_time, "%s", ctime((const time_t *)&(attr)->ctime));
+      c_time[strlen(c_time)-1] = 0;
+      fprintf(stdout, "  ctime         : %Lu (%s)\n", Lu(attr->ctime), c_time);
+   }
+   
+   /* dfile_count is only valid for a file. For a given file, it tells how many
+    *  datafiles there are
+    */
+   if( (attr->mask & PVFS_ATTR_SYS_DFILE_COUNT) &&
+       (attr->mask & PVFS_TYPE_METAFILE))
+   {
+      fprintf(stdout, "  datafiles     : %d\n", attr->dfile_count);
+   }
+   /* dirent_count is only valid on directories */
+   if( (attr->mask & PVFS_ATTR_SYS_DIRENT_COUNT) &&
+       (attr->mask & PVFS_TYPE_DIRECTORY))
+   {
+      fprintf(stdout, "  dir entries   : %Lu\n", Lu(attr->dirent_count));
+   }
+   
+}
+
+static void usage(int argc, char** argv)
+{
+    fprintf(stderr,"Usage: %s [OPTION]... [FILE]...\n", argv[0]); 
+    fprintf(stderr,"Display FILE(s) status \n\n");
+    fprintf(stderr,"  -L, --dereference   follow links\n");
+    fprintf(stderr,"  -V, --verbose       turns on verbose messages\n");
+    fprintf(stderr,"      --help          display this help and exit\n");
+    fprintf(stderr,"      --version       output version information and exit\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-1/src/apps/admin/module.mk.in,v
diff -u -w -p -u -r1.33 -r1.34
--- module.mk.in	1 Jul 2005 20:11:44 -0000	1.33
+++ module.mk.in	11 Jul 2005 20:22:39 -0000	1.34
@@ -8,6 +8,7 @@ ADMINSRC := \
 	$(DIR)/pvfs2-ls.c \
 	$(DIR)/pvfs2-ping.c \
 	$(DIR)/pvfs2-rm.c \
+	$(DIR)/pvfs2-stat.c \
 	$(DIR)/pvfs2-statfs.c \
 	$(DIR)/pvfs2-perf-mon-example.c \
 	$(DIR)/pvfs2-event-mon-example.c \



More information about the PVFS2-CVS mailing list