[LTP] [PATCH 3/3] lib/tst_device.c: add support for overlayfs

Jeff Moyer jmoyer@redhat.com
Mon Feb 3 23:06:00 CET 2025


Add checks for overlayfs in tst_find_backing_dev.  As with btrfs, only
a single device is checked (the upper one) and returned from
tst_find_backing_dev().

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
---
 .gitignore       |  1 +
 INSTALL          |  6 ++---
 lib/Makefile     |  2 +-
 lib/libltp.a     |  1 +
 lib/tst_device.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 4 deletions(-)
 create mode 100644 lib/libltp.a

diff --git a/.gitignore b/.gitignore
index 24f4a4ea8..38bf1fab9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ core
 .gdb_history
 .gdbinit
 lib*.a
+!libltp.a
 .cache.mk
 *.dwo
 *.mod
diff --git a/INSTALL b/INSTALL
index ad43514d4..557cf4abc 100644
--- a/INSTALL
+++ b/INSTALL
@@ -6,15 +6,15 @@ package in any Linux distribution (no specific version is required).
 
 Debian / Ubuntu
 
-	# apt install gcc git make pkgconf autoconf automake bison flex m4 linux-headers-$(uname -r) libc6-dev
+	# apt install gcc git make pkgconf autoconf automake bison flex m4 linux-headers-$(uname -r) libc6-dev libmount-dev
 
 openSUSE / SLES
 
-	# zypper install gcc git make pkg-config autoconf automake bison flex m4 linux-glibc-devel glibc-devel
+	# zypper install gcc git make pkg-config autoconf automake bison flex m4 linux-glibc-devel glibc-devel libmount-devel
 
 Fedora / CentOS / RHEL
 
-	# yum install gcc git make pkgconf autoconf automake bison flex m4 kernel-headers glibc-headers
+	# yum install gcc git make pkgconf autoconf automake bison flex m4 kernel-headers glibc-headers libmount-devel
 
 These are minimal build requirements for git compilation. Some tests require
 extra development files of some libraries, see ci/*.sh. There is also
diff --git a/lib/Makefile b/lib/Makefile
index 67169f149..2f180405e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -14,7 +14,7 @@ else
 FILTER_OUT_LIBSRCS	+= tlibio.c tst_safe_sysv_ipc.c
 endif
 
-INTERNAL_LIB		:= libltp.a
+INTERNAL_LIB		:= libltp_internal.a
 
 pc_file			:= $(DESTDIR)/$(datarootdir)/pkgconfig/ltp.pc
 
diff --git a/lib/libltp.a b/lib/libltp.a
new file mode 100644
index 000000000..006f3557e
--- /dev/null
+++ b/lib/libltp.a
@@ -0,0 +1 @@
+INPUT (libltp_internal.a -lmount)
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 744e08a68..d99da1c51 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -19,6 +19,7 @@
 #include <linux/limits.h>
 #include <sys/vfs.h>
 #include <linux/magic.h>
+#include <libmount/libmount.h>
 #include "lapi/syscalls.h"
 #include "test.h"
 #include "safe_macros.h"
@@ -573,6 +574,65 @@ static void btrfs_get_uevent_path(char *tmp_path, char *uevent_path)
 	SAFE_CLOSEDIR(NULL, dir);
 }
 
+static void overlay_get_dev(struct libmnt_fs *fs, const char *dir_opt,
+			    dev_t *dev)
+{
+	int ret;
+	char *value, *dir_name;
+	size_t val_size;
+	struct stat st;
+
+	ret = mnt_fs_get_option(fs, dir_opt, &value, &val_size);
+	if (ret)
+		tst_brkm(TBROK, NULL,
+			 "overlayfs: no %s in mount options", dir_opt);
+
+	dir_name = calloc(val_size + 1, 1);
+	if (!dir_name)
+		tst_brkm(TBROK | TERRNO, NULL, "calloc failed");
+
+	memcpy(dir_name, value, val_size);
+	if (stat(dir_name, &st) < 0)
+		tst_brkm(TBROK | TERRNO, NULL, "stat failed");
+
+	*dev = st.st_dev;
+	free(dir_name);
+}
+
+/*
+ * NOTE: this will not work for stacked overlay mounts.
+ */
+static void overlay_get_uevent_path(char *tmp_path, char *uevent_path)
+{
+	struct libmnt_table *mtab;
+	struct libmnt_fs *fs;
+	struct stat st;
+	dev_t upper_dev;
+
+	tst_resm(TINFO, "Use OVERLAYFS specific strategy");
+
+	mtab = mnt_new_table();
+	if (!mtab)
+		tst_brkm(TBROK | TERRNO, NULL, "mnt_new_table failed");
+
+	if (mnt_table_parse_file(mtab, "/proc/self/mountinfo") != 0)
+		tst_brkm(TBROK, NULL, "mnt_table_parse_file failed");
+
+	if (stat(tmp_path, &st) < 0)
+		tst_brkm(TBROK | TERRNO, NULL, "stat failed");
+
+	fs = mnt_table_find_devno(mtab, st.st_dev, MNT_ITER_FORWARD);
+	if (!fs)
+		tst_brkm(TBROK, NULL, "mnt_table_find_devno failed");
+
+	overlay_get_dev(fs, "upperdir", &upper_dev);
+	mnt_unref_table(mtab);
+
+	tst_resm(TINFO, "Warning: used first of multiple backing devices.");
+	sprintf(uevent_path, "/sys/dev/block/%d:%d/uevent",
+		major(upper_dev), minor(upper_dev));
+}
+
 __attribute__((nonnull))
 void tst_find_backing_dev(const char *path, char *dev, size_t dev_size)
 {
@@ -600,6 +660,8 @@ void tst_find_backing_dev(const char *path, char *dev, size_t dev_size)
 
 	if (fsbuf.f_type == BTRFS_SUPER_MAGIC) {
 		btrfs_get_uevent_path(tmp_path, uevent_path);
+	} else if (fsbuf.f_type == OVERLAYFS_SUPER_MAGIC) {
+		overlay_get_uevent_path(tmp_path, uevent_path);
 	} else if (dev_major == 0) {
 		tst_brkm(TBROK, NULL, "%s resides on an unsupported pseudo-file system.", path);
 	} else {
-- 
2.43.5



More information about the ltp mailing list