From 493c9da0ad31ec81349a592dddd446cc99a4ff12 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Sat, 28 Apr 2012 13:40:41 -0500 Subject: [PATCH] LU-1351 llapi: Handle special file types in llapi_path2fid() In llapi_path2fid() check for errors from open() and ioctl() that occur on special file types (device, socket, fifo). Add a test in sanity.sh that lfs path2fid will handle each type. Change-Id: Ib411038179b3eff4191e25ac7320558a0ee1c76b Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/2606 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/tests/mcreate.c | 70 ++++++++++++++++++++++++++++++++++++++++----- lustre/tests/sanity.sh | 41 ++++++++++++++++++++++++++ lustre/utils/liblustreapi.c | 4 +-- 3 files changed, 106 insertions(+), 9 deletions(-) diff --git a/lustre/tests/mcreate.c b/lustre/tests/mcreate.c index 9056fa1..0f9ecb3 100644 --- a/lustre/tests/mcreate.c +++ b/lustre/tests/mcreate.c @@ -35,25 +35,81 @@ */ #include +#include #include #include #include #include #include #include +#include + +void usage(const char *prog, int status) +{ + fprintf(status == 0 ? stdout : stderr, + "Usage: %s [OPTION]... FILE\n" + " -d, --device=DEV use device number DEV\n" + " -h, --help dispaly help\n" + " -m, --mode=MODE use mode MODE\n" + " -M, --major=MAJOR use device major MAJOR\n" + " -N, --minor=MINOR use device minor MINOR\n", + prog); + + exit(status); +} int main(int argc, char ** argv) { + struct option opts[] = { + { "device", 1, NULL, 'd' }, + { "help", 0, NULL, 'h' }, + { "mode", 1, NULL, 'm' }, + { "major", 1, NULL, 'M' }, + { "minor", 1, NULL, 'N' }, + { NULL }, + }; + const char *path; + mode_t mode = S_IFREG | 0644; + dev_t dev = 0; int rc; - if (argc < 2) { - printf("Usage %s filename\n", argv[0]); - return 1; + int c; + while ((c = getopt_long(argc, argv, "d:hm:M:N:", opts, NULL)) != -1) { + switch (c) { + case 'd': + dev = strtoul(optarg, NULL, 0); + break; + case 'h': + usage(argv[0], 0); + case 'm': + mode = strtoul(optarg, NULL, 0); + break; + case 'M': + dev = makedev(strtoul(optarg, NULL, 0), minor(dev)); + break; + case 'N': + dev = makedev(major(dev), strtoul(optarg, NULL, 0)); + break; + case '?': + usage(argv[0], 1); + } } - rc = mknod(argv[1], S_IFREG | 0644, 0); - if (rc) { - printf("mknod(%s) error: %s\n", argv[1], strerror(errno)); - } + if (argc - optind != 1) + usage(argv[0], 1); + + path = argv[optind]; + + if ((mode & S_IFMT) == S_IFDIR) + rc = mkdir(path, mode & ~S_IFMT); + else if ((mode & S_IFMT) == S_IFLNK) + rc = symlink("oldpath", path); + else + rc = mknod(path, mode, dev); + + if (rc) + fprintf(stderr, "%s: cannot create `%s' with mode %#o: %s\n", + argv[0], path, mode, strerror(errno)); + return rc; } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 258f439..9ee94b4 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -9127,6 +9127,47 @@ test_225b () { } run_test 225b "Metadata survey sanity with stripe_count = 1" +mcreate_path2fid () { + local mode=$1 + local major=$2 + local minor=$3 + local name=$4 + local desc=$5 + local path=$DIR/$tdir/$name + local fid + local rc + local fid_path + + $MCREATE --mode=$1 --major=$2 --minor=$3 $path || \ + error "error: cannot create $desc" + + fid=$($LFS path2fid $path) + rc=$? + [ $rc -ne 0 ] && error "error: cannot get fid of a $desc" + + fid_path=$($LFS fid2path $DIR $fid) + rc=$? + [ $rc -ne 0 ] && error "error: cannot get path of a $desc by fid" + + [ "$path" == "$fid_path" ] || \ + error "error: fid2path returned \`$fid_path', expected \`$path'" +} + +test_226 () { + rm -rf $DIR/$tdir + mkdir -p $DIR/$tdir + + mcreate_path2fid 0010666 0 0 fifo "FIFO" + mcreate_path2fid 0020666 1 3 null "character special file (null)" + mcreate_path2fid 0020666 1 255 none "character special file (no device)" + mcreate_path2fid 0040666 0 0 dir "directory" + mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)" + mcreate_path2fid 0100666 0 0 file "regular file" + mcreate_path2fid 0120666 0 0 link "symbolic link" + mcreate_path2fid 0140666 0 0 sock "socket" +} +run_test 226 "call path2fid and fid2path on files of all type" + # # tests that do cleanup/setup should be run at the end # diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index bc010c1..4b2a590 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -3733,13 +3733,13 @@ int llapi_path2fid(const char *path, lustre_fid *fid) memset(fid, 0, sizeof(*fid)); fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW); if (fd < 0) { - if (errno == ELOOP) /* symbolic link */ + if (errno == ELOOP || errno == ENXIO) return path2fid_from_lma(path, fid); return -errno; } rc = ioctl(fd, LL_IOC_PATH2FID, fid) < 0 ? -errno : 0; - if (rc == -EINVAL) /* char special device */ + if (rc == -EINVAL || rc == -ENOTTY) rc = path2fid_from_lma(path, fid); close(fd); -- 1.8.3.1