← Documents Documentation/admin-guide/device-mapper/dm-dust.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Device Mapper

dm-dust target

임의 block과 시점에 bad-sector read failure를 재현하고 write-remap, 목록 관리와 logging을 제어하는 dm-dust target입니다.

Source pathDocumentation/admin-guide/device-mapper/dm-dust.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

Bad-sector 상태 모델

dm-dust.rst:1-85

Bad block list, bypass/failure 상태, block 크기와 initial device 생성 절차를 설명합니다.

목록과 failure 제어

dm-dust.rst:86-254

Bad block 추가·삭제·조회·전체 정리, read EIO와 write-remap 및 전체 message를 정리합니다.

Logging과 설계 이유

dm-dust.rst:255-305

Quiet mode toggle과 scsi_debug·dm-flakey 대신 dm-dust가 필요한 이유를 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

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

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

임의 위치의 bad-sector emulation

1-33

`dm-dust` target은 임의 위치의 bad sector 동작과 임의 시점에 failure emulation을 활성화하는 기능을 제공합니다.

평소에는 linear target과 비슷하게 동작합니다. 사용자는 특정 시점에 target으로 message를 보내 지정 block의 read request를 실패시켜 bad sector가 있는 hard disk drive 동작을 흉내 낼 수 있습니다.

Failure가 활성화되어 `dmsetup status`에 `fail_read_on_bad_block`이 표시되면 bad block list에 있는 block read가 EIO(`Input/output error`)로 실패합니다.

Bad block list에 있는 block에 write하면 먼저 그 block을 list에서 제거하고 write 자체는 성공시킵니다. 이는 bad sector가 있는 drive의 `remapped sector` 동작을 emulation합니다.

Bad sector가 생기기 시작한 drive는 알 수 없는 시간과 위치에서 더 많은 bad sector를 만날 가능성이 큽니다. `addbadblock`과 `removebadblock` message로 새 위치를 자유롭게 추가·제거하고, `enable`과 `disable`로 구성된 bad block을 실제 bad로 취급할지 bypass할지 바꿀 수 있습니다. 따라서 test data와 metadata를 먼저 write한 뒤 bad sector가 나타나는 failure event를 simulation할 수 있습니다.

dm-dust bad-block 상태
Add block to bad block listbypass modeenableRead returns EIO
Write bad blockRemove block from listWrite succeedsSector appears remapped

List 구성과 failure enable 상태를 분리하고 write 성공으로 sector remap을 흉내 냅니다.

Table parameter와 device 생성

34-85

dm-dust table은 다음 세 parameter를 받습니다.

<device_path> <offset> <blksz>
dm-dust table parameter
Parameter설명
`device_path`Block device path
`offset`device_path 시작점에서 data area까지의 offset
`blksz`Byte 단위 block 크기; 최소 512, 최대 1073741824, 2의 거듭제곱

Backing device, data offset과 emulation block 크기를 지정합니다.

먼저 사용할 device 크기를 512-byte sector 단위로 확인합니다.

        $ sudo blockdev --getsz /dev/vdb1
        33552384

512-byte block 크기의 `dust1` device는 다음처럼 만듭니다.

        $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 512'

4096-byte block 크기를 사용하려면 마지막 값을 4096으로 지정합니다.

        $ sudo dmsetup create dust1 --table '0 33552384 dust /dev/vdb1 0 4096'

`dmsetup status`에서 `bypass`는 모든 I/O가 underlying device로 통과함을 뜻합니다. `verbose`는 bad block 추가·제거·remap을 자세히 log한다는 뜻입니다. 초기 상태에서는 direct read와 write가 모두 성공합니다.

        $ sudo dmsetup status dust1
        0 33552384 dust 252:17 bypass verbose

        $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=128 iflag=direct
        128+0 records in
        128+0 records out

        $ sudo dd if=/dev/zero of=/dev/mapper/dust1 bs=512 count=128 oflag=direct
        128+0 records in
        128+0 records out
초기 device 상태
항목
Mapped size33552384 sectors
Read behavior`bypass`
Logging`verbose`
Direct read/write모두 성공

Bad block failure가 활성화되기 전에는 linear mapping처럼 동작합니다.

Bad block 추가, failure 활성화와 write remap

86-139

Device의 bad-block emulation이 enabled이든 disabled이든 언제든 `addbadblock`과 `removebadblock` message로 bad block을 추가하거나 제거할 수 있습니다. 다음 예는 block 60, 67, 72를 추가합니다.

        $ sudo dmsetup message dust1 0 addbadblock 60
        kernel: device-mapper: dust: badblock added at block 60

        $ sudo dmsetup message dust1 0 addbadblock 67
        kernel: device-mapper: dust: badblock added at block 67

        $ sudo dmsetup message dust1 0 addbadblock 72
        kernel: device-mapper: dust: badblock added at block 72

추가한 block은 bad block list에 저장됩니다. Device가 `bypass` mode인 동안에는 read와 write가 성공합니다.

        $ sudo dmsetup status dust1
        0 33552384 dust 252:17 bypass

`enable` message를 보내 `fail read on bad block` 동작을 활성화합니다. Status는 `fail_read_on_bad_block`으로 바뀝니다.

        $ sudo dmsetup message dust1 0 enable
        kernel: device-mapper: dust: enabling read failures on bad sectors

        $ sudo dmsetup status dust1
        0 33552384 dust 252:17 fail_read_on_bad_block

이 mode에서 bad block 67을 direct read하면 `Input/output error`가 발생하고 0 byte가 copy됩니다.

        $ sudo dd if=/dev/mapper/dust1 of=/dev/null bs=512 count=1 skip=67 iflag=direct
        dd: error reading '/dev/mapper/dust1': Input/output error
        0+0 records in
        0+0 records out
        0 bytes copied, 0.00040651 s, 0.0 kB/s

반대로 bad block에 write하면 write가 성공하고 해당 block을 bad block list에서 제거합니다. 다음 log는 block 60, 67, 72, 87이 write 때문에 제거된 결과를 보여 줍니다.

        $ sudo dd if=/dev/zero of=/dev/mapper/dust1 bs=512 count=128 oflag=direct
        128+0 records in
        128+0 records out

        kernel: device-mapper: dust: block 60 removed from badblocklist by write
        kernel: device-mapper: dust: block 67 removed from badblocklist by write
        kernel: device-mapper: dust: block 72 removed from badblocklist by write
        kernel: device-mapper: dust: block 87 removed from badblocklist by write
Read failure와 write remap
Bad block listedenable failure modeDirect readEIO / Input-output error
Bad block listedWriteRemove from badblocklistWrite completes

같은 bad block도 operation에 따라 실패하거나 list에서 복구됩니다.

예제 bad block 변화
단계Bad block
추가60, 67, 72
Failure read 예67에서 EIO
Write 뒤 제거 log60, 67, 72, 87

List에 추가한 block은 write 범위에 포함되면 remap된 것처럼 제거됩니다.

중복·누락 error와 block 수 조회

140-169

이미 list에 있는 bad block을 다시 추가하면 `Invalid argument` error와 `already in badblocklist` message가 발생합니다.

        $ sudo dmsetup message dust1 0 addbadblock 88
        device-mapper: message ioctl on dust1  failed: Invalid argument
        kernel: device-mapper: dust: block 88 already in badblocklist

List에 없는 bad block을 제거하려 해도 `Invalid argument` error와 `not found in badblocklist` message가 발생합니다.

        $ sudo dmsetup message dust1 0 removebadblock 87
        device-mapper: message ioctl on dust1  failed: Invalid argument
        kernel: device-mapper: dust: block 87 not found in badblocklist

현재 device에 구성된 bad block 수는 `countbadblocks` message로 셉니다.

        $ sudo dmsetup message dust1 0 countbadblocks

응답 message에는 현재 bad block 수가 표시됩니다.

        countbadblocks: 895 badblock(s) found
Bad-block list validation
요청결과
기존 block 재추가`Invalid argument`, already in badblocklist
없는 block 제거`Invalid argument`, not found in badblocklist
`countbadblocks`현재 list entry 수 출력

List operation은 잘못된 중복·누락 요청을 명시적으로 거부합니다.

조회, 전체 삭제와 목록 출력

170-224

특정 block이 bad block list에 있는지 확인하려면 `queryblock <blknum>`을 사용합니다.

        $ sudo dmsetup message dust1 0 queryblock 72

Block이 list에 있으면 다음 message가 출력됩니다.

        dust_query_block: block 72 found in badblocklist

List에 없으면 다음 message가 출력됩니다.

        dust_query_block: block 72 not found in badblocklist

`queryblock`은 enabled와 disabled mode 모두에서 동작합니다. Device에 I/O를 보내거나 bad-block emulation을 enable하지 않고도 해당 block을 bad로 취급할지 확인할 수 있습니다.

각 block마다 `removebadblock`을 실행하지 않고 list 전체를 비우려면 `clearbadblocks`를 사용합니다.

        $ sudo dmsetup message dust1 0 clearbadblocks

Bad block을 지우면 다음 message가 표시됩니다.

        dust_clear_badblocks: badblocks cleared

지울 bad block이 없으면 별도 message가 표시됩니다.

        dust_clear_badblocks: no badblocks found

`listbadblocks`는 bad block을 한 줄에 하나씩 출력합니다. 다음 예에는 block 1과 2가 있습니다.

        $ sudo dmsetup message dust1 0 listbadblocks
        1
        2

List가 비어 있으면 command는 아무 출력 없이 끝납니다.

        $ sudo dmsetup message dust1 0 listbadblocks
Bad-block inspection command
Command결과
`queryblock <blknum>`특정 block 존재 여부 message
`clearbadblocks`List 전체 삭제 및 결과 message
`listbadblocks`모든 block number 출력; 비어 있으면 출력 없음

I/O를 일으키지 않고 list를 조회·정리할 수 있습니다.

Message command 목록과 제거

225-254

Block number argument가 필요한 operation은 다음 세 가지입니다.

        addbadblock <blknum>
        queryblock <blknum>
        removebadblock <blknum>

`<blknum>`은 device block 크기에 대응하는 device 범위 안의 block number여야 합니다.

Single-argument message command 목록은 다음과 같습니다.

        countbadblocks
        clearbadblocks
        listbadblocks
        disable
        enable
        quiet
dm-dust message command
Command용도
`addbadblock <blknum>`Bad block 추가
`queryblock <blknum>`Bad block 존재 여부 조회
`removebadblock <blknum>`Bad block 제거
`countbadblocks`Bad block 수 출력
`clearbadblocks`Bad block 전체 삭제
`listbadblocks`Bad block 목록 출력
`disable` / `enable`Read-failure emulation 비활성화/활성화
`quiet`Verbose logging toggle

List 조작, emulation 상태와 logging을 runtime에 제어합니다.

시험이 끝나면 `dmsetup remove`로 device를 제거합니다.

        $ sudo dmsetup remove dust1

Quiet mode logging 제어

255-281

Bad block이 많은 test에서는 block 추가·제거·write-remap log가 지나치게 많을 수 있습니다. `quiet` message로 quiet mode를 활성화할 수 있습니다.

        $ sudo dmsetup message dust1 0 quiet

Quiet mode는 add, remove, write로 제거된 operation의 log를 억제합니다. `countbadblocks`와 `queryblock` message의 log는 quiet mode에서도 계속 출력됩니다.

`dmsetup status`에서 `quiet` 표시로 mode를 확인할 수 있습니다.

        $ sudo dmsetup status dust1
        0 33552384 dust 252:17 fail_read_on_bad_block quiet

`quiet` message를 다시 보내면 quiet mode를 끄는 toggle로 동작하며 status가 `verbose`로 돌아옵니다.

        $ sudo dmsetup message dust1 0 quiet

        $ sudo dmsetup status dust1
        0 33552384 dust 252:17 fail_read_on_bad_block verbose

`verbose`가 있으면 정상 logging 상태입니다.

Quiet mode toggle
verbosesend quietquiet: suppress add/remove/remap logssend quiet againverbose

같은 message로 verbose와 quiet logging 상태를 전환합니다.

scsi_debug와 dm-flakey 대신 dm-dust

282-305

`scsi_debug`에는 source code에 hardcode된 한 sector `0x1234`의 read를 실패시키는 `medium error` mode가 있습니다. 하지만 persistent storage로 RAM을 사용해 가능한 device 크기가 크게 줄어듭니다.

`dm-flakey`는 특정 시점이 아니라 지정된 시간 주기에 모든 block 위치의 모든 I/O를 실패시킵니다.

실제 hard disk의 bad sector는 read를 실패시키며 보통 EIO(`I/O error`) 또는 ENODATA(`No data available`)를 반환합니다. 그러나 그 sector에 write는 성공할 수 있고, controller가 더 이상 read error를 겪지 않거나 sector를 reallocate하면 다시 읽을 수 있게 됩니다. 이후 예측할 수 없는 다른 위치에 새 bad sector가 생길 수도 있습니다.

dm-dust는 system memory를 차지하지 않는 수십 GB 이상의 큰 storage device를 바탕으로, 알려진 sector 위치와 알려진 시점에 bad-sector 동작을 나타내는 device를 제공하려고 합니다.

Bad-sector test target 비교
도구제약
`scsi_debug`한 hardcoded sector `0x1234`, RAM storage로 크기 제한
`dm-flakey`지정 주기에 모든 위치의 모든 I/O 실패
`dm-dust`임의 block과 시점, read EIO/ENODATA 및 write-remap 동작, 대용량 backing storage

위치·시점 제어, storage 규모와 write-remap 현실성을 비교합니다.