Skip to content

dwalkes/scsi_fault_injection_test_tool

Repository files navigation

The SCSI fault injection test tool

Revision History:

  rev 1.00  Jan 18 2008 K.Tanaka
    -   Initial Release.


1. Introduction
================
This tool enables to test error handling routines related with the filesystem 
and block I/O of the Linux system by injecting a SCSI fault on the system.

This tool generates "pseudo" faults in the SCSI mid-layer. This could be 
a more realistic SCSI device faults simulation. For example, device faults 
resulting in scsi command timeout, and media faults which could be corrected by 
writing data to the failed sector could be simulated.
User can designate a device currently connected to the system and the target
location within the designated device to inject a fault, so that test program
using this tool could generate an error with a specific access.

Internally, this tool uses SystemTap. This tool rewrite the status code and 
sense data of SCSI command using SytemTap and pass it to the upper layer. 
So the real error handling routine of the upper layer for I/O request can be tested.

This is originally created to test  software RAID (md/dm-mirror)
on Linux. But any upper layer app/driver using the SCSI mid-layer can also apply 
this tool. 


2. Requirements
================
- Linux system (x86 architecture) compiled with debuginfo.
- SystemTap (v5.14.1 or later) installed to the Linux system.

Please see http://sourceware.org/systemtap/index.html for SystemTap.


3. Supported SCSI fault type
============================

This test tool supports to inject the following type of faults. 

3-1. Permanent read error simulation
     This type of fault simulates a permanent media error
     on a particular sector. Any read access to the sector fails, 
     but write will succeed.

3-2. Permanent read /write error simulation
     This type of fault simulates a severe media error.
     Both read and write fails on the particular sector permanently.

3-3. Read error correctable by write simulation
     This type of fault simulates a media fault which could be 
     corrected by writing data to the failed sector. After writing
     to the sector, subsequent reads and writes will both succeed.

3-4. Temporary read error simulation
     This type of fault simulates an accidental fault, just once.

3-5. Temporary write error simulation
     This type of fault simulates an accidental fault, just once.

3-6. Temporary no response on a read access simulation
     This type of fault simulates a situation,such as a congestion,
     resulting in scsi command timeout on a read request. After 
     the congestion disappears, both read and write will succeed.

3-7. Temporary no response on a write access simulation 
     This type of fault simulates a situation,such as a congestion,
     resulting in scsi command timeout on a write request. After 
     the congestion disappears, both read and write will succeed.

3-8. Permanent no response on both read and write access simulation
     This type of fault simulates a device fault resulting in scsi 
     command timeout on a write request. 
     Both read and write fails on the particular sector permanently.


Each fault type can be injected by using SystemTap scripts(*.stp) for each type.

  script name       |       fault type description
 -------------------+-------------------------------------------------------
 disk_rerr.stp      | permanent read error simulation
 disk_rwerr.stp     | permanent read /write error simulation
 sector_rerr.stp    | read error correctable by write simulation
 temporary_rerr.stp | temporary read error simulation
 temporary_werr.stp | temporary write error simulation
 r_timeout.stp      | temporary no response on read access simulation
 w_timeout.stp      | temporary no response on  write access simulation 
 rw_timeout.stp     | permanent no response on both read and write access simulation

disk_rwerr.stp, disk_rerr.stp, sector_rerr.stp, temporary_rerr.stp, temporary_werr.stp
return a "fake" sense data(sense key = 3, ASC = 11, ASCQ = 4) to the upper layer. 
This means a medium error.

The following scripts are also included, but they are for internal use only.
 scsi_fault_injection_common.stp   - common routine for fault injection
 scsi_timeout_injection_common.stp - common routine for timeout injection


4. Usage
=========

The flow is as follows. 
For more detailed example, see the sample_usage.txt.	

1. Setup
  1-1  Install SystemTap and kernel with debuginfo.
       (For more details, see Appendix A)

  1-2  Decompress toolset and move them to an arbitrary directory.


2. Decide the type and target of the fault

  2-1 Fault type
      Choose a fault type you want to inject described above.

  2-2 Target 
      Choose a target device to inject a fault.
      You need to know the (major, minor) number of the target SCSI device.
      If you want to inject a fault by accessing particular file, 
      you need to know the inode number of the file. (e.g. by ls -i command)
      Also, if you want to inject a fault by accessing particular 
      LBA(Logical Block Address) of the target SCSI device, instead 
      of accessing a file, you need to choose the LBA number.

      NOTE. The file, with which you want to inject a fault may be cached
            on memory, but an access to the target device needs to be generated 
            to inject a fault. For confirmation, you should drop all page 
            caches by "echo 1 > /proc/sys/vm/drop_caches".

           
3. Run the stap command

   Run a script to setup a SystemTap hook to cause a fault. Refer to section
   "6. Scripts usage details" for more details.
   By running a script, the hook for injecting a fault is made. 
   If SystemTap shows the string "Pass 5: starting run.", it's ready.


4. Access the target device

   Running the SystemTap script is just only to set a trap. So an access to the target 
   device is needed to inject the fault.
   e.g. If you run "disk_rerr.stp" script, you need to read from the target device
        You can make a read access by a cat command.
        If you run "temporary_werr.stp you need to write to the target device.
        You can make a write access by redirection to the file and a sync command.


5. Check the result
   
   Check the result caused by the fault injection and stop the script.
   If the fault is successfully injected, the script prints the message
   beginning with "scsi_decide_disposition" or "scsi_add_timer" depending 
   on the fault type. 
   The "read/write error response" type of fault scripts (disk_rwerr.stp, 
   disk_rerr.stp, sector_rerr.stp,  temporary_rerr.stp, temporary_werr.stp) 
   will show "scsi_decide_disposition ..." on successfully injected faults.
   The "no response" type of fault scripts (r_timeout.stp, w_timeout.stp, rw_timeout.stp)
   will show "scsi_add_timer ..." on successfully injected faults

   The running SystemTap script can't stop automatically. So you need to 
   stop that by "Ctrl-C" or "pkill stap" command.


5. Scripts usage details
========================

SYNOPSIS
   stap <script name> major minor-min minor-max inode/LBAflag value -g -I <lib directory>


DESCRIPTION   
   Set up a hook to inject a given type of fault by using SystemTap
   Parameters as follows.

       script name: Particular type of fault
             major: Major number of the target device. Generally, 8 for HDD.
        minor-min: Minimum minor number of the target device candidate.
         minor-max: Maximum minor number of the target device candidate.
   inode/LBA flag : 0 or 1. 0 -"value" means LBA, 1- "value" means inode 
             value: inode or LBA value depends on "inode/LBA flag"

                    Note. LBA is not equal to a "block number" managed by a filesystem.
                          Block number is a logical location, but LBA is a physical 
                          location in the device.

     lib directory: Path to the common routine directory. 
                    You need to choose one of the following, depending on your environment.
                    fault_injection_common_scsi_RAID56  - target is SCSI disk using md RAID4/5/6
                    fault_injection_common_scsi         - target is SCSI disk otherwise
                    fault_injection_common_sata_RAID56  - target is SATA disk using md RAID4/5/6
                    fault_injection_common_sata         - target is SATA disk otherwise


  Rules about the range of target device:
   As described in the introduction, this tool is originally for a software RAID evaluation.
   Target device should be given as a range because the software raid does load balancing, 
   and the next access can't be predicted precisely.

   1. Target device candidates can be given by the range from minor-min to minor-max of the given
      major number. The minor numbers are used to distinguish physical disk.
      The first access within the range after SystemTap hook is ready,
      if the destination condition (given by LBA or inode number) met, the accessed 
      device will be the target device and the accessed sector will be the target sector. 
      The target sector and the target device never change until stopping the script.

      e.g.  When (major, minor-min, minor-max) = (8, 0, 49), sda, sdb, sdc, sdd will 
            be target candidates.

    2. Once the target device and the target sector is determined, fault injection
       will only occur on access to the target sector of the target device.

       This means that the "permanent" type of faults can only be injected repeatedly
       on access to the target sector of the target device. Other accesses complete 
       successfully.

    3. If you need to designate a particular target, you should give the same value to
       minor-min and minor-max.

    4. As described earlier, the minor-min and minor-max are used to distinguish physical disk.
       Each scripts can't distinguish disk partition by minor number in the same disk.
       e.g.  If (minor-max, minor-min) = (17, 18) given, it means that the target device 
             will be /dev/sdb.


EXAMPLES

  1. A temporary read error simulation

     #stap ./temporary_rerr.stp 8 1 17 1 5000747 -g -I ./fault_injection_common_sata/
     
     -> Set a temporary read error simulation hook to SCSI HDD(8) /dev/sda(1) or /dev/sdb(17).
        A read access to the file with inode 5000747 on sda or sdb will cause a read error.

  2. A read error correctable by write simulation

     #stap ./sector_rerr.stp 8 33 49 0 40496541 -g -I ./fault_injection_common_scsi/

     -> Set a correctable read error simulation hook to SCSI HDD(8) /dev/sdc(33) or /dev/sdd(49).
        This case the target sector is given by (0, 40496541), means LBA 40496541.
        A read access to one of these disks of LBA=40496541 will cause a read error.
        After read error injected to the LAB=40496541, a write access to the LAB=40496541
        assumed to fix the error. Then, following any access to LBA=40496541 will
        complete successfully.

6. Known Issues and limitations
================================

 - The read and write to inject a fault should be a "mapped" access.
   Direct I/O is not supported yet.

 - Currently run on  x86 architecture.

 
===============================================================================


Appendix A.

Preparing for using systemtap on Fedora8
------------------------------------------
  1. Decompress kernel and move them to an arbitrary location.
     # tar jxf linux-2.6.23.12.tar.bz2

  2. Some setting to compile the kernel

    At least, the following configuration is needed. 

    Loadable module support
     Enable loadable module support [Y]
     Module unloading [Y]
    General setup
     Kernel->user space relay support [Y]
    Instrumentation Support
     Kprobes [Y]
    Kernel hacking
     Kernel debugging [Y]
     Compile the kernel with debug info [Y]

    But you can reuse Fedora's config file.

     # cd linux-2.6.23.12
     # make mrproper
     # cp /boot/config-2.6.23.1-42.fc8 .config
     # make oldconfig
     # make prepare

  3. Build the kernel
     # make -j 4 bzImage
     # make -j 4 modules

  4. Install the kernel
     # make modules_install
     # make install

  5. Create symlinks for SystemTap
     # mkdir -p /usr/lib/debug/lib/modules/2.6.23.12/
     # ln -s /lib/modules/2.6.23.12/kernel /usr/lib/debug/lib/modules/2.6.23.12/
     # ln -s /lib/modules/2.6.23.12/build/vmlinux /usr/lib/debug/lib/modules/2.6.23.12/

  6. reboot the system to boot the new kernel.




About

Fault injection test tool, forked from http://sourceforge.net/projects/scsifaultinjtst/ with support for 3.2 kernels

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages