Add new testcase to verify the flag MNT_EXPIRE of umount2(2). Signed-off-by: Guangwen Feng <fenggw-f...@cn.fujitsu.com> --- runtest/ltplite | 1 + runtest/syscalls | 1 + testcases/kernel/syscalls/.gitignore | 1 + testcases/kernel/syscalls/umount2/umount2_02.c | 180 +++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 testcases/kernel/syscalls/umount2/umount2_02.c
diff --git a/runtest/ltplite b/runtest/ltplite index 3c7fac6..8b37b5a 100644 --- a/runtest/ltplite +++ b/runtest/ltplite @@ -967,6 +967,7 @@ unlink08 unlink08 #umount03 umount03 -D /dev/... umount2_01 umount2_01 +umount2_02 umount2_02 ustat01 ustat01 ustat02 ustat02 diff --git a/runtest/syscalls b/runtest/syscalls index 5fe99b9..51db050 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1316,6 +1316,7 @@ umount02 umount02 umount03 umount03 umount2_01 umount2_01 +umount2_02 umount2_02 ustat01 ustat01 ustat02 ustat02 diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore index 57c64f7..8cda77c 100644 --- a/testcases/kernel/syscalls/.gitignore +++ b/testcases/kernel/syscalls/.gitignore @@ -1004,6 +1004,7 @@ /umount/umount02 /umount/umount03 /umount2/umount2_01 +/umount2/umount2_02 /uname/uname01 /uname/uname02 /uname/uname03 diff --git a/testcases/kernel/syscalls/umount2/umount2_02.c b/testcases/kernel/syscalls/umount2/umount2_02.c new file mode 100644 index 0000000..4e62fe7 --- /dev/null +++ b/testcases/kernel/syscalls/umount2/umount2_02.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2015 Fujitsu Ltd. + * Author: Guangwen Feng <fenggw-f...@cn.fujitsu.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU General Public License + * alone with this program. + */ + +/* + * DESCRIPTION + * Test for feature MNT_EXPIRE of umount2(). + * "Mark the mount point as expired.If a mount point is not currently + * in use, then an initial call to umount2() with this flag fails with + * the error EAGAIN, but marks the mount point as expired. The mount + * point remains expired as long as it isn't accessed by any process. + * A second umount2() call specifying MNT_EXPIRE unmounts an expired + * mount point. This flag cannot be specified with either MNT_FORCE or + * MNT_DETACH. (fails with the error EINVAL)" + */ + +#include <errno.h> +#include <sys/mount.h> + +#include "test.h" +#include "safe_macros.h" +#include "lapi/mount.h" + +#define DIR_MODE (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) +#define MNTPOINT "mntpoint" + +static void setup(void); +static void test_umount2(int i); +static void verify_failure(int i); +static void verify_success(int i); +static void cleanup(void); + +static const char *device; +static const char *fs_type; + +static int mount_flag; + +static struct test_case_t { + int flag; + int exp_errno; + const char *string; +} test_cases[] = { + {MNT_EXPIRE | MNT_FORCE, EINVAL, + "umount2(2) with MNT_EXPIRE | MNT_FORCE expected EINVAL"}, + {MNT_EXPIRE | MNT_DETACH, EINVAL, + "umount2(2) with MNT_EXPIRE | MNT_DETACH expected EINVAL"}, + {MNT_EXPIRE, EAGAIN, + "initial call to umount2(2) with MNT_EXPIRE expected EAGAIN"}, + {MNT_EXPIRE, EAGAIN, + "umount2(2) with MNT_EXPIRE after access(2) expected EAGAIN"}, + {MNT_EXPIRE, 0, + "second call to umount2(2) with MNT_EXPIRE expected success"}, +}; + +char *TCID = "umount2_02"; +int TST_TOTAL = ARRAY_SIZE(test_cases); + +int main(int ac, char **av) +{ + int lc; + int tc; + + tst_parse_opts(ac, av, NULL, NULL); + + setup(); + + for (lc = 0; TEST_LOOPING(lc); lc++) { + tst_count = 0; + + SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, 0, NULL); + mount_flag = 1; + + for (tc = 0; tc < TST_TOTAL; tc++) { + test_umount2(tc); + } + + if (mount_flag) { + SAFE_UMOUNT(cleanup, MNTPOINT); + mount_flag = 0; + } + } + + cleanup(); + tst_exit(); +} + +static void setup(void) +{ + tst_require_root(); + + if ((tst_kvercmp(2, 6, 8)) < 0) { + tst_brkm(TCONF, NULL, "This test can only run on kernels " + "that are 2.6.8 or higher"); + } + + tst_sig(NOFORK, DEF_HANDLER, NULL); + + tst_tmpdir(); + + fs_type = tst_dev_fs_type(); + device = tst_acquire_device(cleanup); + + if (!device) + tst_brkm(TCONF, cleanup, "Failed to obtain block device"); + + tst_mkfs(cleanup, device, fs_type, NULL); + + SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE); + + TEST_PAUSE; +} + +static void test_umount2(int i) +{ + /* a new access removes the expired mark of the mount point */ + if (strstr(test_cases[i].string, "access(2)") != NULL) { + if (access(MNTPOINT, F_OK) == -1) + tst_brkm(TBROK | TERRNO, cleanup, "access(2) failed"); + } + + TEST(umount2(MNTPOINT, test_cases[i].flag)); + + if (test_cases[i].exp_errno != 0) + verify_failure(i); + else + verify_success(i); +} + +static void verify_failure(int i) +{ + if (TEST_RETURN == 0) { + tst_resm(TFAIL, "umount2(2) succeeded unexpectedly, %s", + test_cases[i].string); + mount_flag = 0; + return; + } + + if (TEST_ERRNO != test_cases[i].exp_errno) { + tst_resm(TFAIL | TTERRNO, "umount2(2) failed unexpectedly, %s", + test_cases[i].string); + return; + } + + tst_resm(TPASS, "umount2(2) failed as expected"); +} + +static void verify_success(int i) +{ + if (TEST_RETURN != 0) { + tst_resm(TFAIL | TTERRNO, "umount2(2) failed, %s", + test_cases[i].string); + return; + } + + tst_resm(TPASS, "umount2(2) succeeded as expected"); + mount_flag = 0; +} + +static void cleanup(void) +{ + if (mount_flag && tst_umount(MNTPOINT)) + tst_resm(TWARN | TERRNO, "Failed to unmount"); + + if (device) + tst_release_device(NULL, device); + + tst_rmdir(); +} -- 1.8.4.2 ------------------------------------------------------------------------------ _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list