X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Ftests%2Fcheck_fhandle_syscalls.c;h=63fbc2606336cbc84fed77c863a6e1921d229f58;hb=654b8b6883e8d8f6245146adff7cf99ddea898e8;hp=4460dbf75fabaea7d47609d5cac1e986e267acf4;hpb=6ac2f14f0f622863c330b8b96da9373bad1abeb5;p=fs%2Flustre-release.git diff --git a/lustre/tests/check_fhandle_syscalls.c b/lustre/tests/check_fhandle_syscalls.c index 4460dbf..63fbc26 100644 --- a/lustre/tests/check_fhandle_syscalls.c +++ b/lustre/tests/check_fhandle_syscalls.c @@ -43,11 +43,21 @@ #include #include -#include +#include #define MAX_HANDLE_SZ 128 -#if !defined(HAVE_FHANDLE_GLIBC_SUPPORT) && defined(HAVE_FHANDLE_SYSCALLS) +void usage(char *prog) +{ + fprintf(stderr, "usage: %s \n", + prog); + fprintf(stderr, "the absolute path of a test file on a " + "lustre file system is needed.\n"); + exit(1); +} + + +#ifndef HAVE_FHANDLE_GLIBC_SUPPORT /* Because the kernel supports this functions doesn't mean that glibc does. * Just in case we define what we need */ struct file_handle { @@ -87,7 +97,6 @@ struct file_handle { #define __NR_open_by_handle_at 265 #endif - #endif static inline int @@ -105,29 +114,98 @@ open_by_handle_at(int mnt_fd, struct file_handle *fh, int mode) } #endif -void usage(char *prog) +static int debug_mark(const char *msg) { - fprintf(stderr, "usage: %s \n", - prog); - fprintf(stderr, "the absolute path of a test file on a " - "lustre file system is needed.\n"); - exit(1); + char cmd[4096] = ""; + + snprintf(cmd, sizeof(cmd), "../utils/lctl mark %s 2>/dev/null", msg); + return system(cmd); +} + +/* verify a file contents */ +int check_access(const char *filename, + int mnt_fd, struct file_handle *fh, struct stat *st_orig) +{ + int fd2, rc, len, offset; + struct stat st; + char *readbuf = NULL; + + debug_mark("before open by handle"); + /* Open the file handle */ + fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY | + (S_ISDIR(st_orig->st_mode) ? O_DIRECTORY : 0)); + debug_mark("after open by handle"); + if (fd2 < 0) { + fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename, + strerror(errno)); + if (errno == ESTALE) + fprintf(stderr, "second mountpoint not mounted?\n"); + rc = errno; + goto out_f_handle; + } + + /* Get file size */ + bzero(&st, sizeof(struct stat)); + debug_mark("before stat"); + rc = fstat(fd2, &st); + debug_mark("after stat"); + if (rc < 0) { + fprintf(stderr, "fstat(%s) error: %s\n", filename, + strerror(errno)); + rc = errno; + goto out_fd2; + } + + /* we can't check a ctime due unlink update */ + if (st_orig->st_size != st.st_size || + st_orig->st_ino != st.st_ino || + st_orig->st_mode != st.st_mode || + st_orig->st_mtime != st.st_mtime) { + fprintf(stderr, + "stat data mismatch between fopen and fhandle case\n"); + rc = EINVAL; + goto out_fd2; + } + + if (st.st_size && S_ISREG(st.st_mode)) { + len = st.st_blksize; + readbuf = malloc(len); + if (readbuf == NULL) { + fprintf(stderr, "malloc(%d) error: %s\n", len, + strerror(errno)); + rc = errno; + goto out_fd2; + } + + for (offset = 0; offset < st.st_size; offset += len) { + /* read from the file */ + rc = read(fd2, readbuf, len); + if (rc < 0) { + fprintf(stderr, "read(%s) error: %s\n", + filename, strerror(errno)); + rc = errno; + goto out_readbuf; + } + } + } + rc = 0; +out_readbuf: + free(readbuf); +out_fd2: + close(fd2); +out_f_handle: + return rc; } int main(int argc, char **argv) { -#ifdef HAVE_FHANDLE_SYSCALLS - char *filename, *file, *mount_point = NULL, *readbuf = NULL; - int ret, rc = -EINVAL, mnt_id, mnt_fd, fd1, fd2, i, len, offset; + char *filename, *file; + int ret, rc = -EINVAL, mnt_fd, mnt_id, fd1, i; struct file_handle *fh = NULL; - int file_size, mtime, ctime; struct lu_fid *parent, *fid; - struct mntent *ent; struct stat st; - __ino_t inode; - FILE *mntpt; - if (argc != 2) + if (argc != 3) usage(argv[0]); file = argv[1]; @@ -136,7 +214,15 @@ int main(int argc, char **argv) goto out; } + if (*argv[2] != '/') { + fprintf(stderr, "Need the absolete path of the mount point\n"); + goto out; + } + filename = rindex(file, '/') + 1; + + debug_mark("before first open"); fd1 = open(file, O_RDONLY); + debug_mark("after first open"); if (fd1 < 0) { fprintf(stderr, "open file %s error: %s\n", file, strerror(errno)); @@ -146,7 +232,9 @@ int main(int argc, char **argv) /* Get file stats using fd1 from traditional open */ bzero(&st, sizeof(struct stat)); + debug_mark("before first stat"); rc = fstat(fd1, &st); + debug_mark("after first stat"); if (rc < 0) { fprintf(stderr, "fstat(%s) error: %s\n", file, strerror(errno)); @@ -154,41 +242,12 @@ int main(int argc, char **argv) goto out_fd1; } - inode = st.st_ino; - mtime = st.st_mtime; - ctime = st.st_ctime; - file_size = st.st_size; - - /* Now for the setup to use fhandles */ - mntpt = setmntent("/etc/mtab", "r"); - if (mntpt == NULL) { - fprintf(stderr, "setmntent error: %s\n", - strerror(errno)); - rc = errno; - goto out_fd1; - } - - while (NULL != (ent = getmntent(mntpt))) { - if ((strncmp(file, ent->mnt_dir, strlen(ent->mnt_dir)) == 0) && - (strcmp(ent->mnt_type, "lustre") == 0)) { - mount_point = ent->mnt_dir; - break; - } - } - endmntent(mntpt); - - if (mount_point == NULL) { - fprintf(stderr, "file is not located on a lustre file " - "system?\n"); - goto out_fd1; - } - - filename = rindex(file, '/') + 1; - /* Open mount point directory */ - mnt_fd = open(mount_point, O_DIRECTORY); + debug_mark("before directory open"); + mnt_fd = open(argv[2], O_DIRECTORY); + debug_mark("after directory open"); if (mnt_fd < 0) { - fprintf(stderr, "open(%s) error: %s\n)", mount_point, + fprintf(stderr, "open(%s) error: %s\n)", argv[2], strerror(errno)); rc = errno; goto out_fd1; @@ -205,8 +264,10 @@ int main(int argc, char **argv) fh->handle_bytes = MAX_HANDLE_SZ; /* Convert name to handle */ - ret = name_to_handle_at(mnt_fd, filename, fh, &mnt_id, + debug_mark("before get handle"); + ret = name_to_handle_at(AT_FDCWD, file, fh, &mnt_id, AT_SYMLINK_FOLLOW); + debug_mark("after get handle"); if (ret) { fprintf(stderr, "name_by_handle_at(%s) error: %s\n", filename, strerror(errno)); @@ -215,8 +276,8 @@ int main(int argc, char **argv) } /* Print out the contents of the file handle */ - fprintf(stdout, "fh_bytes: %u\nfh_type: %d\nfh_data: ", - fh->handle_bytes, fh->handle_type); + fprintf(stdout, "file: %s\nfh_bytes: %u\nfh_type: %d\nfh_data: ", + file, fh->handle_bytes, fh->handle_type); for (i = 0; i < fh->handle_bytes; i++) fprintf(stdout, "%02x ", fh->f_handle[i]); fprintf(stdout, "\n"); @@ -228,62 +289,35 @@ int main(int argc, char **argv) fprintf(stdout, "file's parent FID is "DFID"\n", PFID(parent)); fprintf(stdout, "file FID is "DFID"\n", PFID(fid)); - /* Open the file handle */ - fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY); - if (fd2 < 0) { - fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename, - strerror(errno)); - rc = errno; + fprintf(stdout, "access via mount point '%s' - ", argv[2]); + fflush(stdout); + rc = check_access(filename, mnt_fd, fh, &st); + if (rc != 0) goto out_f_handle; - } - - /* Get file size */ - bzero(&st, sizeof(struct stat)); - rc = fstat(fd2, &st); - if (rc < 0) { - fprintf(stderr, "fstat(%s) error: %s\n", filename, - strerror(errno)); - rc = errno; - goto out_fd2; - } - - if (ctime != st.st_ctime || file_size != st.st_size || - inode != st.st_ino || mtime != st.st_mtime) { - fprintf(stderr, "stat data does not match between fopen " - "and fhandle case\n"); - goto out_fd2; - } - - if (st.st_size) { - len = st.st_blksize; - readbuf = malloc(len); - if (readbuf == NULL) { - fprintf(stderr, "malloc(%d) error: %s\n", len, - strerror(errno)); - rc = errno; - goto out_fd2; + fprintf(stdout, "OK \n"); + fflush(stdout); + + if (S_ISREG(st.st_mode)) { + fprintf(stdout, "access after unlink - "); + fflush(stdout); + ret = unlink(file); + if (ret < 0) { + fprintf(stderr, + "can't unlink '%s'. check permissions?\n", + file); + goto out_f_handle; } - for (offset = 0; offset < st.st_size; offset += len) { - /* read from the file */ - rc = read(fd2, readbuf, len); - if (rc < 0) { - fprintf(stderr, "read(%s) error: %s\n", - filename, strerror(errno)); - rc = errno; - goto out_readbuf; - } - } + rc = check_access(filename, mnt_fd, fh, &st); + if (rc != 0) + goto out_f_handle; + fprintf(stdout, "OK\n"); + fflush(stdout); } rc = 0; fprintf(stdout, "check_fhandle_syscalls test Passed!\n"); -out_readbuf: - if (readbuf != NULL) - free(readbuf); -out_fd2: - close(fd2); out_f_handle: free(fh); out_mnt_fd: @@ -292,11 +326,4 @@ out_fd1: close(fd1); out: return rc; -#else /* !HAVE_FHANDLE_SYSCALLS */ - if (argc != 2) - usage(argv[0]); - - fprintf(stderr, "HAVE_FHANDLE_SYSCALLS not defined\n"); - return 0; -#endif /* HAVE_FHANDLE_SYSCALLS */ }