分享、学习、提高
2015/07/31 23:31
文章作者:Enjoy 转载请注明原文链接。
一天,发现/tmp下有大量的文件,排除掉其它已知的文件后,有近100w个文件,导致这个目录下操作非常慢,甚至影响整个系统。

怎么产生的呢?
1.发现文件名有规律,都是wrt头部的9位文件名,如
./wrtDNt7ZF
./wrtGlk121
./wrtJbMYV7
./wrtM7YMGX
./wrt1eIV0r
2.打开几个文件看了下,发现像是某页面的smarty缓存,定位到smarty问题。

找到那个页面,发现在指定的目录下,没有生成smarty缓存,生成到/tmp目录去了?怎么会生成那那边去呢?

搜索smarty的核心代码
smarty_libs\internals\core.write_file.php
27行:$_tmp_file = tempnam($_dirname, 'wrt');

在smarty_core_write_file函数里

查看tempnam的说明:
    在指定目录中建立一个具有唯一文件名的文件。如果该目录不存在,tempnam() 会在系统临时目录中生成一个文件,并返回其文件名。
    如果 PHP 不能在指定的 dir 参数中创建文件,则退回到系统默认值。
    
经测试:
    1.用tempnam()在linux下就是会生成一个6位的随机文件名,加上wrt的前缀,和文件名对应上了!
    2.$_dirname是存在的。

再搜索smarty的核心代码
smarty_libs\internals\core.write_compiled_resource.php
在function smarty_core_write_cache_file函数里
75行左右:
        if(!@is_writable($smarty->cache_dir)) {
            // cache_dir not writable, see if it exists
            if(!@is_dir($smarty->cache_dir)) {
                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
                return false;
            }
            $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
            return false;
        }

        
smarty是使用is_writable和is_dir来判断目录是否可写的,所以当$_dirname不存在或无法写入时都会直接报错。
  
再测试:    
    发现这个$_dirname目录没有x权限。
    
结论:
    $_dirname目录没有x权限时,smarty判断目录是否存在,以及是否有写入权限的判断会被跳过,真正写入时才会发现没有写入权限,导致写入到/tmp目录去了。
    加上x权限,问题就可以解决。
    
一些测试代码:
var_dump(is_dir($dir));
var_dump(file_exists($dir));
var_dump(is_writable($dir));

$_tmp_file = tempnam($dir, 'wrt');
echo $_tmp_file;

drwxr-xr-x.   2 www www   4096 Jul 27 09:40 hx_test
输出
bool(true) bool(true) bool(true) /www/sitedata/9enjoy_cache/hx_test/wrtUKUpgk

chmod -x /www/sitedata/9enjoy_cache/hx_test/
输出
bool(true) bool(true) bool(true) /tmp/wrtDbd58a

chmod u+x /www/sitedata/9enjoy_cache/hx_test/
恢复
bool(true) bool(true) bool(true) /www/sitedata/9enjoy_cache/hx_test/wrtUKUpgk


最后,怎么把这100w个文件删除呢???直接rm肯定把服务器搞挂了。
用find命令找出一些后删除,分多次删除。
发表评论
表情
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
昵称   密码   游客无需密码
网址   电邮   [注册]
               

验证码 不区分大小写