1dm-dust 2======= 3 4This target emulates the behavior of bad sectors at arbitrary 5locations, and the ability to enable the emulation of the failures 6at an arbitrary time. 7 8This target behaves similarly to a linear target. At a given time, 9the user can send a message to the target to start failing read 10requests on specific blocks (to emulate the behavior of a hard disk 11drive with bad sectors). 12 13When the failure behavior is enabled (i.e.: when the output of 14"dmsetup status" displays "fail_read_on_bad_block"), reads of blocks 15in the "bad block list" will fail with EIO ("Input/output error"). 16 17Writes of blocks in the "bad block list will result in the following: 18 191. Remove the block from the "bad block list". 202. Successfully complete the write. 21 22This emulates the "remapped sector" behavior of a drive with bad 23sectors. 24 25Normally, a drive that is encountering bad sectors will most likely 26encounter more bad sectors, at an unknown time or location. 27With dm-dust, the user can use the "addbadblock" and "removebadblock" 28messages to add arbitrary bad blocks at new locations, and the 29"enable" and "disable" messages to modulate the state of whether the 30configured "bad blocks" will be treated as bad, or bypassed. 31This allows the pre-writing of test data and metadata prior to 32simulating a "failure" event where bad sectors start to appear. 33 34Table parameters 35---------------- 36<device_path> <offset> <blksz> 37 38Mandatory parameters: 39 <device_path>: 40 Path to the block device. 41 42 <offset>: 43 Offset to data area from start of device_path 44 45 <blksz>: 46 Block size in bytes 47 48 (minimum 512, maximum 1073741824, must be a power of 2) 49 50Usage instructions 51------------------ 52 53First, find the size (in 512-byte sectors) of the device to be used:: 54 55 $ sudo blockdev --getsz /dev/vdb1 56 33552384 57 58Create the dm-dust device: 59(For a device with a block size of 512 bytes) 60 61:: 62 63 $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 512' 64 65(For a device with a block size of 4096 bytes) 66 67:: 68 69 $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096' 70 71Check the status of the read behavior ("bypass" indicates that all I/O 72will be passed through to the underlying device):: 73 74 $ sudo dmsetup status dust1 75 0 33552384 dust 252:17 bypass 76 77 $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct 78 128+0 records in 79 128+0 records out 80 81 $ sudo dd if=/dev/zero of=/dev/mapper/dust1 bs=512 count=128 oflag=direct 82 128+0 records in 83 128+0 records out 84 85Adding and removing bad blocks 86------------------------------ 87 88At any time (i.e.: whether the device has the "bad block" emulation 89enabled or disabled), bad blocks may be added or removed from the 90device via the "addbadblock" and "removebadblock" messages:: 91 92 $ sudo dmsetup message dust1 0 addbadblock 60 93 kernel: device-mapper: dust: badblock added at block 60 94 95 $ sudo dmsetup message dust1 0 addbadblock 67 96 kernel: device-mapper: dust: badblock added at block 67 97 98 $ sudo dmsetup message dust1 0 addbadblock 72 99 kernel: device-mapper: dust: badblock added at block 72 100 101These bad blocks will be stored in the "bad block list". 102While the device is in "bypass" mode, reads and writes will succeed:: 103 104 $ sudo dmsetup status dust1 105 0 33552384 dust 252:17 bypass 106 107Enabling block read failures 108---------------------------- 109 110To enable the "fail read on bad block" behavior, send the "enable" message:: 111 112 $ sudo dmsetup message dust1 0 enable 113 kernel: device-mapper: dust: enabling read failures on bad sectors 114 115 $ sudo dmsetup status dust1 116 0 33552384 dust 252:17 fail_read_on_bad_block 117 118With the device in "fail read on bad block" mode, attempting to read a 119block will encounter an "Input/output error":: 120 121 $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=1 skip=67 iflag=direct 122 dd: error reading '/dev/mapper/dust1': Input/output error 123 0+0 records in 124 0+0 records out 125 0 bytes copied, 0.00040651 s, 0.0 kB/s 126 127...and writing to the bad blocks will remove the blocks from the list, 128therefore emulating the "remap" behavior of hard disk drives:: 129 130 $ sudo dd if=/dev/zero of=/dev/mapper/dust1 bs=512 count=128 oflag=direct 131 128+0 records in 132 128+0 records out 133 134 kernel: device-mapper: dust: block 60 removed from badblocklist by write 135 kernel: device-mapper: dust: block 67 removed from badblocklist by write 136 kernel: device-mapper: dust: block 72 removed from badblocklist by write 137 kernel: device-mapper: dust: block 87 removed from badblocklist by write 138 139Bad block add/remove error handling 140----------------------------------- 141 142Attempting to add a bad block that already exists in the list will 143result in an "Invalid argument" error, as well as a helpful message:: 144 145 $ sudo dmsetup message dust1 0 addbadblock 88 146 device-mapper: message ioctl on dust1 failed: Invalid argument 147 kernel: device-mapper: dust: block 88 already in badblocklist 148 149Attempting to remove a bad block that doesn't exist in the list will 150result in an "Invalid argument" error, as well as a helpful message:: 151 152 $ sudo dmsetup message dust1 0 removebadblock 87 153 device-mapper: message ioctl on dust1 failed: Invalid argument 154 kernel: device-mapper: dust: block 87 not found in badblocklist 155 156Counting the number of bad blocks in the bad block list 157------------------------------------------------------- 158 159To count the number of bad blocks configured in the device, run the 160following message command:: 161 162 $ sudo dmsetup message dust1 0 countbadblocks 163 164A message will print with the number of bad blocks currently 165configured on the device:: 166 167 kernel: device-mapper: dust: countbadblocks: 895 badblock(s) found 168 169Querying for specific bad blocks 170-------------------------------- 171 172To find out if a specific block is in the bad block list, run the 173following message command:: 174 175 $ sudo dmsetup message dust1 0 queryblock 72 176 177The following message will print if the block is in the list:: 178 179 device-mapper: dust: queryblock: block 72 found in badblocklist 180 181The following message will print if the block is not in the list:: 182 183 device-mapper: dust: queryblock: block 72 not found in badblocklist 184 185The "queryblock" message command will work in both the "enabled" 186and "disabled" modes, allowing the verification of whether a block 187will be treated as "bad" without having to issue I/O to the device, 188or having to "enable" the bad block emulation. 189 190Clearing the bad block list 191--------------------------- 192 193To clear the bad block list (without needing to individually run 194a "removebadblock" message command for every block), run the 195following message command:: 196 197 $ sudo dmsetup message dust1 0 clearbadblocks 198 199After clearing the bad block list, the following message will appear:: 200 201 kernel: device-mapper: dust: clearbadblocks: badblocks cleared 202 203If there were no bad blocks to clear, the following message will 204appear:: 205 206 kernel: device-mapper: dust: clearbadblocks: no badblocks found 207 208Message commands list 209--------------------- 210 211Below is a list of the messages that can be sent to a dust device: 212 213Operations on blocks (requires a <blknum> argument):: 214 215 addbadblock <blknum> 216 queryblock <blknum> 217 removebadblock <blknum> 218 219...where <blknum> is a block number within range of the device 220(corresponding to the block size of the device.) 221 222Single argument message commands:: 223 224 countbadblocks 225 clearbadblocks 226 disable 227 enable 228 quiet 229 230Device removal 231-------------- 232 233When finished, remove the device via the "dmsetup remove" command:: 234 235 $ sudo dmsetup remove dust1 236 237Quiet mode 238---------- 239 240On test runs with many bad blocks, it may be desirable to avoid 241excessive logging (from bad blocks added, removed, or "remapped"). 242This can be done by enabling "quiet mode" via the following message:: 243 244 $ sudo dmsetup message dust1 0 quiet 245 246This will suppress log messages from add / remove / removed by write 247operations. Log messages from "countbadblocks" or "queryblock" 248message commands will still print in quiet mode. 249 250The status of quiet mode can be seen by running "dmsetup status":: 251 252 $ sudo dmsetup status dust1 253 0 33552384 dust 252:17 fail_read_on_bad_block quiet 254 255To disable quiet mode, send the "quiet" message again:: 256 257 $ sudo dmsetup message dust1 0 quiet 258 259 $ sudo dmsetup status dust1 260 0 33552384 dust 252:17 fail_read_on_bad_block verbose 261 262(The presence of "verbose" indicates normal logging.) 263 264"Why not...?" 265------------- 266 267scsi_debug has a "medium error" mode that can fail reads on one 268specified sector (sector 0x1234, hardcoded in the source code), but 269it uses RAM for the persistent storage, which drastically decreases 270the potential device size. 271 272dm-flakey fails all I/O from all block locations at a specified time 273frequency, and not a given point in time. 274 275When a bad sector occurs on a hard disk drive, reads to that sector 276are failed by the device, usually resulting in an error code of EIO 277("I/O error") or ENODATA ("No data available"). However, a write to 278the sector may succeed, and result in the sector becoming readable 279after the device controller no longer experiences errors reading the 280sector (or after a reallocation of the sector). However, there may 281be bad sectors that occur on the device in the future, in a different, 282unpredictable location. 283 284This target seeks to provide a device that can exhibit the behavior 285of a bad sector at a known sector location, at a known time, based 286on a large storage device (at least tens of gigabytes, not occupying 287system memory). 288