转:nfs-ganesha cache lru问题

项目中在使用ganesha2.3.3版本中,遇到一个棘手的问题。
    我们是自己实现的一个分布式文件系统,对接的ganesha-nfs的2.3.3的接口。有一个应用场景是将目录通过nfs挂载给vmware,以建立虚拟机使用。最近在测试强压力测试(vdbench做着压力测试,还开着虚拟机)中,出现了虚拟机开启时报文件不存在的错误,再次开启就好了。
    首先是开启调试日志,预感这种问题应该是在强压力测试下才可能出现的, 让测试想办法再复现。刚开始以为我们文件系统的cache存在问题,进行了一下简单的cache代码排查,暂时没有发现问题。
     终于过了两天测试告诉我们复现了,谢天谢地,兴奋的跑去查日志,查找找不到目录的所有条目,发现一条重要的线索,有一条lookup记录居然通过vdbench中的目录作为父目录,去查找挂载给vmware的文件夹中的目录(名字取得骚气,很容易看出来),我说你们两个一点血缘关系都没有,去找什么,难道想处对象吗?直觉告诉我,可能真的与cache相关,但是不会是我们的cache,而是ganesha中的cache,可惜之前懒,加之工作量大,人手不足,没有仔细看ganesha-nfs的inode cache的代码,不知道为什么会发生这样的事情,只有拿出杀手锏,抓包,通过抓包找到这样发送的原因,在针对性的看代码。
    手动复现抓包真的是一个不可取的工程,而且鬼知道下一次复现是什么时候,包又不能一直在抓着,太大。让测试写了个自动化测试的脚本,给虚拟机开机时,调用抓包,开机成功,重新抓包。开机失败,保存当次抓包的数据。
     漫长等待自动化测试跑了两三天,果然又复现了,这一次还不逮着你。使用最原始但是最有效的方法,将开机成功的包,和开机失败的包一行一行的对比,眼睛都快看瞎了的情况下,终于发现了问题,万恶的lookup.., 在开机时,一次vmware文件夹中的目录在进行lookup .., 居然返回了vdbench中一个目录的句柄,然后客户端傻傻的用这个句柄去查找这个目录,当然是找不到。而在我们的调试日志里,没有出现这一次的lookup..的记录,说明是在ganesha的cache中查到就返回了,我去,果然和我猜的一样,只能去啃2.3.3的代码了,因为最新的ganesha重构了inode cache,代码结构不一样了。
    使用了各种方法,加各种调试日志,使用valgrind查看是否被别人踩错内存,意外的发现里面的cache_entry_t条目的dir.parent没有进行过释放,按理说没有释放最多内存泄漏,也不会出现类似这个问题。但是仔细看了代码后发现,cache条目在lru满了的情况下,会回收重复利用,而新malloc的cache条目由于是使用的calloc,默认初始话为0,回收的时候,没有释放parent条目,也就没有重新初始化为其他的值,在调用cache_inode_new_entry就已经加入到全局的avl树中了,之后才对dir.parent字段进行赋值,在多线程高压的环境下,lookup .. 的时候就可能利用这个时间差,找到了一个回收的cache对应的parent,导致出现了这个问题。
    我让测试将配置文件中的lru的阈值改小进行测试,这个问题果然很快就复现了,哈哈,天助我也,我就在回收的时候将parent释放,并且初始化为NULL,这样应该就不存在这个问题了。合入代码之后,在lru改小的情况下已经跑了三四天了,果然没有出现此问题。如果没有vmware频繁的调用lookup..这个问题估计很难被发现。
    其实在最新的ganesha中,重构之后的mdcache,这个内存泄漏的问题已经不存在了,和ganesha的开发者交流了一下,建议我们使用最新的稳定版的ganesha,因为之前的版本可能还存在这样那样的问题,我们也要考虑换成2.5稳定版的ganesha了,不过这一次调试也是一个学习的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值