Whamcloud - gitweb
LU-18067 utils: lfs getdirstripe hangs on FIFO 61/55861/10
authorRajeev Mishra <rajeevm@hpe.com>
Wed, 24 Jul 2024 21:09:01 +0000 (21:09 +0000)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Aug 2024 21:59:21 +0000 (21:59 +0000)
The command "lfs getdirstripe -r ." hangs when
executed on a directory containing a FIFO file.

Steps to reproduce-

mkfifo testFile
lfs getdirstripe -r .
A test case, test_56ebb, has been added to sanity.sh
to verify this scenario.

Test-Parameters: trivial
HPE-bug-id: LUS-12266
Signed-off-by: Rajeev Mishra <rajeevm@hpe.com>
Change-Id: I62276e94383755a860b4195868dac554f90f7fe8
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55861
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Feng Lei <flei@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Petros Koutoupis <petros.koutoupis@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c

index b10e7e4..871c575 100755 (executable)
@@ -9374,6 +9374,14 @@ test_56eb() {
 }
 run_test 56eb "check lfs getstripe on symlink"
 
+test_56ebb() {
+
+       mkdir $DIR/$tdir
+       mkfifo $DIR/$tdir/$tfile-fifo
+       $LFS getdirstripe -r $DIR/$tdir || error "$LFS getdirstripe -r: $DIR"
+}
+run_test 56ebb "check $LFS getdirstripe for FIFO file"
+
 test_56ec() {
        [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
        local dir=$DIR/$tdir
index 99c9cf0..5b68248 100644 (file)
@@ -1675,9 +1675,15 @@ again:
         */
        if (ret < 0 && errno == ENOTTY && !did_nofollow) {
                int fd, ret2;
+               struct stat st;
 
                did_nofollow = true;
-               fd = open(path, O_RDONLY | O_NOFOLLOW);
+               if (stat(path, &st) != 0)
+                       return -errno;
+               if (S_ISFIFO(st.st_mode))
+                       fd = open(path, O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
+               else
+                       fd = open(path, O_RDONLY | O_NOFOLLOW);
                if (fd < 0) {
                        /* restore original errno */
                        errno = ENOTTY;
@@ -6728,6 +6734,7 @@ static int cb_getstripe(char *path, int p, int *dp, void *data,
        struct find_param *param = (struct find_param *)data;
        int d = dp == NULL ? -1 : *dp, fd = -1;
        int ret = 0;
+       struct stat st;
 
        if (p == -1 && d == -1)
                return -EINVAL;
@@ -6757,6 +6764,11 @@ static int cb_getstripe(char *path, int p, int *dp, void *data,
 
                if (param->fp_no_follow)
                        flag = O_RDONLY | O_NOFOLLOW;
+               if (stat(path, &st) != 0)
+                       return -errno;
+               if (S_ISFIFO(st.st_mode))
+                       flag |= O_NONBLOCK;
+
                fd = open(path, flag);
 
                if (fd == -1)