commit - 21cc568c69c3d3331993c72b5b36b6f8dfa9bcd1
commit + 142ee1a6a87651c3b727ed2bfbacf231d8783a27
blob - dd3ebd11438d2c890e629700699df429f832f6d5
blob + 4ff61ed78acad0a8b635930425a54000e6c24f0e
--- CMakeLists.txt
+++ CMakeLists.txt
cmake_minimum_required (VERSION 3.10.2)
+
+include(CheckFunctionExists)
+
project (unreliablefs
DESCRIPTION "A FUSE-based fault injection filesystem.")
target_include_directories(${PROJECT_NAME} PRIVATE ${FUSE_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${FUSE_LIBRARIES})
+check_function_exists(utimensat HAVE_UTIMENSAT)
+if (${HAVE_UTIMENSAT})
+ target_compile_definitions(${PROJECT_NAME} PUBLIC HAVE_UTIMENSAT)
+endif ()
+
enable_testing()
add_test(NAME pytest COMMAND pytest -c ${PROJECT_SOURCE_DIR}/tests/pytest.ini ${PROJECT_SOURCE_DIR}/tests/
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
blob - c50e3ca4a4d639a08c0031b66104f62b95db33b9
blob + 747bdb57e744d6830967dca557f2160d462abe83
--- tests/test_unreliablefs.py
+++ tests/test_unreliablefs.py
with open(mnt_name, 'w') as fh:
fcntl.flock(fh, fcntl.LOCK_EX | fcntl.LOCK_NB)
fcntl.flock(fh, fcntl.LOCK_UN)
+
+@pytest.mark.parametrize("symlink", (False, True))
+def test_utimens(setup_unreliablefs, symlink):
+ mnt_dir, src_dir = setup_unreliablefs
+ name = name_generator()
+ src_name = pjoin(src_dir, name)
+ mnt_name = pjoin(mnt_dir, name)
+ os_create(mnt_name)
+ linkname = name_generator()
+ link_path = os.path.join(mnt_dir, linkname)
+ os.symlink(mnt_name, link_path)
+ if symlink:
+ target = link_path
+ else:
+ target = mnt_name
+
+ fstat = os.lstat(link_path)
+ link_atime = fstat.st_atime
+ link_mtime = fstat.st_mtime
+
+ fstat = os.lstat(mnt_name)
+ mnt_name_atime = fstat.st_atime + 10
+ mnt_name_mtime = fstat.st_mtime + 10
+ os.utime(target, (mnt_name_atime, mnt_name_mtime))
+
+ fstat = os.lstat(mnt_name)
+ assert fstat.st_atime == mnt_name_atime
+ assert fstat.st_mtime == mnt_name_mtime
+
+ if symlink:
+ fstat = os.lstat(link_path)
+ assert fstat.st_atime == link_atime
+ assert fstat.st_mtime == link_mtime
blob - 634a6331e48b6b251701d956ab4b24a5c93351ce
blob + cc0826a6abbfa403b1d8518fe2c2ec157978d90c
--- unreliablefs.1
+++ unreliablefs.1
.Xr symlink 2 ,
.Xr truncate 2 ,
.Xr unlink 2 ,
+.Xr utimensat 2 ,
.Xr write 2 .
.Pp
Following functions are unsupported on OpenBSD:
blob - 4c49e2c929e3e21b4186fb552ab01f2756f2ecd1
blob + e9ac458231bf34ae4c4ecfbc35e39c6f6409c2c2
--- unreliablefs.c
+++ unreliablefs.c
.flock = unreliable_flock,
.fallocate = unreliable_fallocate,
#endif /* __OpenBSD__ */
+#ifdef HAVE_UTIMENSAT
+ .utimens = unreliable_utimens,
+#endif
};
int main(int argc, char *argv[])
blob - c36cd92b912bb0d19595349075a9844ee785f9e2
blob + f416c6fd23aa5a038a7be649dacca2be8734a0c0
--- unreliablefs_ops.c
+++ unreliablefs_ops.c
#include <sys/xattr.h>
#endif /* __OpenBSD__ */
+#ifdef linux
+/* For pread()/pwrite()/utimensat() */
+#define _XOPEN_SOURCE 700
+#endif
+
#include "unreliablefs_errinj.h"
#include "unreliablefs_ops.h"
return 0;
}
#endif /* __OpenBSD__ */
+
+#ifdef HAVE_UTIMENSAT
+int unreliable_utimens(const char *path, const struct timespec ts[2])
+{
+ int ret = error_inject(path, "utimens");
+ if (ret) {
+ return ret;
+ }
+
+ /* don't use utime/utimes since they follow symlinks */
+ ret = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
+ if (ret == -1) {
+ return -errno;
+ }
+
+ return 0;
+}
+#endif
blob - eaced3f65b1ae24d76b449d97d2df3f97babf0ae
blob + 92b635ecae2da610402feb5f1ba53528f8e0c903
--- unreliablefs_ops.h
+++ unreliablefs_ops.h
struct fuse_file_info *);
#endif /* __OpenBSD__ */
+#ifdef HAVE_UTIMENSAT
+int unreliable_utimens(const char *path, const struct timespec ts[2]);
+#endif
+
#endif /* UNRELIABLEFS_OPS_HH */