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 1 commit
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
36 changes: 36 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,39 @@ 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 */
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;
}
if (ZCG(accel_directives).revalidate_freq != 0) {
accel_startup_ok = false;
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "opcache.file_cache_read_only cannot be enabled when opcache.revalidate_freq is not 0.");
return SUCCESS;
}
if (ZCG(accel_directives).validate_timestamps) {
accel_startup_ok = false;
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "opcache.file_cache_read_only cannot be enabled when opcache.validate_timestamps is enabled.");
return SUCCESS;
}
Copy link
Member

Choose a reason for hiding this comment

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

I think, these checks may be removed.
In case these options are set to 0, opcache will always prefer file_cache, otherwise it'll compile PHP script if it's newer than cached.

} else {
/* opcache.file_cache isn't read only, so ensure the directory is writable */
if ( ZCG(accel_directives).file_cache &&
#ifndef ZEND_WIN32
access(ZCG(accel_directives).file_cache, R_OK | W_OK | X_OK) != 0
#else
_access(ZCG(accel_directives).file_cache, 06) != 0
#endif
) {
accel_startup_ok = false;
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "opcache.file_cache must be a full path of an accessible, writable 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
12 changes: 7 additions & 5 deletions ext/opcache/zend_accelerator_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ static ZEND_INI_MH(OnUpdateFileCache)
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) {
access(ZSTR_VAL(new_value), R_OK | X_OK) != 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Probably, this check may be completely moved into accel_post_startup().

#else
_access(ZSTR_VAL(new_value), 06) != 0) {
_access(ZSTR_VAL(new_value), 04) != 0) {
#endif
zend_accel_error(ACCEL_LOG_WARNING, "opcache.file_cache must be a full path of accessible directory.\n");
new_value = NULL;
Expand Down Expand Up @@ -311,9 +311,10 @@ ZEND_INI_BEGIN()
STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
#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_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)
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)
Copy link
Member

Choose a reason for hiding this comment

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

It's better not to mix new features with white-space changes to keep the path small and easy readable.

#if ENABLE_FILE_CACHE_FALLBACK
STD_PHP_INI_BOOLEAN("opcache.file_cache_fallback" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_fallback, zend_accel_globals, accel_globals)
#endif
Expand Down Expand Up @@ -823,6 +824,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
Loading