public inbox for ltp@lists.linux.it
 help / color / mirror / Atom feed
* [LTP] [PATCH] tst_detach_device: Clear leftover partitions
@ 2025-12-12 10:40 Martin Doucha
  2025-12-12 14:39 ` Petr Vorel
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Martin Doucha @ 2025-12-12 10:40 UTC (permalink / raw)
  To: ltp

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


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-12-18 13:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-12 10:40 [LTP] [PATCH] tst_detach_device: Clear leftover partitions Martin Doucha
2025-12-12 14:39 ` Petr Vorel
2025-12-16 12:13 ` Andrea Cervesato via ltp
2025-12-16 12:16   ` Martin Doucha
2025-12-16 12:19     ` Andrea Cervesato via ltp
2025-12-18 13:11 ` Andrea Cervesato via ltp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox