Skip to content

Commit e9c8621

Browse files
MaxKellermanndevnexen
authored andcommitted
ext/opcache/zend_shared_alloc: use memfd for locking if available
A memfd is a virtual file that has no reachable path, therefore does not clobber any filesystem. It is deleted automatically as soon as the last handle gets closed. The feature is available since Linux kernel 3.17. Closes GH-10589.
1 parent ab99072 commit e9c8621

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ PHP NEWS
7777
(Arnaud)
7878
. Allows W/X bits on page creation on FreeBSD despite system settings.
7979
(David Carlier)
80+
. Added memfd api usage, on Linux, for zend_shared_alloc_create_lock()
81+
to create an abstract anonymous file for the opcache's lock. (Max Kellermann)
8082

8183
- PCNTL:
8284
. SA_ONSTACK is now set for pcntl_signal. (Kévin Dunglas)

ext/opcache/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ if test "$PHP_OPCACHE" != "no"; then
105105

106106
fi
107107

108-
AC_CHECK_FUNCS([mprotect])
108+
AC_CHECK_FUNCS([mprotect memfd_create])
109109

110110
AC_MSG_CHECKING(for sysvipc shared memory support)
111111
AC_RUN_IFELSE([AC_LANG_SOURCE([[

ext/opcache/zend_shared_alloc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
+----------------------------------------------------------------------+
2020
*/
2121

22+
#if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
23+
# ifndef _GNU_SOURCE
24+
# define _GNU_SOURCE
25+
# endif
26+
# include <sys/mman.h>
27+
#endif
28+
2229
#include <errno.h>
2330
#include "ZendAccelerator.h"
2431
#include "zend_shared_alloc.h"
@@ -81,6 +88,18 @@ void zend_shared_alloc_create_lock(char *lockfile_path)
8188
zts_lock = tsrm_mutex_alloc();
8289
#endif
8390

91+
#if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
92+
/* on Linux, we can use a memfd instead of a "real" file, so
93+
* we can do this without a writable filesystem and without
94+
* needing to clean up */
95+
/* note: FreeBSD has memfd_create(), too, but fcntl(F_SETLKW)
96+
* on it fails with EBADF, therefore we use this only on
97+
* Linux */
98+
lock_file = memfd_create("opcache_lock", MFD_CLOEXEC);
99+
if (lock_file >= 0)
100+
return;
101+
#endif
102+
84103
snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX);
85104
lock_file = mkstemp(lockfile_name);
86105
if (lock_file == -1) {

0 commit comments

Comments
 (0)