diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2017-01-10 17:21:56 +0100 |
---|---|---|
committer | Kaleb KEITHLEY <kkeithle@redhat.com> | 2017-02-26 16:47:33 -0500 |
commit | 19aeb28e73c20a9ded183676c6080dc37515513c (patch) | |
tree | 7fa19715d0088717bc9f7dbf57ca1578908db76b /libglusterfs/src/syscall.c | |
parent | 5d499cc221850fb1f83b625df5a113e0b83d0a99 (diff) |
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 <xhernandez@datalab.es>
> Reviewed-on: https://review.gluster.org/16417
> Smoke: Gluster Build System <jenkins@build.gluster.org>
> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
> Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Change-Id: Icaf46ebb440a3a722fd2fd771dd9d2f765b35ef4
BUG: 1424974
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: https://review.gluster.org/16687
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Diffstat (limited to 'libglusterfs/src/syscall.c')
-rw-r--r-- | libglusterfs/src/syscall.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index 7cf1c7757fe..d8b5024f67b 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) { @@ -239,7 +258,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); } |