Skip to content

opcache: support file_cache_read_only (php#16484) #16551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
2e614ae
opcache: support file_cache_read_only (php#16484)
iamacarpet Oct 22, 2024
c32b7ea
Merge remote-tracking branch 'origin/master' into opcache/file_cache_…
iamacarpet Oct 23, 2024
9c42cd1
opcache: file_cache_read_only code review update (php#16484)
iamacarpet Oct 23, 2024
79dd38e
Merge remote-tracking branch 'origin/master' into opcache/file_cache_…
iamacarpet Oct 23, 2024
1197a96
opcache: file_cache_read_only code review update 2 (php#16484)
iamacarpet Oct 23, 2024
86e5178
opcache: file_cache_read_only code review update 3 (php#16484)
iamacarpet Oct 24, 2024
3397f29
Merge remote-tracking branch 'origin/master' into opcache/file_cache_…
iamacarpet Oct 25, 2024
8c43a77
opcache: file_cache_read_only code review update 4 (php#16484)
iamacarpet Oct 25, 2024
8aaa51d
opcache: file_cache_read_only code review update 5 (php#16484)
iamacarpet Oct 29, 2024
3e1c63b
opcache: file_cache_read_only - debug log when active (php#16484)
iamacarpet Oct 29, 2024
9510786
opcache: file_cache_read_only code review update 6 (php#16484)
iamacarpet Oct 29, 2024
c45c69e
opcache: file_cache_read_only - debug log when active 2 (php#16484)
iamacarpet Oct 30, 2024
e5526bd
opcache: file_cache_read_only - fix unit test for Windows (php#16484)
iamacarpet Oct 30, 2024
112b9d6
opcache: file_cache_read_only - documentation consistency (php#16484)
iamacarpet Oct 30, 2024
62765b7
opcache: file_cache_read_only code review update 7 (php#16484)
iamacarpet Nov 5, 2024
35bca09
Merge remote-tracking branch 'origin/master' into opcache/file_cache_…
iamacarpet Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,9 @@ zend_result zend_accel_invalidate(zend_string *filename, bool force)
}

if (ZCG(accel_directives).file_cache) {
if (ZCG(accel_directives).file_cache_read_only) {
return FAILURE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

realpath must be released here

}
zend_file_cache_invalidate(realpath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should skip zend_file_cache_invalidate() here, but not return immediately as we may still want to invalidate the script from SHM (one valid use-case might be that the script is only in SHM, and not in file cache).

}

Expand Down Expand Up @@ -3300,6 +3303,50 @@ static zend_result accel_post_startup(void)
#endif
accel_shared_globals = calloc(1, sizeof(zend_accel_shared_globals));
}

/* opcache.file_cache_read_only should only be enabled when all script files are read-only */
int file_cache_access_mode = 0;

if (ZCG(accel_directives).file_cache_read_only) {
if (!ZCG(accel_directives).file_cache) {
accel_startup_ok = false;
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "opcache.file_cache_read_only is set without a proper setting of opcache.file_cache");
return SUCCESS;
}

/* opcache.file_cache is read only, so ensure the directory is readable */
#ifndef ZEND_WIN32
file_cache_access_mode = R_OK | X_OK;
#else
file_cache_access_mode = 04; // Read access
#endif
} else {
/* opcache.file_cache isn't read only, so ensure the directory is writable */
#ifndef ZEND_WIN32
file_cache_access_mode = R_OK | W_OK | X_OK;
#else
file_cache_access_mode = 06; // Read and write access
#endif
}

if ( ZCG(accel_directives).file_cache ){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: code style

Suggested change
if ( ZCG(accel_directives).file_cache ){
if (ZCG(accel_directives).file_cache) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I guess ‘go fmt’ has made me a bit lazy with manual formatting - thanks for pointing this out!

zend_stat_t buf = {0};

if (!IS_ABSOLUTE_PATH(ZCG(accel_directives).file_cache, strlen(ZCG(accel_directives).file_cache)) ||
zend_stat(ZCG(accel_directives).file_cache, &buf) != 0 ||
!S_ISDIR(buf.st_mode) ||
#ifndef ZEND_WIN32
access(ZCG(accel_directives).file_cache, file_cache_access_mode) != 0
#else
_access(ZCG(accel_directives).file_cache, file_cache_access_mode) != 0
#endif
) {
accel_startup_ok = false;
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "opcache.file_cache must be a full path of an accessible directory");
return SUCCESS;
}
}

#if ENABLE_FILE_CACHE_FALLBACK
file_cache_fallback:
#endif
Expand Down
1 change: 1 addition & 0 deletions ext/opcache/ZendAccelerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ typedef struct _zend_accel_directives {
char *lockfile_path;
#endif
char *file_cache;
bool file_cache_read_only;
bool file_cache_only;
bool file_cache_consistency_checks;
#if ENABLE_FILE_CACHE_FALLBACK
Expand Down
16 changes: 2 additions & 14 deletions ext/opcache/zend_accelerator_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,6 @@ static ZEND_INI_MH(OnUpdateFileCache)
if (new_value) {
if (!ZSTR_LEN(new_value)) {
new_value = NULL;
} else {
zend_stat_t buf = {0};

if (!IS_ABSOLUTE_PATH(ZSTR_VAL(new_value), ZSTR_LEN(new_value)) ||
zend_stat(ZSTR_VAL(new_value), &buf) != 0 ||
!S_ISDIR(buf.st_mode) ||
#ifndef ZEND_WIN32
access(ZSTR_VAL(new_value), R_OK | W_OK | X_OK) != 0) {
#else
_access(ZSTR_VAL(new_value), 06) != 0) {
#endif
zend_accel_error(ACCEL_LOG_WARNING, "opcache.file_cache must be a full path of accessible directory.\n");
new_value = NULL;
}
}
}
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
Expand Down Expand Up @@ -312,6 +298,7 @@ ZEND_INI_BEGIN()
#endif

STD_PHP_INI_ENTRY("opcache.file_cache" , NULL , PHP_INI_SYSTEM, OnUpdateFileCache, accel_directives.file_cache, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.file_cache_read_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_read_only, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.file_cache_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_only, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.file_cache_consistency_checks" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_consistency_checks, zend_accel_globals, accel_globals)
#if ENABLE_FILE_CACHE_FALLBACK
Expand Down Expand Up @@ -823,6 +810,7 @@ ZEND_FUNCTION(opcache_get_configuration)
#endif

add_assoc_string(&directives, "opcache.file_cache", ZCG(accel_directives).file_cache ? ZCG(accel_directives).file_cache : "");
add_assoc_bool(&directives, "opcache.file_cache_read_only", ZCG(accel_directives).file_cache_read_only);
add_assoc_bool(&directives, "opcache.file_cache_only", ZCG(accel_directives).file_cache_only);
add_assoc_bool(&directives, "opcache.file_cache_consistency_checks", ZCG(accel_directives).file_cache_consistency_checks);
#if ENABLE_FILE_CACHE_FALLBACK
Expand Down
4 changes: 4 additions & 0 deletions ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,10 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
}
#endif

if (ZCG(accel_directives).file_cache_read_only) {
return FAILURE;
}

filename = zend_file_cache_get_bin_file_path(script->script.filename);

if (zend_file_cache_mkdir(filename, strlen(ZCG(accel_directives).file_cache)) != SUCCESS) {
Expand Down