Whamcloud - gitweb
LU-1351 llapi: Handle special file types in llapi_path2fid()
authorJohn L. Hammond <jhammond@tacc.utexas.edu>
Sat, 28 Apr 2012 18:40:41 +0000 (13:40 -0500)
committerOleg Drokin <green@whamcloud.com>
Mon, 7 May 2012 19:53:09 +0000 (15:53 -0400)
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 <jhammond@tacc.utexas.edu>
Reviewed-on: http://review.whamcloud.com/2606
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/tests/mcreate.c
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c

index 9056fa1..0f9ecb3 100644 (file)
  */
 
 #include <stdio.h>
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <getopt.h>
+
+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)
 {
 
 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;
 
         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;
 }
         return rc;
 }
index 258f439..9ee94b4 100644 (file)
@@ -9127,6 +9127,47 @@ test_225b () {
 }
 run_test 225b "Metadata survey sanity with stripe_count = 1"
 
 }
 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
 #
 #
 # tests that do cleanup/setup should be run at the end
 #
index bc010c1..4b2a590 100644 (file)
@@ -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) {
         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;
                         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);
                 rc = path2fid_from_lma(path, fid);
 
         close(fd);