From 77c0ff89fbd03f309590d60b481dfb9db23148a1 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 9 Jan 2023 10:07:15 -0800 Subject: [PATCH 1/3] Rename stage-tmpfile to o_tmpfile We had a one-off test that was overly specific to staging from tmpfile. This renames it to a more generic test where we can add more tests of o_tmpfile in general. Signed-off-by: Zach Brown --- tests/golden/{stage-tmpfile => o_tmpfile} | 0 tests/sequence | 2 +- tests/tests/{stage-tmpfile.sh => o_tmpfile.sh} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename tests/golden/{stage-tmpfile => o_tmpfile} (100%) rename tests/tests/{stage-tmpfile.sh => o_tmpfile.sh} (100%) diff --git a/tests/golden/stage-tmpfile b/tests/golden/o_tmpfile similarity index 100% rename from tests/golden/stage-tmpfile rename to tests/golden/o_tmpfile diff --git a/tests/sequence b/tests/sequence index 1bd0d0d9..9a5298a0 100644 --- a/tests/sequence +++ b/tests/sequence @@ -27,7 +27,7 @@ createmany-large-names.sh createmany-rename-large-dir.sh stage-release-race-alloc.sh stage-multi-part.sh -stage-tmpfile.sh +o_tmpfile.sh basic-posix-consistency.sh dirent-consistency.sh mkdir-rename-rmdir.sh diff --git a/tests/tests/stage-tmpfile.sh b/tests/tests/o_tmpfile.sh similarity index 100% rename from tests/tests/stage-tmpfile.sh rename to tests/tests/o_tmpfile.sh From fe33a492c213452e3052c9744e9701dcb22f399e Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 9 Jan 2023 10:13:48 -0800 Subject: [PATCH 2/3] Make o_tmpfile test more generic The o_tmpfile test only did one thing, clean it up a bit so we can add more tests to the file. Signed-off-by: Zach Brown --- tests/golden/o_tmpfile | 1 + tests/tests/o_tmpfile.sh | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/golden/o_tmpfile b/tests/golden/o_tmpfile index 71496330..a1d111f0 100644 --- a/tests/golden/o_tmpfile +++ b/tests/golden/o_tmpfile @@ -1,3 +1,4 @@ +== stage from tmpfile total file size 33669120 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA| * diff --git a/tests/tests/o_tmpfile.sh b/tests/tests/o_tmpfile.sh index 5a77ed8f..9de214ef 100644 --- a/tests/tests/o_tmpfile.sh +++ b/tests/tests/o_tmpfile.sh @@ -1,15 +1,13 @@ # -# Run tmpfile_stage and check the output with hexdump. +# basic tests of O_TMPFILE # t_require_commands stage_tmpfile hexdump +echo "== stage from tmpfile" DEST_FILE="$T_D0/dest_file" - stage_tmpfile $T_D0 $DEST_FILE - hexdump -C "$DEST_FILE" - -rm -fr "$DEST_FILE" +rm -f "$DEST_FILE" t_pass From 9ba2ee5c880da982ed5efef8c47941b98cd98136 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 9 Jan 2023 10:34:46 -0800 Subject: [PATCH 3/3] Add testing of O_TMPFILE umask There were kernels that didn't apply the current umask to inode modes created with O_TMPFILE without acls. Let's have a test running to make sure that we're not surprised if we come across one. Signed-off-by: Zach Brown --- tests/.gitignore | 1 + tests/Makefile | 3 +- tests/golden/o_tmpfile | 7 +++ tests/src/o_tmpfile_umask.c | 97 +++++++++++++++++++++++++++++++++++++ tests/tests/o_tmpfile.sh | 3 ++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/src/o_tmpfile_umask.c diff --git a/tests/.gitignore b/tests/.gitignore index 9da79900..1982cd68 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -8,3 +8,4 @@ src/bulk_create_paths src/find_xattrs src/stage_tmpfile src/create_xattr_loop +src/o_tmpfile_umask diff --git a/tests/Makefile b/tests/Makefile index fcc43df1..9de59268 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,7 +11,8 @@ BIN := src/createmany \ src/stage_tmpfile \ src/find_xattrs \ src/create_xattr_loop \ - src/fragmented_data_extents + src/fragmented_data_extents \ + src/o_tmpfile_umask DEPS := $(wildcard src/*.d) diff --git a/tests/golden/o_tmpfile b/tests/golden/o_tmpfile index a1d111f0..332bb36f 100644 --- a/tests/golden/o_tmpfile +++ b/tests/golden/o_tmpfile @@ -1,3 +1,10 @@ +== non-acl O_TMPFILE creation honors umask +umask 022 +fstat after open(0777): 0100755 +stat after linkat: 0100755 +umask 077 +fstat after open(0777): 0100700 +stat after linkat: 0100700 == stage from tmpfile total file size 33669120 00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA| diff --git a/tests/src/o_tmpfile_umask.c b/tests/src/o_tmpfile_umask.c new file mode 100644 index 00000000..4ac72c85 --- /dev/null +++ b/tests/src/o_tmpfile_umask.c @@ -0,0 +1,97 @@ +/* + * Show the modes of files as we create them with O_TMPFILE and link + * them into the namespace. + * + * Copyright (C) 2022 Versity Software, Inc. 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 v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void linkat_tmpfile_modes(char *dir, char *lpath, mode_t mode) +{ + char proc_self[PATH_MAX]; + struct stat st; + int ret; + int fd; + + umask(mode); + printf("umask 0%o\n", mode); + + fd = open(dir, O_RDWR | O_TMPFILE, 0777); + if (fd < 0) { + perror("open(O_TMPFILE)"); + exit(1); + } + + ret = fstat(fd, &st); + if (ret < 0) { + perror("fstat"); + exit(1); + } + + printf("fstat after open(0777): 0%o\n", st.st_mode); + + snprintf(proc_self, sizeof(proc_self), "/proc/self/fd/%d", fd); + + ret = linkat(AT_FDCWD, proc_self, AT_FDCWD, lpath, AT_SYMLINK_FOLLOW); + if (ret < 0) { + perror("linkat"); + exit(1); + } + + close(fd); + + ret = stat(lpath, &st); + if (ret < 0) { + perror("fstat"); + exit(1); + } + + printf("stat after linkat: 0%o\n", st.st_mode); + + ret = unlink(lpath); + if (ret < 0) { + perror("unlink"); + exit(1); + } +} + +int main(int argc, char **argv) +{ + char *lpath; + char *dir; + + if (argc < 3) { + printf("%s \n", argv[0]); + return 1; + } + + dir = argv[1]; + lpath = argv[2]; + + linkat_tmpfile_modes(dir, lpath, 022); + linkat_tmpfile_modes(dir, lpath, 077); + + return 0; +} diff --git a/tests/tests/o_tmpfile.sh b/tests/tests/o_tmpfile.sh index 9de214ef..a157a969 100644 --- a/tests/tests/o_tmpfile.sh +++ b/tests/tests/o_tmpfile.sh @@ -4,6 +4,9 @@ t_require_commands stage_tmpfile hexdump +echo "== non-acl O_TMPFILE creation honors umask" +o_tmpfile_umask "$T_D0" "$T_D0/umask-file" + echo "== stage from tmpfile" DEST_FILE="$T_D0/dest_file" stage_tmpfile $T_D0 $DEST_FILE