Whamcloud - gitweb
LU-3223 utils: multiple args for path2fid/fid2path 60/6160/7
authorAndreas Dilger <andreas.dilger@intel.com>
Thu, 25 Apr 2013 10:12:20 +0000 (04:12 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 23 Jul 2013 05:50:19 +0000 (05:50 +0000)
Allow "lfs path2fid" to process multiple pathname arguments on
the command-line.  Like "grep" with multiple filenames, it will
print "filename: " at the beginning of the line when processing
multiple files.

Allow "lfd fid2path" to process multiple FID arguments on the
command-line.  All of the pathnames will be printed for each FID,
or can be limited to a single pathname per FID via "--link 0".

Add basic sanity tests for path2fid and fid2path, along with
tests of the multiple-argument options for each command.

Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Signed-off-by: Girish Shilamkar <gshilamkar@ddn.com>
Change-Id: I5c24b92af79cfeeafd4f5910e2f165dc3b500c1e
Reviewed-on: http://review.whamcloud.com/6160
Reviewed-by: Emoly Liu <emoly.liu@intel.com>
Tested-by: Hudson
Reviewed-by: Jian Yu <jian.yu@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
lustre/doc/lfs.1
lustre/tests/sanity.sh
lustre/utils/lfs.c

index 3f43e38..7db5642 100644 (file)
@@ -13,6 +13,8 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
 .br
 .B lfs df [-i] [-h] [--pool|-p <fsname>[.<pool>] [path]
 .br
+.B lfs fid2path [--link <linkno>] <fsname|rootpath> <fid> ...
+.br
 .B lfs find <directory|filename>
         \fB[[!] --atime|-A [-+]N] [[!] --mtime|-M [-+]N] [[!] --ctime|-C [+-]N]
         \fB[--maxdepth|-D N] [[!] --mdt|-m <uuid|index,...>] [--name|-n pattern]
@@ -40,6 +42,8 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
 .B lfs osts
 .RB [ path ]
 .br
+.B path2fid <path> ...
+.br
 .B lfs pool_list <filesystem>[.<pool>] | <pathname>
 .br
 .B lfs quota [-q] [-v] [-o obd_uuid|-I ost_idx|-i mdt_idx] [-u <uname>| -u <uid>|-g <gname>| -g <gid>] <filesystem>
@@ -195,6 +199,18 @@ must be part of the pool or an error will be returned.
 .B setstripe -d
 Delete the default striping on the specified directory.
 .TP
+.B fid2path [--link <linkno>] <fsname|rootpath> <fid> ...
+Print out the pathname(s) for the specified \fIfid\fR(s) from the filesystem
+mounted at \fBrootpath\fR or named \fBfsname\fR.  If a file has multiple
+hard links, then all of the pathnames for that file are printed, unless
+\fB--link\fR limits the printing to only the specified link number (starting
+at 0, in no particular order).  If multiple fids are specified, but only a
+single pathname is needed for each file, use \fB--link 0\fR.
+.TP
+.B path2fid <path> ...
+Print out the FIDs for the specified \fBpath(s)\fR.  If multiple pathnames
+are given, then they will be printed one per line with the path as prefix.
+.TP
 .B pool_list
 .RI { filesystem }[ .poolname "] | {" pathname }
 List the pools in 
index 4bd99e6..1d47653 100644 (file)
@@ -8846,6 +8846,24 @@ dot_lustre_fid_permission_check() {
        rm -rf $test_dir/$tfile-2
 }
 
+test_154A() {
+       [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.1) ]] &&
+               skip "Need MDS version at least 2.4.1" && return
+
+       touch $DIR/$tfile
+       local FID=$($LFS path2fid $DIR/$tfile)
+       [ -z "$FID" ] && error "path2fid unable to get $DIR/$tfile FID"
+
+       # check that we get the same pathname back
+       local FOUND=$($LFS fid2path $MOUNT $FID)
+       [ -z "$FOUND" ] && error "fid2path unable to get $FID path"
+       [ "$FOUND" != "$DIR/$tfile" ] &&
+               error "fid2path(path2fid($DIR/$tfile)) = $FOUND != $DIR/$tfile"
+
+       rm -rf $DIR/$tfile
+}
+run_test 154A "lfs path2fid and fid2path basic checks"
+
 test_154a() {
        [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
        [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.2.51) ]] ||
@@ -8899,6 +8917,33 @@ test_154b() {
 }
 run_test 154b "Open-by-FID for remote directory"
 
+test_154c() {
+       [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.1) ]] &&
+               skip "Need MDS version at least 2.4.1" && return
+
+       touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
+       local FID1=$($LFS path2fid $DIR/$tfile.1)
+       local FID2=$($LFS path2fid $DIR/$tfile.2)
+       local FID3=$($LFS path2fid $DIR/$tfile.3)
+
+       local N=1
+       $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
+               [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
+                       error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
+               local want=FID$N
+               [ "$FID" = "${!want}" ] ||
+                       error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
+               N=$((N + 1))
+       done
+
+       $LFS fid2path $MOUNT $FID1 $FID2 $FID3 | while read PATHNAME; do
+               [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
+                       error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
+               N=$((N + 1))
+       done
+}
+run_test 154c "lfs path2fid and fid2path multiple arguments"
+
 test_155_small_load() {
     local temp=$TMP/$tfile
     local file=$DIR/$tfile
index c9ed502..582c9e7 100644 (file)
@@ -276,16 +276,16 @@ command_t cmdlist[] = {
          "interest to consumer <id>, allowing the system to free up space.\n"
          "An <endrec> of 0 means all records.\n"
          "usage: changelog_clear <mdtname> <id> <endrec>"},
-        {"fid2path", lfs_fid2path, 0,
-         "Resolve the full path to a given FID. For a specific hardlink "
-         "specify link number <linkno>.\n"
-         /* "For a historical name, specify changelog record <recno>.\n" */
-         "usage: fid2path <fsname|rootpath> <fid> [--link <linkno>]"
-                /*[--rec <recno>]*/},
-        {"path2fid", lfs_path2fid, 0, "Display the fid for a given path.\n"
-         "usage: path2fid <path>"},
-        {"data_version", lfs_data_version, 0, "Display file data version for "
-         "a given path.\n" "usage: data_version [-n] <path>"},
+       {"fid2path", lfs_fid2path, 0,
+        "Resolve the full path(s) for given FID(s). For a specific hardlink "
+        "specify link number <linkno>.\n"
+       /* "For a historical link name, specify changelog record <recno>.\n" */
+        "usage: fid2path [--link <linkno>] <fsname|rootpath> <fid> ..."
+               /* [ --rec <recno> ] */ },
+       {"path2fid", lfs_path2fid, 0, "Display the fid(s) for a given path(s).\n"
+        "usage: path2fid <path> ..."},
+       {"data_version", lfs_data_version, 0, "Display file data version for "
+        "a given path.\n" "usage: data_version [-n] <path>"},
        {"hsm_state", lfs_hsm_state, 0, "Display the HSM information (states, "
         "undergoing actions) for given files.\n usage: hsm_state <file> ..."},
        {"hsm_set", lfs_hsm_set, 0, "Set HSM user flag on specified files.\n"
@@ -3030,7 +3030,7 @@ static int lfs_fid2path(int argc, char **argv)
         int linkno = -1;
         int lnktmp;
         int printcur = 0;
-        int rc;
+       int rc = 0;
 
         optind = 0;
 
@@ -3054,68 +3054,88 @@ static int lfs_fid2path(int argc, char **argv)
                         return CMD_HELP;
                 }
         }
-        device = argv[optind++];
-        fid = argv[optind++];
-        if (optind != argc)
-                return CMD_HELP;
 
-        path = calloc(1, PATH_MAX);
+       if (argc < 3)
+               return CMD_HELP;
 
-        lnktmp = (linkno >= 0) ? linkno : 0;
-        while (1) {
-                int oldtmp = lnktmp;
-                long long rectmp = recno;
-                rc = llapi_fid2path(device, fid, path, PATH_MAX, &rectmp,
-                                    &lnktmp);
-                if (rc < 0) {
-                        fprintf(stderr, "%s error: %s\n", argv[0],
-                                strerror(errno = -rc));
-                        break;
-                }
+       device = argv[optind++];
+       path = calloc(1, PATH_MAX);
 
-                if (printcur)
-                        fprintf(stdout, "%lld ", rectmp);
-                if (device[0] == '/') {
-                        fprintf(stdout, "%s", device);
-                        if (device[strlen(device) - 1] != '/')
-                                fprintf(stdout, "/");
-                } else if (path[0] == '\0') {
-                        fprintf(stdout, "/");
-                }
-                fprintf(stdout, "%s\n", path);
+       rc = 0;
+       while (optind < argc) {
+               fid = argv[optind++];
+
+               lnktmp = (linkno >= 0) ? linkno : 0;
+               while (1) {
+                       int oldtmp = lnktmp;
+                       long long rectmp = recno;
+                       int rc2;
+                       rc2 = llapi_fid2path(device, fid, path, PATH_MAX,
+                                            &rectmp, &lnktmp);
+                       if (rc2 < 0) {
+                               fprintf(stderr, "%s: error on FID %s: %s\n",
+                                       argv[0], fid, strerror(errno = -rc2));
+                               if (rc == 0)
+                                       rc = rc2;
+                               break;
+                       }
 
-                if (linkno >= 0)
-                        /* specified linkno */
-                        break;
-                if (oldtmp == lnktmp)
-                        /* no more links */
-                        break;
-        }
+                       if (printcur)
+                               fprintf(stdout, "%lld ", rectmp);
+                       if (device[0] == '/') {
+                               fprintf(stdout, "%s", device);
+                               if (device[strlen(device) - 1] != '/')
+                                       fprintf(stdout, "/");
+                       } else if (path[0] == '\0') {
+                               fprintf(stdout, "/");
+                       }
+                       fprintf(stdout, "%s\n", path);
+
+                       if (linkno >= 0)
+                               /* specified linkno */
+                               break;
+                       if (oldtmp == lnktmp)
+                               /* no more links */
+                               break;
+               }
+       }
 
-        free(path);
-        return rc;
+       free(path);
+       return rc;
 }
 
 static int lfs_path2fid(int argc, char **argv)
 {
-        char *path;
-        lustre_fid fid;
-        int rc;
-
-        if (argc != 2)
-                return CMD_HELP;
-
-        path = argv[1];
-        rc = llapi_path2fid(path, &fid);
-        if (rc) {
-                fprintf(stderr, "can't get fid for %s: %s\n", path,
-                        strerror(errno = -rc));
-                return rc;
-        }
+       char **path;
+       const char *sep = "";
+       lustre_fid fid;
+       int rc = 0;
 
-        printf(DFID"\n", PFID(&fid));
+       if (argc < 2)
+               return CMD_HELP;
+       else if (argc > 2)
+               sep = ": ";
+
+       path = argv + 1;
+       while (*path != NULL) {
+               int err = llapi_path2fid(*path, &fid);
+
+               if (err) {
+                       fprintf(stderr, "%s: can't get fid for %s: %s\n",
+                               argv[0], *path, strerror(-err));
+                       if (rc == 0) {
+                               rc = err;
+                               errno = -err;
+                       }
+                       goto out;
+               }
+               printf("%s%s"DFID"\n", *sep != '\0' ? *path : "", sep,
+                      PFID(&fid));
+out:
+               path++;
+       }
 
-        return 0;
+       return rc;
 }
 
 static int lfs_data_version(int argc, char **argv)