From 3cadf232ea2430f058bf49da9ffb6626ea075624 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Thu, 25 Apr 2013 04:12:20 -0600 Subject: [PATCH] LU-3223 utils: multiple args for path2fid/fid2path 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 Signed-off-by: Girish Shilamkar Change-Id: I5c24b92af79cfeeafd4f5910e2f165dc3b500c1e Reviewed-on: http://review.whamcloud.com/6160 Reviewed-by: Emoly Liu Tested-by: Hudson Reviewed-by: Jian Yu Tested-by: Maloo --- lustre/doc/lfs.1 | 16 ++++++ lustre/tests/sanity.sh | 45 ++++++++++++++++ lustre/utils/lfs.c | 144 ++++++++++++++++++++++++++++--------------------- 3 files changed, 143 insertions(+), 62 deletions(-) diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1 index 3f43e38..7db5642 100644 --- a/lustre/doc/lfs.1 +++ b/lustre/doc/lfs.1 @@ -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 [.] [path] .br +.B lfs fid2path [--link ] ... +.br .B lfs find \fB[[!] --atime|-A [-+]N] [[!] --mtime|-M [-+]N] [[!] --ctime|-C [+-]N] \fB[--maxdepth|-D N] [[!] --mdt|-m ] [--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 ... +.br .B lfs pool_list [.] | .br .B lfs quota [-q] [-v] [-o obd_uuid|-I ost_idx|-i mdt_idx] [-u | -u |-g | -g ] @@ -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 ] ... +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 ... +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 diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4bd99e6..1d47653 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index c9ed502..582c9e7 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -276,16 +276,16 @@ command_t cmdlist[] = { "interest to consumer , allowing the system to free up space.\n" "An of 0 means all records.\n" "usage: changelog_clear "}, - {"fid2path", lfs_fid2path, 0, - "Resolve the full path to a given FID. For a specific hardlink " - "specify link number .\n" - /* "For a historical name, specify changelog record .\n" */ - "usage: fid2path [--link ]" - /*[--rec ]*/}, - {"path2fid", lfs_path2fid, 0, "Display the fid for a given path.\n" - "usage: path2fid "}, - {"data_version", lfs_data_version, 0, "Display file data version for " - "a given path.\n" "usage: data_version [-n] "}, + {"fid2path", lfs_fid2path, 0, + "Resolve the full path(s) for given FID(s). For a specific hardlink " + "specify link number .\n" + /* "For a historical link name, specify changelog record .\n" */ + "usage: fid2path [--link ] ..." + /* [ --rec ] */ }, + {"path2fid", lfs_path2fid, 0, "Display the fid(s) for a given path(s).\n" + "usage: path2fid ..."}, + {"data_version", lfs_data_version, 0, "Display file data version for " + "a given path.\n" "usage: data_version [-n] "}, {"hsm_state", lfs_hsm_state, 0, "Display the HSM information (states, " "undergoing actions) for given files.\n usage: hsm_state ..."}, {"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) -- 1.8.3.1