论文部分内容阅读
基于Linux内核的操作系统在世界上被广泛应用。一方面,超过90%的最强大的超级计算机是建立在Linux内核基础之上的。另一方面,占领移动设备最大份额市场的操作系统Android也是基于Linux而形成的。在企业系统中,使用Linux的机会越来越大,因为用户期望的是非常高的可靠性。在Linux内核中,设备驱动程序是最为重要也最为常见的关键组件之一。当然,还有许多其它重要的内核组件,例如网络堆栈、文件系统、声音和视频基础结构、提供虚拟化支持的子系统等等。测试Linux内核模块在故障情况下的行为是很重要的。为了开展故障测试,许多科学家试图通过不同的技术技巧创造一个人为的故障场景和注入相关故障。故障注入是Linux内核模块的一个重要研究和应用领域,其主要目的是在异常情况下检查和确认内核组件的行为。尽管这种情况很少发生,而且难以预料,但这却使得有关负责处理对应故障的代码很难检测到或把这种错误限制在有限的范围内。在正常测试的实施过程中,唯一能够发现这些问题的方法是人工引入一些随机性的错误。随机故障注入的工作远远优于完全没有异常的测试,但是它也有自身的一些缺点。故障注入或故障模拟技术通常通过调节故障发生和错误处理代码的执行来最大限度地减少或克服这些困难。在Linux故障注入和故障模拟方法中,可以使用不同的故障注入工具或技术,不过它们都无法满足所有各种故障情形的注入或者在支持用户注入自己想要注入的故障方面缺乏灵活性,然而这却正是关于错误处理代码的系统评估所需要的。Linux内核模块的故障模拟测试是一项重要的任务。它与用户空间应用程序不同,Linux内核模块可能会直接访问正在被内核的其它部分所使用的某些内存区域。内核模块可以在较低层级与硬件进行通信,而且可能还拥有一些在内核之外的空间几乎不可能具备的其它功能。故障注入通常会尝试验证有关系统响应是否与发生在不同范围的故障相吻合,或者有关系统响应与所要求的规格不相匹配。在正常情况下,首先在系统分析阶段确定某些系统状态和时间节点,然后在相应状态和时间节点中注入故障。测试人员往往对相关设计非常了解,然后他们会以确定的方式设计对应的测试用例。我在自己的硕士学位论文研究课题中,着重分析和研究了现有的一些主要故障注入工具或框架,例如LTP(LinuxTestProject,即Linux测试项目),KEDR(Kernel Device Driver at Runtime,即内核设备驱动程序运行时故障注入),SCSI故障注入器和 Linux 故障注入框架(Linux Fault Injection Framework,简记作 LFI)。在论文中,我首先描述了所有工具的一般故障注入框架,然后描述了每种故障注入工具的具体框架或工作机理。进一步说,一个对于所有工具通用的方法描述如下:首先,使用不同的框架并不是一件很容易的事情。在Linux测试实验中,我们试图通过利用不同的框架注入相应的故障。为此,需要分析、研究在Linux平台上(我们具体采用的是Ubuntu桌面操作系统)的故障注入的一般行为特征和流程。鉴于我们选择了 Linux内核源码、模块和设备驱动程序作为研究目标,所以,我们通过研究故障注入对内核的一般影响,从而整理完成了对应不同工具所提供的不同的故障注入功能以及相应于不同注入对象和目标的实现方法。经过大量的关于Linux内核故障注入的调查、分析、实验和研究,最后我们决定基于四种不同的故障注入平台(包括LTP、KEDR、SCSI和LFI)开展研究工作。其次,要想有效地研究故障注入的行为,就需要根据实验要求来选择合适的工具。故障注入工具的选择基本上是继续在第一步上所进行的研究,按照LFI、LTP、KEDR和SCSI这样的顺序依次选择相应的框架或工具进行分析、研究和实验例证。第三,在成功完成第二步之后,按照对应故障注入实验的具体要求,安装所选的故障注入工具。每种故障注入工具的安装可能会有所不同,具体取决于相应的故障注入功能和支持要求。第四,当把故障注入工具完全安装成功后,就可以选择相应工具的故障支持。只能注入被选定提供的故障类型。一旦选择了故障类型,那么故障类型的参数(如概率、时间、冗余、循环和永久性等)同时也应当被指定。成功完成所有这些步骤后,就把对应故障注入到了目标对象或受害者身上。最后,收集故障注入的测试实验结果。每种工具都提供了自己的收集结果的各种方法(如syslog和dmesg)以及可用来保存相关输出结果的特定文件。根据采用不同工具进行实验所收集到的故障注入成功的有效测试结果,对它们展开纵向或横向的比较,从而验证它们的效率、行为、时延、容易程度以及类型故障支持等。1 Linux故障注入(LFI)Linux内核集成了一个故障注入框架。开发人员可以使用此框架来实现简单的故障注入工具,可以测试内核子系统的实现和设备驱动程序。本章介绍了我们在应用Linux故障注入框架注入故障时的经验。a)Page-failb)Failslab以及我们发现的局限性。2 Linux测试项目(LTP)在故障路径上调整内核执行进程的能力已经被众所周知很长时间了。如上所述,Linux内核集成了一个故障注入框架,这个基础设施可以被用来诱导不同内核部件的任意故障。现在,Linux故障注入框架被应用在LTP(Linux测试项目)测试用例,根据故障内核故障注入。LTP是本实验的两种方式使用:a)错误的内核。b)稳定的内核3运行时内核驱动程序(KEDR)KEDR强制目标模块的某些调用失败。KEDR主要是通过目标模块使一些调用失败。也许,KEDR模拟故障实际上是调用特定的目标函数的失效。用户可以对方案进行修改和控制(哪个功能可能在哪种情况下,会面临失败)。在本实验中,KEDR故障模拟在两个条件下得到验证:a)在 KEDR 中,为 kmalloc、vmalloc 和字符设备(cfake0、cfake1)注入故障。b)在不同的条件下比较kedr-sample-target模块4 SCSI Fault Injector该工具主要集中在Linux上的RAID(md/dm-miror)软件测试。该工具也可以适用于任何使用SCSI中间层的上层驱动程序/应用程序。本实验中使用此工具,RAID1(dev/md0,dev/md127)通过使用选项sector_rerr.stp(通过写入模拟可读取错误)在其上应用故障进行测试。但是它需要知道目标SCSI设备的(主要,次要)号码。或者使用特定文件,文件的inode号(例如,通过ls-i命令)指出文件位置。LTP,KEDR,LFI和SCSI故障注入工具用于Linux的结果从彼此各不相同。对于LTP(Linux测试项目),在错误的内核下进行了三次测试,每次都有不同的概率百分比和循环次数。首先,测试了 mm(内存管理),它在错误的内核下成功运行,而没有任何的出错信息或失败。但是dma-threat-dio用例在错误的内核下失败了。在49个中只有7个测试通过,42个失败(85.7%失败发生)。在第三次测试中,错误的内核下的mmap压力(内存映射压力)也会失败。内存映射压力04完全失败,但内存映射压力02会给出警告消息。KEDR工具用于研究内置模块(Kedr-sample-target)和定制内核模块(ExampleLKM)的故障模拟和内存泄漏的检测。两个模块"无法分配内存"和设备驱动程序(cfake0/cafakel)的故障模拟结果相同,两个模块的"出错地址"的模拟结果也是相同的。每个模块的检测内存泄漏结果有所不同,对于kedr-sample-target"allocation 3和可能泄漏possible leak 2"但是,自定义内核模块(ExampleLKM.c)"allocation 2 可能泄漏 possible leak 0"。这些结果在 debugfs 目录(sys/kernel/debug/kedr-fault-simulation/cat last fault)下被进一步验证。使用SCSI工具在RAID1下注入"故障,mdadm方法用于创建RAID1。它由sdc和sdb硬盘组成。选择注入的故障类型为"读取可校正错误"。一旦在dev/md127设备上成功注入了故障,在从syslog读取scsi脚本之后,它显示"SCSI-decision-decomposition major = 8 minor = 16 scmd = 4122759912"。一旦注入了故障,sdb 将被恢复,因为注入的故障sdb被更正,并且md127由于与sdb的关联而自动恢复。LFI不支持kedr-sample-target,因为注入内存分配失败,模块在读写操作中需要内存分配,但对于读写操作没有内存分配功能,所以没有故障可以被注入。每个测试对每个工具需要不同级别的空间,也可以这样说每个工具对空间的要求是不同的。在这几个工具中,LTP需要最大的空间,而KEDR需要较少的带有GB的空间。每个工具所需的时间取决于当时的测试或被测试的类型。通过不同的工具成功地注入故障后,观察哪种工具在哪个方面(比较基于特征,支持,设计和易用性)更好。LTP比其他的要更好,但同时从支持(只支持几种类型的故障)上看KEDR比LTP是更低的。在缓解的行为上,LFI低于其他,SCSI在所有方面都适中,意味着处于中间位置。