From d0cfa638df48da39562ca8cfadee1347a2923b36 Mon Sep 17 00:00:00 2001 From: Rajeev Mishra Date: Wed, 24 Jul 2024 21:09:01 +0000 Subject: [PATCH] LU-18067 utils: lfs getdirstripe hangs on FIFO 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 Change-Id: I62276e94383755a860b4195868dac554f90f7fe8 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55861 Reviewed-by: Andreas Dilger Reviewed-by: Feng Lei Reviewed-by: Shaun Tancheff Reviewed-by: Petros Koutoupis Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- lustre/tests/sanity.sh | 8 ++++++++ lustre/utils/liblustreapi.c | 14 +++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index b10e7e4..871c575 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 99c9cf0..5b68248 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -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) -- 1.8.3.1