[LTP] [PATCH] tst_detach_device: Clear leftover partitions
Martin Doucha
mdoucha@suse.cz
Fri Dec 12 11:40:23 CET 2025
Some kernels have a race condition during loop device release
which results in partitions being left over on unattached device.
The partitions then cause mkfs.vfat failures in later tests.
Check for loop device partitions after detaching it and clear them
if necessary.
Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
lib/tst_device.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 6ae914720..85f5f8cac 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -239,7 +239,7 @@ uint64_t tst_get_device_size(const char *dev_path)
return size/1024/1024;
}
-int tst_detach_device_by_fd(const char *dev, int *dev_fd)
+static int detach_loop_fd(const char *dev, int *dev_fd)
{
int ret, i, retval = 1;
@@ -275,6 +275,83 @@ exit:
return retval;
}
+static int find_loop_device_partition(const char *dev, char *part_path,
+ unsigned int path_size)
+{
+ int dev_num = -1;
+ unsigned int i;
+
+ snprintf(part_path, path_size, "%sp1", dev);
+
+ if (!access(part_path, F_OK))
+ return 1;
+
+ /* Parse loop device number */
+ for (i = 0; i < ARRAY_SIZE(dev_loop_variants); i++) {
+ if (sscanf(dev, dev_loop_variants[i], &dev_num) == 1)
+ break;
+
+ dev_num = -1;
+ }
+
+ if (dev_num < 0) {
+ tst_resm(TWARN, "Cannot parse %s device number", dev);
+ return 0;
+ }
+
+ snprintf(part_path, path_size, "/sys/block/loop%d/loop%dp1", dev_num,
+ dev_num);
+
+ if (!access(part_path, F_OK))
+ return 1;
+
+ /* The loop device has no leftover partitions */
+ return 0;
+}
+
+static int clear_loop_device_partitions(const char *dev)
+{
+ char part_path[PATH_MAX];
+ struct loop_info loopinfo = {};
+ int dev_fd;
+
+ if (!find_loop_device_partition(dev, part_path, PATH_MAX))
+ return 0;
+
+ tst_resm(TWARN, "Detached device %s has leftover partitions", dev);
+ tst_fill_file(DEV_FILE, 0, 1024 * 1024, 1);
+ tst_attach_device(dev, DEV_FILE);
+ dev_fd = open(dev, O_RDWR);
+
+ if (dev_fd < 0) {
+ tst_resm(TWARN | TERRNO,
+ "Cannot clear leftover partitions on %s", dev);
+ /* Do not detach device to prevent infinite recursion */
+ return 1;
+ }
+
+ loopinfo.lo_flags = LO_FLAGS_PARTSCAN;
+ ioctl(dev_fd, LOOP_SET_STATUS, &loopinfo);
+
+ if (!access(part_path, F_OK)) {
+ tst_resm(TWARN, "Cannot clear leftover partitions on %s", dev);
+ detach_loop_fd(dev, &dev_fd);
+ return 1;
+ }
+
+ return detach_loop_fd(dev, &dev_fd);
+}
+
+int tst_detach_device_by_fd(const char *dev, int *dev_fd)
+{
+ int ret = detach_loop_fd(dev, dev_fd);
+
+ if (!ret)
+ ret = clear_loop_device_partitions(dev);
+
+ return ret;
+}
+
int tst_detach_device(const char *dev)
{
int dev_fd, ret;
--
2.51.0
More information about the ltp
mailing list