ID: 48677 Updated by: j...@php.net Reported By: rickt at rickt dot org -Status: Open +Status: Feedback Bug Type: Safe Mode/open_basedir Operating System: CentOS 4 update 5 PHP Version: 5.2.10
Previous Comments: ------------------------------------------------------------------------ [2009-06-24 21:09:49] ras...@php.net But what are these lstats? Are they the result of a realpath call? as in something like: lstat64 / lstat64 /var lstat64 /var/www and at the end of this chain does it result in an ENOENT? If so, PHP 5.3 will help a bit with this because we have replaced the realpath syscall with our own version which will cache the stats within realpath. Currently in PHP <5.3 we only cache a successful realpath call, so if you are missing on your include_path there is no cache for the miss and you will see the stats on every request. It is extremely important that you do not miss. All includes relative to your script should be: include './path/foo.php'; and all include_path includes should be: include 'path/bar.php'; where your include_path has just '/some/dir' in it and the file would be in /some/dir/path/bar.php If you do not do it this way and bounce through multiple include_paths in order to find a file, open_basedir is super painful. If you are doing all this, you could either be overflowing your realpath_cache in which case making it larger might solve it, or alternatively you could be calling clearstatcache() somewhere which will blow away your realpath_cache. This is also fixed in 5.3 where I added a flag to force a realpath_cache clear from that call, but by default it won't clear it anymore. Just as a reference, Yahoo has open_basedir enabled on all their servers, and if you understand and follow all of the above, your stats will go away, I guarantee it. ------------------------------------------------------------------------ [2009-06-24 17:39:10] rickt at rickt dot org Description: ------------ This is related to bug ID 43946. I too am seeing terrible performance when using open_basedir. Even when using the various hints/tips about open_basedir (put "." at the end, put most-frequently-used include paths at the beginning of the variable, etc), and despite our best efforts at reducing the number of entries within open_basedir, with only 3 entries (including ".") we see an enormous CPU hit. Reproduce code: --------------- A site that with no open_basedir set had an average CPU load of about 90-98% idle with 1-2% in system time. With open_basedir set, CPU load immediately climbs to 0-1% idle, and up to 91+% in system time, as can be seen below via the output from sar: --- snip --- 07:00:03 PM CPU %user %nice %system %iowait %idle 07:10:04 PM all 1.41 0.00 1.29 0.47 96.84 07:20:02 PM all 0.44 0.00 0.69 0.44 98.43 07:30:01 PM all 3.33 0.00 22.97 0.32 73.37 07:40:05 PM all 9.83 0.00 74.31 0.09 15.77 07:50:03 PM all 8.33 0.00 90.48 0.01 1.18 08:00:03 PM all 7.85 0.00 91.39 0.00 0.75 08:10:05 PM all 7.67 0.00 90.51 0.08 1.74 08:20:02 PM all 7.68 0.00 91.65 0.03 0.64 08:30:02 PM all 7.64 0.00 91.75 0.03 0.58 08:40:02 PM all 8.24 0.00 90.95 0.06 0.75 08:50:04 PM all 9.30 0.00 66.71 2.68 21.31 09:00:05 PM all 9.04 0.00 64.47 0.13 26.36 09:10:01 PM all 9.13 0.00 64.76 0.14 25.96 09:20:03 PM all 9.65 0.00 34.30 0.25 55.80 09:30:07 PM all 10.21 0.00 3.40 0.37 86.01 09:40:02 PM all 9.66 0.00 3.18 0.39 86.77 09:50:02 PM all 9.52 0.00 3.16 0.37 86.95 10:00:03 PM all 9.42 0.00 3.13 0.38 87.07 Average: all 7.75 0.00 11.53 0.46 80.26 --- snip --- We added the open_basedir entry (with only 3 folders) at around 07:25 and you can see the massive spike at 07:30:01. Our docroot/code bases are clean and don't have that many includes/requires. We turned off the open_basedir and restarted our fcgis at around 09:25 and the immediate dropoff in load can of course be seen. Having straced the processes in question, we see enormous amounts of lstat()s and readlink()s etc. Google reveals some interesting things, specific to the change that occurred in PHP 5.1.5, specific to the php_check_specific_open_basedir() function. I guess that further security-checking code was added to limit the possibility of escaping the open_basedir using symlinks. Expected result: ---------------- n/a Actual result: -------------- n/a ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=48677&edit=1