* [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.