author | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-06-17 01:09:37 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-06-17 01:26:05 UTC |
parent | 3449d9c2ae0374e603e6499513f5088ed9bf0614 |
doc/posix.rst | +102 | -0 |
diff --git a/doc/posix.rst b/doc/posix.rst new file mode 100644 index 0000000..3876320 --- /dev/null +++ b/doc/posix.rst @@ -0,0 +1,102 @@ + +Simulating failures in the POSIX API +==================================== + +When developing robust sofware, developers often consider the cases when the +classic POSIX functions return failure. + +Testing that fault-handling code is a problem because under normal conditions +it's hard to make the POSIX functions fail, and generating abnormal conditions +is usually difficult. + +For example, getting **malloc()** to fail can represent using up all your +memory, and at that point your test case might not even work. Or getting I/O +operations to fail might involve filling up the disk which is very +undesirable, or generating a very special environment which is difficult to +reproduce. + +libfiu comes with some tools that can be used to perform fault injection in +the POSIX API (which includes the C standard library functions) *without* +having to modify the application's source code, that can help to simulate +scenarios like the ones described above in an easy and reproducible way. + + +fiu-run +------- + +The first of those tools is an application called *fiu-run*. + +Suppose you want to run the classic program "fortune" (which some would +definitely consider mission critical) and see how it behaves on the presence +of **read()** errors. With **fiu-run**, you can do it like this:: + + $ fiu-run -x -e posix/io/rw/read -p 1 fortune + +That enables the failure point with the name **posix/io/rw/read** with 1% +probability to fail **on each call**, and then runs fortune. The *-x* +parameter tells **fiu-run** to enable fault injection in the POSIX API. + +Run it several times and you can see that sometimes it works, but sometimes it +doesn't, reporting an error reading, which means a *read()* failed as +expected. + +When fortune is run, every time fortune calls **read()** it has a 1% chance to +fail, which selects an errno at random from the list of the ones that read() +is allowed to return. If you want to select an specific errno, you can do it +by passing its numerical value using the *-i* parameter. + +The name of the failure points are fixed, and there is at least one for each +function that libfiu supports injecting failures to. Not all POSIX is +included, but most of the important pieces are, and it is easily extended. See +below for details. + +To see the list of supported functions and names, see the +**preload/posix/function_list** file that comes in the libfiu tarball. + + +fiu-ctrl +-------- + +Sometimes it is more interesting to simulate failures at a given point in time +instead of from the beginning, as **fiu-run** does. + +To that end, you can combine **fiu-run** with the second tool, called +*fiu-ctrl*. + +Let's suppose you want to see what the "top" program does when it can't open +files. First, we run it with **fiu-run**:: + + $ fiu-run -x top + +Everything should look normal. Then, in another terminal, we make **open()** +fail unconditionally:: + + $ fiu-ctrl -e posix/io/oc/open `pidof top` + +After that moment, the top display will probably be empty, because it can't +read process information. Now let's disable that failure point, so **open()** +works again:: + + $ fiu-ctrl -d posix/io/oc/open `pidof top` + +And everything should have gone back to normal. + + +How does it work +---------------- + +libfiu comes with two preload libraries: **fiu_run_preload** and +**fiu_posix_preload**. + +The first one is loaded using **LD_PRELOAD** (see **ld.so(8)** for more +information) by **fiu-run**, and can enable failure points and start libfiu's +remote control capabilities before the program begins to run. + +The second one is also loaded using **LD_PRELOAD** by **fiu-run** when the +*-x* parameter is given, and provides libfiu-enabled wrappers for the POSIX +functions, allowing the user to inject failures in them. + +**fiu-ctrl** communicates with the applications launched by +**fiu-run** via the libfiu remote control capabilities. + +