Hi,
Does the pvfs2-viewdist.c program work for you?
Do let us know,
Thanks,
Murali
On Thu, 15 Dec 2005, Wei-keng Liao wrote:
>
> I am running a few I/O benchmarks by exercising different stripe sizes on
> PVFS2. For each stripe size, I change
> PVFS_DIST_SIMPLE_STRIPE_DEFAULT_STRIP_SIZE and rebuild PVFS2.
>
> I need to verify the stripe size of a newly-created PVFS2 file.
> Can someone provide such a utility? (pvfs2-stat supposes to but does not
> provide such info.) Thanks.
>
> Wei-keng Liao
> _______________________________________________
> PVFS2-users mailing list
> [email protected]
> http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users
>
>
/*
* (C) 2001 Clemson University and The University of Chicago
*
* See COPYING in top-level directory.
*/
/* pvfs2-viewdist
* View the distribution information of a file
* by using extended attributes!
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libgen.h>
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
#define __PINT_REQPROTO_ENCODE_FUNCS_C
#include "pvfs2.h"
#include "str-utils.h"
#include "pint-sysint-utils.h"
#include "pint-distribution.h"
#include "pvfs2-dist-basic.h"
#include "pvfs2-dist-simple-stripe.h"
#include "pvfs2-dist-varstrip.h"
#include "pint-util.h"
struct options
{
char *srcfile;
};
enum object_type {
UNIX_FILE,
PVFS2_FILE
};
typedef struct pvfs2_file_object_s {
PVFS_fs_id fs_id;
PVFS_object_ref ref;
char pvfs2_path[PVFS_NAME_MAX];
char user_path[PVFS_NAME_MAX];
PVFS_sys_attr attr;
PVFS_permissions perms;
} pvfs2_file_object;
typedef struct unix_file_object_s {
int fd;
int mode;
char path[NAME_MAX];
PVFS_fs_id fs_id;
} unix_file_object;
typedef struct file_object_s {
int fs_type;
union {
unix_file_object ufs;
pvfs2_file_object pvfs2;
} u;
} file_object;
static struct options* parse_args(int argc, char* argv[]);
static void usage(int argc, char** argv);
static int resolve_filename(file_object *obj, char *filename);
static int generic_open(file_object *obj, PVFS_credentials *credentials);
static int generic_server_location(file_object *obj, PVFS_credentials *creds,
char **servers, int *nservers);
#ifndef HAVE_ATTR_XATTR_H
/* prototype taken from fgetxattr(2) man page on a FC 4 system */
ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
#endif
#define DIST_KEY "metafile_dist"
#define DFILE_KEY "datafile_handles"
static int generic_dist(file_object *obj, PVFS_credentials *creds,
char **dist, int *size)
{
char *buffer = (char *) malloc(4096);
int ret;
if (obj->fs_type == UNIX_FILE)
{
if ((ret = fgetxattr(obj->u.ufs.fd, DIST_KEY, buffer, 4096)) < 0)
{
perror("fgetxattr:");
return -1;
}
*size = ret;
}
else
{
PVFS_ds_keyval key, val;
key.buffer = DIST_KEY;
key.buffer_sz = strlen(DIST_KEY) + 1;
val.buffer = buffer;
val.buffer_sz = 4096;
if ((ret = PVFS_sys_geteattr(obj->u.pvfs2.ref,
creds, &key, &val)) < 0)
{
PVFS_perror("PVFS_sys_geteattr failed %d\n", ret);
return -1;
}
*size = val.read_sz;
}
*dist = buffer;
return 0;
}
/*
* nservers is an in-out style parameter
* servers is allocated memory upto *nservers and each element inside that
* is allocated internally in this function.
* callers job is to free up all the memory
*/
static int generic_server_location(file_object *obj, PVFS_credentials *creds,
char **servers, int *nservers)
{
char *buffer = (char *) malloc(4096);
int ret, num_dfiles, count;
PVFS_fs_id fsid;
if (obj->fs_type == UNIX_FILE)
{
if ((ret = fgetxattr(obj->u.ufs.fd, DFILE_KEY, buffer, 4096)) < 0)
{
perror("fgetxattr:");
return -1;
}
fsid = obj->u.ufs.fs_id;
}
else
{
PVFS_ds_keyval key, val;
key.buffer = DFILE_KEY;
key.buffer_sz = strlen(DFILE_KEY) + 1;
val.buffer = buffer;
val.buffer_sz = 4096;
if ((ret = PVFS_sys_geteattr(obj->u.pvfs2.ref,
creds, &key, &val)) < 0)
{
PVFS_perror("PVFS_sys_geteattr failed %d\n", ret);
return -1;
}
ret = val.read_sz;
fsid = obj->u.pvfs2.fs_id;
}
/*
* At this point, we know all the dfile handles
*/
num_dfiles = (ret / sizeof(PVFS_handle));
count = num_dfiles < *nservers ? num_dfiles : *nservers;
for (ret = 0; ret < count; ret++)
{
PVFS_handle *ptr = (PVFS_handle *) ((char *) buffer + ret * sizeof(PVFS_handle));
servers[ret] = (char *) calloc(1, PVFS_MAX_SERVER_ADDR_LEN);
if (servers[ret] == NULL)
{
break;
}
/* ignore any errors */
PINT_cached_config_get_server_name(
servers[ret], PVFS_MAX_SERVER_ADDR_LEN,
*ptr, fsid);
}
if (ret != count)
{
int j;
for (j = 0; j < ret; j++)
{
free(servers[j]);
servers[j] = NULL;
}
return -1;
}
*nservers = count;
return 0;
}
int main(int argc, char ** argv)
{
struct options* user_opts = NULL;
file_object src;
PINT_dist dist;
char *dist_buf = NULL;
int dist_size;
int64_t ret;
PVFS_credentials credentials;
char *servers[256];
int i, nservers = 256;
memset(&dist, 0, sizeof(dist));
user_opts = parse_args(argc, argv);
if (!user_opts)
{
fprintf(stderr, "Error, failed to parse command line arguments\n");
return(-1);
}
ret = PVFS_util_init_defaults();
if (ret < 0)
{
PVFS_perror("PVFS_util_init_defaults", ret);
return(-1);
}
memset(&src, 0, sizeof(src));
resolve_filename(&src, user_opts->srcfile);
PVFS_util_gen_credentials(&credentials);
ret = generic_open(&src, &credentials);
if (ret < 0)
{
fprintf(stderr, "Could not open %s\n", user_opts->srcfile);
goto main_out;
}
ret = generic_dist(&src, &credentials, &dist_buf, &dist_size);
if (ret < 0)
{
fprintf(stderr, "Could not read distribution information!\n");
goto main_out;
}
ret = generic_server_location(&src, &credentials, servers, &nservers);
if (ret < 0)
{
fprintf(stderr, "Could not read server location information!\n");
goto main_out;
}
/* okay now print out by deserializing the buffer */
PINT_dist_decode(&dist, dist_buf);
printf("dist_name = %s\n", dist.dist_name);
if (strcmp(dist.dist_name, PVFS_DIST_SIMPLE_STRIPE_NAME) == 0)
{
PVFS_simple_stripe_params params;
PINT_dist_getparams(¶ms, &dist);
printf("strip_size = %ld\n", (unsigned long)(params.strip_size));
}
printf("Number of datafiles/servers = %d\n", nservers);
for (i = 0; i < nservers; i++)
{
printf("Server %d - %s\n", i, servers[i]);
free(servers[i]);
}
main_out:
PVFS_sys_finalize();
free(user_opts);
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[] = "vf:";
int one_opt = 0;
struct options* tmp_opts = NULL;
/* 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('v'):
printf("%s\n", PVFS2_VERSION);
exit(0);
case('f'):
tmp_opts->srcfile = optarg;
break;
case('?'):
usage(argc, argv);
exit(EXIT_FAILURE);
}
}
if (tmp_opts->srcfile == NULL)
{
usage(argc, argv);
exit(EXIT_FAILURE);
}
return(tmp_opts);
}
static void usage(int argc, char** argv)
{
fprintf(stderr,
"Usage: %s ARGS \n", argv[0]);
fprintf(stderr, "Where ARGS is one or more of"
"\n-f <file name>\t\t\tPVFS2 file pathname"
"\n-v\t\t\t\tprint version number and exit\n");
return;
}
/* resolve_filename:
* given 'filename', find the PVFS2 fs_id and relative pvfs_path. In case of
* error, assume 'filename' is a unix file.
*/
static int resolve_filename(file_object *obj, char *filename)
{
int ret;
ret = PVFS_util_resolve(filename, &(obj->u.pvfs2.fs_id),
obj->u.pvfs2.pvfs2_path, PVFS_NAME_MAX);
if (ret < 0)
{
obj->fs_type = UNIX_FILE;
strncpy(obj->u.ufs.path, filename, NAME_MAX);
} else {
obj->fs_type = PVFS2_FILE;
strncpy(obj->u.pvfs2.user_path, filename, PVFS_NAME_MAX);
}
return 0;
}
/* generic_open:
* given a file_object, perform the apropriate open calls.
*/
static int generic_open(file_object *obj, PVFS_credentials *credentials)
{
struct stat stat_buf;
PVFS_sysresp_lookup resp_lookup;
PVFS_sysresp_getattr resp_getattr;
PVFS_object_ref ref;
int ret = -1;
if (obj->fs_type == UNIX_FILE)
{
PINT_statfs_t statfsbuf;
memset(&stat_buf, 0, sizeof(struct stat));
stat(obj->u.ufs.path, &stat_buf);
if (!S_ISREG(stat_buf.st_mode))
{
fprintf(stderr, "Not a file!\n");
return(-1);
}
obj->u.ufs.fd = open(obj->u.ufs.path, O_RDONLY);
obj->u.ufs.mode = (int)stat_buf.st_mode;
if (obj->u.ufs.fd < 0)
{
perror("open");
fprintf(stderr, "could not open %s\n", obj->u.ufs.path);
return (-1);
}
if (PINT_statfs_fd_lookup(obj->u.ufs.fd, &statfsbuf) < 0)
{
perror("fstatfs:");
fprintf(stderr, "could not fstatfs %s\n", obj->u.ufs.path);
}
memcpy(&obj->u.ufs.fs_id, &PINT_statfs_fsid(&statfsbuf),
sizeof(PINT_statfs_fsid(&statfsbuf)));
return 0;
}
else
{
memset(&resp_lookup, 0, sizeof(PVFS_sysresp_lookup));
ret = PVFS_sys_lookup(obj->u.pvfs2.fs_id,
(char *) obj->u.pvfs2.pvfs2_path,
credentials,
&resp_lookup,
PVFS2_LOOKUP_LINK_FOLLOW);
if (ret < 0)
{
PVFS_perror("PVFS_sys_lookup", ret);
return (-1);
}
ref.handle = resp_lookup.ref.handle;
ref.fs_id = resp_lookup.ref.fs_id;
memset(&resp_getattr, 0, sizeof(PVFS_sysresp_getattr));
ret = PVFS_sys_getattr(ref, PVFS_ATTR_SYS_ALL,
credentials, &resp_getattr);
if (ret)
{
fprintf(stderr, "Failed to do pvfs2 getattr on %s\n",
obj->u.pvfs2.pvfs2_path);
return -1;
}
if (resp_getattr.attr.objtype != PVFS_TYPE_METAFILE)
{
fprintf(stderr, "Not a meta file!\n");
return -1;
}
obj->u.pvfs2.perms = resp_getattr.attr.perms;
memcpy(&obj->u.pvfs2.attr, &resp_getattr.attr,
sizeof(PVFS_sys_attr));
obj->u.pvfs2.attr.mask = PVFS_ATTR_SYS_ALL_SETABLE;
obj->u.pvfs2.ref = ref;
}
return 0;
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ts=8 sts=4 sw=4 expandtab
*/
_______________________________________________
PVFS2-users mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users