[LTP] [PATCH] lib: make tst_detach_device_by_fd() also close dev_fd
Jan Stancek
jstancek@redhat.com
Thu Aug 15 08:37:10 CEST 2024
Since commit 18048c1af783 ("loop: Fix a race between loop detach and loop open")
detach operation is deferred to the last close of the device.
Make tst_detach_device_by_fd() also close dev_fd, and leave it up to
caller to re-open it for further use.
Reported-by: Gulam Mohamed <gulam.mohamed@oracle.com>
Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
include/tst_device.h | 4 +++-
lib/tst_device.c | 10 ++++++++--
testcases/kernel/syscalls/ioctl/ioctl09.c | 1 +
testcases/kernel/syscalls/ioctl/ioctl_loop01.c | 1 +
testcases/kernel/syscalls/ioctl/ioctl_loop02.c | 1 +
testcases/kernel/syscalls/ioctl/ioctl_loop04.c | 1 +
testcases/kernel/syscalls/ioctl/ioctl_loop06.c | 5 ++++-
testcases/kernel/syscalls/ioctl/ioctl_loop07.c | 2 ++
8 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/include/tst_device.h b/include/tst_device.h
index 391fb4e568f1..2597fb4e235e 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -67,7 +67,9 @@ int tst_attach_device(const char *dev_path, const char *file_path);
uint64_t tst_get_device_size(const char *dev_path);
/*
- * Detaches a file from a loop device fd.
+ * Detaches a file from a loop device fd. @dev_fd needs to be the
+ * last descriptor opened. Call to this function will close it,
+ * it is up to caller to open it again for further usage.
*
* @dev_path Path to the loop device e.g. /dev/loop0
* @dev_fd a open fd for the loop device
diff --git a/lib/tst_device.c b/lib/tst_device.c
index d659b54cfdee..723f6ca06375 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -243,17 +243,23 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd)
/* keep trying to clear LOOPDEV until we get ENXIO, a quick succession
* of attach/detach might not give udev enough time to complete
+ *
+ * Since 18048c1af783 ("loop: Fix a race between loop detach and loop open")
+ * device is detached only after last close.
*/
for (i = 0; i < 40; i++) {
ret = ioctl(dev_fd, LOOP_CLR_FD, 0);
- if (ret && (errno == ENXIO))
+ if (ret && (errno == ENXIO)) {
+ SAFE_CLOSE(NULL, dev_fd);
return 0;
+ }
if (ret && (errno != EBUSY)) {
tst_resm(TWARN,
"ioctl(%s, LOOP_CLR_FD, 0) unexpectedly failed with: %s",
dev, tst_strerrno(errno));
+ SAFE_CLOSE(NULL, dev_fd);
return 1;
}
@@ -262,6 +268,7 @@ int tst_detach_device_by_fd(const char *dev, int dev_fd)
tst_resm(TWARN,
"ioctl(%s, LOOP_CLR_FD, 0) no ENXIO for too long", dev);
+ SAFE_CLOSE(NULL, dev_fd);
return 1;
}
@@ -276,7 +283,6 @@ int tst_detach_device(const char *dev)
}
ret = tst_detach_device_by_fd(dev, dev_fd);
- close(dev_fd);
return ret;
}
diff --git a/testcases/kernel/syscalls/ioctl/ioctl09.c b/testcases/kernel/syscalls/ioctl/ioctl09.c
index ca682ee9ad71..9c79210864b8 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl09.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl09.c
@@ -88,6 +88,7 @@ static void verify_ioctl(void)
check_partition(2, true);
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop01.c b/testcases/kernel/syscalls/ioctl/ioctl_loop01.c
index a4d191a2e982..2f0df3b27972 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop01.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop01.c
@@ -93,6 +93,7 @@ static void verify_ioctl_loop(void)
check_loop_value(0, LO_FLAGS_PARTSCAN, 0);
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop02.c b/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
index 380fd10069ab..fa193924a448 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop02.c
@@ -103,6 +103,7 @@ static void verify_ioctl_loop(unsigned int n)
SAFE_CLOSE(file_fd);
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop04.c b/testcases/kernel/syscalls/ioctl/ioctl_loop04.c
index 5b7506ea44df..f1021cc77d7b 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop04.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop04.c
@@ -63,6 +63,7 @@ static void verify_ioctl_loop(void)
SAFE_CLOSE(file_fd);
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
unlink("test.img");
attach_flag = 0;
}
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop06.c b/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
index 64800b4ee44b..317f693a0458 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
@@ -57,8 +57,10 @@ static void verify_ioctl_loop(unsigned int n)
if (TST_RET == 0) {
tst_res(TFAIL, "Set block size succeed unexpectedly");
- if (tcases[n].ioctl_flag == LOOP_CONFIGURE)
+ if (tcases[n].ioctl_flag == LOOP_CONFIGURE) {
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
+ }
return;
}
if (TST_ERR == EINVAL)
@@ -87,6 +89,7 @@ static void run(unsigned int n)
}
if (attach_flag) {
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
loopconfig.block_size = *(tc->setvalue);
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop07.c b/testcases/kernel/syscalls/ioctl/ioctl_loop07.c
index d44f36212f5b..68db79558fb4 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop07.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop07.c
@@ -73,6 +73,7 @@ static void verify_ioctl_loop(unsigned int n)
/*Reset*/
if (tc->ioctl_flag == LOOP_CONFIGURE) {
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
} else {
loopinfo.lo_sizelimit = 0;
TST_RETRY_FUNC(ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo), TST_RETVAL_EQ0);
@@ -101,6 +102,7 @@ static void run(unsigned int n)
}
if (attach_flag) {
tst_detach_device_by_fd(dev_path, dev_fd);
+ dev_fd = SAFE_OPEN(dev_path, O_RDWR);
attach_flag = 0;
}
loopconfig.info.lo_sizelimit = tc->set_sizelimit;
--
2.43.0
More information about the ltp
mailing list