[LTP] [PATCH] tst_umount: Retry open() after umount to handle delayed device release

Li Wang liwang@redhat.com
Wed Aug 6 09:44:05 CEST 2025


Currently, tst_umount() in lib/tst_device.c tries to repeatedly umount()
a mount point, with a retry loop if it gets EBUSY. However, after umount()
reports success, devices (especially loop devices) can still be held open
by another process or kernel, delaying their actual release. This can lead
to race conditions when the next operation tries to reuse the device like
mkfs.ext3 error:

  ==== setxattr01 ====
  command: setxattr01
  tst_test.c:1953: TINFO: LTP version: 20250530
  ...
  tst_supported_fs_types.c:48: TINFO: mkfs is not needed for tmpfs
  tst_test.c:1888: TINFO: === Testing on ext2 ===
  tst_test.c:1217: TINFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
  mke2fs 1.47.1 (20-May-2024)
  tst_test.c:1229: TINFO: Mounting /dev/loop0 to /tmp/LTP_setd24dAf/mntpoint fstyp=ext2 flags=0
  ...
  setxattr01.c:174: TPASS: setxattr(2) failed: ERANGE (34)
  setxattr01.c:174: TPASS: setxattr(2) failed: EFAULT (14)
  tst_test.c:1888: TINFO: === Testing on ext3 ===
  tst_test.c:1217: TINFO: Formatting /dev/loop0 with ext3 opts='' extra opts='' mke2fs 1.47.1 (20-May-2024)

  /dev/loop0 is apparently in use by the system; will not make a filesystem here!
  tst_test.c:1217: TBROK: mkfs.ext3 failed with exit code 1

  ==== close_range01 ====
  command: close_range01
  tst_test.c:1953: TINFO: LTP version: 20250530
  ...
  tst_test.c:1888: TINFO: === Testing on ext2 ===
  tst_test.c:1217: TINFO: Formatting /dev/loop0 with ext2 opts='' extra opts=''
  mke2fs 1.47.1 (20-May-2024)
  tst_test.c:1229: TINFO: Mounting /dev/loop0 to /tmp/LTP_cloXeXI39/mnt fstyp=ext2 flags=0
  ...
  close_range01.c:188: TPASS: No kernel taints
  tst_test.c:1888: TINFO: === Testing on ext3 ===
  tst_test.c:1217: TINFO: Formatting /dev/loop0 with ext3 opts='' extra opts='' mke2fs 1.47.1 (20-May-2024)

  /dev/loop0 is apparently in use by the system; will not make a filesystem here!
  tst_test.c:1217: TBROK: mkfs.ext3 failed with exit code 1

This patch improves robustness by, after a successful umount(), attempting to
open() the device in O_RDWR mode and retrying if open() fails with EBUSY,
similar to how umount() is retried. This ensures that tst_umount() only returns
success after the device is truly available for reuse, reducing race conditions
in rapid test cycles.

Signed-off-by: Li Wang <liwang@redhat.com>
---
 lib/tst_device.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/lib/tst_device.c b/lib/tst_device.c
index 6d1abf065..7f0a4f8a4 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -397,14 +397,37 @@ int tst_clear_device(const char *dev)
 
 int tst_umount(const char *path)
 {
-	int err, ret, i;
+	int err, ret, i, j;
 
 	for (i = 0; i < 50; i++) {
 		ret = umount(path);
 		err = errno;
 
-		if (!ret)
+		if (!ret) {
+			/* After successful umount, check device open busy */
+			for (j = 0; j < 50; j++) {
+				int fd = open(path, O_RDWR);
+				if (fd >= 0) {
+					close(fd);
+					break;
+				}
+				if (errno == EBUSY) {
+					tst_resm(TINFO, "open('%s') got EBUSY after umount, retry %d...",
+						path, j+1);
+					usleep(100000);
+					continue;
+				}
+				break;
+			}
+			if (j == 50) {
+				tst_resm(TWARN, "Device '%s' is still busy after %d open retries",
+					path, 10);
+				errno = EBUSY;
+				return -1;
+			}
+
 			return 0;
+		}
 
 		if (err != EBUSY) {
 			tst_resm(TWARN, "umount('%s') failed with %s",
-- 
2.50.1



More information about the ltp mailing list