pnfs执行truncate失败的BUG解析
来源:互联网 发布:hd2软件下载 编辑:程序博客网 时间:2024/04/30 09:38
Bug 名称
Truncate操作失败
Bug 描述
使用fstest工具,先执行create再执行truncate后,服务器会返回EIO,而不是期望的0,过一段时间之后,重复执行truncate则成功。
这是导致truncate测试用例所有失败的唯一原因。具体测试脚本在fstest/tests/truncate目录下。
Bug 重现过程
1. 在客户端挂载目录下,使用fstest创建一个文件
命令:./fstest create aaa 0644
2. 执行truncate操作
命令:./fstest truncate aaa 1234567
3. 会显示EIO
出现bug的系统日志
客户端日志:
服务器端日志:
Bug 分析
现象分析
根据操作不成功的返回值EIO,很难分析出具体原因,因为EIO是经过err_map操作之后的映射值,具体错误的返回值需要在log中定位。
log分析
1. 根据客户端和服务器的错误返回值10038,得出对应的宏定义是ERR_OPENMODE;
2. 通过在服务器端日志的3903行(见上图)分析,定位出错的具体代码函数。
3. 通过步骤1和步骤2,结合阅读代码,得出结论:在函数nfs4_preprocess_stateid_op中,走如下流程:
经过判断,当前stateid是存在 对应的delegation的,然后进入check_delemode()函数,该函数代码如下:
在2295行,经过打printk,断定dp->dl_type的值为NFS4_OPEN_DELEAGATE_READ。
4. 经过阅读PNFS协议,发现在setattr()操作之前进行的open()操作,服务器会尝试授予delegation.
5. 阅读服务器端open()操作代码,发现调用nfs4_open_delegation(current_fh, open, stp)后,入口参数open,中含有op_share_access变量,经过打印输入,其值为NFS4_SHARE_ACCESS_READ。在随后进行的分配delegation操作中,会把分配给它的delegation设置为NFS4_SHARE_ACCESS_READ。当客户端下次持有这个delegation来执行setattr操作时,由于设置了修改size的标志位,导致delegation的类型判断失败,操作失败。
6. 若在shell中执行touch命令创建文件,然后在执行truncate系统调用,则不会出现同样错误,是因为touch触发的系统调用是:open("cc", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666);而测试脚本中的创建命令是open(STR(0), O_CREAT | O_EXCL, NUM(1));两者相比,创建时候的标志位设置不同,导致服务器接收到的open操作,入口参数的op_share_access不同,从而测试脚本的命令可以获得读权限的delegation,而touch命令则无法获取delegation。
7. 对于使用测试脚本创建文件,过一段时间后在执行truncate操作可以成功。
是由于客户端会每60秒执行nfs4_renew_state(struct work_struct *work)操作,此操作会检查是否存在“unreferenced”的delegation,若有则将其释放。
而truncate操作之后,会执行文件的close操作,删除对应dentry,使得open操作得到的delegation变成“unreferenced”,在nfs4_renew_state()操作中被删除。也就是说,文件被创建之后,只要客户端执行了nfs4_renew_state操作,再执行truncate操作,就可以成功。
8.由于nfs4_renew_state()操作是定期执行的,而truncate操作是随机发生的,导致之前的第一次操作失败后,间隔“不确定的时间”,再次成功。
Bug定位
执行修改文件大小的操作时候,客户端持有的delegation类型为NFS4_SHARE_ACCESS_READ。
解决方案
在客户端发送setattr()请求之前,检查修改size的标志位是否设置,若设置,则释放delegation。
在函数nfs_setattr()中,添加如下代码:
验证
验证通过。
代码以及文档的提交路径
- pnfs执行truncate失败的BUG解析
- pNFS
- pNFS
- 上传市场失败aapt解析错误bug
- 单步执行遇到的离奇问题?一个简单的赋值语句都执行失败的bug
- 弹对话框失败的bug
- Access,Update失败的BUG
- 三副本的PNFS重构流程
- hibernate 在执行truncate SQL语句时的异常处理
- crontab执行失败的问题
- 执行文件的renameTo失败
- Glide加载图片失败的Bug?
- PHP 执行多条 truncate
- PNFS 中CALL BACK机制的客户端代码
- TinyOS bug程序的执行01(T-Check中的bug)
- pNFS概述
- pNFS overview
- click点击一次,执行多次的bug
- android listview仿iphone弹簧特效
- 数列(sequence)
- 中华人民共和国学科分类与代码国家标准(GB/T 13745-2009)_ 510 520
- java JDK版本切换(ubuntu)
- 使用序列化进行Clone
- pnfs执行truncate失败的BUG解析
- Asp.net中的Timer与updatepanel控件
- Dialog学习笔记
- Linux的Service/Daemon
- curl 以http方式读取文件并保存
- Oracle hash join
- HP MSA2000高性能双机容错方案
- 在tableview索引中显示搜索符号的方法
- [Linux C]递归遍历指定目录下的子目录和文件