Whamcloud - gitweb
LU-16605 lfs: Add -0 option to fid2path 36/51736/8
authorArshad Hussain <arshad.hussain@aeoncomputing.com>
Tue, 18 Jul 2023 11:50:47 +0000 (17:20 +0530)
committerOleg Drokin <green@whamcloud.com>
Mon, 7 Aug 2023 03:50:22 +0000 (03:50 +0000)
Currently fid2path adds '\n' after printing
pathnames. Add '-0' option to fid2path to
add NUL('\0') at the end after printing out
pathnames instead of '\n'. This allows
pathnames that contain newlines('\n') to be
correctly interpreted by binaries like xargs.

Without -0 option:
$ lfs fid2path /mnt/lustre 0x200000401:0x1:0x0
/mnt/lustre/Test
_file
/mnt/lustre/Link_
file

With -0 option:
$ lfs fid2path -0 /mnt/lustre 0x200000401:0x1:0x0 | xargs --null
/mnt/lustre/test
_file /mnt/lustre/link_
file

Test-case sanity/226e added.

Test-Parameters: trivial testlist=sanity
Reported-by: Simon Westersund <simon.westersund@csc.fi>
Signed-off-by: Simon Westersund <simon.westersund@csc.fi>
Signed-off-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Change-Id: I9e3e32cde6c6abe83df48afd191ec167c74ac7e6
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51736
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Timothy Day <timday@amazon.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-fid2path.1
lustre/tests/sanity.sh
lustre/utils/lfs.c

index b554d35..aa2a5ab 100644 (file)
@@ -16,6 +16,9 @@ specified, or relative to the filesystem mount point if
 is provided.
 .SH OPTIONS
 .TP
+\fB\-0\fR, \fB\-\-print0\fR
+Print the full pathname, followed by a NUL character instead of the newline character.
+.TP
 \fB\-f\fR, \fB\-\-print\-fid\fR
 Print the FID with the path.
 .TP
@@ -31,6 +34,14 @@ pathname is needed for each file, use
 .TP
 .B $ lfs fid2path /mnt/testfs [0x200000403:0x11f:0x0]
 /mnt/testfs/etc/hosts
+.TP
+.B $ lfs fid2path -0 /mnt/lustre 0x200000401:0x6:0x0 | xargs --null
+/mnt/lustre/Test_
+.br
+ file /mnt/lustre/Link_
+.br
+ file
+
 .SH SEE ALSO
 .BR lfs (1),
 .BR lfs-getstripe (1),
index 0445ebb..17bfb1c 100755 (executable)
@@ -20808,6 +20808,34 @@ test_226c () {
 }
 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
 
+test_226e () {
+       (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
+               skip "Need client at least version 2.15.56"
+
+       # Define filename with 'newline' and a space
+       local testfile="Test"$'\n'"file 01"
+       # Define link name with multiple 'newline' and a space
+       local linkfile="Link"$'\n'"file "$'\n'"01"
+       # Remove prior hard link
+       rm -f $DIR/"$linkfile"
+
+       # Create file
+       touch $DIR/"$testfile"
+       # Create link
+       ln $DIR/"$testfile" $DIR/"$linkfile"
+
+       local fid=$($LFS getstripe -F "$DIR/$testfile") ||
+               error "getstripe failed on $DIR/$testfile"
+
+       # Call with -0 option
+       local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
+               echo "FILE:" | grep -c "FILE:")
+
+       # With -0 option the output should be exactly 2 lines.
+       (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
+}
+run_test 226e "Verify path2fid -0 option with newline and space"
+
 # LU-1299 Executing or running ldd on a truncated executable does not
 # cause an out-of-memory condition.
 test_227() {
index 4889fb0..381d940 100644 (file)
@@ -484,7 +484,7 @@ command_t cmdlist[] = {
         "Resolve the full path(s) for given FID(s). For a specific hardlink "
         "specify link number <linkno>.\n"
         "usage: fid2path [--print-fid|-f] [--print-link|-c] [--link|-l <linkno>] "
-        "<fsname|root> <fid>..."},
+        "[--print0|-0] <fsname|root> <fid>..."},
        {"path2fid", lfs_path2fid, 0, "Display the fid(s) for a given path(s).\n"
         "usage: path2fid [--parents] <path> ..."},
        {"rmfid", lfs_rmfid, 0, "Remove file(s) by FID(s)\n"
@@ -9628,13 +9628,14 @@ static void rstripc(char *str, int c)
 static int lfs_fid2path(int argc, char **argv)
 {
        struct option long_opts[] = {
+               { .val = '0',   .name = "print0",       .has_arg = no_argument },
                { .val = 'c',   .name = "cur",  .has_arg = no_argument },
                { .val = 'c',   .name = "current",      .has_arg = no_argument },
                { .val = 'c',   .name = "print-link",   .has_arg = no_argument },
                { .val = 'f',   .name = "print-fid",    .has_arg = no_argument },
                { .val = 'l',   .name = "link", .has_arg = required_argument },
                { .name = NULL } };
-       char short_opts[] = "cfl:pr:";
+       char short_opts[] = "0cfl:pr:";
        bool print_link = false;
        bool print_fid = false;
        bool print_mnt_dir;
@@ -9644,12 +9645,16 @@ static int lfs_fid2path(int argc, char **argv)
        long long recno = -1;
        int linkno = -1;
        char *endptr = NULL;
+       char link_separator = '\n';
        int rc = 0;
        int c;
        int i;
 
        while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
                switch (c) {
+               case '0':
+                       link_separator = '\0';
+                       break;
                case 'c':
                        print_link = true;
                        break;
@@ -9774,10 +9779,10 @@ static int lfs_fid2path(int argc, char **argv)
                         * Note that llapi_fid2path() returns "" for the root
                         * FID. */
 
-                       printf("%s%s%s\n",
+                       printf("%s%s%s%c",
                               print_mnt_dir ? mnt_dir : "",
-                              (print_mnt_dir || *path_buf == '\0') ? "/" : "",
-                              path_buf);
+                              (print_mnt_dir || *path_buf == '\0') ?
+                              "/" : "", path_buf, link_separator);
 
                        if (linkno >= 0)
                                /* specified linkno */