From 14b26480e26dbb2e40db039c4fad95548247dddd Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Tue, 10 Jan 2017 17:21:56 +0100 Subject: posix: Fix creation of files with S_ISVTX on FreeBSD On FreeBSD the S_ISVTX flag is completely ignored when creating a regular file. Since gluster needs to create files with this flag set, specialy for DHT link files, it's necessary to force the flag. This fix does this by calling fchmod() after creating a file that must have this flag set. > Change-Id: I51eecfe4642974df6106b9084a0b144835a4997a > BUG: 1411228 > Signed-off-by: Xavier Hernandez > Reviewed-on: https://review.gluster.org/16417 > Smoke: Gluster Build System > NetBSD-regression: NetBSD Build System > CentOS-regression: Gluster Build System > Reviewed-by: Raghavendra Bhat > Reviewed-by: Kaleb KEITHLEY Change-Id: I2087516383bd132c59bbab98eda8f2243a2163fe BUG: 1424973 Signed-off-by: Xavier Hernandez Reviewed-on: https://review.gluster.org/16686 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System Reviewed-by: Raghavendra Bhat Reviewed-by: Shyamsundar Ranganathan --- libglusterfs/src/syscall.c | 47 +++++++++++++++++++++++++----------- libglusterfs/src/syscall.h | 6 ++++- xlators/cluster/ec/src/ec-code.c | 2 +- xlators/mgmt/glusterd/src/glusterd.c | 2 +- xlators/storage/posix/src/posix.c | 6 ++--- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index 7336e06891a..4e4c6a728da 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -57,25 +57,44 @@ sys_fstatat(int dirfd, const char *pathname, struct stat *buf, int flags) int -sys_openat(int dirfd, const char *pathname, int flags, ...) -{ - mode_t mode = 0; - if (flags & O_CREAT) { - va_list ap; - va_start(ap, flags); - mode = va_arg(ap, int); - va_end(ap); - } +sys_openat(int dirfd, const char *pathname, int flags, int mode) +{ + int fd; #ifdef GF_DARWIN_HOST_OS if (fchdir(dirfd) < 0) return -1; - return open (pathname, flags, mode); -#else - return openat (dirfd, pathname, flags, mode); -#endif + fd = open (pathname, flags, mode); + /* TODO: Shouldn't we restore the old current directory */ +#else /* GF_DARWIN_HOST_OS */ + fd = openat (dirfd, pathname, flags, mode); +#ifdef __FreeBSD__ + /* On FreeBSD S_ISVTX flag is ignored for an open() with O_CREAT set. + * We need to force the flag using fchmod(). */ + if ((fd >= 0) && + ((flags & O_CREAT) != 0) && ((mode & S_ISVTX) != 0)) { + sys_fchmod(fd, mode); + /* TODO: It's unlikely that fchmod could fail here. However, + if it fails we cannot always restore the old state + (if the file existed, we cannot recover it). We would + need many more system calls to correctly handle all + possible cases and it doesn't worth it. For now we + simply ignore the error. */ + } +#endif /* __FreeBSD__ */ +#endif /* !GF_DARWIN_HOST_OS */ + + return fd; } + +int +sys_open(const char *pathname, int flags, int mode) +{ + return sys_openat(AT_FDCWD, pathname, flags, mode); +} + + DIR * sys_opendir (const char *name) { @@ -256,7 +275,7 @@ sys_utimes (const char *filename, const struct timeval times[2]) int sys_creat (const char *pathname, mode_t mode) { - return creat (pathname, mode); + return sys_open(pathname, O_CREAT | O_TRUNC | O_WRONLY, mode); } diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h index 1a2658b94f1..b1bcad138c5 100644 --- a/libglusterfs/src/syscall.h +++ b/libglusterfs/src/syscall.h @@ -63,8 +63,12 @@ sys_fstat (int fd, struct stat *buf); int sys_fstatat (int dirfd, const char *pathname, struct stat *buf, int flags); + +int +sys_open (const char *pathname, int flags, int mode); + int -sys_openat (int dirfd, const char *pathname, int flags, ...); +sys_openat (int dirfd, const char *pathname, int flags, int mode); DIR *sys_opendir (const char *name); diff --git a/xlators/cluster/ec/src/ec-code.c b/xlators/cluster/ec/src/ec-code.c index 9647a08287c..25a501e61b7 100644 --- a/xlators/cluster/ec/src/ec-code.c +++ b/xlators/cluster/ec/src/ec-code.c @@ -963,7 +963,7 @@ ec_code_detect(xlator_t *xl, const char *def) return NULL; } - file.fd = sys_openat(AT_FDCWD, PROC_CPUINFO, O_RDONLY); + file.fd = sys_open(PROC_CPUINFO, O_RDONLY, 0); if (file.fd < 0) { goto out; } diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index 88361877efe..11d4b8bc79f 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -947,7 +947,7 @@ check_prepare_mountbroker_root (char *mountbroker_root) dfd0 = dup (dfd); for (;;) { - ret = sys_openat (dfd, "..", O_RDONLY); + ret = sys_openat (dfd, "..", O_RDONLY, 0); if (ret != -1) { dfd2 = ret; ret = sys_fstat (dfd2, &st2); diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index c989d5527a1..aa7e7404099 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -2006,7 +2006,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this, if (fdstat_requested || (priv->background_unlink && IA_ISREG (loc->inode->ia_type))) { - fd = open (real_path, O_RDONLY); + fd = sys_open (real_path, O_RDONLY, 0); if (fd == -1) { op_ret = -1; op_errno = errno; @@ -2867,7 +2867,7 @@ posix_create (call_frame_t *frame, xlator_t *this, if (priv->o_direct) _flags |= O_DIRECT; - _fd = open (real_path, _flags, mode); + _fd = sys_open (real_path, _flags, mode); if (_fd == -1) { op_errno = errno; @@ -3028,7 +3028,7 @@ posix_open (call_frame_t *frame, xlator_t *this, if (priv->o_direct) flags |= O_DIRECT; - _fd = open (real_path, flags, 0); + _fd = sys_open (real_path, flags, 0); if (_fd == -1) { op_ret = -1; op_errno = errno; -- cgit