@@ -76,4 +76,8 @@ void safe_touch(const char *file, const int lineno,
const char *pathname,
mode_t mode, const struct timespec times[2]);
+/* helper functions to setup overlayfs mountpoint */
+void create_overlay_dirs(void);
+int mount_overlay(const char *file, const int lineno, int skip);
+
#endif /* SAFE_FILE_OPS_FN */
@@ -50,6 +50,12 @@ enum {
TST_GB = 1073741824,
};
+#define OVL_BASE_MNTPOINT "mntpoint"
+#define OVL_LOWER OVL_BASE_MNTPOINT"/lower"
+#define OVL_UPPER OVL_BASE_MNTPOINT"/upper"
+#define OVL_WORK OVL_BASE_MNTPOINT"/work"
+#define OVL_MNT OVL_BASE_MNTPOINT"/ovl"
+
/*
* @path: path is the pathname of any file within the mounted file system
* @mult: mult should be TST_KB, TST_MB or TST_GB
@@ -59,4 +59,10 @@
safe_touch(__FILE__, __LINE__, NULL, \
(pathname), (mode), (times))
+#define SAFE_MOUNT_OVERLAY() \
+ ((void) mount_overlay(__FILE__, __LINE__, 1))
+
+#define TST_MOUNT_OVERLAY() \
+ (mount_overlay(__FILE__, __LINE__, 0) == 0)
+
#endif /* TST_SAFE_FILE_OPS */
@@ -121,6 +121,7 @@ struct tst_test {
int needs_root:1;
int forks_child:1;
int needs_device:1;
+ int needs_overlay:1;
int needs_checkpoints:1;
int format_device:1;
int mount_device:1;
new file mode 100644
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <dirent.h>
+#include <errno.h>
+#include <sys/mount.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_fs.h"
+
+#define TST_FS_SETUP_OVERLAYFS_MSG "overlayfs is not configured in this kernel"
+#define TST_FS_SETUP_OVERLAYFS_CONFIG "lowerdir="OVL_LOWER",upperdir="OVL_UPPER",workdir="OVL_WORK
+
+void create_overlay_dirs(void)
+{
+ DIR *dir = opendir(OVL_LOWER);
+ if (dir == NULL) {
+ SAFE_MKDIR(OVL_LOWER, 0755);
+ SAFE_MKDIR(OVL_UPPER, 0755);
+ SAFE_MKDIR(OVL_WORK, 0755);
+ SAFE_MKDIR(OVL_MNT, 0755);
+ return;
+ }
+ closedir(dir);
+}
+
+int mount_overlay(const char *file, const int lineno, int skip)
+{
+ int ret = 0;
+
+ create_overlay_dirs();
+ ret = mount("overlay", OVL_MNT, "overlay", 0,
+ TST_FS_SETUP_OVERLAYFS_CONFIG);
+ if (ret == 0)
+ return 0;
+
+ if (errno == ENODEV) {
+ if (skip) {
+ tst_brk(TCONF, "%s:%d: " TST_FS_SETUP_OVERLAYFS_MSG,
+ file, lineno);
+ } else {
+ tst_res(TINFO, "%s:%d: " TST_FS_SETUP_OVERLAYFS_MSG,
+ file, lineno);
+ }
+ } else {
+ tst_brk(TBROK | TERRNO, "overlayfs mount failed");
+ }
+ return ret;
+}
@@ -50,6 +50,7 @@ static int iterations = 1;
static float duration = -1;
static pid_t main_pid, lib_pid;
static int mntpoint_mounted;
+static int ovl_mounted;
static struct timespec tst_start_time; /* valid only for test pid */
struct results {
@@ -871,6 +872,17 @@ static void do_setup(int argc, char *argv[])
prepare_device();
}
+ if (tst_test->needs_overlay && !tst_test->mount_device) {
+ tst_brk(TBROK, "tst_test->mount_device must be set");
+ }
+ if (tst_test->needs_overlay && !mntpoint_mounted) {
+ tst_brk(TBROK, "tst_test->mntpoint must be mounted");
+ }
+ if (tst_test->needs_overlay && !ovl_mounted) {
+ SAFE_MOUNT_OVERLAY();
+ ovl_mounted = 1;
+ }
+
if (tst_test->resource_files)
copy_resources();
@@ -891,6 +903,9 @@ static void do_test_setup(void)
static void do_cleanup(void)
{
+ if (ovl_mounted)
+ SAFE_UMOUNT(OVL_MNT);
+
if (mntpoint_mounted)
tst_umount(tst_test->mntpoint);