File: injectingfaults.tex

package info (click to toggle)
faumachine 20180503-4
  • links: PTS
  • area: main
  • in suites: buster
  • size: 61,272 kB
  • sloc: ansic: 272,290; makefile: 6,199; asm: 4,251; sh: 3,022; perl: 886; xml: 563; pascal: 311; lex: 214; vhdl: 204
file content (377 lines) | stat: -rw-r--r-- 17,046 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
%
% Copyright (C) 2003-2009 FAUmachine Team <info@faumachine.org>.
% This program is free software. You can redistribute it and/or modify it
% under the terms of the GNU General Public License, either version 2 of
% the License, or (at your option) any later version. See COPYING.
%

This chapter tells you how to make the hardware of your virtual machine
fail. Section \ref{s:injectingfaults.faults} gives you an overview over
available failures. You can use the graphical user interface to inject
faults interactively (section \ref{s:injectingfaults.gui} or you can
include fault injection into your scripts for automated testing
(sections \ref{s:injectingfaults.auto} and \ref{s:testautomation}).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Available Failures}
\label{s:injectingfaults.faults}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The following sections show in which ways you can make your virtual
hardware fail.

We distinguish between transient and permanent faults. An example for a
transient fault is a bitflip, an example for a permant fault is a
stuck-at-one fault.

In a bitflip, a single bit (e.g.\ in a processor register or in main
memory) flips to zero (if it was one, before) or to one (if it was zero,
before).
That is all, nothing more happens. So if the next thing you do is write
a new value to the register or memory location containing the flipped
bit, this bit will happily change state to the new value and you won't
even notice anything bad has happened.
Of course, if the next thing you do is read from this register or memory
location, you will get the faulty value and bad things may or may not
happen.

Things are different for a permant fault. Permant in this case does not
mean ``forever''. It just means, that this fault is not transient and
may persist for a certain duration of time.
A stuck-at-one fault is such a permant fault. A bit becomes stuck at
the value one and does not change its value any more. Even if the next
thing you do is write a new value to the register or memory location
containing the flipped bit, and the bit should really be zero after the
write, it won't be, because it is stuck at the value one.

%%======================================================================
\subsection{Processor Failures}
\label{s:injectingfaults.faults.cpu}
%%======================================================================
The only failures you can currently induce in the processor are random
transient bitflips in processor registers. 

You will have to specify the processor (on single processor machines
the processor usually has the ID 0), the register and the bit to flip.
Since the processor of the virtual machines are all i386 architecture
processors, the possible registers are
``eax'', ``ebx'', ``ecx'', ``edx'', ``edi'', ``esi'', ``ebp'', ``esp'',
``eip'', ``eflags'', ``ds'', ``es'', ``fs'', and ``gs''.

Legal bit-IDs to flip are 0 to 31 for the long registers and 0 to 15 for
the short ones.

%%======================================================================
\subsection{Main Memory Failures}
\label{s:injectingfaults.faults.mem}
%%======================================================================
The only failures you can currently induce in the main memory are random
transient bitflips.

You will have to specify the address of the byte in which you want to
flip the bit as well as the bit to flip.
%%======================================================================
\subsection{Block Device Failures}
\label{s:injectingfaults.faults.block}
%%======================================================================
The only failures you can currently induce in a block device are
permanent failures of random bytes on this device.

You will have to specify the device, the first affected byte and the
number of affected bytes (range). Any time the operating systems tries
to read or write from the affected parts of this block device, the
controller will return an error code.

Of course you can specify several ranges for the same device.
%%======================================================================
\subsection{Network Failures}
\label{s:injectingfaults.faults.net}
%%======================================================================
You can make the network interfaces lose packets when sending and
receiving. These are permanent faults, i.e.\ the affected network
interface will lose packets as long as this fault is active (turned on).

You will have to specify the network interface, whether it is a send or
receive problem and the percentage of packages lost (0\% means no
packets are lost which is equivalent to no failure).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Injecting Faults Using the GUI}
\label{s:injectingfaults.gui}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Fault injection via the graphical user interface lets you inject faults
interactively at your leisure using the \GUIMenu{Inject}-menu.

%%======================================================================
\subsection{Creating a New Fault Description}
\label{s:injectingfaults.gui.new}
%%======================================================================
To create a new fault description, you will need to specify the
necessary information conerning your fault (see section
\ref{s:injectingfaults.faults}) in the \GUIWindow{Fault
Description}-window. You can open this window using the
entry \GUIMenu{Show List} from the \GUIMenu{Inject}-menu and then choosing
\GUIButton{Add}. You can also choose \GUIMenu{Edit New} from the
\GUIMenu{Inject}-menu directly.

This window will give you a list of the hardware devices available for
fault injection to the left. If you choose a device, a new list or text
entry field will appear to let you enter more details.

If you choose a memory device, you will have to enter the address of the
affected byte as a hexadecimal number. After you have entered this
number and hit the Return-Key, you can choose the number of the bit to
flip from a list. After you have chosen a number, an
\GUIButton{OK}-button will appear in the lower left hand corner of the
window.
Choose \GUIButton{OK} to add the new fault to the list of
currently loaded fault descriptions.
Choose \GUIButton{Cancel} anytime
to abort creating a new fault description.

%%======================================================================
\subsection{Editing an Existing Fault Description}
\label{s:injectingfaults.gui.edit}
%%======================================================================
To edit an existing fault description choose entry \GUIMenu{Show List}
from the \GUIMenu{Inject}-menu to display the list of loaded fault
descriptions. Then choose a fault description and click
\GUIButton{Edit}. The \GUIWindow{Fault Description}-window filled with
the details of the chosen fault description will appear. 
Choose \GUIButton{OK} to commit the changes to this fault description.
Choose \GUIButton{Cancel} anytime
to abort the changes.

%%======================================================================
\subsection{Deleting an Existing Fault Description}
\label{s:injectingfaults.gui.delete}
%%======================================================================
To delete an existing fault description choose entry \GUIMenu{Show List}
from the \GUIMenu{Inject}-menu to display the list of loaded fault
descriptions. Then choose a fault description and click
\GUIButton{Delete}. You will not be asked to confirm the deletion!
If the fault is currently active, this
will \emph{not} deactivate the fault! Use with care!

%%======================================================================
\subsection{Saving Fault Descriptions to a File}
\label{s:injectingfaults.gui.save}
%%======================================================================
You can save the currently loaded list of fault descriptions to a file.
Choose entry \GUIMenu{Show List} from the \GUIMenu{Inject}-menu to
display the list of loaded fault descriptions.
Click \GUIButton{Save} and a file selection box will pop up to let you
select a filename and location for saving. Click \GUIButton{OK} in the
file selection box to save the list of fault descriptions.
%%======================================================================
\subsection{Loading Fault Descriptions from a File}
\label{s:injectingfaults.gui.load}
%%======================================================================
If you have previously saved a fault description list (see section
\ref{s:injectingfaults.gui.save}, you can load it again. 
Choose entry \GUIMenu{Show List} from the \GUIMenu{Inject}-menu to
display the list of currently loaded fault descriptions.
Click \GUIButton{Load} and a file selection box will pop up to let you
select the filename and location of the file to load. Click \GUIButton{OK} in the
file selection box to actually load the file. The fault descriptions
from the file will be appended to the list of currently loaded fault
descriptions. If you do not want this, use \GUIButton{Clear} first, to
clear the current list of fault descriptions. If there are
currently active faults, this will \emph{not} deactivate these
faults! Use with care!

%% FIXME
Don't try to load a file which does not contain fault descriptions in
the right format! This will currently crash the GUI.
%%======================================================================
\subsection{Miscellaneous and Summary}
\label{s:injectingfaults.gui.misc}
%%======================================================================
Use the \GUIMenu{Show List} to look at the list of faults currently
loaded. This list tells you whether the fault is currently active
and shows you the fault description.

There are buttons for the following actions along the bottom of the
\GUIWindow{Show Fault List}-window:
\begin{description}
\item[\GUIButton{Load}]{
	Load a previously saved fault description list from a file, appending it to
	the list of currently loaded fault descriptions.
}
\item[\GUIButton{Save}]{
	Save a fault description list to a file.
}
\item[\GUIButton{Add}]{
	Add a fault description to the list.
}
\item[\GUIButton{Edit}]{
	Edit the selected fault description.
}
\item[\GUIButton{Delete}]{
	Delete the selected fault description. If the fault is currently active, this
	will \emph{not} deactivate the fault! Use with care!
}
\item[\GUIButton{Clear}]{
	Clear the fault description list. This unloads the fault
	description list. If there are
	currently active faults, this will \emph{not} deactivate these
	faults! Use with care!
}
\item[\GUIButton{Close}]{
	Close the window. This does not unload or clear the fault list
	and does not deactivate any faults. It simply gets the window
	out of your way.
}
\end{description}

You can create or edit a faultload file even when the virtual machine
is not turned on. Choose \GUIMenu{Inject}\rArrow\GUIMenu{Show List} to
show the list of currently loaded fault descriptions. Choose
\GUIButton{Add} to add a new fault description.

\removed{%
%%======================================================================
\subsection{ Interpreting Tracer Output}
%%======================================================================
To be added ...
}%/removed


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Automated Fault Injection}
\label{s:injectingfaults.auto}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Please refer to section \ref{s:testautomation} for general information
on how to use Expect for test automation and automatic experiment
control. This section only treats fault injection via Expect.

\command{expect} is an automatic experiment controller, which can  wait for
certain events to occur on a virtual machine and in return send some
input  to this virtual machine. The input \command{expect} sends will usually
simulate a user sitting in front of the machine. Events occurring on a
virtual machine are such things as screen output (e.g. the login-prompt
appearing). \command{expect} is generating a workload.

Additionally, \command{expect} may activate/deactivate faults in a
virtual machine. \command{expect} is generating a faultload.
\command{expect} is able to activate all faults defined in
\Filename{example/faultloads/README}.

Currently, we use it as experiment
controller creating a workload in a client/server system, see example
in \Filename{example/oracle}. For a short description:
\command{serial\_interface} is used to translate the input/output
of a serial port of a node into \command{expect}-events. Using this
Babel-fish it is possible to respond to characters on a serial line
in \command{expect}-protocol.
Then, \command{expect} logs in at four virtual machines each over serial
port \Filename{ttyS0} starting application servers on the serial
ports (\Filename{ttyS1}, \Filename{ttyS2} and \Filename{ttyS3}).
\command{expect} simulates the user by creating
partly random input at the masks of the application servers at all
serial interface simultanously. In detail: there are 4 virtual
machines each running 3 application servers at its serial ports.
Thus, there are 12 serial interfaces controlled with \command{expect}.

Additionally \command{expect} creates a faultload at the virtual
machine running an Oracle database server. The fault is selectable
via setting a generic from the command line starting \command{expect}
For this setup \command{expect} seems to work well.

If you want \command{expect} to wait for the login-prompt, for example,
your virtual machine will have to fulfill the following requirements:
\begin{itemize}
\item{
        Configure the virtual machine to have a serial interface
        (\ref{s:configmanual.ser}).
}
\item{
        Configure your virtual machine to run a \command{getty}
        listening on the serial interface. (Don't use \command{mgetty}
        for the moment!) Debian-\command{getty} has been tested and
        works, whereas Caldera-\command{getty} does not work.
        
        It should probably work to insert a line such as
\begin{alltt}
T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
\end{alltt}
        into \Filename{/etc/inittab} on your virtual machine. On
        Debian-machines, for example, you will just need to uncomment this line.
}
\item{
	Connect a serial\_terminal or serial\_pattern to the
	corresponding serial interface of that virtual machine
	(\Filename{system.vhdl}).
}
\item{
	Write a login script in a VHDL-process, sending the login name,
	after recognition of the login: prompt.
}
\end{itemize}

Ready to go. Good Luck!

To inject faults clamp shortcuts to the fault injector signals
of the components. E.g. if you want to make the harddisk inoperatable
a piece of VHDL source could be:

\begin{alltt}
    SIGNAL disk\_fault : boolean;
    .
    .
    .
    hda : idedisk PORT MAP(ide => ide\_bus);
    .
    .
    .
    inject : PROCESS BEGIN
        disk\_fault'shortcut\_out\_add("hda\%byte\_fault/0/0");
        disk\_fault <= 1=1;
        WAIT;
    END PROCESS inject;
\end{alltt}

Here is some rough information on the syntax of the fault descriptions
which you can use in the shortcut (printf-like notation):
You will have to substitute the VHDL-name of the component instead of
"cpu", "eth", "hd", "memory".
\begin{alltt}
    /cpu/%d/%s/%d
    /eth/%d/%s/%d
    /hd/%c/%d/%d
    /memory/%d/%d

Semantics:
    /cpu/<cpu-id>/<register>/<bit>
        <cpu-id>: The ID of the CPU. For monoprocessors this is 0, possible
            values for multiprocessors depend on the setup.
        <register>: Which register. Possible registers are most
            intel-architecture registers, eg. eax, ebx, ecx, esp, eip etc.
        <bit>: Which bit to flip. Must be between 1 and 32 (inclusive).

    /eth/<interface>/<type>/<percent>
        <interface>: Interface number, possible values are usually between 0 and
            15. Which interfaces are available depends on the configuration.
        <type>: "receive" or "send"
        <percent>: Percentage of packages to drop.

    /fd/<drive>/<start>/<range>
        <drive>: Which drive (usually 0 or 1 are possible). Availability depends
            on the node configuration.
        <start>: First defect byte.
        <range>: How many defect bytes. All bytes falling within
            <start> .. <start>+<range> are defect.
            if range is -1, the whole disk is defect

    /hd/<drive>/<start>/<range>
        <drive>: Which drive (usually a, b, c etc. are possible). Availability depends
            on the node configuration.
        <start>: First defect byte.
        <range>: How many defect bytes. All bytes falling within
            <start> .. <start>+<range> are defect.
            if range is -1, the whole disk is defect

    /memory/<address>/<bit>
        <address>: Address of the defect word (must be word aligned).
        <bit>: Which bit to flip. Must be between 1 and 32 (inclusive).
\end{alltt}