All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device
@ 2017-10-11 14:41 Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems Cyril Hrubis
                   ` (15 more replies)
  0 siblings, 16 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

If we cal tst_mkfs() from a test more than once we end up with the very
same bug we already fixed by clearing the device in
tst_acquire_device(), i.e. some mkfs programs will not format it when
there is a valid FS signature there. But we have to clear the device for
the shell tests as well.

So this commit adds tst_clear_device() function that is both called from
the tst_mkfs() and from the shell tst_device helper to clear up the
first 512k of the device.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 include/tst_device.h       | 10 ++++++++++
 lib/tst_device.c           | 19 +++++++++++--------
 lib/tst_mkfs.c             |  4 ++++
 testcases/lib/tst_device.c |  5 +++++
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/include/tst_device.h b/include/tst_device.h
index 897696dd9..7ac288368 100644
--- a/include/tst_device.h
+++ b/include/tst_device.h
@@ -34,4 +34,14 @@ extern struct tst_device *tst_device;
  */
 int tst_umount(const char *path);
 
+/*
+ * Clears a first few blocks of the device. This is needed when device has
+ * already been formatted with a filesystems, subset of mkfs.foo utils aborts
+ * the operation if it finds a filesystem signature there.
+ *
+ * Note that this is called from tst_mkfs() automatically, so you probably will
+ * not need to use this from the test yourself.
+ */
+int tst_clear_device(const char *dev);
+
 #endif	/* TST_DEVICE_H__ */
diff --git a/lib/tst_device.c b/lib/tst_device.c
index 67432caf6..6ad6c47f6 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -245,15 +245,8 @@ const char *tst_acquire_device__(unsigned int size)
 
 		ltp_dev_size = ltp_dev_size/1024/1024;
 
-		if (acq_dev_size <= ltp_dev_size) {
-			if (tst_fill_file(dev, 0, 1024, 512)) {
-				tst_resm(TWARN | TERRNO,
-					 "Failed to clear the first 512k of %s",
-					 dev);
-			}
-
+		if (acq_dev_size <= ltp_dev_size)
 			return dev;
-		}
 
 		tst_resm(TINFO, "Skipping $LTP_DEV size %"PRIu64"MB, requested size %uMB",
 				ltp_dev_size, acq_dev_size);
@@ -319,6 +312,16 @@ int tst_release_device(const char *dev)
 	return ret;
 }
 
+int tst_clear_device(const char *dev)
+{
+	if (tst_fill_file(dev, 0, 1024, 512)) {
+		tst_resm(TWARN, "Failed to clear 512k block on %s", dev);
+		return 1;
+	}
+
+	return 0;
+}
+
 int tst_umount(const char *path)
 {
 	int err, ret, i;
diff --git a/lib/tst_mkfs.c b/lib/tst_mkfs.c
index f2e40ecd6..7385a939f 100644
--- a/lib/tst_mkfs.c
+++ b/lib/tst_mkfs.c
@@ -18,6 +18,7 @@
 #include "test.h"
 #include "ltp_priv.h"
 #include "tst_mkfs.h"
+#include "tst_device.h"
 
 #define OPTS_MAX 32
 
@@ -75,6 +76,9 @@ void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void),
 
 	argv[pos] = NULL;
 
+	if (tst_clear_device(dev))
+		tst_brkm(TBROK, cleanup_fn, "tst_clear_device() failed");
+
 	tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'",
 	         dev, fs_type, fs_opts_str, extra_opt ? extra_opt : "");
 	ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, 1);
diff --git a/testcases/lib/tst_device.c b/testcases/lib/tst_device.c
index d33cac613..9afaeb1ef 100644
--- a/testcases/lib/tst_device.c
+++ b/testcases/lib/tst_device.c
@@ -59,6 +59,11 @@ static int acquire_device(int argc, char *argv[])
 	if (!device)
 		return 1;
 
+	if (tst_clear_device(device)) {
+		tst_release_device(device);
+		return 1;
+	}
+
 	printf("%s", device);
 
 	return 0;
-- 
2.13.5


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

* [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-11-09 18:38   ` Sandeep Patil
  2017-10-11 14:41 ` [LTP] [PATCH v3 03/16] SAFE_MOUNT: Handle FUSE mounts as well Cyril Hrubis
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

A filesystem is supported if kernel can mount it (we do not get ENODEV
when we attempt to mount it) and if there is mkfs installed so that we
can format a test device.

The function starts with a whitelist of filesystems to use and loops
over them filtering out unsupported ones, then finally returns a list
of filesystem that could be used for the testing.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 include/tst_fs.h             |   4 ++
 lib/tst_supported_fs_types.c | 118 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 lib/tst_supported_fs_types.c

diff --git a/include/tst_fs.h b/include/tst_fs.h
index 52befbec9..1f6d2bab5 100644
--- a/include/tst_fs.h
+++ b/include/tst_fs.h
@@ -146,6 +146,10 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
  */
 int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
 
+/*
+ * Returns NULL-terminated array of kernel-supported filesystems.
+ */
+const char **tst_get_supported_fs_types(void);
 
 #ifdef TST_TEST_H__
 static inline long tst_fs_type(const char *path)
diff --git a/lib/tst_supported_fs_types.c b/lib/tst_supported_fs_types.c
new file mode 100644
index 000000000..a23b1ed52
--- /dev/null
+++ b/lib/tst_supported_fs_types.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_fs.h"
+
+static const char *const fs_type_whitelist[] = {
+	"ext2",
+	"ext3",
+	"ext4",
+	"xfs",
+	"btrfs",
+	"vfat",
+	"exfat",
+	"ntfs",
+	NULL
+};
+
+static const char *fs_types[ARRAY_SIZE(fs_type_whitelist)];
+
+static int has_mkfs(const char *fs_type)
+{
+	char buf[128];
+	int ret;
+
+	sprintf(buf, "mkfs.%s >/dev/null 2>&1", fs_type);
+
+	ret = tst_system(buf);
+
+	if (WEXITSTATUS(ret) == 127) {
+		tst_res(TINFO, "mkfs.%s does not exist", fs_type);
+		return 0;
+	}
+
+	tst_res(TINFO, "mkfs.%s does exist", fs_type);
+	return 1;
+}
+
+static int has_kernel_support(const char *fs_type)
+{
+	static int fuse_supported = -1;
+	const char *tmpdir = getenv("TMPDIR");
+	char buf[128];
+	int ret;
+
+	if (!tmpdir)
+		tmpdir = "/tmp";
+
+	mount("/dev/zero", tmpdir, fs_type, 0, NULL);
+	if (errno != ENODEV) {
+		tst_res(TINFO, "Kernel supports %s", fs_type);
+		return 1;
+	}
+
+	/* Is FUSE supported by kernel? */
+	if (fuse_supported == -1) {
+		ret = open("/dev/fuse", O_RDWR);
+		if (ret < 0) {
+			fuse_supported = 0;
+		} else {
+			fuse_supported = 1;
+			SAFE_CLOSE(ret);
+		}
+	}
+
+	if (!fuse_supported)
+		return 0;
+
+	/* Is FUSE implementation installed? */
+	sprintf(buf, "mount.%s >/dev/null 2>&1", fs_type);
+
+	ret = tst_system(buf);
+	if (WEXITSTATUS(ret) == 127) {
+		tst_res(TINFO, "Filesystem %s is not supported", fs_type);
+		return 0;
+	}
+
+	tst_res(TINFO, "FUSE does support %s", fs_type);
+	return 1;
+}
+
+static int is_supported(const char *fs_type)
+{
+	return has_kernel_support(fs_type) && has_mkfs(fs_type);
+}
+
+const char **tst_get_supported_fs_types(void)
+{
+	unsigned int i, j = 0;
+
+	for (i = 0; fs_type_whitelist[i]; i++) {
+		if (is_supported(fs_type_whitelist[i]))
+			fs_types[j++] = fs_type_whitelist[i];
+	}
+
+	return fs_types;
+}
-- 
2.13.5


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

* [LTP] [PATCH v3 03/16] SAFE_MOUNT: Handle FUSE mounts as well
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 04/16] lib/tst_test: Add .all_filesystems flag Cyril Hrubis
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

FUSE mounts can be only mounted by the corresponding mount.$fs_type handler.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 lib/safe_macros.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 7ca1849fa..c4aed0b30 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -699,6 +699,23 @@ int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),
 	return rval;
 }
 
+static const char *const fuse_fs_types[] = {
+	"exfat",
+	"ntfs",
+};
+
+static int is_fuse(const char *fs_type)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(fuse_fs_types); i++) {
+		if (!strcmp(fuse_fs_types[i], fs_type))
+			return 1;
+	}
+
+	return 0;
+}
+
 int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
 	       const char *source, const char *target,
 	       const char *filesystemtype, unsigned long mountflags,
@@ -708,6 +725,28 @@ int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
 
 	rval = mount(source, target, filesystemtype, mountflags, data);
 
+	/*
+	 * The FUSE filesystem executes mount.fuse helper, which tries to
+	 * execute corresponding binary name which is encoded@the start of
+	 * the source string and separated by # from the device name.
+         *
+	 * The mount helpers are called mount.$fs_type.
+	 */
+	if (rval == -1 && errno == ENODEV && is_fuse(filesystemtype)) {
+		char buf[1024];
+		int ret;
+
+		tst_resm(TINFO, "Trying FUSE...");
+		snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'",
+			 filesystemtype, source, target);
+
+		ret = tst_system(buf);
+		if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0)
+			return 0;
+
+		errno = ENODEV;
+	}
+
 	if (rval == -1) {
 		tst_brkm(TBROK | TERRNO, cleanup_fn,
 			 "%s:%d: mount(%s, %s, %s, %lu, %p) failed",
-- 
2.13.5


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

* [LTP] [PATCH v3 04/16] lib/tst_test: Add .all_filesystems flag
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 03/16] SAFE_MOUNT: Handle FUSE mounts as well Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs() Cyril Hrubis
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

This commit adds a support for re-runing a test on all available
filesystems simply by turning on .all_filesystems flag in the tst_test
structure.

The .all_filesystems flag implies .needs_device, the .format_filesystem and
.mount_filesystem works as usuall but the device is formatted and mounted for
each filesystem before we run the test function. The .setup and .cleanup
functions are executed for each filesystem. The currently tested filesystem
type is stored in the tst_device->fs_type.

This allows us to easily run a test that tests filesystem specific
syscall for all supported filesystems without a need to hardcode all fs
types into a runtest file and with a minimal changes to the test code.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 include/tst_test.h |   9 +++++
 lib/tst_test.c     | 117 ++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 97 insertions(+), 29 deletions(-)

diff --git a/include/tst_test.h b/include/tst_test.h
index ad468e8cf..e0dd12708 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -125,6 +125,15 @@ struct tst_test {
 	int format_device:1;
 	int mount_device:1;
 	int needs_rofs:1;
+	/*
+	 * If set the test function will be executed for all available
+	 * filesystems and the current filesytem type would be set in the
+	 * tst_device->fs_type.
+	 *
+	 * The test setup and cleanup are executed before/after __EACH__ call
+	 * to the test function.
+	 */
+	int all_filesystems:1;
 
 	/* Minimal device size in megabytes */
 	unsigned int dev_min_size;
diff --git a/lib/tst_test.c b/lib/tst_test.c
index f8b3fb491..8460cecec 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -678,6 +678,20 @@ static void assert_test_fn(void)
 		tst_brk(TBROK, "You can define tcnt only for test()");
 }
 
+static void prepare_device(void)
+{
+	if (tst_test->format_device) {
+		SAFE_MKFS(tdev.dev, tdev.fs_type, tst_test->dev_fs_opts,
+			  tst_test->dev_extra_opt);
+	}
+
+	if (tst_test->mount_device) {
+		SAFE_MOUNT(tdev.dev, tst_test->mntpoint, tdev.fs_type,
+			   tst_test->mnt_flags, tst_test->mnt_data);
+		mntpoint_mounted = 1;
+	}
+}
+
 static void do_setup(int argc, char *argv[])
 {
 	if (!tst_test)
@@ -710,6 +724,9 @@ static void do_setup(int argc, char *argv[])
 		tst_test->format_device = 1;
 	}
 
+	if (tst_test->all_filesystems)
+		tst_test->needs_device = 1;
+
 	setup_ipc();
 
 	if (needs_tmpdir() && !tst_tmpdir_created())
@@ -718,8 +735,8 @@ static void do_setup(int argc, char *argv[])
 	if (tst_test->mntpoint)
 		SAFE_MKDIR(tst_test->mntpoint, 0777);
 
-	if ((tst_test->needs_rofs || tst_test->mount_device) &&
-	    !tst_test->mntpoint) {
+	if ((tst_test->needs_rofs || tst_test->mount_device ||
+	     tst_test->all_filesystems) && !tst_test->mntpoint) {
 		tst_brk(TBROK, "tst_test->mntpoint must be set!");
 	}
 
@@ -753,17 +770,8 @@ static void do_setup(int argc, char *argv[])
 		else
 			tdev.fs_type = tst_dev_fs_type();
 
-		if (tst_test->format_device) {
-			SAFE_MKFS(tdev.dev, tdev.fs_type,
-			          tst_test->dev_fs_opts,
-				  tst_test->dev_extra_opt);
-		}
-
-		if (tst_test->mount_device) {
-			SAFE_MOUNT(tdev.dev, tst_test->mntpoint, tdev.fs_type,
-				   tst_test->mnt_flags, tst_test->mnt_data);
-			mntpoint_mounted = 1;
-		}
+		if (!tst_test->all_filesystems)
+			prepare_device();
 	}
 
 	if (tst_test->resource_files)
@@ -859,6 +867,11 @@ static void add_paths(void)
 	free(new_path);
 }
 
+static void heartbeat(void)
+{
+	kill(getppid(), SIGUSR1);
+}
+
 static void testrun(void)
 {
 	unsigned int i = 0;
@@ -886,8 +899,7 @@ static void testrun(void)
 			break;
 
 		run_tests();
-
-		kill(getppid(), SIGUSR1);
+		heartbeat();
 	}
 
 	do_test_cleanup();
@@ -960,23 +972,13 @@ void tst_set_timeout(int timeout)
 	if (getpid() == lib_pid)
 		alarm(results->timeout);
 	else
-		kill(getppid(), SIGUSR1);
+		heartbeat();
 }
 
-void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
+static int fork_testrun(void)
 {
 	int status;
 
-	lib_pid = getpid();
-	tst_test = self;
-
-	do_setup(argc, argv);
-
-	TCID = tst_test->tid;
-
-	SAFE_SIGNAL(SIGALRM, alarm_handler);
-	SAFE_SIGNAL(SIGUSR1, heartbeat_handler);
-
 	if (tst_test->timeout)
 		tst_set_timeout(tst_test->timeout);
 	else
@@ -1001,7 +1003,7 @@ void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
 	SAFE_SIGNAL(SIGINT, SIG_DFL);
 
 	if (WIFEXITED(status) && WEXITSTATUS(status))
-		do_exit(WEXITSTATUS(status));
+		return WEXITSTATUS(status);
 
 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) {
 		tst_res(TINFO, "If you are running on slow machine, "
@@ -1012,5 +1014,62 @@ void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
 	if (WIFSIGNALED(status))
 		tst_brk(TBROK, "Test killed by %s!", tst_strsig(WTERMSIG(status)));
 
-	do_exit(0);
+	return 0;
+}
+
+static int run_tcases_per_fs(void)
+{
+	int ret = 0;
+	unsigned int i;
+	const char *const *filesystems = tst_get_supported_fs_types();
+
+	if (!filesystems[0])
+		tst_brk(TCONF, "There are no supported filesystems");
+
+	for (i = 0; filesystems[i]; i++) {
+		tdev.fs_type = filesystems[i];
+
+		prepare_device();
+
+		ret = fork_testrun();
+
+		if (mntpoint_mounted) {
+			tst_umount(tst_test->mntpoint);
+			mntpoint_mounted = 0;
+		}
+
+		if (ret == TCONF) {
+			update_results(ret);
+			continue;
+		}
+
+		if (ret == 0)
+			continue;
+
+		do_exit(ret);
+	}
+
+	return ret;
+}
+
+void tst_run_tcases(int argc, char *argv[], struct tst_test *self)
+{
+	int ret;
+
+	lib_pid = getpid();
+	tst_test = self;
+
+	do_setup(argc, argv);
+
+	TCID = tst_test->tid;
+
+	SAFE_SIGNAL(SIGALRM, alarm_handler);
+	SAFE_SIGNAL(SIGUSR1, heartbeat_handler);
+
+	if (tst_test->all_filesystems)
+		ret = run_tcases_per_fs();
+	else
+		ret = fork_testrun();
+
+	do_exit(ret);
 }
-- 
2.13.5


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

* [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs()
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (2 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 04/16] lib/tst_test: Add .all_filesystems flag Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-11-09 18:50   ` Sandeep Patil
  2017-10-11 14:41 ` [LTP] [PATCH v3 06/16] syscalls/fallocate05: New test Cyril Hrubis
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Adds a simple helper to fill a filesystem.

All the funciton does is to create and write to files in a given
directory until write() fails with ENOSPC.

This is intended to be used in various filesystem related tests such as
fallocate and stress tests.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 include/tst_fs.h  |  5 +++++
 lib/tst_fill_fs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 lib/tst_fill_fs.c

diff --git a/include/tst_fs.h b/include/tst_fs.h
index 1f6d2bab5..0ad535c2b 100644
--- a/include/tst_fs.h
+++ b/include/tst_fs.h
@@ -151,6 +151,11 @@ int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
  */
 const char **tst_get_supported_fs_types(void);
 
+/*
+ * Creates and writes to files on given path until write fails with ENOSPC
+ */
+void tst_fill_fs(const char *path, int verbose);
+
 #ifdef TST_TEST_H__
 static inline long tst_fs_type(const char *path)
 {
diff --git a/lib/tst_fill_fs.c b/lib/tst_fill_fs.c
new file mode 100644
index 000000000..6b2bbbcd7
--- /dev/null
+++ b/lib/tst_fill_fs.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+#include "tst_fs.h"
+
+void tst_fill_fs(const char *path, int verbose)
+{
+	int i = 0;
+	char file[PATH_MAX];
+	char buf[4096];
+	size_t len;
+	ssize_t ret;
+	int fd;
+
+	for (;;) {
+		len = random() % (1024 * 102400);
+
+		snprintf(file, sizeof(file), "%s/file%i", path, i++);
+
+		if (verbose)
+			tst_res(TINFO, "Creating file %s size %zu", file, len);
+
+		fd = SAFE_OPEN(file, O_WRONLY | O_CREAT, 0700);
+
+		while (len) {
+			ret = write(fd, buf, MIN(len, sizeof(buf)));
+
+			if (ret < 0) {
+				SAFE_CLOSE(fd);
+
+				if (errno != ENOSPC)
+					tst_brk(TBROK | TERRNO, "write()");
+
+				tst_res(TINFO | TERRNO, "write()");
+				return;
+			}
+
+			len -= ret;
+		}
+
+		SAFE_CLOSE(fd);
+	}
+}
-- 
2.13.5


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

* [LTP] [PATCH v3 06/16] syscalls/fallocate05: New test
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (3 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs() Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 07/16] syscalls/msync04: Run test for all filesystems Cyril Hrubis
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Tests that fallocate() works fine when filesystem is full.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/syscalls                                  |   1 +
 testcases/kernel/syscalls/.gitignore              |   1 +
 testcases/kernel/syscalls/fallocate/fallocate05.c | 104 ++++++++++++++++++++++
 3 files changed, 106 insertions(+)
 create mode 100644 testcases/kernel/syscalls/fallocate/fallocate05.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 2362a231d..a31d15da6 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -160,6 +160,7 @@ fallocate01 fallocate01
 fallocate02 fallocate02
 fallocate03 fallocate03
 fallocate04 fallocate04
+fallocate05 fallocate05
 
 #posix_fadvise test cases
 posix_fadvise01                      posix_fadvise01
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 930f3f999..a91abd9f0 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -141,6 +141,7 @@
 /fallocate/fallocate02
 /fallocate/fallocate03
 /fallocate/fallocate04
+/fallocate/fallocate05
 /fchdir/fchdir01
 /fchdir/fchdir02
 /fchdir/fchdir03
diff --git a/testcases/kernel/syscalls/fallocate/fallocate05.c b/testcases/kernel/syscalls/fallocate/fallocate05.c
new file mode 100644
index 000000000..1fac26adb
--- /dev/null
+++ b/testcases/kernel/syscalls/fallocate/fallocate05.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Tests that writing to fallocated file works when filesystem is full.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "tst_test.h"
+#include "lapi/fallocate.h"
+
+#define MNTPOINT "mntpoint"
+#define FALLOCATE_SIZE 8192
+
+static int fd;
+
+static void run(void)
+{
+	char buf[FALLOCATE_SIZE];
+	ssize_t ret;
+
+	fd = SAFE_OPEN(MNTPOINT "/test_file", O_WRONLY | O_CREAT);
+
+	if (fallocate(fd, 0, 0, FALLOCATE_SIZE)) {
+		if (errno == EOPNOTSUPP) {
+			tst_res(TCONF | TERRNO, "fallocate() not supported");
+			SAFE_CLOSE(fd);
+			return;
+		}
+
+		tst_brk(TBROK | TERRNO,
+			"fallocate(fd, 0, 0, %i)", FALLOCATE_SIZE);
+	}
+
+	tst_fill_fs(MNTPOINT, 1);
+
+	ret = write(fd, buf, sizeof(buf));
+
+	if (ret < 0)
+		tst_res(TFAIL | TERRNO, "write() failed unexpectedly");
+	else
+		tst_res(TPASS, "write() wrote %zu bytes", ret);
+
+	ret = fallocate(fd, 0, FALLOCATE_SIZE, FALLOCATE_SIZE);
+	if (ret != -1)
+		tst_brk(TFAIL, "fallocate() succeeded unexpectedly");
+
+	if (errno != ENOSPC)
+		tst_brk(TFAIL | TERRNO, "fallocate() should fail with ENOSPC");
+
+	tst_res(TPASS | TERRNO, "fallocate() on full FS");
+
+	ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE, 0, FALLOCATE_SIZE);
+	if (ret == -1) {
+		if (errno == EOPNOTSUPP)
+			tst_brk(TCONF, "fallocate(FALLOC_FL_PUNCH_HOLE)");
+
+		tst_brk(TBROK | TERRNO, "fallocate(FALLOC_FL_PUNCH_HOLE)");
+	}
+	tst_res(TPASS, "fallocate(FALLOC_FL_PUNCH_HOLE)");
+
+	ret = write(fd, buf, 10);
+	if (ret == -1)
+		tst_res(TFAIL | TERRNO, "write()");
+	else
+		tst_res(TPASS, "write()");
+
+	SAFE_CLOSE(fd);
+}
+
+static void cleanup(void)
+{
+	if (fd > 0)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.cleanup = cleanup,
+	.test_all = run,
+};
-- 
2.13.5


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

* [LTP] [PATCH v3 07/16] syscalls/msync04: Run test for all filesystems
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (4 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 06/16] syscalls/fallocate05: New test Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 08/16] syscalls/fallocate04: Convert to the new library Cyril Hrubis
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/msync/msync04.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/testcases/kernel/syscalls/msync/msync04.c b/testcases/kernel/syscalls/msync/msync04.c
index 4f70ca1ef..9dec3c1d9 100644
--- a/testcases/kernel/syscalls/msync/msync04.c
+++ b/testcases/kernel/syscalls/msync/msync04.c
@@ -109,5 +109,6 @@ static struct tst_test test = {
 	.needs_root = 1,
 	.mntpoint = "msync04",
 	.mount_device = 1,
+	.all_filesystems = 1,
 	.min_kver = "2.6.25",
 };
-- 
2.13.5


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

* [LTP] [PATCH v3 08/16] syscalls/fallocate04: Convert to the new library
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (5 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 07/16] syscalls/msync04: Run test for all filesystems Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 09/16] syscalls/fallocate04: Run test for all filesystems Cyril Hrubis
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/fallocate/fallocate04.c | 169 ++++++++++------------
 1 file changed, 77 insertions(+), 92 deletions(-)

diff --git a/testcases/kernel/syscalls/fallocate/fallocate04.c b/testcases/kernel/syscalls/fallocate/fallocate04.c
index a6729161c..4916c8b47 100644
--- a/testcases/kernel/syscalls/fallocate/fallocate04.c
+++ b/testcases/kernel/syscalls/fallocate/fallocate04.c
@@ -30,13 +30,9 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
 #include "lapi/fallocate.h"
 
-char *TCID = "fallocate04";
-int TST_TOTAL = 5;
-
 static int fd;
 static const char fname[] = "fallocate04.txt";
 static size_t block_size;
@@ -44,28 +40,18 @@ static size_t buf_size;
 
 #define NUM_OF_BLOCKS	3
 
-static int verbose;
-static const option_t options[] = {
-	{"v", &verbose, NULL},
-	{NULL, NULL, NULL}
-};
-
-static void help(void)
-{
-	printf("  -v      Verbose\n");
-}
+static char *verbose;
 
 static void cleanup(void)
 {
-	close(fd);
-	tst_rmdir();
+	SAFE_CLOSE(fd);
 }
 
 static void get_blocksize(void)
 {
 	struct stat file_stat;
 
-	SAFE_FSTAT(cleanup, fd, &file_stat);
+	SAFE_FSTAT(fd, &file_stat);
 
 	block_size = file_stat.st_blksize;
 	buf_size = NUM_OF_BLOCKS * block_size;
@@ -77,7 +63,7 @@ static size_t get_allocsize(void)
 
 	fsync(fd);
 
-	SAFE_FSTAT(cleanup, fd, &file_stat);
+	SAFE_FSTAT(fd, &file_stat);
 
 	return file_stat.st_blocks * 512;
 }
@@ -93,9 +79,7 @@ static void fill_tst_buf(char buf[])
 
 static void setup(void)
 {
-	tst_tmpdir();
-
-	fd = SAFE_OPEN(cleanup, fname, O_RDWR | O_CREAT, 0700);
+	fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700);
 
 	get_blocksize();
 }
@@ -104,86 +88,86 @@ static void check_file_data(const char exp_buf[], size_t size)
 {
 	char rbuf[size];
 
-	tst_resm(TINFO, "reading the file, compare with expected buffer");
+	tst_res(TINFO, "reading the file, compare with expected buffer");
 
-	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
-	SAFE_READ(cleanup, 1, fd, rbuf, size);
+	SAFE_LSEEK(fd, 0, SEEK_SET);
+	SAFE_READ(1, fd, rbuf, size);
 
 	if (memcmp(exp_buf, rbuf, size)) {
 		if (verbose) {
-			tst_resm_hexd(TINFO, exp_buf, size, "expected:");
-			tst_resm_hexd(TINFO, rbuf, size, "but read:");
+			tst_res_hexd(TINFO, exp_buf, size, "expected:");
+			tst_res_hexd(TINFO, rbuf, size, "but read:");
 		}
-		tst_brkm(TFAIL, cleanup, "not expected file data");
+		tst_brk(TFAIL, "not expected file data");
 	}
 }
 
 static void test01(void)
 {
-	tst_resm(TINFO, "allocate '%zu' bytes", buf_size);
+	tst_res(TINFO, "allocate '%zu' bytes", buf_size);
 
 	if (fallocate(fd, 0, 0, buf_size) == -1) {
 		if (errno == ENOSYS || errno == EOPNOTSUPP)
-			tst_brkm(TCONF, cleanup, "fallocate() not supported");
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate() failed");
+			tst_brk(TCONF, "fallocate() not supported");
+		tst_brk(TFAIL | TERRNO, "fallocate() failed");
 	}
 
 	char buf[buf_size];
 
 	fill_tst_buf(buf);
 
-	SAFE_WRITE(cleanup, 1, fd, buf, buf_size);
+	SAFE_WRITE(1, fd, buf, buf_size);
 
-	tst_resm(TPASS, "test-case succeeded");
+	tst_res(TPASS, "test-case succeeded");
 }
 
 static void test02(void)
 {
 	size_t alloc_size0 = get_allocsize();
 
-	tst_resm(TINFO, "read allocated file size '%zu'", alloc_size0);
-	tst_resm(TINFO, "make a hole with FALLOC_FL_PUNCH_HOLE");
+	tst_res(TINFO, "read allocated file size '%zu'", alloc_size0);
+	tst_res(TINFO, "make a hole with FALLOC_FL_PUNCH_HOLE");
 
 	if (tst_kvercmp(2, 6, 38) < 0) {
-		tst_brkm(TCONF, cleanup,
-			 "FALLOC_FL_PUNCH_HOLE needs Linux 2.6.38 or newer");
+		tst_brk(TCONF,
+			"FALLOC_FL_PUNCH_HOLE needs Linux 2.6.38 or newer");
 	}
 
 	if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
 	    block_size, block_size) == -1) {
 		if (errno == EOPNOTSUPP) {
-			tst_brkm(TCONF, cleanup,
-			         "FALLOC_FL_PUNCH_HOLE not supported");
+			tst_brk(TCONF,
+			        "FALLOC_FL_PUNCH_HOLE not supported");
 		}
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate() failed");
+		tst_brk(TFAIL | TERRNO, "fallocate() failed");
 	}
 
-	tst_resm(TINFO, "check that file has a hole with lseek(,,SEEK_HOLE)");
+	tst_res(TINFO, "check that file has a hole with lseek(,,SEEK_HOLE)");
 	off_t ret = lseek(fd, 0, SEEK_HOLE);
 
 	if (ret != (ssize_t)block_size) {
 		/* exclude error when kernel doesn't have SEEK_HOLE support */
 		if (errno != EINVAL) {
-			tst_brkm(TFAIL | TERRNO, cleanup,
+			tst_brk(TFAIL | TERRNO,
 				 "fallocate() or lseek() failed");
 		}
 		if (tst_kvercmp(3, 1, 0) < 0) {
-			tst_resm(TINFO, "lseek() doesn't support SEEK_HOLE, "
+			tst_res(TINFO, "lseek() doesn't support SEEK_HOLE, "
 				 "this is expected for < 3.1 kernels");
 		} else {
-			tst_brkm(TBROK | TERRNO, cleanup,
+			tst_brk(TBROK | TERRNO,
 				 "lseek() doesn't support SEEK_HOLE");
 		}
 	} else {
-		tst_resm(TINFO, "found a hole at '%ld' offset", ret);
+		tst_res(TINFO, "found a hole@'%ld' offset", ret);
 	}
 
 	size_t alloc_size1 = get_allocsize();
 
-	tst_resm(TINFO, "allocated file size before '%zu' and after '%zu'",
+	tst_res(TINFO, "allocated file size before '%zu' and after '%zu'",
 		 alloc_size0, alloc_size1);
 	if ((alloc_size0 - block_size) != alloc_size1)
-		tst_brkm(TFAIL, cleanup, "not expected allocated size");
+		tst_brk(TFAIL, "not expected allocated size");
 
 	char exp_buf[buf_size];
 
@@ -192,29 +176,29 @@ static void test02(void)
 
 	check_file_data(exp_buf, buf_size);
 
-	tst_resm(TPASS, "test-case succeeded");
+	tst_res(TPASS, "test-case succeeded");
 }
 
 static void test03(void)
 {
-	tst_resm(TINFO, "zeroing file space with FALLOC_FL_ZERO_RANGE");
+	tst_res(TINFO, "zeroing file space with FALLOC_FL_ZERO_RANGE");
 
 	if (tst_kvercmp(3, 15, 0) < 0) {
-		tst_brkm(TCONF, cleanup,
-			 "FALLOC_FL_ZERO_RANGE needs Linux 3.15 or newer");
+		tst_brk(TCONF,
+			"FALLOC_FL_ZERO_RANGE needs Linux 3.15 or newer");
 	}
 
 	size_t alloc_size0 = get_allocsize();
 
-	tst_resm(TINFO, "read current allocated file size '%zu'", alloc_size0);
+	tst_res(TINFO, "read current allocated file size '%zu'", alloc_size0);
 
 	if (fallocate(fd, FALLOC_FL_ZERO_RANGE, block_size - 1,
 	    block_size + 2) == -1) {
 		if (errno == EOPNOTSUPP) {
-			tst_brkm(TCONF, cleanup,
-			         "FALLOC_FL_ZERO_RANGE not supported");
+			tst_brk(TCONF,
+			        "FALLOC_FL_ZERO_RANGE not supported");
 		}
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate failed");
+		tst_brk(TFAIL | TERRNO, "fallocate failed");
 	}
 
 	/* The file hole in the specified range must be allocated and
@@ -222,10 +206,10 @@ static void test03(void)
 	 */
 	size_t alloc_size1 = get_allocsize();
 
-	tst_resm(TINFO, "allocated file size before '%zu' and after '%zu'",
+	tst_res(TINFO, "allocated file size before '%zu' and after '%zu'",
 		 alloc_size0, alloc_size1);
 	if ((alloc_size0 + block_size) != alloc_size1)
-		tst_brkm(TFAIL, cleanup, "not expected allocated size");
+		tst_brk(TFAIL, "not expected allocated size");
 
 	char exp_buf[buf_size];
 
@@ -234,32 +218,32 @@ static void test03(void)
 
 	check_file_data(exp_buf, buf_size);
 
-	tst_resm(TPASS, "test-case succeeded");
+	tst_res(TPASS, "test-case succeeded");
 }
 
 static void test04(void)
 {
-	tst_resm(TINFO, "collapsing file space with FALLOC_FL_COLLAPSE_RANGE");
+	tst_res(TINFO, "collapsing file space with FALLOC_FL_COLLAPSE_RANGE");
 
 	size_t alloc_size0 = get_allocsize();
 
-	tst_resm(TINFO, "read current allocated file size '%zu'", alloc_size0);
+	tst_res(TINFO, "read current allocated file size '%zu'", alloc_size0);
 
 	if (fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, block_size,
 	    block_size) == -1) {
 		if (errno == EOPNOTSUPP) {
-			tst_brkm(TCONF, cleanup,
-			         "FALLOC_FL_COLLAPSE_RANGE not supported");
+			tst_brk(TCONF,
+			        "FALLOC_FL_COLLAPSE_RANGE not supported");
 		}
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate failed");
+		tst_brk(TFAIL | TERRNO, "fallocate failed");
 	}
 
 	size_t alloc_size1 = get_allocsize();
 
-	tst_resm(TINFO, "allocated file size before '%zu' and after '%zu'",
+	tst_res(TINFO, "allocated file size before '%zu' and after '%zu'",
 		 alloc_size0, alloc_size1);
 	if ((alloc_size0 - block_size) != alloc_size1)
-		tst_brkm(TFAIL, cleanup, "not expected allocated size");
+		tst_brk(TFAIL, "not expected allocated size");
 
 	size_t size = buf_size - block_size;
 	char tmp_buf[buf_size];
@@ -274,36 +258,36 @@ static void test04(void)
 	exp_buf[block_size - 1] = exp_buf[block_size] = '\0';
 	check_file_data(exp_buf, size);
 
-	tst_resm(TPASS, "test-case succeeded");
+	tst_res(TPASS, "test-case succeeded");
 }
 
 static void test05(void)
 {
-	tst_resm(TINFO, "inserting space with FALLOC_FL_INSERT_RANGE");
+	tst_res(TINFO, "inserting space with FALLOC_FL_INSERT_RANGE");
 
 	size_t alloc_size0 = get_allocsize();
 
-	tst_resm(TINFO, "read current allocated file size '%zu'", alloc_size0);
+	tst_res(TINFO, "read current allocated file size '%zu'", alloc_size0);
 
 	if (fallocate(fd, FALLOC_FL_INSERT_RANGE, block_size,
 	    block_size) == -1) {
 		if (errno == EOPNOTSUPP) {
-			tst_brkm(TCONF, cleanup,
-				 "FALLOC_FL_INSERT_RANGE not supported");
+			tst_brk(TCONF,
+				"FALLOC_FL_INSERT_RANGE not supported");
 		}
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate failed");
+		tst_brk(TFAIL | TERRNO, "fallocate failed");
 	}
 
 	/* allocate space and ensure that it filled with zeroes */
 	if (fallocate(fd, FALLOC_FL_ZERO_RANGE, block_size, block_size) == -1)
-		tst_brkm(TFAIL | TERRNO, cleanup, "fallocate failed");
+		tst_brk(TFAIL | TERRNO, "fallocate failed");
 
 	size_t alloc_size1 = get_allocsize();
 
-	tst_resm(TINFO, "allocated file size before '%zu' and after '%zu'",
+	tst_res(TINFO, "allocated file size before '%zu' and after '%zu'",
 		 alloc_size0, alloc_size1);
 	if ((alloc_size0 + block_size) != alloc_size1)
-		tst_brkm(TFAIL, cleanup, "not expected allocated size");
+		tst_brk(TFAIL, "not expected allocated size");
 
 	char exp_buf[buf_size];
 
@@ -312,26 +296,27 @@ static void test05(void)
 
 	check_file_data(exp_buf, buf_size);
 
-	tst_resm(TPASS, "test-case succeeded");
+	tst_res(TPASS, "test-case succeeded");
 }
 
-int main(int argc, char *argv[])
+static void run(void)
 {
-	int lc;
-
-	tst_parse_opts(argc, argv, options, help);
-
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); ++lc) {
-		test01();
-		test02();
-		test03();
-		test04();
-		test05();
-	}
+	test01();
+	test02();
+	test03();
+	test04();
+	test05();
+}
 
-	cleanup();
+static struct tst_option opts[] = {
+	{"v", &verbose, "-v       Turns on verbose mode"},
+	{NULL, NULL, NULL}
+};
 
-	tst_exit();
-}
+static struct tst_test test = {
+	.options = opts,
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = run,
+	.needs_tmpdir = 1,
+};
-- 
2.13.5


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

* [LTP] [PATCH v3 09/16] syscalls/fallocate04: Run test for all filesystems
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (6 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 08/16] syscalls/fallocate04: Convert to the new library Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 10/16] syscalls/setxattr01: Convert to the new library Cyril Hrubis
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/fallocate/fallocate04.c | 49 +++++++++++++----------
 1 file changed, 28 insertions(+), 21 deletions(-)

diff --git a/testcases/kernel/syscalls/fallocate/fallocate04.c b/testcases/kernel/syscalls/fallocate/fallocate04.c
index 4916c8b47..e576d728d 100644
--- a/testcases/kernel/syscalls/fallocate/fallocate04.c
+++ b/testcases/kernel/syscalls/fallocate/fallocate04.c
@@ -34,19 +34,15 @@
 #include "lapi/fallocate.h"
 
 static int fd;
-static const char fname[] = "fallocate04.txt";
 static size_t block_size;
 static size_t buf_size;
 
+#define MNTPOINT "fallocate"
+#define FNAME MNTPOINT "/fallocate.txt"
 #define NUM_OF_BLOCKS	3
 
 static char *verbose;
 
-static void cleanup(void)
-{
-	SAFE_CLOSE(fd);
-}
-
 static void get_blocksize(void)
 {
 	struct stat file_stat;
@@ -77,13 +73,6 @@ static void fill_tst_buf(char buf[])
 		memset(buf + i * block_size, 'a' + i, block_size);
 }
 
-static void setup(void)
-{
-	fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700);
-
-	get_blocksize();
-}
-
 static void check_file_data(const char exp_buf[], size_t size)
 {
 	char rbuf[size];
@@ -299,13 +288,26 @@ static void test05(void)
 	tst_res(TPASS, "test-case succeeded");
 }
 
-static void run(void)
+static void (*tcases[])(void) = {
+	test01, test02, test03, test04, test05
+};
+
+static void run(unsigned int i)
+{
+	tcases[i]();
+}
+
+static void setup(void)
+{
+	fd = SAFE_OPEN(FNAME, O_RDWR | O_CREAT, 0700);
+
+	get_blocksize();
+}
+
+static void cleanup(void)
 {
-	test01();
-	test02();
-	test03();
-	test04();
-	test05();
+	if (fd > 0)
+		SAFE_CLOSE(fd);
 }
 
 static struct tst_option opts[] = {
@@ -315,8 +317,13 @@ static struct tst_option opts[] = {
 
 static struct tst_test test = {
 	.options = opts,
-	.setup = setup,
 	.cleanup = cleanup,
-	.test_all = run,
+	.setup = setup,
+	.test = run,
+	.tcnt = ARRAY_SIZE(tcases),
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
 	.needs_tmpdir = 1,
+	.needs_root = 1,
 };
-- 
2.13.5


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

* [LTP] [PATCH v3 10/16] syscalls/setxattr01: Convert to the new library.
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (7 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 09/16] syscalls/fallocate04: Run test for all filesystems Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 11/16] syscalls/setxattr01: Run test for all filesystems Cyril Hrubis
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/setxattr/setxattr01.c | 138 +++++++++---------------
 1 file changed, 51 insertions(+), 87 deletions(-)

diff --git a/testcases/kernel/syscalls/setxattr/setxattr01.c b/testcases/kernel/syscalls/setxattr/setxattr01.c
index 359991e3f..86df7ba73 100644
--- a/testcases/kernel/syscalls/setxattr/setxattr01.c
+++ b/testcases/kernel/syscalls/setxattr/setxattr01.c
@@ -57,10 +57,7 @@
 #ifdef HAVE_SYS_XATTR_H
 # include <sys/xattr.h>
 #endif
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "setxattr01";
+#include "tst_test.h"
 
 #ifdef HAVE_SYS_XATTR_H
 #define XATTR_NAME_MAX 255
@@ -69,157 +66,124 @@ char *TCID = "setxattr01";
 #define XATTR_TEST_KEY "user.testkey"
 #define XATTR_TEST_VALUE "this is a test value"
 #define XATTR_TEST_VALUE_SIZE 20
+#define FNAME "setxattr01testfile"
 
-static void setup(void);
-static void cleanup(void);
-
-char filename[BUFSIZ];
-char long_key[XATTR_NAME_LEN];
-char *long_value;
+static char long_key[XATTR_NAME_LEN];
+static char *long_value;
+static char *xattr_value = XATTR_TEST_VALUE;
 
 struct test_case {
-	char *fname;
 	char *key;
-	char *value;
+	char **value;
 	size_t size;
 	int flags;
 	int exp_err;
 };
 struct test_case tc[] = {
 	{			/* case 00, invalid flags */
-	 .fname = filename,
-	 .key = XATTR_TEST_KEY,
-	 .value = XATTR_TEST_VALUE,
+	 .key = long_key,
+	 .value = &xattr_value,
 	 .size = XATTR_TEST_VALUE_SIZE,
 	 .flags = ~0,
 	 .exp_err = EINVAL,
 	 },
 	{			/* case 01, replace non-existing attribute */
-	 .fname = filename,
 	 .key = XATTR_TEST_KEY,
-	 .value = XATTR_TEST_VALUE,
+	 .value = &xattr_value,
 	 .size = XATTR_TEST_VALUE_SIZE,
 	 .flags = XATTR_REPLACE,
 	 .exp_err = ENODATA,
 	 },
-	{			/* case 02, long key name, key will be set in setup() */
-	 .fname = filename,
-	 .key = NULL,
-	 .value = XATTR_TEST_VALUE,
+	{			/* case 02, long key name */
+	 .key = long_key,
+	 .value = &xattr_value,
 	 .size = XATTR_TEST_VALUE_SIZE,
 	 .flags = XATTR_CREATE,
 	 .exp_err = ERANGE,
 	 },
-	{			/* case 03, long value, value will be set in setup() */
-	 .fname = filename,
+	{			/* case 03, long value */
 	 .key = XATTR_TEST_KEY,
-	 .value = NULL,
+	 .value = &long_value,
 	 .size = XATTR_SIZE_MAX + 1,
 	 .flags = XATTR_CREATE,
 	 .exp_err = E2BIG,
 	 },
 	{			/* case 04, zero length value */
-	 .fname = filename,
 	 .key = XATTR_TEST_KEY,
-	 .value = XATTR_TEST_VALUE,
+	 .value = &xattr_value,
 	 .size = 0,
 	 .flags = XATTR_CREATE,
 	 .exp_err = 0,
 	 },
 	{			/* case 05, create existing attribute */
-	 .fname = filename,
 	 .key = XATTR_TEST_KEY,
-	 .value = XATTR_TEST_VALUE,
+	 .value = &xattr_value,
 	 .size = XATTR_TEST_VALUE_SIZE,
 	 .flags = XATTR_CREATE,
 	 .exp_err = EEXIST,
 	 },
 	{			/* case 06, replace existing attribute */
-	 .fname = filename,
 	 .key = XATTR_TEST_KEY,
-	 .value = XATTR_TEST_VALUE,
+	 .value = &xattr_value,
 	 .size = XATTR_TEST_VALUE_SIZE,
 	 .flags = XATTR_REPLACE,
 	 .exp_err = 0,
-	 },
+	},
 };
 
-int TST_TOTAL = sizeof(tc) / sizeof(tc[0]);
-
-int main(int argc, char *argv[])
+static void verify_setxattr(unsigned int i)
 {
-	int lc;
-	int i;
+	TEST(setxattr(FNAME, tc[i].key, *tc[i].value, tc[i].size, tc[i].flags));
 
-	tst_parse_opts(argc, argv, NULL, NULL);
+	if (TEST_RETURN == -1 && TEST_ERRNO == EOPNOTSUPP)
+		tst_brk(TCONF, "setxattr() not supported");
 
-	setup();
+	if (!tc[i].exp_err) {
+		if (TEST_RETURN) {
+			tst_res(TFAIL | TTERRNO,
+				"setxattr() failed with %li", TEST_RETURN);
+			return;
+		}
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
+		tst_res(TPASS, "setxattr() passed");
+		return;
+	}
 
-		for (i = 0; i < TST_TOTAL; i++) {
-			TEST(setxattr(tc[i].fname, tc[i].key, tc[i].value,
-				      tc[i].size, tc[i].flags));
+	if (TEST_RETURN == 0) {
+		tst_res(TFAIL, "setxattr() passed unexpectedly");
+		return;
+	}
 
-			if (TEST_ERRNO == tc[i].exp_err) {
-				tst_resm(TPASS | TTERRNO, "expected behavior");
-			} else {
-				tst_resm(TFAIL | TTERRNO, "unexpected behavior "
-					 "- expected errno %d - Got",
-					 tc[i].exp_err);
-			}
-		}
+	if (TEST_ERRNO != tc[i].exp_err) {
+		tst_res(TFAIL | TTERRNO, "setxattr() should fail with %s",
+			tst_strerrno(tc[i].exp_err));
+		return;
 	}
 
-	cleanup();
-	tst_exit();
+	tst_res(TPASS | TTERRNO, "setxattr() failed");
 }
 
 static void setup(void)
 {
-	int fd;
-
-	tst_require_root();
+	SAFE_TOUCH(FNAME, 0644, NULL);
 
-	tst_tmpdir();
-
-	/* Test for xattr support */
-	fd = SAFE_CREAT(cleanup, "testfile", 0644);
-	close(fd);
-	if (setxattr("testfile", "user.test", "test", 4, XATTR_CREATE) == -1)
-		if (errno == ENOTSUP)
-			tst_brkm(TCONF, cleanup, "No xattr support in fs or "
-				 "mount without user_xattr option");
-
-	/* Create test file */
-	snprintf(filename, BUFSIZ, "setxattr01testfile");
-	fd = SAFE_CREAT(cleanup, filename, 0644);
-	close(fd);
-
-	/* Prepare test cases */
 	snprintf(long_key, 6, "%s", "user.");
 	memset(long_key + 5, 'k', XATTR_NAME_LEN - 5);
 	long_key[XATTR_NAME_LEN - 1] = '\0';
-	tc[2].key = long_key;
 
-	long_value = malloc(XATTR_SIZE_MAX + 2);
-	if (!long_value)
-		tst_brkm(TBROK | TERRNO, cleanup, "malloc failed");
+	long_value = SAFE_MALLOC(XATTR_SIZE_MAX + 2);
 	memset(long_value, 'v', XATTR_SIZE_MAX + 2);
 	long_value[XATTR_SIZE_MAX + 1] = '\0';
-	tc[3].value = long_value;
-
-	TEST_PAUSE;
 }
 
-static void cleanup(void)
-{
-	tst_rmdir();
-}
+static struct tst_test test = {
+	.setup = setup,
+	.test = verify_setxattr,
+	.tcnt = ARRAY_SIZE(tc),
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+};
+
 #else /* HAVE_SYS_XATTR_H */
-int main(int argc, char *argv[])
-{
-	tst_brkm(TCONF, NULL, "<sys/xattr.h> does not exist.");
-}
+TST_TEST_TCONF("<sys/xattr.h> does not exist");
 #endif
-- 
2.13.5


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

* [LTP] [PATCH v3 11/16] syscalls/setxattr01: Run test for all filesystems
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (8 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 10/16] syscalls/setxattr01: Convert to the new library Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 12/16] syscallse/setxattr02: Convert to the new library Cyril Hrubis
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/setxattr/setxattr01.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/testcases/kernel/syscalls/setxattr/setxattr01.c b/testcases/kernel/syscalls/setxattr/setxattr01.c
index 86df7ba73..4db56123a 100644
--- a/testcases/kernel/syscalls/setxattr/setxattr01.c
+++ b/testcases/kernel/syscalls/setxattr/setxattr01.c
@@ -66,7 +66,8 @@
 #define XATTR_TEST_KEY "user.testkey"
 #define XATTR_TEST_VALUE "this is a test value"
 #define XATTR_TEST_VALUE_SIZE 20
-#define FNAME "setxattr01testfile"
+#define MNTPOINT "mntpoint"
+#define FNAME MNTPOINT"/setxattr01testfile"
 
 static char long_key[XATTR_NAME_LEN];
 static char *long_value;
@@ -165,8 +166,6 @@ static void verify_setxattr(unsigned int i)
 
 static void setup(void)
 {
-	SAFE_TOUCH(FNAME, 0644, NULL);
-
 	snprintf(long_key, 6, "%s", "user.");
 	memset(long_key + 5, 'k', XATTR_NAME_LEN - 5);
 	long_key[XATTR_NAME_LEN - 1] = '\0';
@@ -174,12 +173,17 @@ static void setup(void)
 	long_value = SAFE_MALLOC(XATTR_SIZE_MAX + 2);
 	memset(long_value, 'v', XATTR_SIZE_MAX + 2);
 	long_value[XATTR_SIZE_MAX + 1] = '\0';
+
+	SAFE_TOUCH(FNAME, 0644, NULL);
 }
 
 static struct tst_test test = {
 	.setup = setup,
 	.test = verify_setxattr,
 	.tcnt = ARRAY_SIZE(tc),
+	.mntpoint = MNTPOINT,
+	.mount_device = 1,
+	.all_filesystems = 1,
 	.needs_tmpdir = 1,
 	.needs_root = 1,
 };
-- 
2.13.5


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

* [LTP] [PATCH v3 12/16] syscallse/setxattr02: Convert to the new library
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (9 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 11/16] syscalls/setxattr01: Run test for all filesystems Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 13/16] syscalls/fsync01: " Cyril Hrubis
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/setxattr/setxattr02.c | 120 ++++++++----------------
 1 file changed, 41 insertions(+), 79 deletions(-)

diff --git a/testcases/kernel/syscalls/setxattr/setxattr02.c b/testcases/kernel/syscalls/setxattr/setxattr02.c
index 6d39236a3..0b6ecb3fa 100644
--- a/testcases/kernel/syscalls/setxattr/setxattr02.c
+++ b/testcases/kernel/syscalls/setxattr/setxattr02.c
@@ -57,10 +57,7 @@
 #ifdef HAVE_SYS_XATTR_H
 # include <sys/xattr.h>
 #endif
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "setxattr02";
+#include "tst_test.h"
 
 #ifdef HAVE_SYS_XATTR_H
 #define XATTR_TEST_KEY "user.testkey"
@@ -75,9 +72,6 @@ char *TCID = "setxattr02";
 #define BLK      "setxattr02blk"
 #define SOCK     "setxattr02sock"
 
-static void setup(void);
-static void cleanup(void);
-
 struct test_case {
 	char *fname;
 	char *key;
@@ -145,91 +139,59 @@ static struct test_case tc[] = {
 	 },
 };
 
-int TST_TOTAL = sizeof(tc) / sizeof(tc[0]);
-
-int main(int argc, char *argv[])
+static void verify_setxattr(unsigned int i)
 {
-	int lc;
-	int i;
+	TEST(setxattr(tc[i].fname, tc[i].key, tc[i].value, tc[i].size, tc[i].flags));
 
-	tst_parse_opts(argc, argv, NULL, NULL);
+	if (TEST_RETURN == -1 && TEST_ERRNO == EOPNOTSUPP)
+		tst_brk(TCONF, "setxattr() not supported");
 
-	setup();
+	if (!tc[i].exp_err) {
+		if (TEST_RETURN) {
+			tst_res(TFAIL | TTERRNO,
+				"setxattr() failed with %li", TEST_RETURN);
+			return;
+		}
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
+		tst_res(TPASS, "setxattr() passed");
+		return;
+	}
 
-		for (i = 0; i < TST_TOTAL; i++) {
-			TEST(setxattr(tc[i].fname, tc[i].key, tc[i].value,
-				      tc[i].size, tc[i].flags));
+	if (TEST_RETURN == 0) {
+		tst_res(TFAIL, "setxattr() passed unexpectedly");
+		return;
+	}
 
-			if (TEST_ERRNO == tc[i].exp_err) {
-				tst_resm(TPASS | TTERRNO, "expected behavior");
-			} else {
-				tst_resm(TFAIL | TTERRNO, "unexpected behavior "
-					 "- expected errno %d - Got",
-					 tc[i].exp_err);
-			}
-		}
+	if (TEST_ERRNO != tc[i].exp_err) {
+		tst_res(TFAIL | TTERRNO, "setxattr() should fail with %s",
+			tst_strerrno(tc[i].exp_err));
+		return;
 	}
 
-	cleanup();
-	tst_exit();
+	tst_res(TPASS | TTERRNO, "setxattr() failed");
 }
 
 static void setup(void)
 {
-	int fd;
-	dev_t dev;
-
-	tst_require_root();
-
-	tst_tmpdir();
-
-	/* Test for xattr support */
-	fd = SAFE_CREAT(cleanup, "testfile", 0644);
-	close(fd);
-	if (setxattr("testfile", "user.test", "test", 4, XATTR_CREATE) == -1)
-		if (errno == ENOTSUP)
-			tst_brkm(TCONF, cleanup, "No xattr support in fs or "
-				 "mount without user_xattr option");
-	unlink("testfile");
-
-	/* Create test files */
-	fd = SAFE_CREAT(cleanup, FILENAME, 0644);
-	close(fd);
-
-	SAFE_MKDIR(cleanup, DIRNAME, 0644);
-
-	SAFE_SYMLINK(cleanup, FILENAME, SYMLINK);
-
-	if (mknod(FIFO, S_IFIFO | 0777, 0) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "Create FIFO(%s) failed",
-			 FIFO);
-
-	dev = makedev(1, 3);
-	if (mknod(CHR, S_IFCHR | 0777, dev) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "Create char special(%s)"
-			 " failed", CHR);
-
-	if (mknod(BLK, S_IFBLK | 0777, 0) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "Create block special(%s)"
-			 " failed", BLK);
-
-	if (mknod(SOCK, S_IFSOCK | 0777, 0) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "Create socket(%s) failed",
-			 SOCK);
-
-	TEST_PAUSE;
+	dev_t dev = makedev(1, 3);
+
+	SAFE_TOUCH(FILENAME, 0644, NULL);
+	SAFE_MKDIR(DIRNAME, 0644);
+	SAFE_SYMLINK(FILENAME, SYMLINK);
+	SAFE_MKNOD(FIFO, S_IFIFO | 0777, 0);
+	SAFE_MKNOD(CHR, S_IFCHR | 0777, dev);
+	SAFE_MKNOD(BLK, S_IFBLK | 0777, 0);
+	SAFE_MKNOD(SOCK, S_IFSOCK | 0777, 0);
 }
 
-static void cleanup(void)
-{
-	tst_rmdir();
-}
+static struct tst_test test = {
+	.setup = setup,
+	.test = verify_setxattr,
+	.tcnt = ARRAY_SIZE(tc),
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+};
+
 #else /* HAVE_SYS_XATTR_H */
-int main(int argc, char *argv[])
-{
-	tst_brkm(TCONF, NULL, "<sys/xattr.h> does not exist.");
-}
+TST_TEST_TCONF("<sys/xattr.h> does not exist");
 #endif
-- 
2.13.5


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

* [LTP] [PATCH v3 13/16] syscalls/fsync01: Convert to the new library.
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (10 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 12/16] syscallse/setxattr02: Convert to the new library Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 14/16] syscalls/fsync01: Run test for all filesystems Cyril Hrubis
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/fsync/fsync01.c | 157 +++++-------------------------
 1 file changed, 27 insertions(+), 130 deletions(-)

diff --git a/testcases/kernel/syscalls/fsync/fsync01.c b/testcases/kernel/syscalls/fsync/fsync01.c
index d7cc4f0a4..af35902bd 100644
--- a/testcases/kernel/syscalls/fsync/fsync01.c
+++ b/testcases/kernel/syscalls/fsync/fsync01.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ *    AUTHOR		: William Roske
+ *    CO-PILOT		: Dave Fenner
  *
  * 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
@@ -30,149 +32,44 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
  *
  */
-/* $Id: fsync01.c,v 1.6 2009/10/26 14:55:47 subrata_modak Exp $ */
-/**********************************************************
- *
- *    OS Test - Silicon Graphics, Inc.
- *
- *    TEST IDENTIFIER	: fsync01
- *
- *    EXECUTED BY	: anyone
- *
- *    TEST TITLE	: Basic test for fsync(2)
- *
- *    PARENT DOCUMENT	: usctpl01
- *
- *    TEST CASE TOTAL	: 1
- *
- *    WALL CLOCK TIME	: 1
- *
- *    CPU TYPES		: ALL
- *
- *    AUTHOR		: William Roske
- *
- *    CO-PILOT		: Dave Fenner
- *
- *    DATE STARTED	: 03/30/92
- *
- *    INITIAL RELEASE	: UNICOS 7.0
- *
- *    TEST CASES
- *
- * 	1.) fsync(2) returns...(See Description)
- *
- *    INPUT SPECIFICATIONS
- * 	The standard options for system call tests are accepted.
- *	(See the parse_opts(3) man page).
- *
- *    OUTPUT SPECIFICATIONS
- *$
- *    DURATION
- * 	Terminates - with frequency and infinite modes.
- *
- *    SIGNALS
- * 	Uses SIGUSR1 to pause before test if option set.
- * 	(See the parse_opts(3) man page).
- *
- *    RESOURCES
- * 	None
- *
- *    ENVIRONMENTAL NEEDS
- *      No run-time environmental needs.
- *
- *    SPECIAL PROCEDURAL REQUIREMENTS
- * 	None
- *
- *    INTERCASE DEPENDENCIES
- * 	None
- *
- *    DETAILED DESCRIPTION
- *	This is a Phase I test for the fsync(2) system call.  It is intended
- *	to provide a limited exposure of the system call, for now.  It
- *	should/will be extended when full functional tests are written for
- *	fsync(2).
- *
- * 	Setup:
- * 	  Setup signal handling.
- *	  Pause for SIGUSR1 if option specified.
- *
- * 	Test:
- *	 Loop if the proper options are given.
- * 	  Execute system call
- *	  Check return code, if system call failed (return=-1)
- *		Log the errno and Issue a FAIL message.
- *	  Otherwise, Issue a PASS message.
- *
- * 	Cleanup:
- * 	  Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
 
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
+#include <unistd.h>
 #include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-
-void setup();
-void cleanup();
+#include <stdio.h>
 
-char *TCID = "fsync01";
-int TST_TOTAL = 1;
+#include "tst_test.h"
 
-char fname[255];
-int fd;
-char *buf = "davef";
+static char fname[255];
+static int fd;
+#define BUF "davef"
 
-int main(int ac, char **av)
+static void verify_fsync(void)
 {
-	int lc;
-
-	tst_parse_opts(ac, av, NULL, NULL);
-
-	setup();
+	SAFE_WRITE(1, fd, BUF, sizeof(BUF));
 
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
+	TEST(fsync(fd));
 
-		tst_count = 0;
-
-		if (write(fd, buf, strlen(buf)) == -1)
-			tst_brkm(TBROK | TERRNO, cleanup, "write failed");
-		TEST(fsync(fd));
-
-		if (TEST_RETURN == -1)
-			tst_resm(TFAIL | TTERRNO, "fsync failed");
-		else
-			tst_resm(TPASS, "fsync returned %ld", TEST_RETURN);
-
-	}
-
-	cleanup();
-	tst_exit();
+	if (TEST_RETURN == -1)
+		tst_res(TFAIL | TTERRNO, "fsync failed");
+	else
+		tst_res(TPASS, "fsync() returned %ld", TEST_RETURN);
 }
 
-void setup(void)
+static void setup(void)
 {
-
-	tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
-	TEST_PAUSE;
-
-	tst_tmpdir();
-
 	sprintf(fname, "tfile_%d", getpid());
-	if ((fd = open(fname, O_RDWR | O_CREAT, 0700)) == -1)
-		tst_brkm(TBROK | TERRNO, cleanup, "open failed");
+	fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700);
 }
 
-void cleanup(void)
+static void cleanup(void)
 {
-	if (close(fd) == -1)
-		tst_resm(TWARN, "close failed");
-
-	tst_rmdir();
-
+	if (fd > 0)
+		SAFE_CLOSE(fd);
 }
+
+static struct tst_test test = {
+	.cleanup = cleanup,
+	.setup = setup,
+	.test_all = verify_fsync,
+	.needs_tmpdir = 1,
+};
-- 
2.13.5


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

* [LTP] [PATCH v3 14/16] syscalls/fsync01: Run test for all filesystems.
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (11 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 13/16] syscalls/fsync01: " Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-10-11 14:41 ` [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads Cyril Hrubis
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

+ do write() + fsync() 10 times

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 testcases/kernel/syscalls/fsync/fsync01.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/testcases/kernel/syscalls/fsync/fsync01.c b/testcases/kernel/syscalls/fsync/fsync01.c
index af35902bd..c93b131f2 100644
--- a/testcases/kernel/syscalls/fsync/fsync01.c
+++ b/testcases/kernel/syscalls/fsync/fsync01.c
@@ -45,19 +45,23 @@ static int fd;
 
 static void verify_fsync(void)
 {
-	SAFE_WRITE(1, fd, BUF, sizeof(BUF));
+	unsigned int i;
 
-	TEST(fsync(fd));
+	for (i = 0; i < 10; i++) {
+		SAFE_WRITE(1, fd, BUF, sizeof(BUF));
 
-	if (TEST_RETURN == -1)
-		tst_res(TFAIL | TTERRNO, "fsync failed");
-	else
-		tst_res(TPASS, "fsync() returned %ld", TEST_RETURN);
+		TEST(fsync(fd));
+
+		if (TEST_RETURN == -1)
+			tst_res(TFAIL | TTERRNO, "fsync failed");
+		else
+			tst_res(TPASS, "fsync() returned %ld", TEST_RETURN);
+	}
 }
 
 static void setup(void)
 {
-	sprintf(fname, "tfile_%d", getpid());
+	sprintf(fname, "mntpoint/tfile_%d", getpid());
 	fd = SAFE_OPEN(fname, O_RDWR | O_CREAT, 0700);
 }
 
@@ -72,4 +76,8 @@ static struct tst_test test = {
 	.setup = setup,
 	.test_all = verify_fsync,
 	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.mount_device = 1,
+	.mntpoint = "mntpoint",
+	.all_filesystems = 1,
 };
-- 
2.13.5


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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (12 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 14/16] syscalls/fsync01: Run test for all filesystems Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-11-09 10:03   ` Li Wang
  2017-10-11 14:41 ` [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines Cyril Hrubis
  2017-11-01 12:24 ` [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
  15 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Runs CPU+2 threads that write into FS until they got ENOSPC, then delete
a file and continue.

Older exfat fails with EIO instead of ENOSPC, it has been fixed in:

commit ca112f07b115a419250b6526e71345dcd29e4d67
Author: relan <relan@users.noreply.github.com>
Date:   Tue Dec 27 17:22:12 2016 +0300

    Propagate ENOSPC on write.

at:

https://github.com/relan/exfat/

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/fs                             |   2 +
 testcases/kernel/fs/fs_fill/.gitignore |   1 +
 testcases/kernel/fs/fs_fill/Makefile   |  22 ++++++
 testcases/kernel/fs/fs_fill/fs_fill.c  | 122 +++++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 testcases/kernel/fs/fs_fill/.gitignore
 create mode 100644 testcases/kernel/fs/fs_fill/Makefile
 create mode 100644 testcases/kernel/fs/fs_fill/fs_fill.c

diff --git a/runtest/fs b/runtest/fs
index 33a8412fd..3fa210a9f 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -76,3 +76,5 @@ fs_racer fs_racer.sh -t 5
 quota_remount_test01 quota_remount_test01.sh
 
 isofs isofs.sh
+
+fs_fill fs_fill
diff --git a/testcases/kernel/fs/fs_fill/.gitignore b/testcases/kernel/fs/fs_fill/.gitignore
new file mode 100644
index 000000000..ebdfb439f
--- /dev/null
+++ b/testcases/kernel/fs/fs_fill/.gitignore
@@ -0,0 +1 @@
+fs_fill
diff --git a/testcases/kernel/fs/fs_fill/Makefile b/testcases/kernel/fs/fs_fill/Makefile
new file mode 100644
index 000000000..f0e092b13
--- /dev/null
+++ b/testcases/kernel/fs/fs_fill/Makefile
@@ -0,0 +1,22 @@
+# Copyright (c) 2017 Linux Test Project
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# 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.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+top_srcdir              ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+CFLAGS += -pthread
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/fs_fill/fs_fill.c b/testcases/kernel/fs/fs_fill/fs_fill.c
new file mode 100644
index 000000000..a50a22fd2
--- /dev/null
+++ b/testcases/kernel/fs/fs_fill/fs_fill.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Runs several threads that fills up the filesystem repeatedly.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include "tst_safe_pthread.h"
+#include "tst_test.h"
+
+#define MNTPOINT "mntpoint"
+
+static volatile int run;
+static unsigned int nthreads;
+static int enospc_cnt;
+
+struct worker {
+	char dir[PATH_MAX];
+};
+
+static void *worker(void *p)
+{
+	struct worker *w = p;
+	DIR *d;
+	struct dirent *ent;
+	char file[PATH_MAX];
+
+	SAFE_MKDIR(w->dir, 0700);
+
+	while (run) {
+		tst_fill_fs(w->dir, 0);
+
+		tst_atomic_inc(&enospc_cnt);
+
+		d = SAFE_OPENDIR(w->dir);
+		while ((ent = SAFE_READDIR(d))) {
+
+			if (!strcmp(ent->d_name, ".") ||
+			    !strcmp(ent->d_name, ".."))
+				continue;
+
+			snprintf(file, sizeof(file), "%s/%s",
+				 w->dir, ent->d_name);
+
+			tst_res(TINFO, "Unlinking %s", file);
+
+			SAFE_UNLINK(file);
+			break;
+		}
+		SAFE_CLOSEDIR(d);
+	}
+
+	return NULL;
+}
+
+static void testrun(void)
+{
+	struct worker workers[nthreads];
+	pthread_t threads[nthreads];
+	unsigned int i, ms;
+
+	run = 1;
+	for (i = 0; i < nthreads; i++) {
+		snprintf(workers[i].dir, sizeof(workers[i].dir),
+			 MNTPOINT "/thread%i", i + 1);
+		SAFE_PTHREAD_CREATE(&threads[i], NULL, worker, &workers[i]);
+	}
+
+	for (ms = 0; ; ms++) {
+		usleep(1000);
+
+		if (ms >= 1000 && enospc_cnt)
+			break;
+
+		if (enospc_cnt > 100)
+			break;
+	}
+
+	run = 0;
+	for (i = 0; i < nthreads; i++)
+		SAFE_PTHREAD_JOIN(threads[i], NULL);
+
+	tst_res(TPASS, "Got %i ENOSPC runtime %ims", enospc_cnt, ms);
+}
+
+static void setup(void)
+{
+	nthreads = tst_ncpus_conf() + 2;
+
+	tst_res(TINFO, "Running %i writer threads", nthreads);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.all_filesystems = 1,
+	.setup = setup,
+	.test_all = testrun,
+};
-- 
2.13.5


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

* [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (13 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads Cyril Hrubis
@ 2017-10-11 14:41 ` Cyril Hrubis
  2017-11-09 18:51   ` Sandeep Patil
  2017-11-01 12:24 ` [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
  15 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-10-11 14:41 UTC (permalink / raw)
  To: ltp

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 doc/test-writing-guidelines.txt | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
index 15d418954..133cb9372 100644
--- a/doc/test-writing-guidelines.txt
+++ b/doc/test-writing-guidelines.txt
@@ -914,12 +914,27 @@ then.
 If '.format_device' flag is set the device is formatted with a filesystem as
 well. You can use '.dev_fs_type' to override the default filesystem type if
 needed and pass additional options to mkfs via '.dev_fs_opts' and
-'.dev_extra_opt' pointers.
+'.dev_extra_opt' pointers. Note that '.format_device' implies '.needs_device'
+there is no need to set both.
 
 If '.mount_device' is set, the device is mounted at '.mntpoint' which is used
 to pass a directory name that will be created and used as mount destination.
 You can pass additional flags and data to the mount command via '.mnt_flags'
-and '.mnt_data' pointers.
+and '.mnt_data' pointers. Note that '.mount_device' implies '.needs_device'
+and '.format_device' so there is no need to set the later two.
+
+If '.needs_rofs' is set, read-only filesystem is mounted at '.mntpoint' this
+one is supposed to be used for 'EROFS' tests.
+
+If '.all_filesystems' is set the test function is executed for all supported
+filesystems. Supported filesystems are detected based on existence of the
+'mkfs.$fs' helper and on kernel support to mount it. For each supported
+filesystem the 'tst_device.fs_type' is set to the currently tested fs type, if
+'.format_device' is set the device is formatted as well, if '.mount_device' is
+set it's mounted at '.mntpoint'. Also the test timeout is reset for each
+execution of the test fuction. This flag is expected to be used for filesystem
+related syscalls that are at least partly implemented in the filesystem
+specific code e.g. fallocate().
 
 [source,c]
 -------------------------------------------------------------------------------
-- 
2.13.5


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

* [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device
  2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
                   ` (14 preceding siblings ...)
  2017-10-11 14:41 ` [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines Cyril Hrubis
@ 2017-11-01 12:24 ` Cyril Hrubis
  2017-11-02  9:26   ` Jan Stancek
  15 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-11-01 12:24 UTC (permalink / raw)
  To: ltp

Hi!
Ping?

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device
  2017-11-01 12:24 ` [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
@ 2017-11-02  9:26   ` Jan Stancek
  2017-11-02 13:15     ` Cyril Hrubis
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Stancek @ 2017-11-02  9:26 UTC (permalink / raw)
  To: ltp


----- Original Message -----
> Hi!
> Ping?

Hi,

The only changes against v2 are in last 2 patches we discussed,
so no objections from me.

Regards,
Jan

> 
> --
> Cyril Hrubis
> chrubis@suse.cz
> 
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
> 

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

* [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device
  2017-11-02  9:26   ` Jan Stancek
@ 2017-11-02 13:15     ` Cyril Hrubis
  0 siblings, 0 replies; 27+ messages in thread
From: Cyril Hrubis @ 2017-11-02 13:15 UTC (permalink / raw)
  To: ltp

Hi!
> The only changes against v2 are in last 2 patches we discussed,
> so no objections from me.

Rebased and pushed, thanks for the review.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-10-11 14:41 ` [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads Cyril Hrubis
@ 2017-11-09 10:03   ` Li Wang
  2017-11-09 10:19     ` Cyril Hrubis
  0 siblings, 1 reply; 27+ messages in thread
From: Li Wang @ 2017-11-09 10:03 UTC (permalink / raw)
  To: ltp

Hi Cyril,

This case always broken in SAFE_* operations, seems the reason is no
space left on the device,
so I wonder if is it necessary to create so many thread "CPUs + 2" to
run the test?

What about just creating half of CPU number thread (nthreads =
tst_ncpus_conf()/2 + 1) there?

$ git diff
diff --git a/testcases/kernel/fs/fs_fill/fs_fill.c
b/testcases/kernel/fs/fs_fill/fs_fill.c
index a50a22f..13207c4 100644
--- a/testcases/kernel/fs/fs_fill/fs_fill.c
+++ b/testcases/kernel/fs/fs_fill/fs_fill.c
@@ -106,7 +106,7 @@ static void testrun(void)

 static void setup(void)
 {
-       nthreads = tst_ncpus_conf() + 2;
+       nthreads = tst_ncpus_conf()/2 + 1;

        tst_res(TINFO, "Running %i writer threads", nthreads);
 }


Broken message:
==============
fs_fill.c:104: PASS: Got 73 ENOSPC runtime 1000ms
tst_mkfs.c:83: INFO: Formatting /dev/loop1 with xfs opts='' extra opts=''
tst_test.c:970: INFO: Timeout per run is 0h 05m 00s
fs_fill.c:111: INFO: Running 66 writer threads
safe_macros.c:225: BROK: tst_fill_fs.c:43:
open(mntpoint/thread48/file0,65,0700) failed: ENOSPC



-- 
Li Wang
liwang@redhat.com

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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-11-09 10:03   ` Li Wang
@ 2017-11-09 10:19     ` Cyril Hrubis
  2017-11-09 10:43       ` Li Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-11-09 10:19 UTC (permalink / raw)
  To: ltp

Hi!
> This case always broken in SAFE_* operations, seems the reason is no
> space left on the device,
> so I wonder if is it necessary to create so many thread "CPUs + 2" to
> run the test?
> 
> What about just creating half of CPU number thread (nthreads =
> tst_ncpus_conf()/2 + 1) there?
> 
> $ git diff
> diff --git a/testcases/kernel/fs/fs_fill/fs_fill.c
> b/testcases/kernel/fs/fs_fill/fs_fill.c
> index a50a22f..13207c4 100644
> --- a/testcases/kernel/fs/fs_fill/fs_fill.c
> +++ b/testcases/kernel/fs/fs_fill/fs_fill.c
> @@ -106,7 +106,7 @@ static void testrun(void)
> 
>  static void setup(void)
>  {
> -       nthreads = tst_ncpus_conf() + 2;
> +       nthreads = tst_ncpus_conf()/2 + 1;
> 
>         tst_res(TINFO, "Running %i writer threads", nthreads);
>  }

This does not fix the problem, only makes it less likely.

The correct fix is to use open() instead of SAFE_OPEN() in the
tst_fill_fs() and just return from the function when we get ENOSPC. I
can fix that, or you can send the patch. Either way thanks for pointing
out the mistake.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-11-09 10:19     ` Cyril Hrubis
@ 2017-11-09 10:43       ` Li Wang
  2017-11-09 10:50         ` Cyril Hrubis
  0 siblings, 1 reply; 27+ messages in thread
From: Li Wang @ 2017-11-09 10:43 UTC (permalink / raw)
  To: ltp

On Thu, Nov 9, 2017 at 6:19 PM, Cyril Hrubis <chrubis@suse.cz> wrote:
> Hi!
>> This case always broken in SAFE_* operations, seems the reason is no
>> space left on the device,
>> so I wonder if is it necessary to create so many thread "CPUs + 2" to
>> run the test?
>>
>> What about just creating half of CPU number thread (nthreads =
>> tst_ncpus_conf()/2 + 1) there?
>>
>> $ git diff
>> diff --git a/testcases/kernel/fs/fs_fill/fs_fill.c
>> b/testcases/kernel/fs/fs_fill/fs_fill.c
>> index a50a22f..13207c4 100644
>> --- a/testcases/kernel/fs/fs_fill/fs_fill.c
>> +++ b/testcases/kernel/fs/fs_fill/fs_fill.c
>> @@ -106,7 +106,7 @@ static void testrun(void)
>>
>>  static void setup(void)
>>  {
>> -       nthreads = tst_ncpus_conf() + 2;
>> +       nthreads = tst_ncpus_conf()/2 + 1;
>>
>>         tst_res(TINFO, "Running %i writer threads", nthreads);
>>  }
>
> This does not fix the problem, only makes it less likely.

Actually yes. Retest and failed again.

>
> The correct fix is to use open() instead of SAFE_OPEN() in the
> tst_fill_fs() and just return from the function when we get ENOSPC. I
> can fix that, or you can send the patch. Either way thanks for pointing
> out the mistake.

The broken are not only in tst_fills_fs() function but also come from
SAFE_MKDIR(w->dir, 0700),
SAFE_OPENDIR(w->dir) and SAFE_UNLINK(file).

   safe_macros.c:169: BROK: fs_fill.c:49:
mkdir(mntpoint/thread21,0700) failed: ENOSPC

If we just handle the 'ENOSPC' in tst_fill_fs(), I doubt that test
will be broken as well.


-- 
Li Wang
liwang@redhat.com

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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-11-09 10:43       ` Li Wang
@ 2017-11-09 10:50         ` Cyril Hrubis
  2017-11-09 10:58           ` Li Wang
  0 siblings, 1 reply; 27+ messages in thread
From: Cyril Hrubis @ 2017-11-09 10:50 UTC (permalink / raw)
  To: ltp

Hi!
> > The correct fix is to use open() instead of SAFE_OPEN() in the
> > tst_fill_fs() and just return from the function when we get ENOSPC. I
> > can fix that, or you can send the patch. Either way thanks for pointing
> > out the mistake.
> 
> The broken are not only in tst_fills_fs() function but also come from
> SAFE_MKDIR(w->dir, 0700),

Ok, we have to create the directories in the testrun() function before
we attempt to run the threads, that should fix this particular problem.

> SAFE_OPENDIR(w->dir) and SAFE_UNLINK(file).

The opendir() should not fail with ENOSPC since that only reads the
directory content.

And the unlink() should not fail with ENOSPC as well. Since unlink()
actually deletes a file, if that breaks because filesystem is full
you lost since you cannot free any space by removing files...

So fixing the tst_fill_fs() and doing the mkdir() before we start these
threads should IMHO fix the test.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads
  2017-11-09 10:50         ` Cyril Hrubis
@ 2017-11-09 10:58           ` Li Wang
  0 siblings, 0 replies; 27+ messages in thread
From: Li Wang @ 2017-11-09 10:58 UTC (permalink / raw)
  To: ltp

On Thu, Nov 9, 2017 at 6:50 PM, Cyril Hrubis <chrubis@suse.cz> wrote:
> Hi!
>> > The correct fix is to use open() instead of SAFE_OPEN() in the
>> > tst_fill_fs() and just return from the function when we get ENOSPC. I
>> > can fix that, or you can send the patch. Either way thanks for pointing
>> > out the mistake.
>>
>> The broken are not only in tst_fills_fs() function but also come from
>> SAFE_MKDIR(w->dir, 0700),
>
> Ok, we have to create the directories in the testrun() function before
> we attempt to run the threads, that should fix this particular problem.
>
>> SAFE_OPENDIR(w->dir) and SAFE_UNLINK(file).
>
> The opendir() should not fail with ENOSPC since that only reads the
> directory content.
>
> And the unlink() should not fail with ENOSPC as well. Since unlink()
> actually deletes a file, if that breaks because filesystem is full
> you lost since you cannot free any space by removing files...
>
> So fixing the tst_fill_fs() and doing the mkdir() before we start these
> threads should IMHO fix the test.

OK, Thanks for your analysis. Let me try to fix the mistake and test
on my system.

Will send a new patch if I can confirm the issue being fully fixed like this.


-- 
Li Wang
liwang@redhat.com

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

* [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems
  2017-10-11 14:41 ` [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems Cyril Hrubis
@ 2017-11-09 18:38   ` Sandeep Patil
  0 siblings, 0 replies; 27+ messages in thread
From: Sandeep Patil @ 2017-11-09 18:38 UTC (permalink / raw)
  To: ltp

On Wed, Oct 11, 2017 at 04:41:16PM +0200, Cyril Hrubis wrote:
> A filesystem is supported if kernel can mount it (we do not get ENODEV
> when we attempt to mount it) and if there is mkfs installed so that we
> can format a test device.
> 
> The function starts with a whitelist of filesystems to use and loops
> over them filtering out unsupported ones, then finally returns a list
> of filesystem that could be used for the testing.
> 
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>  include/tst_fs.h             |   4 ++
>  lib/tst_supported_fs_types.c | 118 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 122 insertions(+)
>  create mode 100644 lib/tst_supported_fs_types.c
> 
> diff --git a/include/tst_fs.h b/include/tst_fs.h
> index 52befbec9..1f6d2bab5 100644
> --- a/include/tst_fs.h
> +++ b/include/tst_fs.h
> @@ -146,6 +146,10 @@ int tst_get_path(const char *prog_name, char *buf, size_t buf_len);
>   */
>  int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
>  
> +/*
> + * Returns NULL-terminated array of kernel-supported filesystems.
> + */
> +const char **tst_get_supported_fs_types(void);
>  
>  #ifdef TST_TEST_H__
>  static inline long tst_fs_type(const char *path)
> diff --git a/lib/tst_supported_fs_types.c b/lib/tst_supported_fs_types.c
> new file mode 100644
> index 000000000..a23b1ed52
> --- /dev/null
> +++ b/lib/tst_supported_fs_types.c
> @@ -0,0 +1,118 @@
> +/*
> + * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/mount.h>
> +#include <sys/wait.h>
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_fs.h"
> +
> +static const char *const fs_type_whitelist[] = {
> +	"ext2",
> +	"ext3",
> +	"ext4",
> +	"xfs",
> +	"btrfs",
> +	"vfat",
> +	"exfat",
> +	"ntfs",
> +	NULL
> +};
> +
> +static const char *fs_types[ARRAY_SIZE(fs_type_whitelist)];
> +
> +static int has_mkfs(const char *fs_type)
> +{
> +	char buf[128];
> +	int ret;
> +
> +	sprintf(buf, "mkfs.%s >/dev/null 2>&1", fs_type);
> +
> +	ret = tst_system(buf);
> +
> +	if (WEXITSTATUS(ret) == 127) {
> +		tst_res(TINFO, "mkfs.%s does not exist", fs_type);
> +		return 0;
> +	}
> +
> +	tst_res(TINFO, "mkfs.%s does exist", fs_type);
> +	return 1;
> +}
> +
> +static int has_kernel_support(const char *fs_type)
> +{
> +	static int fuse_supported = -1;
> +	const char *tmpdir = getenv("TMPDIR");
> +	char buf[128];
> +	int ret;
> +
> +	if (!tmpdir)
> +		tmpdir = "/tmp";
> +
> +	mount("/dev/zero", tmpdir, fs_type, 0, NULL);
> +	if (errno != ENODEV) {
> +		tst_res(TINFO, "Kernel supports %s", fs_type);
> +		return 1;
> +	}
> +
> +	/* Is FUSE supported by kernel? */
> +	if (fuse_supported == -1) {
> +		ret = open("/dev/fuse", O_RDWR);
> +		if (ret < 0) {
> +			fuse_supported = 0;
> +		} else {
> +			fuse_supported = 1;
> +			SAFE_CLOSE(ret);
> +		}
> +	}
> +
> +	if (!fuse_supported)
> +		return 0;
> +
> +	/* Is FUSE implementation installed? */
> +	sprintf(buf, "mount.%s >/dev/null 2>&1", fs_type);
> +
> +	ret = tst_system(buf);
> +	if (WEXITSTATUS(ret) == 127) {
> +		tst_res(TINFO, "Filesystem %s is not supported", fs_type);
> +		return 0;
> +	}
> +
> +	tst_res(TINFO, "FUSE does support %s", fs_type);
> +	return 1;
> +}
> +
> +static int is_supported(const char *fs_type)
> +{
> +	return has_kernel_support(fs_type) && has_mkfs(fs_type);
> +}

It will be nice if this was an exported API as well.

Other than that, this is very useful for a bunch of tests
that rely on formatting + mounting devices for error checks.

Acked-by: Sandeep Patil <sspatil@google.com>

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

* [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs()
  2017-10-11 14:41 ` [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs() Cyril Hrubis
@ 2017-11-09 18:50   ` Sandeep Patil
  0 siblings, 0 replies; 27+ messages in thread
From: Sandeep Patil @ 2017-11-09 18:50 UTC (permalink / raw)
  To: ltp

On Wed, Oct 11, 2017 at 04:41:19PM +0200, Cyril Hrubis wrote:
> Adds a simple helper to fill a filesystem.
> 
> All the funciton does is to create and write to files in a given

s/funciton/function

> directory until write() fails with ENOSPC.
> 
> This is intended to be used in various filesystem related tests such as
> fallocate and stress tests.

Couple of other use cases
 - To fill a filesystem would be to create nested directories for EMLINK
   testing in order to test file system limit(s) (e.g. syscalls/mkdir)
 - Filling a filesystem with empty files (e.g syscalls/rename etc )

 That said, the function can be expanded to do this at a later time as well
 based on the function parameters.


> 
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>  include/tst_fs.h  |  5 +++++
>  lib/tst_fill_fs.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 68 insertions(+)
>  create mode 100644 lib/tst_fill_fs.c
> 
> diff --git a/include/tst_fs.h b/include/tst_fs.h
> index 1f6d2bab5..0ad535c2b 100644
> --- a/include/tst_fs.h
> +++ b/include/tst_fs.h
> @@ -151,6 +151,11 @@ int tst_fill_file(const char *path, char pattern, size_t bs, size_t bcount);
>   */
>  const char **tst_get_supported_fs_types(void);
>  
> +/*
> + * Creates and writes to files on given path until write fails with ENOSPC
> + */
> +void tst_fill_fs(const char *path, int verbose);
> +
>  #ifdef TST_TEST_H__
>  static inline long tst_fs_type(const char *path)
>  {
> diff --git a/lib/tst_fill_fs.c b/lib/tst_fill_fs.c
> new file mode 100644
> index 000000000..6b2bbbcd7
> --- /dev/null
> +++ b/lib/tst_fill_fs.c
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_fs.h"
> +
> +void tst_fill_fs(const char *path, int verbose)
> +{
> +	int i = 0;
> +	char file[PATH_MAX];
> +	char buf[4096];
> +	size_t len;
> +	ssize_t ret;
> +	int fd;
> +
> +	for (;;) {
> +		len = random() % (1024 * 102400);
> +
> +		snprintf(file, sizeof(file), "%s/file%i", path, i++);
> +
> +		if (verbose)
> +			tst_res(TINFO, "Creating file %s size %zu", file, len);
> +
> +		fd = SAFE_OPEN(file, O_WRONLY | O_CREAT, 0700);
> +
> +		while (len) {
> +			ret = write(fd, buf, MIN(len, sizeof(buf)));
> +
> +			if (ret < 0) {
> +				SAFE_CLOSE(fd);
> +
> +				if (errno != ENOSPC)
> +					tst_brk(TBROK | TERRNO, "write()");
> +
> +				tst_res(TINFO | TERRNO, "write()");
> +				return;
> +			}
> +
> +			len -= ret;
> +		}
> +
> +		SAFE_CLOSE(fd);
> +	}
> +}

Reviewed-by: Sandeep Patil <sspatil@google.com>

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

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

* [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines
  2017-10-11 14:41 ` [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines Cyril Hrubis
@ 2017-11-09 18:51   ` Sandeep Patil
  0 siblings, 0 replies; 27+ messages in thread
From: Sandeep Patil @ 2017-11-09 18:51 UTC (permalink / raw)
  To: ltp

On Wed, Oct 11, 2017 at 04:41:30PM +0200, Cyril Hrubis wrote:
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>  doc/test-writing-guidelines.txt | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/test-writing-guidelines.txt b/doc/test-writing-guidelines.txt
> index 15d418954..133cb9372 100644
> --- a/doc/test-writing-guidelines.txt
> +++ b/doc/test-writing-guidelines.txt
> @@ -914,12 +914,27 @@ then.
>  If '.format_device' flag is set the device is formatted with a filesystem as
>  well. You can use '.dev_fs_type' to override the default filesystem type if
>  needed and pass additional options to mkfs via '.dev_fs_opts' and
> -'.dev_extra_opt' pointers.
> +'.dev_extra_opt' pointers. Note that '.format_device' implies '.needs_device'
> +there is no need to set both.
>  
>  If '.mount_device' is set, the device is mounted at '.mntpoint' which is used
>  to pass a directory name that will be created and used as mount destination.
>  You can pass additional flags and data to the mount command via '.mnt_flags'
> -and '.mnt_data' pointers.
> +and '.mnt_data' pointers. Note that '.mount_device' implies '.needs_device'
> +and '.format_device' so there is no need to set the later two.
> +
> +If '.needs_rofs' is set, read-only filesystem is mounted at '.mntpoint' this
> +one is supposed to be used for 'EROFS' tests.

I probably should have done this with the patches. :(

<snip>

Acked-by: Sandeep Patil <sspatil@google.com>

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

end of thread, other threads:[~2017-11-09 18:51 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11 14:41 [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 02/16] lib: Add interface to list supported filesystems Cyril Hrubis
2017-11-09 18:38   ` Sandeep Patil
2017-10-11 14:41 ` [LTP] [PATCH v3 03/16] SAFE_MOUNT: Handle FUSE mounts as well Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 04/16] lib/tst_test: Add .all_filesystems flag Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 05/16] lib/tst_fs: Add tst_fill_fs() Cyril Hrubis
2017-11-09 18:50   ` Sandeep Patil
2017-10-11 14:41 ` [LTP] [PATCH v3 06/16] syscalls/fallocate05: New test Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 07/16] syscalls/msync04: Run test for all filesystems Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 08/16] syscalls/fallocate04: Convert to the new library Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 09/16] syscalls/fallocate04: Run test for all filesystems Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 10/16] syscalls/setxattr01: Convert to the new library Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 11/16] syscalls/setxattr01: Run test for all filesystems Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 12/16] syscallse/setxattr02: Convert to the new library Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 13/16] syscalls/fsync01: " Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 14/16] syscalls/fsync01: Run test for all filesystems Cyril Hrubis
2017-10-11 14:41 ` [LTP] [PATCH v3 15/16] fs/fs_fill: Add a test to fill a FS in a few threads Cyril Hrubis
2017-11-09 10:03   ` Li Wang
2017-11-09 10:19     ` Cyril Hrubis
2017-11-09 10:43       ` Li Wang
2017-11-09 10:50         ` Cyril Hrubis
2017-11-09 10:58           ` Li Wang
2017-10-11 14:41 ` [LTP] [PATCH v3 16/16] doc: Update device flags in test-writing-guidelines Cyril Hrubis
2017-11-09 18:51   ` Sandeep Patil
2017-11-01 12:24 ` [LTP] [PATCH v3 01/16] lib/tst_mkfs: Clear first 512k of the device Cyril Hrubis
2017-11-02  9:26   ` Jan Stancek
2017-11-02 13:15     ` Cyril Hrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.