From: Christian Brauner Date: Fri, 30 Mar 2018 04:54:40 +0000 (+0200) Subject: lxclock: use thread-safe *_OFD_* fcntl() locks X-Git-Tag: lxc-2.0.10~179 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b41008b4f4d597706e7af2b4c73601ea8a144b60;p=thirdparty%2Flxc.git lxclock: use thread-safe *_OFD_* fcntl() locks If they aren't available fallback to BSD flock()s. Closes #2245. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c index b5ecdcb5b..31dbd1c13 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c @@ -54,8 +54,8 @@ static inline void dump_stacktrace(void) size = backtrace(array, MAX_STACKDEPTH); strings = backtrace_symbols(array, size); - // Using fprintf here as our logging module is not thread safe - fprintf(stderr, "\tObtained %zu stack frames.\n", size); + /* Using fprintf here as our logging module is not thread safe. */ + fprintf(stderr, "\tObtained %zu stack frames\n", size); for (i = 0; i < size; i++) fprintf(stderr, "\t\t%s\n", strings[i]); @@ -195,7 +195,7 @@ int lxclock(struct lxc_lock *l, int timeout) case LXC_LOCK_ANON_SEM: if (!timeout) { ret = sem_wait(l->u.sem); - if (ret == -1) + if (ret < 0) saved_errno = errno; } else { struct timespec ts; @@ -205,7 +205,7 @@ int lxclock(struct lxc_lock *l, int timeout) } ts.tv_sec += timeout; ret = sem_timedwait(l->u.sem, &ts); - if (ret == -1) + if (ret < 0) saved_errno = errno; } break; @@ -220,21 +220,22 @@ int lxclock(struct lxc_lock *l, int timeout) goto out; } if (l->u.f.fd == -1) { - l->u.f.fd = open(l->u.f.fname, O_RDWR|O_CREAT, - S_IWUSR | S_IRUSR); + l->u.f.fd = open(l->u.f.fname, O_CREAT | O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_NOCTTY, S_IWUSR | S_IRUSR); if (l->u.f.fd == -1) { ERROR("Error opening %s", l->u.f.fname); saved_errno = errno; goto out; } } + memset(&lk, 0, sizeof(struct flock)); lk.l_type = F_WRLCK; lk.l_whence = SEEK_SET; - lk.l_start = 0; - lk.l_len = 0; - ret = fcntl(l->u.f.fd, F_SETLKW, &lk); - if (ret == -1) + ret = fcntl(l->u.f.fd, F_OFD_SETLKW, &lk); + if (ret < 0) { + if (errno == EINVAL) + ret = flock(l->u.f.fd, LOCK_EX); saved_errno = errno; + } break; } @@ -259,13 +260,15 @@ int lxcunlock(struct lxc_lock *l) break; case LXC_LOCK_FLOCK: if (l->u.f.fd != -1) { + memset(&lk, 0, sizeof(struct flock)); lk.l_type = F_UNLCK; lk.l_whence = SEEK_SET; - lk.l_start = 0; - lk.l_len = 0; - ret = fcntl(l->u.f.fd, F_SETLK, &lk); - if (ret < 0) + ret = fcntl(l->u.f.fd, F_OFD_SETLK, &lk); + if (ret < 0) { + if (errno == EINVAL) + ret = flock(l->u.f.fd, LOCK_EX | LOCK_NB); saved_errno = errno; + } close(l->u.f.fd); l->u.f.fd = -1; } else diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h index e097216ee..32cb1dd67 100644 --- a/src/lxc/lxclock.h +++ b/src/lxc/lxclock.h @@ -23,12 +23,25 @@ #ifndef __LXC_LXCLOCK_H #define __LXC_LXCLOCK_H -#include /* For O_* constants */ -#include /* For mode constants */ -#include +#include #include #include +#include +#include #include +#include + +#ifndef F_OFD_GETLK +#define F_OFD_GETLK 36 +#endif + +#ifndef F_OFD_SETLK +#define F_OFD_SETLK 37 +#endif + +#ifndef F_OFD_SETLKW +#define F_OFD_SETLKW 38 +#endif #define LXC_LOCK_ANON_SEM 1 /*!< Anonymous semaphore lock */ #define LXC_LOCK_FLOCK 2 /*!< flock(2) lock */