====== Fault Injection ====== Student: Anton Kuijsten\\ Mentors: Cristiano Giuffrida, Arun Thomas\\ git repository: [[https://github.com/Stichting-MINIX-Research-Foundation/gsoc/tree/2012-fault|minix-fault]]\\ ===== Abstract ===== The goal of this project is to implement a new compiler-based fault injection tool which can be used for reliability testing on MINIX 3 . This should improve the existing Software Implemented Fault Injection (SWIFI) tool included in the MINIX distribution, which is based on tracing and can only be used for a limited number of OS components. The tool will be implemented as an LLVM transformation pass. At link time, it will be able to inject various fault types, each with its own probability. Fault injection can be limited to a selection of functions. At run time, a probability can be set to manage global fault occurence, and statistics on fault occurences can be dumped. ===== Current Status ===== |**Done**|**Item**|**Percentage Complete**|**Comments**| | {o} |basic fault injection functionality (midterm)|0%| | | {o} |added statistics and dynamically adjustable fault occurence probabilities|0%| | ===== Status Reports ===== **//Week 1 (30-05)//** Loading of a pass in llvm-2.9 works, when installed from pkgsrc. Binary packages for llvm-2.9 and llvm-3.1 can't load passes dynamically, probably because they're not built with dynamic library support. Also, llvm-3.1 from pkgsrc produces an error during the build process. A simple hello world pass can be compiled in isolation from the llvm source code. Only the llvm headers need to be available. In the future, it might be a good idea to include these in the installation of a binary llvm package. I'll look into a fast way to integrate pass usage into the buildsystem (compiler driver or changes to makefiles). Later this summer, the llvm gold linker might become available on Minix, after which a better and more permanent solution can be applied. **//Week 2 - 3 (10-06)//** Llvm pass loading is integrated into the buildsystem of the minix-fault git repository. A compiler driver from another llvm project is added to the source tree in commands/llvmdrv. Passes are added to lib/libllvm. Make rules are added to share/mk/minix.llvm.mk. A basic block cloning function is added in the fault injector pass. The cloned blocks are not yet reachable (there is no branch instruction from the first basic block to the first cloned block), but branch instructions between basic blocks seem to be mapped correctly. This pass is not tested much, but the llvm assembly output looks good at first glance. By setting environment variables when calling make, the passes can be activated. LLVM_CONFIG=TEST for the hello world pass, LLVM_CONFIG=FAULT for the fault injector pass, and LLVM_DEBUG=info for more information on the commands that are executed by the llvm compiler driver (llvmdrv). For compiling the passes, you need to install clang 2.9 from pkgsrc (not from pkgin). Also, the llvm header files from pkgsrc need to be copied to the source tree. See lib/libllvm/README for instructions. As of now, some subdirectories of /usr/src don't build correctly when a pass is used. Therefore, only build servers/, drivers/ and lib/ with LLVM_CONFIG=[...]. Also, servers/inet, servers/vm, drivers/acpi and drivers/random get build errors that are not yet solved. Use these commands to build and install the libraries and the working servers and drivers with the hello world pass: * make world * LLVM_CONF=TEST LLVM_DEBUG=info make -C lib clean all install * LLVM_CONF=TEST LLVM_DEBUG=info make -C drivers clean * LLVM_CONF=TEST LLVM_DEBUG=info make -C servers clean * make -C drivers/random all install * make -C drivers/acpi all install * LLVM_CONF=TEST LLVM_DEBUG=info make -C drivers all install * make -C servers/inet all install * make -C servers/vm all install * LLVM_CONF=TEST LLVM_DEBUG=info make -C servers all install * make -C tools/ hdboot The bytecode input and output from a pass can be converted into readable llvm assembly with: llvm-dis /usr/src/servers/vfs/main.bcc -o /usr/src/servers/vfs/main.bcc.ll && llvm-dis /usr/src/servers/vfs/main.BCC -o /usr/src/servers/vfs/main.BCC.ll **//Week 4//** The pass is now better integrated into the build system. Now, everything can be built with: * LLVM_CONF=FAULT make world If lib/, servers/, and drivers/ were already build, they have to be cleaned first. Otherwise, they will be skipped, because the targets seem to be up to date. **//Week 5//** A library is added to lib/libllvm/faultlib (the other subdirectories of lib/libllvm are llvm passes). This library is linked into the instrumented binaries of services. It contains code and variable to disable/enable fault execution, and (in the future) print out statistics. Also, a command line tool is added to commands/faultinjector. The tool can be used to disable/enable fault execution, and to run a test function in faultlib. A command line argument is added to the pass, so that a comma separated list of functions that have to be instrumented can be specified. Currently, no fault is injected. Instead, a printf("cloned\n") statement is added to each cloned basic block. To test all new features: * make includes mkfiles * LLVM_CONF=FAULT make -C lib/ clean * repeat make clean command for servers/ and drivers/ * LLVM_CONF=FAULT make -C lib/libllvm clean all install # it is important the the passes are installed before the libraries and services are built * LLVM_CONF=FAULT make world * (restart) * run: faultinjector