All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests
@ 2016-01-29 12:05 Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 1/5] lib/tst_dir_is_empty: add a library function Alexey Kodanev
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

v3:
* squash last patch into the previous,
* open: make use of SAFE_OPEN during the test,
* openat: add tst_openat_tmp(int mode),
* remove test_dir, use ".",
* use tst_brkm(TFAIL, ...) for test assertions,
* strncmp() -> memcpy(),
* more verbose test-case's TPASS message.

v2:
* move dir_not_empty() -> tst_dir_is_empty() to a library,
* add SAFE_LINKAT, SAFE_READLINK macros,
* move O_TMPFILE definition to lapi/fcntl.h
* use relative path for test_dir,
* enable len_strict in SAFE_WRITE,
* set constant buffer size.

Alexey Kodanev (5):
  lib/tst_dir_is_empty: add a library function
  include/lapi/fcntl.h: add O_TMPFILE definition
  lib/safe_macros: add linkat()
  lib/safe_macros: add readlink()
  kernel/syscalls: add new test with 'open() + O_TMPFILE'

 include/lapi/fcntl.h                        |    4 +
 include/safe_macros.h                       |   13 ++
 include/test.h                              |    8 +
 lib/safe_macros.c                           |   35 ++++
 lib/tst_dir_is_empty.c                      |   49 +++++
 runtest/syscalls                            |    2 +
 testcases/kernel/syscalls/.gitignore        |    2 +
 testcases/kernel/syscalls/open/open14.c     |  253 ++++++++++++++++++++++++++
 testcases/kernel/syscalls/openat/openat03.c |  263 +++++++++++++++++++++++++++
 9 files changed, 629 insertions(+), 0 deletions(-)
 create mode 100644 lib/tst_dir_is_empty.c
 create mode 100644 testcases/kernel/syscalls/open/open14.c
 create mode 100644 testcases/kernel/syscalls/openat/openat03.c


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

* [LTP] [PATCH v3 1/5] lib/tst_dir_is_empty: add a library function
  2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
@ 2016-01-29 12:05 ` Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 2/5] include/lapi/fcntl.h: add O_TMPFILE definition Alexey Kodanev
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

Checks if a given directory is empty.

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 include/test.h         |    8 +++++++
 lib/tst_dir_is_empty.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 lib/tst_dir_is_empty.c

diff --git a/include/test.h b/include/test.h
index fc07dae..c364b75 100644
--- a/include/test.h
+++ b/include/test.h
@@ -441,6 +441,14 @@ int tst_fs_fill_hardlinks(void (*cleanup) (void), const char *dir);
 int tst_fs_fill_subdirs(void (*cleanup) (void), const char *dir);
 
 /*
+ * lib/tst_dir_is_empty.c
+ *
+ * Checks if a given directory contains any entities,
+ * returns 1 if directory is empty, 0 otherwise
+ */
+int tst_dir_is_empty(void (*cleanup) (void), const char *name, int verbose);
+
+/*
  * lib/tst_pid.c
  *
  * Get a pid value not used by the OS
diff --git a/lib/tst_dir_is_empty.c b/lib/tst_dir_is_empty.c
new file mode 100644
index 0000000..75df50d
--- /dev/null
+++ b/lib/tst_dir_is_empty.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * 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/>.
+ *
+ * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
+ *
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include "test.h"
+#include "safe_macros.h"
+
+int tst_dir_is_empty(void (cleanup_fn)(void), const char *name, int verbose)
+{
+	struct dirent *entry;
+	DIR *dir = SAFE_OPENDIR(cleanup_fn, name);
+	int ret = 1;
+
+	while ((entry = SAFE_READDIR(cleanup_fn, dir)) != NULL) {
+		const char *file = entry->d_name;
+
+		if (!strcmp(file, "..") || !strcmp(file, "."))
+			continue;
+
+		if (verbose)
+			tst_resm(TINFO, "found a file: %s", file);
+		ret = 0;
+		break;
+	}
+
+	SAFE_CLOSEDIR(cleanup_fn, dir);
+
+	return ret;
+}
-- 
1.7.1


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

* [LTP] [PATCH v3 2/5] include/lapi/fcntl.h: add O_TMPFILE definition
  2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 1/5] lib/tst_dir_is_empty: add a library function Alexey Kodanev
@ 2016-01-29 12:05 ` Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 3/5] lib/safe_macros: add linkat() Alexey Kodanev
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 include/lapi/fcntl.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/lapi/fcntl.h b/include/lapi/fcntl.h
index d0bb713..1ea3fb4 100644
--- a/include/lapi/fcntl.h
+++ b/include/lapi/fcntl.h
@@ -23,6 +23,10 @@
 # define O_CLOEXEC 02000000
 #endif
 
+#ifndef O_TMPFILE
+# define O_TMPFILE (020000000 | O_DIRECTORY)
+#endif
+
 #ifndef F_DUPFD_CLOEXEC
 # define F_DUPFD_CLOEXEC 1030
 #endif
-- 
1.7.1


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

* [LTP] [PATCH v3 3/5] lib/safe_macros: add linkat()
  2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 1/5] lib/tst_dir_is_empty: add a library function Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 2/5] include/lapi/fcntl.h: add O_TMPFILE definition Alexey Kodanev
@ 2016-01-29 12:05 ` Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 4/5] lib/safe_macros: add readlink() Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE' Alexey Kodanev
  4 siblings, 0 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 include/safe_macros.h |    7 +++++++
 lib/safe_macros.c     |   18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/include/safe_macros.h b/include/safe_macros.h
index ab09699..e4041d4 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -157,6 +157,13 @@ int	safe_link(const char *file, const int lineno,
 #define SAFE_LINK(cleanup_fn, oldpath, newpath) \
         safe_link(__FILE__, __LINE__, cleanup_fn, (oldpath), (newpath))
 
+int	safe_linkat(const char *file, const int lineno,
+		    void (cleanup_fn)(void), int olddirfd, const char *oldpath,
+		    int newdirfd, const char *newpath, int flags);
+#define SAFE_LINKAT(cleanup_fn, olddirfd, oldpath, newdirfd, newpath, flags) \
+	safe_linkat(__FILE__, __LINE__, cleanup_fn, (olddirfd), (oldpath), \
+		    (newdirfd), (newpath), (flags))
+
 int	safe_symlink(const char *file, const int lineno,
                      void (cleanup_fn)(void), const char *oldpath,
                      const char *newpath);
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 173d72f..9fa6ac4 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -391,6 +391,24 @@ int safe_link(const char *file, const int lineno,
 	return rval;
 }
 
+int safe_linkat(const char *file, const int lineno,
+		void (cleanup_fn)(void), int olddirfd, const char *oldpath,
+		int newdirfd, const char *newpath, int flags)
+{
+	int rval;
+
+	rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
+
+	if (rval == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup_fn,
+			 "%s:%d: linkat(%d,%s,%d,%s,%d) failed",
+			 file, lineno, olddirfd, oldpath, newdirfd,
+			 newpath, flags);
+	}
+
+	return rval;
+}
+
 int safe_symlink(const char *file, const int lineno,
                  void (cleanup_fn)(void), const char *oldpath,
                  const char *newpath)
-- 
1.7.1


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

* [LTP] [PATCH v3 4/5] lib/safe_macros: add readlink()
  2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
                   ` (2 preceding siblings ...)
  2016-01-29 12:05 ` [LTP] [PATCH v3 3/5] lib/safe_macros: add linkat() Alexey Kodanev
@ 2016-01-29 12:05 ` Alexey Kodanev
  2016-01-29 12:05 ` [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE' Alexey Kodanev
  4 siblings, 0 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 include/safe_macros.h |    6 ++++++
 lib/safe_macros.c     |   17 +++++++++++++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/include/safe_macros.h b/include/safe_macros.h
index e4041d4..8545c97 100644
--- a/include/safe_macros.h
+++ b/include/safe_macros.h
@@ -164,6 +164,12 @@ int	safe_linkat(const char *file, const int lineno,
 	safe_linkat(__FILE__, __LINE__, cleanup_fn, (olddirfd), (oldpath), \
 		    (newdirfd), (newpath), (flags))
 
+ssize_t	safe_readlink(const char *file, const int lineno,
+		      void (cleanup_fn)(void), const char *path,
+		      char *buf, size_t bufsize);
+#define SAFE_READLINK(cleanup_fn, path, buf, bufsize) \
+	safe_readlink(__FILE__, __LINE__, cleanup_fn, (path), (buf), (bufsize))
+
 int	safe_symlink(const char *file, const int lineno,
                      void (cleanup_fn)(void), const char *oldpath,
                      const char *newpath);
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 9fa6ac4..5a05c84 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -409,6 +409,23 @@ int safe_linkat(const char *file, const int lineno,
 	return rval;
 }
 
+ssize_t safe_readlink(const char *file, const int lineno,
+		  void (cleanup_fn)(void), const char *path,
+		  char *buf, size_t bufsize)
+{
+	ssize_t rval;
+
+	rval = readlink(path, buf, bufsize);
+
+	if (rval == -1) {
+		tst_brkm(TBROK | TERRNO, cleanup_fn,
+			 "%s:%d: readlink(%s,%p,%zu) failed",
+			 file, lineno, path, buf, bufsize);
+	}
+
+	return rval;
+}
+
 int safe_symlink(const char *file, const int lineno,
                  void (cleanup_fn)(void), const char *oldpath,
                  const char *newpath)
-- 
1.7.1


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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
                   ` (3 preceding siblings ...)
  2016-01-29 12:05 ` [LTP] [PATCH v3 4/5] lib/safe_macros: add readlink() Alexey Kodanev
@ 2016-01-29 12:05 ` Alexey Kodanev
  2016-02-09 13:32   ` Cyril Hrubis
  2016-04-25 14:35   ` Jan Stancek
  4 siblings, 2 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-01-29 12:05 UTC (permalink / raw)
  To: ltp

Test does the following steps:
* create an unnamed temporary file in TMP directory,
* write data into it,
* check that file not visible in the filesystem,
* name the file and check that it becomes visible in FS,
* create multiple directories and related temporary files,
* create multiple directories and link files into them. Check
  that files permissions correspond to the ones specified with
  open()/openat().

'openat() + O_TMPFILE' test repeats the same steps.

Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
 runtest/syscalls                            |    2 +
 testcases/kernel/syscalls/.gitignore        |    2 +
 testcases/kernel/syscalls/open/open14.c     |  253 ++++++++++++++++++++++++++
 testcases/kernel/syscalls/openat/openat03.c |  263 +++++++++++++++++++++++++++
 4 files changed, 520 insertions(+), 0 deletions(-)
 create mode 100644 testcases/kernel/syscalls/open/open14.c
 create mode 100644 testcases/kernel/syscalls/openat/openat03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 7173f22..3439948 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -721,10 +721,12 @@ open10 open10
 open11 open11
 open12 open12
 open13 open13
+open14 open14
 
 #openat test cases
 openat01 openat01
 openat02 openat02
+openat03 openat03
 
 mincore01 mincore01
 mincore02 mincore02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index d5f21ef..6451dc4 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -624,9 +624,11 @@
 /open/open12
 /open/open12_child
 /open/open13
+/open/open14
 /openat/openat01
 /openat/openat02
 /openat/openat02_child
+/openat/openat03
 /pathconf/pathconf01
 /pause/pause01
 /pause/pause02
diff --git a/testcases/kernel/syscalls/open/open14.c b/testcases/kernel/syscalls/open/open14.c
new file mode 100644
index 0000000..f5cd373
--- /dev/null
+++ b/testcases/kernel/syscalls/open/open14.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2015-2016 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * 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/>.
+ *
+ * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+
+char *TCID = "open14";
+int TST_TOTAL = 3;
+static ssize_t size;
+static char buf[1024];
+static const ssize_t blocks_num = 4;
+static struct stat st;
+
+static void cleanup(void)
+{
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_tmpdir();
+
+	size = sizeof(buf);
+
+	memset(buf, 1, size);
+
+	int fd = open(".", O_TMPFILE | O_RDWR, 0600);
+
+	if (fd == -1) {
+		if (errno == EISDIR)
+			tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
+
+		tst_brkm(TBROK | TERRNO, cleanup, "open() failed");
+	}
+
+	SAFE_CLOSE(cleanup, fd);
+}
+
+static void write_file(int fd)
+{
+	int i;
+
+	for (i = 0; i < blocks_num; ++i)
+		SAFE_WRITE(cleanup, 1, fd, buf, size);
+}
+
+void test01(void)
+{
+	int fd;
+	char path[PATH_MAX], tmp[PATH_MAX];
+
+	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+	fd = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
+
+	tst_resm(TINFO, "writing data to the file");
+	write_file(fd);
+
+	SAFE_FSTAT(cleanup, fd, &st);
+	tst_resm(TINFO, "file size is '%zu'", st.st_size);
+
+	if (st.st_size != blocks_num * size) {
+		tst_resm(TFAIL, "not expected size: '%zu' != '%zu'",
+			 st.st_size, blocks_num * size);
+		SAFE_CLOSE(cleanup, fd);
+		return;
+	}
+
+	tst_resm(TINFO, "looking for the file in '.'");
+	if (!tst_dir_is_empty(cleanup, ".", 1))
+		tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
+	tst_resm(TINFO, "file not found, OK");
+
+	snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
+	SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
+
+	tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
+	SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
+		    AT_SYMLINK_FOLLOW);
+
+	if (tst_dir_is_empty(cleanup, ".", 1))
+		tst_brkm(TFAIL, cleanup, "file not found");
+
+	SAFE_UNLINK(cleanup, "tmpfile");
+	SAFE_CLOSE(cleanup, fd);
+
+	tst_resm(TPASS, "single file tests passed");
+}
+
+static void read_file(int fd)
+{
+	int i;
+	char tmp[size];
+
+	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
+
+	for (i = 0; i < blocks_num; ++i) {
+		SAFE_READ(cleanup, 0, fd, tmp, size);
+		if (memcmp(buf, tmp, size))
+			tst_brkm(TFAIL, cleanup, "got unexepected data");
+	}
+}
+
+static void test02(void)
+{
+	const int files_num = 100;
+	int i, fd[files_num];
+	char path[PATH_MAX];
+
+	tst_resm(TINFO, "create files in multiple directories");
+	for (i = 0; i < files_num; ++i) {
+		snprintf(path, PATH_MAX, "tst02_%d", i);
+		SAFE_MKDIR(cleanup, path, 0700);
+		SAFE_CHDIR(cleanup, path);
+
+		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
+
+		write_file(fd[i]);
+	}
+
+	tst_resm(TINFO, "removing test directories");
+	for (i = files_num - 1; i >= 0; --i) {
+		SAFE_CHDIR(cleanup, "..");
+		snprintf(path, PATH_MAX, "tst02_%d", i);
+		SAFE_RMDIR(cleanup, path);
+	}
+
+	tst_resm(TINFO, "writing/reading temporary files");
+	for (i = 0; i < files_num; ++i) {
+		write_file(fd[i]);
+		read_file(fd[i]);
+	}
+
+	tst_resm(TINFO, "closing temporary files");
+	for (i = 0; i < files_num; ++i)
+		SAFE_CLOSE(cleanup, fd[i]);
+
+	tst_resm(TPASS, "multiple files tests passed");
+}
+
+static void link_tmp_file(int fd)
+{
+	char path1[PATH_MAX], path2[PATH_MAX];
+
+	snprintf(path1, PATH_MAX,  "/proc/self/fd/%d", fd);
+	snprintf(path2, PATH_MAX,  "tmpfile_%d", fd);
+
+	SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
+		    AT_SYMLINK_FOLLOW);
+}
+
+static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
+
+static void test03(void)
+{
+	const int files_num = 100;
+	int i, fd[files_num];
+	char path[PATH_MAX];
+	struct stat st;
+	unsigned int j;
+	mode_t mask = umask(0);
+
+	umask(mask);
+
+	tst_resm(TINFO, "create multiple directories, link files into them");
+	tst_resm(TINFO, "and check file permissions");
+	for (i = 0, j = 0; i < files_num; ++i) {
+
+		snprintf(path, PATH_MAX, "tst03_%d", i);
+		SAFE_MKDIR(cleanup, path, 0700);
+		SAFE_CHDIR(cleanup, path);
+
+		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR,
+				  tst_perm[j]);
+
+		write_file(fd[i]);
+		read_file(fd[i]);
+
+		link_tmp_file(fd[i]);
+
+		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+
+		SAFE_LSTAT(cleanup, path, &st);
+
+		mode_t exp_mode = tst_perm[j] & ~mask;
+
+		if ((st.st_mode & ~S_IFMT) != exp_mode) {
+			tst_brkm(TFAIL, cleanup,
+				"file mode read %o, but expected %o",
+				st.st_mode & ~S_IFMT, exp_mode);
+		}
+
+		if (++j >= ARRAY_SIZE(tst_perm))
+			j = 0;
+	}
+
+	tst_resm(TINFO, "remove files, directories");
+	for (i = files_num - 1; i >= 0; --i) {
+		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+		SAFE_UNLINK(cleanup, path);
+		SAFE_CLOSE(cleanup, fd[i]);
+
+		SAFE_CHDIR(cleanup, "..");
+
+		snprintf(path, PATH_MAX, "tst03_%d", i);
+		SAFE_RMDIR(cleanup, path);
+	}
+
+	tst_resm(TPASS, "file permission tests passed");
+}
+
+int main(int ac, char *av[])
+{
+	int lc;
+
+	tst_parse_opts(ac, av, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); ++lc) {
+		tst_count = 0;
+		test01();
+		test02();
+		test03();
+	}
+
+	cleanup();
+	tst_exit();
+}
diff --git a/testcases/kernel/syscalls/openat/openat03.c b/testcases/kernel/syscalls/openat/openat03.c
new file mode 100644
index 0000000..441c84b
--- /dev/null
+++ b/testcases/kernel/syscalls/openat/openat03.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015-2016 Oracle and/or its affiliates. All Rights Reserved.
+ *
+ * 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/>.
+ *
+ * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "test.h"
+#include "safe_macros.h"
+#include "lapi/fcntl.h"
+#include "openat.h"
+
+char *TCID = "openat03";
+int TST_TOTAL = 3;
+static ssize_t size;
+static char buf[1024];
+static const ssize_t blocks_num = 4;
+static struct stat st;
+
+static void cleanup(void)
+{
+	tst_rmdir();
+}
+
+static void setup(void)
+{
+	tst_tmpdir();
+
+	size = sizeof(buf);
+
+	memset(buf, 1, size);
+
+	int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, 0600);
+
+	if (fd == -1) {
+		if (errno == EISDIR)
+			tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
+
+		tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
+	}
+
+	SAFE_CLOSE(cleanup, fd);
+}
+
+static int tst_openat_tmp(int mode)
+{
+	int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, mode);
+
+	if (fd >= 0)
+		return fd;
+
+	tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
+}
+
+static void write_file(int fd)
+{
+	int i;
+
+	for (i = 0; i < blocks_num; ++i)
+		SAFE_WRITE(cleanup, 1, fd, buf, size);
+}
+
+void test01(void)
+{
+	int fd;
+	char path[PATH_MAX], tmp[PATH_MAX];
+
+	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
+	fd = tst_openat_tmp(0600);
+
+	tst_resm(TINFO, "writing data to the file");
+	write_file(fd);
+
+	SAFE_FSTAT(cleanup, fd, &st);
+	tst_resm(TINFO, "file size is '%zu'", st.st_size);
+
+	if (st.st_size != blocks_num * size) {
+		tst_resm(TFAIL, "not expected size: '%zu' != '%zu'",
+			 st.st_size, blocks_num * size);
+		SAFE_CLOSE(cleanup, fd);
+		return;
+	}
+
+	tst_resm(TINFO, "looking for the file in '.'");
+	if (!tst_dir_is_empty(cleanup, ".", 1))
+		tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
+	tst_resm(TINFO, "file not found, OK");
+
+	snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
+	SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
+
+	tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
+	SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
+		    AT_SYMLINK_FOLLOW);
+
+	if (tst_dir_is_empty(cleanup, ".", 1))
+		tst_brkm(TFAIL, cleanup, "file not found");
+
+	SAFE_UNLINK(cleanup, "tmpfile");
+	SAFE_CLOSE(cleanup, fd);
+
+	tst_resm(TPASS, "single file tests passed");
+}
+
+static void read_file(int fd)
+{
+	int i;
+	char tmp[size];
+
+	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
+
+	for (i = 0; i < blocks_num; ++i) {
+		SAFE_READ(cleanup, 0, fd, tmp, size);
+		if (memcmp(buf, tmp, size))
+			tst_brkm(TFAIL, cleanup, "got unexepected data");
+	}
+}
+
+static void test02(void)
+{
+	const int files_num = 100;
+	int i, fd[files_num];
+	char path[PATH_MAX];
+
+	tst_resm(TINFO, "create files in multiple directories");
+	for (i = 0; i < files_num; ++i) {
+		snprintf(path, PATH_MAX, "tst02_%d", i);
+		SAFE_MKDIR(cleanup, path, 0700);
+		SAFE_CHDIR(cleanup, path);
+
+		fd[i] = tst_openat_tmp(0600);
+
+		write_file(fd[i]);
+	}
+
+	tst_resm(TINFO, "removing test directories");
+	for (i = files_num - 1; i >= 0; --i) {
+		SAFE_CHDIR(cleanup, "..");
+		snprintf(path, PATH_MAX, "tst02_%d", i);
+		SAFE_RMDIR(cleanup, path);
+	}
+
+	tst_resm(TINFO, "writing/reading temporary files");
+	for (i = 0; i < files_num; ++i) {
+		write_file(fd[i]);
+		read_file(fd[i]);
+	}
+
+	tst_resm(TINFO, "closing temporary files");
+	for (i = 0; i < files_num; ++i)
+		SAFE_CLOSE(cleanup, fd[i]);
+
+	tst_resm(TPASS, "multiple files tests passed");
+}
+
+static void link_tmp_file(int fd)
+{
+	char path1[PATH_MAX], path2[PATH_MAX];
+
+	snprintf(path1, PATH_MAX,  "/proc/self/fd/%d", fd);
+	snprintf(path2, PATH_MAX,  "tmpfile_%d", fd);
+
+	SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
+		    AT_SYMLINK_FOLLOW);
+}
+
+static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
+
+static void test03(void)
+{
+	const int files_num = 100;
+	int i, fd[files_num];
+	char path[PATH_MAX];
+	struct stat st;
+	unsigned int j;
+	mode_t mask = umask(0);
+
+	umask(mask);
+
+	tst_resm(TINFO, "create multiple directories, link files into them");
+	tst_resm(TINFO, "and check file permissions");
+	for (i = 0, j = 0; i < files_num; ++i) {
+
+		snprintf(path, PATH_MAX, "tst03_%d", i);
+		SAFE_MKDIR(cleanup, path, 0700);
+		SAFE_CHDIR(cleanup, path);
+
+		fd[i] = tst_openat_tmp(tst_perm[j]);
+
+		write_file(fd[i]);
+		read_file(fd[i]);
+
+		link_tmp_file(fd[i]);
+
+		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+
+		SAFE_LSTAT(cleanup, path, &st);
+
+		mode_t exp_mode = tst_perm[j] & ~mask;
+
+		if ((st.st_mode & ~S_IFMT) != exp_mode) {
+			tst_brkm(TFAIL, cleanup,
+				"file mode read %o, but expected %o",
+				st.st_mode & ~S_IFMT, exp_mode);
+		}
+
+		if (++j >= ARRAY_SIZE(tst_perm))
+			j = 0;
+	}
+
+	tst_resm(TINFO, "remove files, directories");
+	for (i = files_num - 1; i >= 0; --i) {
+		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
+		SAFE_UNLINK(cleanup, path);
+		SAFE_CLOSE(cleanup, fd[i]);
+
+		SAFE_CHDIR(cleanup, "..");
+
+		snprintf(path, PATH_MAX, "tst03_%d", i);
+		SAFE_RMDIR(cleanup, path);
+	}
+
+	tst_resm(TPASS, "file permission tests passed");
+}
+
+int main(int ac, char *av[])
+{
+	int lc;
+
+	tst_parse_opts(ac, av, NULL, NULL);
+
+	setup();
+
+	for (lc = 0; TEST_LOOPING(lc); ++lc) {
+		tst_count = 0;
+		test01();
+		test02();
+		test03();
+	}
+
+	cleanup();
+	tst_exit();
+}
-- 
1.7.1


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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-01-29 12:05 ` [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE' Alexey Kodanev
@ 2016-02-09 13:32   ` Cyril Hrubis
  2016-02-10  8:36     ` Alexey Kodanev
  2016-04-25 14:35   ` Jan Stancek
  1 sibling, 1 reply; 13+ messages in thread
From: Cyril Hrubis @ 2016-02-09 13:32 UTC (permalink / raw)
  To: ltp

Hi!
> +#define _GNU_SOURCE
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +
> +#include "test.h"
> +#include "safe_macros.h"
> +#include "lapi/fcntl.h"
> +
> +char *TCID = "open14";
> +int TST_TOTAL = 3;
> +static ssize_t size;
> +static char buf[1024];
> +static const ssize_t blocks_num = 4;
> +static struct stat st;
> +
> +static void cleanup(void)
> +{
> +	tst_rmdir();
> +}
> +
> +static void setup(void)
> +{
> +	tst_tmpdir();
> +
> +	size = sizeof(buf);
> +
> +	memset(buf, 1, size);
> +
> +	int fd = open(".", O_TMPFILE | O_RDWR, 0600);
> +
> +	if (fd == -1) {
> +		if (errno == EISDIR)
> +			tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
> +
> +		tst_brkm(TBROK | TERRNO, cleanup, "open() failed");
> +	}
> +
> +	SAFE_CLOSE(cleanup, fd);
> +}
> +
> +static void write_file(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < blocks_num; ++i)
> +		SAFE_WRITE(cleanup, 1, fd, buf, size);
> +}
> +
> +void test01(void)
> +{
> +	int fd;
> +	char path[PATH_MAX], tmp[PATH_MAX];
> +
> +	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
> +	fd = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
> +
> +	tst_resm(TINFO, "writing data to the file");
> +	write_file(fd);
> +
> +	SAFE_FSTAT(cleanup, fd, &st);
> +	tst_resm(TINFO, "file size is '%zu'", st.st_size);
> +
> +	if (st.st_size != blocks_num * size) {
> +		tst_resm(TFAIL, "not expected size: '%zu' != '%zu'",
> +			 st.st_size, blocks_num * size);
> +		SAFE_CLOSE(cleanup, fd);
> +		return;
> +	}
> +
> +	tst_resm(TINFO, "looking for the file in '.'");
> +	if (!tst_dir_is_empty(cleanup, ".", 1))
> +		tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
> +	tst_resm(TINFO, "file not found, OK");
> +
> +	snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
> +	SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
> +
> +	tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
> +	SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
> +		    AT_SYMLINK_FOLLOW);
> +
> +	if (tst_dir_is_empty(cleanup, ".", 1))
> +		tst_brkm(TFAIL, cleanup, "file not found");
> +
> +	SAFE_UNLINK(cleanup, "tmpfile");
> +	SAFE_CLOSE(cleanup, fd);
> +
> +	tst_resm(TPASS, "single file tests passed");
> +}
> +
> +static void read_file(int fd)
> +{
> +	int i;
> +	char tmp[size];
> +
> +	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
> +
> +	for (i = 0; i < blocks_num; ++i) {
> +		SAFE_READ(cleanup, 0, fd, tmp, size);
> +		if (memcmp(buf, tmp, size))
> +			tst_brkm(TFAIL, cleanup, "got unexepected data");
> +	}
> +}
> +
> +static void test02(void)
> +{
> +	const int files_num = 100;
> +	int i, fd[files_num];
> +	char path[PATH_MAX];
> +
> +	tst_resm(TINFO, "create files in multiple directories");
> +	for (i = 0; i < files_num; ++i) {
> +		snprintf(path, PATH_MAX, "tst02_%d", i);
> +		SAFE_MKDIR(cleanup, path, 0700);
> +		SAFE_CHDIR(cleanup, path);
> +
> +		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR, 0600);
> +
> +		write_file(fd[i]);

We don't have to write the file here, if I'm not mistaken.

> +	}
> +
> +	tst_resm(TINFO, "removing test directories");
> +	for (i = files_num - 1; i >= 0; --i) {
> +		SAFE_CHDIR(cleanup, "..");
> +		snprintf(path, PATH_MAX, "tst02_%d", i);
> +		SAFE_RMDIR(cleanup, path);
> +	}
> +
> +	tst_resm(TINFO, "writing/reading temporary files");
> +	for (i = 0; i < files_num; ++i) {
> +		write_file(fd[i]);
> +		read_file(fd[i]);
> +	}
> +
> +	tst_resm(TINFO, "closing temporary files");
> +	for (i = 0; i < files_num; ++i)
> +		SAFE_CLOSE(cleanup, fd[i]);
> +
> +	tst_resm(TPASS, "multiple files tests passed");
> +}
> +
> +static void link_tmp_file(int fd)
> +{
> +	char path1[PATH_MAX], path2[PATH_MAX];
> +
> +	snprintf(path1, PATH_MAX,  "/proc/self/fd/%d", fd);
> +	snprintf(path2, PATH_MAX,  "tmpfile_%d", fd);
> +
> +	SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
> +		    AT_SYMLINK_FOLLOW);
> +}
> +
> +static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
> +
> +static void test03(void)
> +{
> +	const int files_num = 100;
> +	int i, fd[files_num];
> +	char path[PATH_MAX];
> +	struct stat st;
> +	unsigned int j;
> +	mode_t mask = umask(0);
> +
> +	umask(mask);
> +
> +	tst_resm(TINFO, "create multiple directories, link files into them");
> +	tst_resm(TINFO, "and check file permissions");
> +	for (i = 0, j = 0; i < files_num; ++i) {
> +
> +		snprintf(path, PATH_MAX, "tst03_%d", i);
> +		SAFE_MKDIR(cleanup, path, 0700);
> +		SAFE_CHDIR(cleanup, path);
> +
> +		fd[i] = SAFE_OPEN(cleanup, ".", O_TMPFILE | O_RDWR,
> +				  tst_perm[j]);

You can just use i % ARRAY_SIZE(tst_perms) instead of the j variable.

> +
> +		write_file(fd[i]);
> +		read_file(fd[i]);
> +
> +		link_tmp_file(fd[i]);
> +
> +		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
> +
> +		SAFE_LSTAT(cleanup, path, &st);
> +
> +		mode_t exp_mode = tst_perm[j] & ~mask;
> +
> +		if ((st.st_mode & ~S_IFMT) != exp_mode) {
> +			tst_brkm(TFAIL, cleanup,
> +				"file mode read %o, but expected %o",
> +				st.st_mode & ~S_IFMT, exp_mode);
> +		}
> +
> +		if (++j >= ARRAY_SIZE(tst_perm))
> +			j = 0;
> +	}
> +
> +	tst_resm(TINFO, "remove files, directories");
> +	for (i = files_num - 1; i >= 0; --i) {
> +		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
> +		SAFE_UNLINK(cleanup, path);
> +		SAFE_CLOSE(cleanup, fd[i]);
> +
> +		SAFE_CHDIR(cleanup, "..");
> +
> +		snprintf(path, PATH_MAX, "tst03_%d", i);
> +		SAFE_RMDIR(cleanup, path);
> +	}
> +
> +	tst_resm(TPASS, "file permission tests passed");
> +}
> +
> +int main(int ac, char *av[])
> +{
> +	int lc;
> +
> +	tst_parse_opts(ac, av, NULL, NULL);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); ++lc) {
> +		tst_count = 0;
> +		test01();
> +		test02();
> +		test03();
> +	}
> +
> +	cleanup();
> +	tst_exit();
> +}
> diff --git a/testcases/kernel/syscalls/openat/openat03.c b/testcases/kernel/syscalls/openat/openat03.c
> new file mode 100644
> index 0000000..441c84b
> --- /dev/null
> +++ b/testcases/kernel/syscalls/openat/openat03.c
> @@ -0,0 +1,263 @@
> +/*
> + * Copyright (c) 2015-2016 Oracle and/or its affiliates. All Rights Reserved.
> + *
> + * 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/>.
> + *
> + * Author: Alexey Kodanev <alexey.kodanev@oracle.com>
> + *
> + */
> +
> +#define _GNU_SOURCE
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +
> +#include "test.h"
> +#include "safe_macros.h"
> +#include "lapi/fcntl.h"
> +#include "openat.h"
> +
> +char *TCID = "openat03";
> +int TST_TOTAL = 3;
> +static ssize_t size;
> +static char buf[1024];
> +static const ssize_t blocks_num = 4;
> +static struct stat st;
> +
> +static void cleanup(void)
> +{
> +	tst_rmdir();
> +}
> +
> +static void setup(void)
> +{
> +	tst_tmpdir();
> +
> +	size = sizeof(buf);
> +
> +	memset(buf, 1, size);
> +
> +	int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, 0600);
> +
> +	if (fd == -1) {
> +		if (errno == EISDIR)
> +			tst_brkm(TCONF, cleanup, "O_TMPFILE not supported");
> +
> +		tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
> +	}
> +
> +	SAFE_CLOSE(cleanup, fd);
> +}
> +
> +static int tst_openat_tmp(int mode)
> +{
> +	int fd = openat(AT_FDCWD, ".", O_TMPFILE | O_RDWR, mode);
> +
> +	if (fd >= 0)
> +		return fd;
> +
> +	tst_brkm(TBROK | TERRNO, cleanup, "openat() failed");
> +}

Any identifier that starts with tst_ or TST_ is reserved for test
library. Can you rename it to something else (do_openat) or so that we
avoid possible future collision.

> +static void write_file(int fd)
> +{
> +	int i;
> +
> +	for (i = 0; i < blocks_num; ++i)
> +		SAFE_WRITE(cleanup, 1, fd, buf, size);
> +}
> +
> +void test01(void)
> +{
> +	int fd;
> +	char path[PATH_MAX], tmp[PATH_MAX];
> +
> +	tst_resm(TINFO, "creating a file with O_TMPFILE flag");
> +	fd = tst_openat_tmp(0600);
> +
> +	tst_resm(TINFO, "writing data to the file");
> +	write_file(fd);
> +
> +	SAFE_FSTAT(cleanup, fd, &st);
> +	tst_resm(TINFO, "file size is '%zu'", st.st_size);
> +
> +	if (st.st_size != blocks_num * size) {
> +		tst_resm(TFAIL, "not expected size: '%zu' != '%zu'",
> +			 st.st_size, blocks_num * size);
> +		SAFE_CLOSE(cleanup, fd);
> +		return;
> +	}
> +
> +	tst_resm(TINFO, "looking for the file in '.'");
> +	if (!tst_dir_is_empty(cleanup, ".", 1))
> +		tst_brkm(TFAIL, cleanup, "found a file, this is not expected");
> +	tst_resm(TINFO, "file not found, OK");
> +
> +	snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
> +	SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
> +
> +	tst_resm(TINFO, "renaming '%s' -> 'tmpfile'", tmp);
> +	SAFE_LINKAT(cleanup, AT_FDCWD, path, AT_FDCWD, "tmpfile",
> +		    AT_SYMLINK_FOLLOW);
> +
> +	if (tst_dir_is_empty(cleanup, ".", 1))
> +		tst_brkm(TFAIL, cleanup, "file not found");
> +
> +	SAFE_UNLINK(cleanup, "tmpfile");
> +	SAFE_CLOSE(cleanup, fd);
> +
> +	tst_resm(TPASS, "single file tests passed");
> +}
> +
> +static void read_file(int fd)
> +{
> +	int i;
> +	char tmp[size];
> +
> +	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
> +
> +	for (i = 0; i < blocks_num; ++i) {
> +		SAFE_READ(cleanup, 0, fd, tmp, size);
> +		if (memcmp(buf, tmp, size))
> +			tst_brkm(TFAIL, cleanup, "got unexepected data");
> +	}
> +}
> +
> +static void test02(void)
> +{
> +	const int files_num = 100;
> +	int i, fd[files_num];
> +	char path[PATH_MAX];
> +
> +	tst_resm(TINFO, "create files in multiple directories");
> +	for (i = 0; i < files_num; ++i) {
> +		snprintf(path, PATH_MAX, "tst02_%d", i);
> +		SAFE_MKDIR(cleanup, path, 0700);
> +		SAFE_CHDIR(cleanup, path);
> +
> +		fd[i] = tst_openat_tmp(0600);
> +
> +		write_file(fd[i]);

Here as well.

> +	}
> +
> +	tst_resm(TINFO, "removing test directories");
> +	for (i = files_num - 1; i >= 0; --i) {
> +		SAFE_CHDIR(cleanup, "..");
> +		snprintf(path, PATH_MAX, "tst02_%d", i);
> +		SAFE_RMDIR(cleanup, path);
> +	}
> +
> +	tst_resm(TINFO, "writing/reading temporary files");
> +	for (i = 0; i < files_num; ++i) {
> +		write_file(fd[i]);
> +		read_file(fd[i]);
> +	}
> +
> +	tst_resm(TINFO, "closing temporary files");
> +	for (i = 0; i < files_num; ++i)
> +		SAFE_CLOSE(cleanup, fd[i]);
> +
> +	tst_resm(TPASS, "multiple files tests passed");
> +}
> +
> +static void link_tmp_file(int fd)
> +{
> +	char path1[PATH_MAX], path2[PATH_MAX];
> +
> +	snprintf(path1, PATH_MAX,  "/proc/self/fd/%d", fd);
> +	snprintf(path2, PATH_MAX,  "tmpfile_%d", fd);
> +
> +	SAFE_LINKAT(cleanup, AT_FDCWD, path1, AT_FDCWD, path2,
> +		    AT_SYMLINK_FOLLOW);
> +}
> +
> +static const int tst_perm[] = { 0, 07777, 001, 0755, 0644, 0440 };
> +
> +static void test03(void)
> +{
> +	const int files_num = 100;
> +	int i, fd[files_num];
> +	char path[PATH_MAX];
> +	struct stat st;
> +	unsigned int j;
> +	mode_t mask = umask(0);
> +
> +	umask(mask);
> +
> +	tst_resm(TINFO, "create multiple directories, link files into them");
> +	tst_resm(TINFO, "and check file permissions");
> +	for (i = 0, j = 0; i < files_num; ++i) {
> +
> +		snprintf(path, PATH_MAX, "tst03_%d", i);
> +		SAFE_MKDIR(cleanup, path, 0700);
> +		SAFE_CHDIR(cleanup, path);
> +
> +		fd[i] = tst_openat_tmp(tst_perm[j]);

Here as well.

> +		write_file(fd[i]);
> +		read_file(fd[i]);
> +
> +		link_tmp_file(fd[i]);
> +
> +		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
> +
> +		SAFE_LSTAT(cleanup, path, &st);
> +
> +		mode_t exp_mode = tst_perm[j] & ~mask;
> +
> +		if ((st.st_mode & ~S_IFMT) != exp_mode) {
> +			tst_brkm(TFAIL, cleanup,
> +				"file mode read %o, but expected %o",
> +				st.st_mode & ~S_IFMT, exp_mode);
> +		}
> +
> +		if (++j >= ARRAY_SIZE(tst_perm))
> +			j = 0;
> +	}
> +
> +	tst_resm(TINFO, "remove files, directories");
> +	for (i = files_num - 1; i >= 0; --i) {
> +		snprintf(path, PATH_MAX, "tmpfile_%d", fd[i]);
> +		SAFE_UNLINK(cleanup, path);
> +		SAFE_CLOSE(cleanup, fd[i]);
> +
> +		SAFE_CHDIR(cleanup, "..");
> +
> +		snprintf(path, PATH_MAX, "tst03_%d", i);
> +		SAFE_RMDIR(cleanup, path);
> +	}
> +
> +	tst_resm(TPASS, "file permission tests passed");
> +}
> +
> +int main(int ac, char *av[])
> +{
> +	int lc;
> +
> +	tst_parse_opts(ac, av, NULL, NULL);
> +
> +	setup();
> +
> +	for (lc = 0; TEST_LOOPING(lc); ++lc) {
> +		tst_count = 0;
> +		test01();
> +		test02();
> +		test03();
> +	}
> +
> +	cleanup();
> +	tst_exit();
> +}


The rest of the patchset looks good.

Acked with the minor issues I pointed out fixed.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-02-09 13:32   ` Cyril Hrubis
@ 2016-02-10  8:36     ` Alexey Kodanev
  0 siblings, 0 replies; 13+ messages in thread
From: Alexey Kodanev @ 2016-02-10  8:36 UTC (permalink / raw)
  To: ltp

Hi,
On 02/09/2016 04:32 PM, Cyril Hrubis wrote:
> The rest of the patchset looks good.
> Acked with the minor issues I pointed out fixed. 

Thank you for review, fixed patch-set applied.

Best regards,
Alexey

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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-01-29 12:05 ` [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE' Alexey Kodanev
  2016-02-09 13:32   ` Cyril Hrubis
@ 2016-04-25 14:35   ` Jan Stancek
  2016-04-25 15:04     ` Cyril Hrubis
  2016-04-25 15:12     ` Alexey Kodanev
  1 sibling, 2 replies; 13+ messages in thread
From: Jan Stancek @ 2016-04-25 14:35 UTC (permalink / raw)
  To: ltp





----- Original Message -----
> From: "Alexey Kodanev" <alexey.kodanev@oracle.com>
> To: ltp@lists.linux.it
> Cc: "vasily isaenko" <vasily.isaenko@oracle.com>
> Sent: Friday, 29 January, 2016 1:05:50 PM
> Subject: [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() +	O_TMPFILE'
> 
> Test does the following steps:
> * create an unnamed temporary file in TMP directory,
> * write data into it,
> * check that file not visible in the filesystem,
> * name the file and check that it becomes visible in FS,
> * create multiple directories and related temporary files,
> * create multiple directories and link files into them. Check
>   that files permissions correspond to the ones specified with
>   open()/openat().
> 
> 'openat() + O_TMPFILE' test repeats the same steps.
> 
> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>

Alexey,

do you know if this maybe depends on some config option or
support on glibc side?

I'm running 4.5 kernel and both open14 and openat03 are failing
for me. I tried xfs and ext4, both failed.

...
chdir("/tmp/opepC2qHH")                 = 0
openat(AT_FDCWD, ".", O_RDWR|O_DIRECTORY|0x400000) = 3
close(3)                                = 0
umask(0)                                = 022
umask(022)                              = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x3ff816c0000
write(1, "open14      0  TINFO  :  create "..., 75open14      0  TINFO  :  create multiple directories, link files into them
) = 75
write(1, "open14      0  TINFO  :  and che"..., 52open14      0  TINFO  :  and check file permissions
) = 52
mkdirat(AT_FDCWD, "tst03_0", 0700)      = 0
chdir("tst03_0")                        = 0
openat(AT_FDCWD, ".", O_RDWR|O_DIRECTORY|0x400000) = 3
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
lseek(3, 0, SEEK_SET)                   = 0
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
linkat(AT_FDCWD, "/proc/self/fd/3", AT_FDCWD, "tmpfile_3", AT_SYMLINK_FOLLOW) = 0
newfstatat(AT_FDCWD, "tmpfile_3", {st_mode=S_IFREG, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
write(1, "open14      1  TFAIL  :  open14."..., 74open14      1  TFAIL  :  open14.c:212: file mode read 0, but expected 755

Regards,
Jan

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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-04-25 14:35   ` Jan Stancek
@ 2016-04-25 15:04     ` Cyril Hrubis
  2016-04-25 15:12     ` Alexey Kodanev
  1 sibling, 0 replies; 13+ messages in thread
From: Cyril Hrubis @ 2016-04-25 15:04 UTC (permalink / raw)
  To: ltp

Hi!
> I'm running 4.5 kernel and both open14 and openat03 are failing
> for me. I tried xfs and ext4, both failed.

For me openat03 fails on ext4 and tmpfs as well but open14 works fine on
4.1.13. Which is kind of strange.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-04-25 15:12     ` Alexey Kodanev
@ 2016-04-25 15:07       ` Cyril Hrubis
  2016-04-26  9:47         ` Jan Stancek
  0 siblings, 1 reply; 13+ messages in thread
From: Cyril Hrubis @ 2016-04-25 15:07 UTC (permalink / raw)
  To: ltp

Hi!
> If the issue with mode... it can be because glibc doesn't process mode
> argument unless O_CREAT is found. In our case we have O_TMPFILE instead.
> 
> Here is the link to bugzilla:
> 
> "open() and openat() ignore 'mode' with O_TMPFILE"
> https://sourceware.org/bugzilla/show_bug.cgi?id=17523

What I see matches the the behavior in Comment 5.

-- 
Cyril Hrubis
chrubis@suse.cz

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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-04-25 14:35   ` Jan Stancek
  2016-04-25 15:04     ` Cyril Hrubis
@ 2016-04-25 15:12     ` Alexey Kodanev
  2016-04-25 15:07       ` Cyril Hrubis
  1 sibling, 1 reply; 13+ messages in thread
From: Alexey Kodanev @ 2016-04-25 15:12 UTC (permalink / raw)
  To: ltp

Hi Jan,

On 04/25/2016 05:35 PM, Jan Stancek wrote:
>
>
>
> ----- Original Message -----
>> From: "Alexey Kodanev" <alexey.kodanev@oracle.com>
>> To: ltp@lists.linux.it
>> Cc: "vasily isaenko" <vasily.isaenko@oracle.com>
>> Sent: Friday, 29 January, 2016 1:05:50 PM
>> Subject: [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() +	O_TMPFILE'
>>
>> Test does the following steps:
>> * create an unnamed temporary file in TMP directory,
>> * write data into it,
>> * check that file not visible in the filesystem,
>> * name the file and check that it becomes visible in FS,
>> * create multiple directories and related temporary files,
>> * create multiple directories and link files into them. Check
>>    that files permissions correspond to the ones specified with
>>    open()/openat().
>>
>> 'openat() + O_TMPFILE' test repeats the same steps.
>>
>> Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
> Alexey,
>
> do you know if this maybe depends on some config option or
> support on glibc side?
>
> I'm running 4.5 kernel and both open14 and openat03 are failing
> for me. I tried xfs and ext4, both failed.
>
> ...
> chdir("/tmp/opepC2qHH")                 = 0
> openat(AT_FDCWD, ".", O_RDWR|O_DIRECTORY|0x400000) = 3
> close(3)                                = 0
> umask(0)                                = 022
> umask(022)                              = 0
> fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
> mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x3ff816c0000
> write(1, "open14      0  TINFO  :  create "..., 75open14      0  TINFO  :  create multiple directories, link files into them
> ) = 75
> write(1, "open14      0  TINFO  :  and che"..., 52open14      0  TINFO  :  and check file permissions
> ) = 52
> mkdirat(AT_FDCWD, "tst03_0", 0700)      = 0
> chdir("tst03_0")                        = 0
> openat(AT_FDCWD, ".", O_RDWR|O_DIRECTORY|0x400000) = 3
> write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> write(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> lseek(3, 0, SEEK_SET)                   = 0
> read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> read(3, "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"..., 1024) = 1024
> linkat(AT_FDCWD, "/proc/self/fd/3", AT_FDCWD, "tmpfile_3", AT_SYMLINK_FOLLOW) = 0
> newfstatat(AT_FDCWD, "tmpfile_3", {st_mode=S_IFREG, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
> write(1, "open14      1  TFAIL  :  open14."..., 74open14      1  TFAIL  :  open14.c:212: file mode read 0, but expected 755

If the issue with mode... it can be because glibc doesn't process mode
argument unless O_CREAT is found. In our case we have O_TMPFILE instead.

Here is the link to bugzilla:

"open() and openat() ignore 'mode' with O_TMPFILE"
https://sourceware.org/bugzilla/show_bug.cgi?id=17523

Thanks,
Alexey

> Regards,
> Jan


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

* [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
  2016-04-25 15:07       ` Cyril Hrubis
@ 2016-04-26  9:47         ` Jan Stancek
  0 siblings, 0 replies; 13+ messages in thread
From: Jan Stancek @ 2016-04-26  9:47 UTC (permalink / raw)
  To: ltp





----- Original Message -----
> From: "Cyril Hrubis" <chrubis@suse.cz>
> To: "Alexey Kodanev" <alexey.kodanev@oracle.com>
> Cc: "Jan Stancek" <jstancek@redhat.com>, "vasily isaenko" <vasily.isaenko@oracle.com>, ltp@lists.linux.it
> Sent: Monday, 25 April, 2016 5:07:35 PM
> Subject: Re: [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE'
> 
> Hi!
> > If the issue with mode... it can be because glibc doesn't process mode
> > argument unless O_CREAT is found. In our case we have O_TMPFILE instead.
> > 
> > Here is the link to bugzilla:
> > 
> > "open() and openat() ignore 'mode' with O_TMPFILE"
> > https://sourceware.org/bugzilla/show_bug.cgi?id=17523

Thanks. Jeff Bastian independently found this BZ as well. 
systemtap confirms, that mode remains 0, even when testcase is
passing non-zero values.

sys_openat ., dfd=0xffffffffffffff9c filename=0x40ac50 flags=0x404002 mode=0x0

> 
> What I see matches the the behavior in Comment 5.

I'm on aarch64, so that may explain why both fail for me.

After applying this patch:
  https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=65f6f938cd562a614a68e15d0581a34b177ec29d
both testcases passed.

Regards,
Jan

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

end of thread, other threads:[~2016-04-26  9:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-29 12:05 [LTP] [PATCH v3 0/6] add open/openat + O_TMPFILE tests Alexey Kodanev
2016-01-29 12:05 ` [LTP] [PATCH v3 1/5] lib/tst_dir_is_empty: add a library function Alexey Kodanev
2016-01-29 12:05 ` [LTP] [PATCH v3 2/5] include/lapi/fcntl.h: add O_TMPFILE definition Alexey Kodanev
2016-01-29 12:05 ` [LTP] [PATCH v3 3/5] lib/safe_macros: add linkat() Alexey Kodanev
2016-01-29 12:05 ` [LTP] [PATCH v3 4/5] lib/safe_macros: add readlink() Alexey Kodanev
2016-01-29 12:05 ` [LTP] [PATCH v3 5/5] kernel/syscalls: add new test with 'open() + O_TMPFILE' Alexey Kodanev
2016-02-09 13:32   ` Cyril Hrubis
2016-02-10  8:36     ` Alexey Kodanev
2016-04-25 14:35   ` Jan Stancek
2016-04-25 15:04     ` Cyril Hrubis
2016-04-25 15:12     ` Alexey Kodanev
2016-04-25 15:07       ` Cyril Hrubis
2016-04-26  9:47         ` Jan Stancek

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.