Hi John
Does the attached patch fix it?
It was a mistake in the code (not in the way you are using it). I only
tested the VFS code path and not the system interface path. Thanks for
the reports!
> pascal006:~>pvfs2-viewdist -f /mnt/pvfs2/hosts
> Not a meta file!
> Could not open /mnt/pvfs2/hosts
>
> The file does exist though:
> pascal006:~>pvfs2-ls /mnt/pvfs2/hosts
> hosts
>
> Am I doing something funny?
>
> Btw, the usage for pvfs2-viewdist is incorrect. It says:
> Usage: pvfs2-viewdist ARGS src_file dest_file
> where ARGS are blah.
> But the code only looks at ARGS and not for src_file and dest_file. Must
> have been copied from pvfs2-cp. :)
Oops. How embarassing :) I fixed that in the attached patch..
> Thanks by the way for all of the speedy replies I've been getting. It
> really helps a lot to have such a well-monitored and well-supported
> mailing list.
Thank you for all reports!
Murali
>
> John
>
> On Mon, 21 Nov 2005, Murali Vilayannur wrote:
>
> > Hi,
> > Could you give the attached patch a go and see if it works out?
> > All it does is print the servers that hold chunks/strips of a file (both
> > for the VFS and system interface users) using xattrs.
> > Patch is against CVS.
> > P.S: RobR, I noticed that we arenot setting the fs_id field of the
> > statfs structure (statfs/fstatfs system call). Is/are there any
> > reason/reasons for not doing so?
> > I need that change to have VFS clients know the fs_id.
> > Thanks
> > Murali
> >
> > On Mon, 21 Nov 2005, Hamza KAYA wrote:
> >
> > > Hi,
> > > Thank you for the code. It works great:) I was able to find the
> > > distribution parameters of a file which was created by varstrip-dist.
> > > So by setting the jitter variable to a constant value in
> > > PINT_cached_config_get_next_io, I'll be able to find the physical
> > > mapping of a file to the datanodes, at least I hope so:) am I wrong?
> > >
> > > Thanks very much.
> > >
> > > P.S.:
> > > I posted this mail directly to Murali. So I re-post it to the list.
> > > Sorry for the inconvenience.
> > >
> > > --
> > > Hamza
> > >
> > > On 11/18/05, Murali Vilayannur <[EMAIL PROTECTED]> wrote:
> > > > Hi,
> > > > Does the attached program tell you the distribution at least? Compile it
> > > > like you compile pvfs2-cp or some other program. It uses the VFS
> > > > fgetxattr
> > > > system call or the PVFS2 pvfs_sys_geteattr.
> > > > If it works, then I will work on it some more and print out more of
> > > > the information that you wanted...
> > > > Thanks,
> > > > Murali
> > > >
> > > > On Fri, 18 Nov 2005, Hamza KAYA wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > Using PVFS2 system calls I was able to apply the varstrip
> > > > > distribution. Using pvfs2-fs-dump I can see the results. But I can't
> > > > > find out the reverse operation. I mean how can I learn the
> > > > > distribution of a file or the physical location of a given file using
> > > > > system calls?
> > > > >
> > > > > --
> > > > > hamza
> > > > >
> > > > > _______________________________________________
> > > > > PVFS2-users mailing list
> > > > > [email protected]
> > > > > http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users
> > > > >
> > > > >
> > > >
> > > >
> > >
> > > _______________________________________________
> > > PVFS2-users mailing list
> > > [email protected]
> > > http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users
> > >
> > >
>
>
diff -Naur pvfs2/src/apps/admin/module.mk.in
new_pvfs2/src/apps/admin/module.mk.in
--- pvfs2/src/apps/admin/module.mk.in 2005-08-03 15:02:19.000000000 -0500
+++ new_pvfs2/src/apps/admin/module.mk.in 2005-11-23 14:21:29.000000000
-0600
@@ -19,6 +19,7 @@
$(DIR)/pvfs2-fs-dump.c\
$(DIR)/pvfs2-fsck.c\
$(DIR)/pvfs2-cp.c \
+ $(DIR)/pvfs2-viewdist.c \
$(DIR)/pvfs2-touch.c \
$(DIR)/pvfs2-remove-object.c \
$(DIR)/pvfs2-ln.c
diff -Naur pvfs2/src/apps/admin/pvfs2-viewdist.c
new_pvfs2/src/apps/admin/pvfs2-viewdist.c
--- pvfs2/src/apps/admin/pvfs2-viewdist.c 1969-12-31 17:00:00.000000000
-0700
+++ new_pvfs2/src/apps/admin/pvfs2-viewdist.c 2005-11-23 14:21:10.000000000
-0600
@@ -0,0 +1,417 @@
+/*
+ * (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>
+#include <sys/statfs.h>
+#include <attr/xattr.h>
+
+#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"
+
+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);
+
+#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)
+ {
+ struct statfs 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 (fstatfs(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, &statfsbuf.f_fsid, sizeof(statfsbuf.f_fsid));
+ 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
+ */
diff -Naur pvfs2/src/kernel/linux-2.6/pvfs2-utils.c
new_pvfs2/src/kernel/linux-2.6/pvfs2-utils.c
--- pvfs2/src/kernel/linux-2.6/pvfs2-utils.c 2005-11-11 15:31:08.000000000
-0600
+++ new_pvfs2/src/kernel/linux-2.6/pvfs2-utils.c 2005-11-23
14:24:09.000000000 -0600
@@ -72,6 +72,11 @@
*/
inode->i_blksize = pvfs_bufmap_size_query();
inode->i_blkbits = PAGE_CACHE_SHIFT;
+ pvfs2_print("attrs->mask = %x (%d, objtype = %d), size = %ld\n",
+ attrs->mask, attrs->mask & PVFS_ATTR_SYS_SIZE,
+ attrs->objtype,
+ (unsigned long) attrs->size);
+
if ((attrs->objtype == PVFS_TYPE_METAFILE) &&
(attrs->mask & PVFS_ATTR_SYS_SIZE))
@@ -464,6 +469,27 @@
/* Extended attributes helper functions */
+static char *xattr_non_zero_terminated[] = {
+ "datafile_handles"
+};
+
+/*
+ * this function returns
+ * 0 if the val corresponding to name is known to be not terminated with an
explicit \0
+ * 1 if the val corresponding to name is known to be \0 terminated
+ */
+static int xattr_zero_terminated(const char *name)
+{
+ int i;
+ static int xattr_count = sizeof(xattr_non_zero_terminated)/sizeof(char *);
+ for (i = 0;i < xattr_count; i++)
+ {
+ if (strcmp(name, xattr_non_zero_terminated[i]) == 0)
+ return 0;
+ }
+ return 1;
+}
+
/*
* Tries to get a specified key's attributes of a given
* file into a user-specified buffer. Note that the getxattr
@@ -532,17 +558,33 @@
*/
if (ret == 0)
{
+ ssize_t new_length;
length = new_op->downcall.resp.getxattr.val_sz;
+ /*
+ * if the xattr corresponding to name was not terminated with a \0
+ * then we return the entire response length
+ */
+ if (xattr_zero_terminated(name) == 0)
+ {
+ new_length = length;
+ }
+ /*
+ * if it was terminated by a \0 then we return 1 less for the
getfattr
+ * programs to play nicely with displaying it
+ */
+ else {
+ new_length = length - 1;
+ }
/* Just return the length of the queried attribute after
* subtracting the \0 thingie */
if (size == 0)
{
- ret = length - 1;
+ ret = new_length;
}
else
{
/* check to see if key length is > provided buffer size */
- if (length - 1 > size)
+ if (new_length > size)
{
ret = -ERANGE;
}
@@ -551,8 +593,8 @@
/* No size problems */
memset(buffer, 0, size);
memcpy(buffer, new_op->downcall.resp.getxattr.val,
- length - 1);
- ret = length - 1;
+ new_length);
+ ret = new_length;
pvfs2_print("pvfs2_getxattr: key: %s, val_length: %d\n",
name, (int) ret);
}
diff -Naur pvfs2/src/kernel/linux-2.6/super.c
new_pvfs2/src/kernel/linux-2.6/super.c
--- pvfs2/src/kernel/linux-2.6/super.c 2005-10-07 16:03:08.000000000 -0500
+++ new_pvfs2/src/kernel/linux-2.6/super.c 2005-11-23 14:24:39.000000000
-0600
@@ -345,6 +345,7 @@
new_op->downcall.resp.statfs.blocks_total);
buf->f_type = sb->s_magic;
+ memcpy(&buf->f_fsid, &(PVFS2_SB(sb)->fs_id),
sizeof(PVFS2_SB(sb)->fs_id));
buf->f_bsize = sb->s_blocksize;
buf->f_namelen = PVFS2_NAME_LEN;
_______________________________________________
PVFS2-users mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-users