2008年底我所在的团队设计和实现了一个块设备驱动,简单正确性测试与稳定性测试都能顺利通过,但是在高并发正确性测试过程中,却遇到了一个非常令人费解的问题:在高并发运行一段时间之后,出现了正确性问题,数据diff出错!
遇到这样的问题,我首先想到了驱动的实现出了问题,因此,对驱动中的关键模块进行了大量的code review,并且局部算法进行了重新编写以及采用单元测试用例进行单元测试。这样的分析、测试持续进行了两个星期,可以说是毫无进展。由于是正确性问题,所以,当正确性出现问题时,kernel的日志中没有提示任何信息,根本就无法跟踪故障的现场,无法知道到底哪个地方出现了问题。在这样的情况下,我甚至怀疑Linux系统中的某些模块是否出了问题,在这样的猜疑之下,用相同的用例对其它的模块进行了测试,测试结果推翻了我的猜想。
在过年前的一个礼拜,可恶的BUG依然缠绕着我,到最后我甚至将整个系统用另一种思路重新写了一遍,问题依然存在,这就说明根本就不是实现的问题。后来与一个同事争论一个问题:Linux块设备层是否可以保证对同一个扇区的读写请求次序?我的观点是可以,他持有相反的意见。在争论无果的情况下,我决定由我的驱动保证对同一扇区的读写请求次序,假设Linux块设备层不能保证对同一扇区的读写请求次序。在这样的想法驱动下,我做了测试用例。元月29日下班前测试用例实现完毕,利用春节假期采用新的用例对系统进行测试…
春节的测试是我抱有希望的测试,在折腾了三个星期的分析、测试过程中,我实在想不出系统中还存在何种问题?初七上班之后终于有了牛年第一个好消息,测试顺利通过了,这就说明正确性问题的根源在于“同一扇区的读写请求乱序了”。块设备层根本无法保证同一扇区的读写请求顺序,我以前的想法与实际偏离了,这也是导致问题的根本。
为什么块设备层无法保证同一扇区的读写请求次序呢?这不是块设备层应该所承担的责任吗?仔细想想,这种读写次序的保证一方面可以由文件系统实现;另一方面可以由块设备层实现。如果由块设备层来实现,其处于文件系统的下方,那么实现复杂度相对较高;如果由文件系统来保证,由于处于系统的最顶层,实现复杂度相对较低。Linux的发展思路是这样的责任由文件系统来承担,块设备层无需提供相应的机制保证读写请求的次序,这样块设备层可以对请求做相应的优化,无需考虑其他正确性因素。现在想想Linux这样的处理是合情合理的。
这个BUG的解决过程可以说是艰辛的,这个BUG纠正了我对块设备层的一个不正确假设。在此,我也提醒大家在块设备设计过程中应该注意这个问题,IBM的dm-cache驱动同样忽略了这个问题。
用户377235 2012-1-29 15:46
用户377235 2012-1-29 15:45
用户411565 2009-6-18 10:37
用户193005 2009-6-17 11:51