An in depth understanding of PHP principles of Session Gc is a small probability Notice

  • 2020-03-31 21:38:22
  • OfStack

If you are using PHP installed in apt under ubuntu/Debian, you may encounter this tip with a small probability when using Session.
 
PHP Notice: session_start(): ps_files_cleanup_dir: 
opendir(/var/lib/php5) failed: Permission denied (13) 
in /home/laruence/www/htdocs/index.php on line 22 

This is because, in PHP, if you use file_handler as the save handler of Session, there is a probability that you will run the Session Gc procedure every time session_start.
 
//There are omitted
int nrdels = -1; 
nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg(TSRMLS_C)); 
if (nrand < PS(gc_probability)) { 
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels TSRMLS_CC); 
} 
//There are omitted

The reason for this warning is that in apt PHP, the default directory of session /var/lib-php5 has permission of 733 with sticky bit, i.e
 
drwx-wx-wt root roo 

However, workers in PHP generally run under the non-root identity, so they have no permission to open this folder (but since it can be written, it will not affect the normal Session file reading). Therefore, the following code in s_gc will trigger the Notice mentioned at the beginning:
 
//For the file handler, s_gc indirectly calls ps_files_cleanup_dir:
dir = opendir(dirname); 
if (!dir) { 
php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
"ps_files_cleanup_dir: opendir(%s) failed: %s (%d)", 
dirname, strerror(errno), errno); 
return (0); 
} 

Of course, under ubuntu/Debian, there is still gc collection, which is only done by the external cron process. The default is /etc/cron.d/php5:,
 
09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] 
&& [ -d /var/lib/php5 ] && find /var/lib/php5/ 
-type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 
| xargs -n 200 -r -0 r 

In addition, it can be seen that when determining whether s_gc is running, there are two key variables: PS(gc_divisor) and PS(gc_probability), which respectively correspond to two configuration items of the same name of the runtime configuration item of session:
Session.gc_probability and session.gc_divisor, which default to 1 and 100, respectively.
Php_combined_lcg is a random number generator, generating random Numbers in the range of 0 to 1, so the above discriminant is equivalent to:
 
rand < probability / gc_diviso 

In other words, by default, you can call a gc procedure about 100 times.
To turn off this Notice, simply set:
Session.gc_probability = 0, making s_gc completely impossible to run.
Of course, you can also change the permissions of this folder...
Finally, thanks to CFC4N for this question.
Author: Laruence()
This paper address: http://www.laruence.com/2011/03/29/1949.html

Related articles: