← Documents Documentation/admin-guide/device-mapper/thin-provisioning.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Device Mapper

Thin provisioning

공유 data pool, 재귀 snapshot, separate metadata, 공간 event와 recovery를 구현하는 thin-pool·thin target의 cookbook과 전체 message·status reference입니다.

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

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

1. 요약·해설

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

Pool과 metadata 설계

thin-provisioning.rst:1-155

Shared pool, recursive snapshot, metadata sizing, block geometry와 crash·space recovery를 설명합니다.

Thin·snapshot cookbook

thin-provisioning.rst:156-258

24-bit device 생성, internal·external snapshot과 올바른 activation·deactivation 순서를 보여 줍니다.

Target reference

thin-provisioning.rst:259-427

thin-pool constructor·feature·status·message와 thin target 크기·status semantics를 정리합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 =================
2 Thin provisioning
3 =================
4
5 Introduction
6 ============
7
8 This document describes a collection of device-mapper targets that
9 between them implement thin-provisioning and snapshots.
10
11 The main highlight of this implementation, compared to the previous
12 implementation of snapshots, is that it allows many virtual devices to
13 be stored on the same data volume. This simplifies administration and
14 allows the sharing of data between volumes, thus reducing disk usage.
15
16 Another significant feature is support for an arbitrary depth of
17 recursive snapshots (snapshots of snapshots of snapshots ...). The
18 previous implementation of snapshots did this by chaining together
19 lookup tables, and so performance was O(depth). This new
20 implementation uses a single data structure to avoid this degradation
21 with depth. Fragmentation may still be an issue, however, in some
22 scenarios.
23
24 Metadata is stored on a separate device from data, giving the
25 administrator some freedom, for example to:
26
27 - Improve metadata resilience by storing metadata on a mirrored volume
28 but data on a non-mirrored one.
29
30 - Improve performance by storing the metadata on SSD.
31
32 Status
33 ======
34
35 These targets are considered safe for production use. But different use
36 cases will have different performance characteristics, for example due
37 to fragmentation of the data volume.
38
39 If you find this software is not performing as expected please mail
40 dm-devel@redhat.com with details and we'll try our best to improve
41 things for you.
42
43 Userspace tools for checking and repairing the metadata have been fully
44 developed and are available as 'thin_check' and 'thin_repair'. The name
45 of the package that provides these utilities varies by distribution (on
46 a Red Hat distribution it is named 'device-mapper-persistent-data').
47
48 Cookbook
49 ========
50
51 This section describes some quick recipes for using thin provisioning.
52 They use the dmsetup program to control the device-mapper driver
53 directly. End users will be advised to use a higher-level volume
54 manager such as LVM2 once support has been added.
55
56 Pool device
57 -----------
58
59 The pool device ties together the metadata volume and the data volume.
60 It maps I/O linearly to the data volume and updates the metadata via
61 two mechanisms:
62
63 - Function calls from the thin targets
64
65 - Device-mapper 'messages' from userspace which control the creation of new
66 virtual devices amongst other things.
67
68 Setting up a fresh pool device
69 ------------------------------
70
71 Setting up a pool device requires a valid metadata device, and a
72 data device. If you do not have an existing metadata device you can
73 make one by zeroing the first 4k to indicate empty metadata.
74
75 dd if=/dev/zero of=$metadata_dev bs=4096 count=1
76
77 The amount of metadata you need will vary according to how many blocks
78 are shared between thin devices (i.e. through snapshots). If you have
79 less sharing than average you'll need a larger-than-average metadata device.
80
81 As a guide, we suggest you calculate the number of bytes to use in the
82 metadata device as 48 * $data_dev_size / $data_block_size but round it up
83 to 2MiB if the answer is smaller. If you're creating large numbers of
84 snapshots which are recording large amounts of change, you may find you
85 need to increase this.
86
87 The largest size supported is 16GiB: If the device is larger,
88 a warning will be issued and the excess space will not be used.
89
90 Reloading a pool table
91 ----------------------
92
93 You may reload a pool's table, indeed this is how the pool is resized
94 if it runs out of space. (N.B. While specifying a different metadata
95 device when reloading is not forbidden at the moment, things will go
96 wrong if it does not route I/O to exactly the same on-disk location as
97 previously.)
98
99 Using an existing pool device
100 -----------------------------
101
102 ::
103
104 dmsetup create pool \
105 --table "0 20971520 thin-pool $metadata_dev $data_dev \
106 $data_block_size $low_water_mark"
107
108 $data_block_size gives the smallest unit of disk space that can be
109 allocated at a time expressed in units of 512-byte sectors.
110 $data_block_size must be between 128 (64KiB) and 2097152 (1GiB) and a
111 multiple of 128 (64KiB). $data_block_size cannot be changed after the
112 thin-pool is created. People primarily interested in thin provisioning
113 may want to use a value such as 1024 (512KiB). People doing lots of
114 snapshotting may want a smaller value such as 128 (64KiB). If you are
115 not zeroing newly-allocated data, a larger $data_block_size in the
116 region of 262144 (128MiB) is suggested.
117
118 $low_water_mark is expressed in blocks of size $data_block_size. If
119 free space on the data device drops below this level then a dm event
120 will be triggered which a userspace daemon should catch allowing it to
121 extend the pool device. Only one such event will be sent.
122
123 No special event is triggered if a just resumed device's free space is below
124 the low water mark. However, resuming a device always triggers an
125 event; a userspace daemon should verify that free space exceeds the low
126 water mark when handling this event.
127
128 A low water mark for the metadata device is maintained in the kernel and
129 will trigger a dm event if free space on the metadata device drops below
130 it.
131
132 Updating on-disk metadata
133 -------------------------
134
135 On-disk metadata is committed every time a FLUSH or FUA bio is written.
136 If no such requests are made then commits will occur every second. This
137 means the thin-provisioning target behaves like a physical disk that has
138 a volatile write cache. If power is lost you may lose some recent
139 writes. The metadata should always be consistent in spite of any crash.
140
141 If data space is exhausted the pool will either error or queue IO
142 according to the configuration (see: error_if_no_space). If metadata
143 space is exhausted or a metadata operation fails: the pool will error IO
144 until the pool is taken offline and repair is performed to 1) fix any
145 potential inconsistencies and 2) clear the flag that imposes repair.
146 Once the pool's metadata device is repaired it may be resized, which
147 will allow the pool to return to normal operation. Note that if a pool
148 is flagged as needing repair, the pool's data and metadata devices
149 cannot be resized until repair is performed. It should also be noted
150 that when the pool's metadata space is exhausted the current metadata
151 transaction is aborted. Given that the pool will cache IO whose
152 completion may have already been acknowledged to upper IO layers
153 (e.g. filesystem) it is strongly suggested that consistency checks
154 (e.g. fsck) be performed on those layers when repair of the pool is
155 required.
156
157 Thin provisioning
158 -----------------
159
160 i) Creating a new thinly-provisioned volume.
161
162 To create a new thinly- provisioned volume you must send a message to an
163 active pool device, /dev/mapper/pool in this example::
164
165 dmsetup message /dev/mapper/pool 0 "create_thin 0"
166
167 Here '0' is an identifier for the volume, a 24-bit number. It's up
168 to the caller to allocate and manage these identifiers. If the
169 identifier is already in use, the message will fail with -EEXIST.
170
171 ii) Using a thinly-provisioned volume.
172
173 Thinly-provisioned volumes are activated using the 'thin' target::
174
175 dmsetup create thin --table "0 2097152 thin /dev/mapper/pool 0"
176
177 The last parameter is the identifier for the thinp device.
178
179 Internal snapshots
180 ------------------
181
182 i) Creating an internal snapshot.
183
184 Snapshots are created with another message to the pool.
185
186 N.B. If the origin device that you wish to snapshot is active, you
187 must suspend it before creating the snapshot to avoid corruption.
188 This is NOT enforced at the moment, so please be careful!
189
190 ::
191
192 dmsetup suspend /dev/mapper/thin
193 dmsetup message /dev/mapper/pool 0 "create_snap 1 0"
194 dmsetup resume /dev/mapper/thin
195
196 Here '1' is the identifier for the volume, a 24-bit number. '0' is the
197 identifier for the origin device.
198
199 ii) Using an internal snapshot.
200
201 Once created, the user doesn't have to worry about any connection
202 between the origin and the snapshot. Indeed the snapshot is no
203 different from any other thinly-provisioned device and can be
204 snapshotted itself via the same method. It's perfectly legal to
205 have only one of them active, and there's no ordering requirement on
206 activating or removing them both. (This differs from conventional
207 device-mapper snapshots.)
208
209 Activate it exactly the same way as any other thinly-provisioned volume::
210
211 dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 1"
212
213 External snapshots
214 ------------------
215
216 You can use an external **read only** device as an origin for a
217 thinly-provisioned volume. Any read to an unprovisioned area of the
218 thin device will be passed through to the origin. Writes trigger
219 the allocation of new blocks as usual.
220
221 One use case for this is VM hosts that want to run guests on
222 thinly-provisioned volumes but have the base image on another device
223 (possibly shared between many VMs).
224
225 You must not write to the origin device if you use this technique!
226 Of course, you may write to the thin device and take internal snapshots
227 of the thin volume.
228
229 i) Creating a snapshot of an external device
230
231 This is the same as creating a thin device.
232 You don't mention the origin at this stage.
233
234 ::
235
236 dmsetup message /dev/mapper/pool 0 "create_thin 0"
237
238 ii) Using a snapshot of an external device.
239
240 Append an extra parameter to the thin target specifying the origin::
241
242 dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 0 /dev/image"
243
244 N.B. All descendants (internal snapshots) of this snapshot require the
245 same extra origin parameter.
246
247 Deactivation
248 ------------
249
250 All devices using a pool must be deactivated before the pool itself
251 can be.
252
253 ::
254
255 dmsetup remove thin
256 dmsetup remove snap
257 dmsetup remove pool
258
259 Reference
260 =========
261
262 'thin-pool' target
263 ------------------
264
265 i) Constructor
266
267 ::
268
269 thin-pool <metadata dev> <data dev> <data block size (sectors)> \
270 <low water mark (blocks)> [<number of feature args> [<arg>]*]
271
272 Optional feature arguments:
273
274 skip_block_zeroing:
275 Skip the zeroing of newly-provisioned blocks.
276
277 ignore_discard:
278 Disable discard support.
279
280 no_discard_passdown:
281 Don't pass discards down to the underlying
282 data device, but just remove the mapping.
283
284 read_only:
285 Don't allow any changes to be made to the pool
286 metadata. This mode is only available after the
287 thin-pool has been created and first used in full
288 read/write mode. It cannot be specified on initial
289 thin-pool creation.
290
291 error_if_no_space:
292 Error IOs, instead of queueing, if no space.
293
294 Data block size must be between 64KiB (128 sectors) and 1GiB
295 (2097152 sectors) inclusive.
296
297
298 ii) Status
299
300 ::
301
302 <transaction id> <used metadata blocks>/<total metadata blocks>
303 <used data blocks>/<total data blocks> <held metadata root>
304 ro|rw|out_of_data_space [no_]discard_passdown [error|queue]_if_no_space
305 needs_check|- metadata_low_watermark
306
307 transaction id:
308 A 64-bit number used by userspace to help synchronise with metadata
309 from volume managers.
310
311 used data blocks / total data blocks
312 If the number of free blocks drops below the pool's low water mark a
313 dm event will be sent to userspace. This event is edge-triggered and
314 it will occur only once after each resume so volume manager writers
315 should register for the event and then check the target's status.
316
317 held metadata root:
318 The location, in blocks, of the metadata root that has been
319 'held' for userspace read access. '-' indicates there is no
320 held root.
321
322 discard_passdown|no_discard_passdown
323 Whether or not discards are actually being passed down to the
324 underlying device. When this is enabled when loading the table,
325 it can get disabled if the underlying device doesn't support it.
326
327 ro|rw|out_of_data_space
328 If the pool encounters certain types of device failures it will
329 drop into a read-only metadata mode in which no changes to
330 the pool metadata (like allocating new blocks) are permitted.
331
332 In serious cases where even a read-only mode is deemed unsafe
333 no further I/O will be permitted and the status will just
334 contain the string 'Fail'. The userspace recovery tools
335 should then be used.
336
337 error_if_no_space|queue_if_no_space
338 If the pool runs out of data or metadata space, the pool will
339 either queue or error the IO destined to the data device. The
340 default is to queue the IO until more space is added or the
341 'no_space_timeout' expires. The 'no_space_timeout' dm-thin-pool
342 module parameter can be used to change this timeout -- it
343 defaults to 60 seconds but may be disabled using a value of 0.
344
345 needs_check
346 A metadata operation has failed, resulting in the needs_check
347 flag being set in the metadata's superblock. The metadata
348 device must be deactivated and checked/repaired before the
349 thin-pool can be made fully operational again. '-' indicates
350 needs_check is not set.
351
352 metadata_low_watermark:
353 Value of metadata low watermark in blocks. The kernel sets this
354 value internally but userspace needs to know this value to
355 determine if an event was caused by crossing this threshold.
356
357 iii) Messages
358
359 create_thin <dev id>
360 Create a new thinly-provisioned device.
361 <dev id> is an arbitrary unique 24-bit identifier chosen by
362 the caller.
363
364 create_snap <dev id> <origin id>
365 Create a new snapshot of another thinly-provisioned device.
366 <dev id> is an arbitrary unique 24-bit identifier chosen by
367 the caller.
368 <origin id> is the identifier of the thinly-provisioned device
369 of which the new device will be a snapshot.
370
371 delete <dev id>
372 Deletes a thin device. Irreversible.
373
374 set_transaction_id <current id> <new id>
375 Userland volume managers, such as LVM, need a way to
376 synchronise their external metadata with the internal metadata of the
377 pool target. The thin-pool target offers to store an
378 arbitrary 64-bit transaction id and return it on the target's
379 status line. To avoid races you must provide what you think
380 the current transaction id is when you change it with this
381 compare-and-swap message.
382
383 reserve_metadata_snap
384 Reserve a copy of the data mapping btree for use by userland.
385 This allows userland to inspect the mappings as they were when
386 this message was executed. Use the pool's status command to
387 get the root block associated with the metadata snapshot.
388
389 release_metadata_snap
390 Release a previously reserved copy of the data mapping btree.
391
392 'thin' target
393 -------------
394
395 i) Constructor
396
397 ::
398
399 thin <pool dev> <dev id> [<external origin dev>]
400
401 pool dev:
402 the thin-pool device, e.g. /dev/mapper/my_pool or 253:0
403
404 dev id:
405 the internal device identifier of the device to be
406 activated.
407
408 external origin dev:
409 an optional block device outside the pool to be treated as a
410 read-only snapshot origin: reads to unprovisioned areas of the
411 thin target will be mapped to this device.
412
413 The pool doesn't store any size against the thin devices. If you
414 load a thin target that is smaller than you've been using previously,
415 then you'll have no access to blocks mapped beyond the end. If you
416 load a target that is bigger than before, then extra blocks will be
417 provisioned as and when needed.
418
419 ii) Status
420
421 <nr mapped sectors> <highest mapped sector>
422 If the pool has encountered device errors and failed, the status
423 will just contain the string 'Fail'. The userspace recovery
424 tools should then be used.
425
426 In the case where <nr mapped sectors> is 0, there is no highest
427 mapped sector and the value of <highest mapped sector> is unspecified.
428

3. 한국어 전문 번역

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

공유 pool과 임의 깊이 snapshot

1-31

이 문서는 thin provisioning과 snapshot을 함께 구현하는 Device Mapper target 모음을 설명합니다.

기존 snapshot 구현과 비교한 가장 큰 특징은 같은 data volume에 많은 virtual device를 저장할 수 있다는 점입니다. 관리가 단순해지고 volume 사이에서 data를 공유해 disk 사용량을 줄일 수 있습니다.

Snapshot의 snapshot을 계속 만드는 임의 깊이 recursive snapshot도 지원합니다. 기존 구현은 lookup table을 chain으로 연결해 성능이 `O(depth)`였지만 새 구현은 단일 data structure를 사용해 깊이에 따른 성능 저하를 피합니다. 다만 일부 scenario에서는 fragmentation이 여전히 문제가 될 수 있습니다.

Recursive snapshot lookup
기존: snapshot depth NLookup table chain N단계`O(depth)`
새 thin snapshot단일 shared mapping structureDepth 증가에 따른 lookup 저하 회피

중첩 깊이만큼 table을 따라가던 방식 대신 공용 metadata structure에서 mapping을 찾습니다.

Metadata는 data와 별도 device에 저장하므로 관리자가 배치를 선택할 수 있습니다. 예를 들어 data는 non-mirrored volume에 두면서 metadata만 mirrored volume에 저장해 resilience를 높이거나, metadata를 SSD에 저장해 성능을 높일 수 있습니다.

Metadata 분리 배치
배치효과
Metadata는 mirror, data는 non-mirrorMetadata resilience 향상
Metadata는 SSDMetadata operation 성능 향상

Data와 metadata의 성능·복원력 요구를 독립적으로 설계합니다.

Production 상태와 userspace 도구

32-54

이 target들은 production use에 안전한 것으로 간주됩니다. 다만 data volume fragmentation 등의 영향으로 use case마다 성능 특성이 달라질 수 있습니다.

예상과 다른 성능 문제가 있으면 자세한 내용을 `dm-devel@redhat.com`으로 보내 개선을 요청할 수 있습니다.

Metadata를 검사·수리하는 userspace tool은 `thin_check`와 `thin_repair`로 완성되어 있습니다. Utility를 제공하는 package 이름은 distribution마다 다르며 Red Hat 계열에서는 `device-mapper-persistent-data`입니다.

운영 도구
도구 또는 package역할
`thin_check`Metadata consistency 검사
`thin_repair`Metadata 수리
`device-mapper-persistent-data`Red Hat 계열 package 이름

Pool metadata의 검증과 복구를 userspace utility로 수행합니다.

Cookbook은 `dmsetup`으로 Device Mapper driver를 직접 제어하는 빠른 사용법을 설명합니다. 일반 사용자는 지원이 갖춰진 high-level volume manager인 LVM2를 사용하는 것이 권장됩니다.

제어 계층
Cookbook`dmsetup` 직접 제어Device Mapper target
일반 사용자LVM2Device Mapper target

문서 예제는 직접 message를 사용하지만 운영 환경에서는 volume manager가 이를 관리할 수 있습니다.

Pool device와 metadata 초기화·크기 산정

55-89

Pool device는 metadata volume과 data volume을 연결합니다. I/O는 data volume에 linear하게 mapping하고, thin target의 function call과 virtual device 생성 등을 제어하는 userspace Device Mapper message 두 방식으로 metadata를 갱신합니다.

Thin pool 구성
Thin device I/O`thin-pool`Data volume
Thin target function call + dm messagePool metadata updateMetadata volume

Data I/O와 mapping metadata를 분리하면서 thin target과 userspace message가 공통 metadata를 갱신합니다.

새 pool에는 유효한 metadata device와 data device가 필요합니다. 기존 metadata가 없으면 첫 4 KiB를 zero 처리해 빈 metadata임을 표시합니다.

    dd if=/dev/zero of=$metadata_dev bs=4096 count=1

필요한 metadata 양은 snapshot을 통한 thin device 간 block 공유량에 따라 달라집니다. 평균보다 공유가 적으면 평균보다 큰 metadata device가 필요합니다.

권장 metadata byte 수는 `48 * $data_dev_size / $data_block_size`입니다. 계산 결과가 2 MiB보다 작으면 2 MiB로 올립니다. 변경량이 큰 snapshot을 많이 만들면 더 늘려야 할 수 있습니다.

지원하는 최대 metadata 크기는 16 GiB입니다. 더 큰 device를 사용하면 warning을 내고 초과 공간은 사용하지 않습니다.

Metadata sizing
항목기준
권장 byte 수`48 * data_dev_size / data_block_size`
최소 권장2 MiB
지원 상한16 GiB
증설 요인Snapshot 수와 기록되는 변경량 증가

Data block 수와 sharing 정도를 바탕으로 metadata 용량을 잡습니다.

Pool reload, data block과 low water mark

90-130

Pool table은 reload할 수 있으며 공간이 부족할 때 pool을 resize하는 방법도 table reload입니다. Reload 시 다른 metadata device를 지정하는 것이 현재 금지되지는 않지만, 이전과 정확히 같은 on-disk location으로 I/O를 route하지 않으면 문제가 발생합니다.

기존 metadata·data device로 pool을 만드는 예는 다음과 같습니다.

::

    dmsetup create pool \
	--table "0 20971520 thin-pool $metadata_dev $data_dev \
		 $data_block_size $low_water_mark"

`$data_block_size`는 한 번에 할당할 수 있는 최소 disk 공간이며 512-byte sector 단위입니다. 값은 128(64 KiB) 이상 2097152(1 GiB) 이하이고 128의 배수여야 하며, thin-pool 생성 뒤에는 바꿀 수 없습니다.

Data block size 선택
크기권장 use case
`128`64 KiBSnapshot이 많은 workload
`1024`512 KiB일반 thin provisioning 중심
`262144`128 MiB새 block을 zero하지 않을 때 제안
`2097152`1 GiB지원 최대값

주 사용 패턴에 따라 allocation granularity를 선택합니다.

`$low_water_mark`는 `$data_block_size` block 단위입니다. Data device free space가 이 값 아래로 내려가면 dm event를 한 번 발생시키고, userspace daemon은 이를 받아 pool을 확장해야 합니다.

막 resume한 device의 free space가 이미 low water mark 아래여도 전용 event를 따로 만들지는 않습니다. 하지만 resume 자체는 항상 event를 발생시키므로 userspace daemon은 이를 처리할 때 free space가 low water mark를 넘는지 검사해야 합니다.

Kernel은 metadata device에도 low water mark를 유지하며 metadata free space가 그 아래로 내려가면 dm event를 발생시킵니다.

Low-water event 처리
Data free block 감소Low water mark crossingDm event 1회Daemon status 확인Pool 확장
Device resume항상 eventFree space와 watermark 비교
Metadata free block 감소Metadata watermark crossingDm event

Edge-triggered data event와 resume event에서 userspace가 실제 free space를 다시 확인합니다.

Commit 주기와 공간 고갈 복구

131-155

On-disk metadata는 `FLUSH` 또는 `FUA` bio를 쓸 때마다 commit합니다. 그런 request가 없으면 1초마다 commit합니다. 따라서 thin-provisioning target은 volatile write cache가 있는 physical disk처럼 동작하며 전원을 잃으면 최근 write 일부가 사라질 수 있지만 crash 뒤에도 metadata 자체는 항상 consistent해야 합니다.

Metadata commit trigger
`FLUSH` 또는 `FUA` bio즉시 metadata commit
해당 request 없음1초 경과Metadata commit
Power loss최근 uncommitted write 손실 가능마지막 metadata commit은 consistent

Explicit durability request가 없더라도 주기적으로 transaction을 commit합니다.

Data space가 고갈되면 pool 설정의 `error_if_no_space`에 따라 I/O를 error 처리하거나 queue합니다.

Metadata space가 고갈되거나 metadata operation이 실패하면 pool을 offline으로 전환하고 repair할 때까지 I/O를 error 처리합니다. Repair는 잠재적 inconsistency를 고치고 repair 강제 flag를 지워야 합니다. Metadata device를 수리한 뒤 resize하면 정상 동작으로 돌아갈 수 있습니다.

공간 고갈 동작
문제즉시 동작복구
Data space 고갈설정에 따라 error 또는 queueData pool 확장
Metadata space 고갈I/O error, transaction abortOffline check·repair 후 resize
Metadata operation 실패`needs_check` repair 요구Flag를 지우는 repair

Data와 metadata 부족은 영향과 복구 절차가 다릅니다.

Pool이 repair 필요 상태이면 repair 전에는 data와 metadata device를 resize할 수 없습니다. Metadata space 고갈 시 현재 metadata transaction도 abort됩니다.

Pool이 이미 upper I/O layer, 예를 들어 filesystem에 completion을 알린 I/O를 cache하고 있을 수 있으므로 pool repair가 필요했다면 해당 상위 계층에도 `fsck` 같은 consistency check를 수행할 것을 강하게 권장합니다.

Metadata failure 복구
Metadata 고갈·operation 실패Current transaction abortPool offline`thin_check`·`thin_repair`Metadata resizeFilesystem `fsck`정상 운영

Pool만 수리하는 데서 끝내지 않고 이미 completion을 받은 상위 filesystem도 검사합니다.

24-bit thin id 생성과 activation

156-178

새 thinly-provisioned volume을 만들려면 active pool device에 message를 보냅니다. 예제 pool은 `/dev/mapper/pool`입니다.

    dmsetup message /dev/mapper/pool 0 "create_thin 0"

`0`은 volume identifier이며 24-bit number입니다. Caller가 id를 할당하고 관리해야 합니다. 이미 사용 중인 identifier이면 message는 `-EEXIST`로 실패합니다.

Thinly-provisioned volume은 `thin` target으로 activate합니다.

    dmsetup create thin --table "0 2097152 thin /dev/mapper/pool 0"

Table의 마지막 parameter `0`이 activate할 thin device identifier입니다.

Thin device lifecycle 시작
Caller가 24-bit id 선택`create_thin 0`Pool metadata entry`thin ... pool 0`Thin device active

Pool metadata에 id를 만든 뒤 같은 id를 thin target table에서 activate합니다.

Thin identifier
항목규칙
Bit width24-bit
할당 주체Caller/userspace
중복 id`-EEXIST`
Activation`thin` target 마지막 parameter

Pool 내부 device를 userspace가 고유하게 관리합니다.

Internal snapshot과 독립 activation

179-212

Internal snapshot은 pool에 또 다른 message를 보내 만듭니다. Snapshot할 origin device가 active라면 corruption을 막기 위해 먼저 suspend해야 합니다. 현재 이 요구 사항은 강제되지 않으므로 반드시 주의해야 합니다.

  ::

    dmsetup suspend /dev/mapper/thin
    dmsetup message /dev/mapper/pool 0 "create_snap 1 0"
    dmsetup resume /dev/mapper/thin

`create_snap 1 0`에서 `1`은 새 snapshot의 24-bit volume id이고 `0`은 origin device id입니다.

안전한 internal snapshot 생성
Origin thin active`dmsetup suspend thin``create_snap 1 0``dmsetup resume thin`Origin + snapshot

Active origin을 quiesce한 상태에서 pool metadata snapshot을 만들고 다시 resume합니다.

생성 뒤에는 origin과 snapshot의 연결을 사용자가 별도로 관리할 필요가 없습니다. Snapshot은 다른 thinly-provisioned device와 다르지 않으며 같은 방식으로 다시 snapshot할 수 있습니다.

Origin과 snapshot 중 하나만 active여도 합법적이며 둘의 activation·removal 순서 요구도 없습니다. 이 점은 conventional Device Mapper snapshot과 다릅니다.

다른 thin volume과 똑같이 activate합니다.

    dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 1"
Internal snapshot 특성
단계규칙
생성 전Active origin을 반드시 suspend
생성 후일반 thin device처럼 동작
Recursive snapshot허용
Activation/removal 순서요구 없음

생성 순간의 suspend 요구와 생성 뒤 독립성은 서로 구분해야 합니다.

Read-only external origin과 deactivation

213-258

Pool 밖의 read-only device를 thinly-provisioned volume의 external origin으로 사용할 수 있습니다. Thin device의 unprovisioned area를 read하면 origin으로 전달하고, write하면 평소처럼 새 block을 할당합니다.

External origin I/O
Provisioned readThin pool data block
Unprovisioned readExternal read-only origin
WriteThin pool 새 block allocation

아직 allocation되지 않은 read만 base image로 통과시키고 write는 pool 안에 새 block을 만듭니다.

VM host가 guest를 thin volume에서 실행하면서 base image는 다른 device에 두고 여러 VM이 공유하려는 경우에 사용할 수 있습니다.

이 기법을 사용할 때 origin device에는 절대 write하면 안 됩니다. Thin device에는 write할 수 있고 thin volume의 internal snapshot도 만들 수 있습니다.

External device의 snapshot 생성 단계는 thin device 생성과 같으며 이때는 origin을 지정하지 않습니다.

  ::

    dmsetup message /dev/mapper/pool 0 "create_thin 0"

사용할 때 `thin` target에 external origin을 추가 parameter로 붙입니다.

    dmsetup create snap --table "0 2097152 thin /dev/mapper/pool 0 /dev/image"

이 snapshot의 모든 descendant, 즉 internal snapshot도 같은 extra origin parameter가 필요합니다.

Pool을 deactivate하기 전에 pool을 사용하는 모든 device를 먼저 deactivate해야 합니다.

::

    dmsetup remove thin
    dmsetup remove snap
    dmsetup remove pool
Deactivation 순서
`dmsetup remove thin``dmsetup remove snap``dmsetup remove pool`

Dependent thin·snapshot target을 제거한 뒤 마지막에 pool을 제거합니다.

thin-pool constructor와 feature argument

259-297

`thin-pool` target constructor 형식은 다음과 같습니다.

    ::

      thin-pool <metadata dev> <data dev> <data block size (sectors)> \
	        <low water mark (blocks)> [<number of feature args> [<arg>]*]

`skip_block_zeroing`은 새로 provision한 block을 zero 처리하지 않습니다. `ignore_discard`는 discard 지원을 끕니다. `no_discard_passdown`은 mapping만 제거하고 discard를 underlying data device로 전달하지 않습니다.

`read_only`는 pool metadata 변경과 새 block allocation을 금지합니다. Thin-pool을 생성해 full read/write mode로 한 번 사용한 뒤에만 선택할 수 있으며 최초 생성에는 지정할 수 없습니다.

`error_if_no_space`는 공간이 없을 때 I/O를 queue하지 않고 error 처리합니다.

thin-pool optional feature
Feature동작
`skip_block_zeroing`새 provision block zero 생략
`ignore_discard`Discard 지원 비활성화
`no_discard_passdown`Mapping만 제거하고 underlying discard 생략
`read_only`Pool metadata 변경 금지, 최초 생성에는 불가
`error_if_no_space`공간 부족 I/O를 error 처리

Block 초기화, discard, metadata write와 out-of-space 정책을 제어합니다.

Data block size는 128 sector(64 KiB) 이상 2097152 sector(1 GiB) 이하입니다.

Constructor geometry
Parameter역할
`metadata dev`Persistent mapping metadata
`data dev`Provisioned block storage
`data block size`64 KiB~1 GiB allocation unit
`low water mark`Data block 기준 event threshold

Metadata·data device와 allocation·event 단위를 함께 정의합니다.

thin-pool status와 failure state

298-356

`thin-pool` status 형식은 다음과 같습니다.

    ::

      <transaction id> <used metadata blocks>/<total metadata blocks>
      <used data blocks>/<total data blocks> <held metadata root>
      ro|rw|out_of_data_space [no_]discard_passdown [error|queue]_if_no_space
      needs_check|- metadata_low_watermark

`transaction id`는 volume manager의 metadata와 pool metadata를 동기화하도록 userspace가 사용하는 임의의 64-bit number입니다. Used/total metadata block과 used/total data block은 각 공간 사용량을 나타냅니다.

Free data block 수가 pool low water mark 아래로 내려가면 userspace에 dm event를 보냅니다. Resume마다 한 번만 발생하는 edge-triggered event이므로 volume manager는 event를 등록한 뒤 target status를 확인해야 합니다.

`held metadata root`는 userspace read access용으로 hold한 metadata root의 block 위치입니다. `-`는 held root가 없음을 뜻합니다.

`discard_passdown|no_discard_passdown`은 discard를 underlying device로 실제 전달하는지 나타냅니다. Table load 때 활성화해도 underlying device가 지원하지 않으면 비활성화될 수 있습니다.

`ro|rw|out_of_data_space`는 pool mode입니다. 특정 device failure를 만나면 metadata를 바꿀 수 없는 read-only mode로 전환합니다. Read-only조차 안전하지 않은 심각한 경우에는 더 이상 I/O를 허용하지 않고 status는 `Fail`만 표시하므로 userspace recovery tool을 사용해야 합니다.

`error_if_no_space|queue_if_no_space`는 data 또는 metadata 공간 부족 시 I/O를 error 처리할지 queue할지 나타냅니다. 기본은 공간 추가 또는 `no_space_timeout` 만료까지 queue하는 것입니다. `no_space_timeout` module parameter 기본값은 60초이며 0으로 timeout을 비활성화할 수 있습니다.

`needs_check`는 metadata operation 실패로 superblock flag가 설정됐음을 뜻합니다. Metadata device를 deactivate하고 검사·수리해야 pool을 다시 완전하게 운영할 수 있습니다. `-`는 flag가 없음을 뜻합니다.

`metadata_low_watermark`는 block 단위 metadata low watermark입니다. Kernel이 내부 설정하지만 userspace는 event가 이 threshold crossing 때문에 발생했는지 판단하기 위해 값을 알아야 합니다.

thin-pool status field
Field의미
`transaction id`Userspace 동기화용 64-bit id
`used/total metadata blocks`Metadata 공간 사용량
`used/total data blocks`Data 공간 사용량
`held metadata root`Userspace snapshot root 또는 `-`
`ro|rw|out_of_data_space`Pool access mode
`[no_]discard_passdown`Underlying discard 전달 여부
`[error|queue]_if_no_space`공간 부족 I/O 정책
`needs_check|-`Metadata repair flag
`metadata_low_watermark`Metadata event threshold

동기화 id, 공간 사용량, mode와 recovery flag를 한 status에 보고합니다.

Pool failure escalation
`rw`Device 또는 metadata failure`ro`Read-only도 unsafe`Fail`Userspace recovery
Space 부족`queue_if_no_space` 또는 `error_if_no_space`확장·timeout

Failure 심각도에 따라 rw에서 ro, 최종적으로 Fail과 offline recovery로 진행합니다.

Thin device·snapshot과 metadata snapshot message

357-391
    create_thin <dev id>
    create_snap <dev id> <origin id>
    delete <dev id>
    set_transaction_id <current id> <new id>

`create_thin <dev id>`는 caller가 선택한 고유 24-bit id로 새 thin device를 만듭니다. `create_snap <dev id> <origin id>`는 origin thin device의 snapshot을 만듭니다. `delete <dev id>`는 thin device를 되돌릴 수 없게 삭제합니다.

`set_transaction_id <current id> <new id>`는 LVM 같은 userland volume manager가 외부 metadata를 pool 내부 metadata와 동기화하는 데 씁니다. Pool은 임의 64-bit transaction id를 저장해 status로 반환합니다. Race를 피하도록 현재 값이라고 생각하는 id를 함께 보내는 compare-and-swap message입니다.

Transaction id compare-and-swap
Status에서 current id 읽기`set_transaction_id current new`현재 값 비교일치New id 저장
불일치Race 감지갱신 거부

Userspace가 기대한 current id가 일치할 때만 새 id로 전환합니다.

    reserve_metadata_snap
    release_metadata_snap

`reserve_metadata_snap`은 userland가 message 실행 시점의 mapping을 검사하도록 data mapping B-tree copy를 예약합니다. Pool status에서 metadata snapshot의 root block을 얻습니다. `release_metadata_snap`은 이전에 예약한 copy를 해제합니다.

Userspace metadata snapshot
`reserve_metadata_snap`Data mapping B-tree copy holdStatus의 held root 조회Userspace mapping 검사`release_metadata_snap`

Mapping B-tree root를 hold하고 status로 위치를 전달한 뒤 검사가 끝나면 release합니다.

thin-pool message
Message목적
`create_thin`새 24-bit id thin device 생성
`create_snap`Thin device snapshot 생성
`delete`Thin device 영구 삭제
`set_transaction_id`64-bit id compare-and-swap
`reserve_metadata_snap`Mapping B-tree snapshot hold
`release_metadata_snap`Held metadata snapshot 해제

Device lifecycle, synchronization과 metadata inspection을 제어합니다.

thin target constructor, 크기와 status

392-427

`thin` target constructor 형식은 다음과 같습니다.

    ::

        thin <pool dev> <dev id> [<external origin dev>]
thin constructor
Parameter의미
`pool dev`Thin-pool device, 예: `/dev/mapper/my_pool` 또는 `253:0`
`dev id`Activate할 pool 내부 device identifier
`external origin dev`Unprovisioned read를 받을 선택적 read-only device

Pool 내부 id를 activate하고 선택적으로 external read-only origin을 연결합니다.

Pool은 thin device의 크기를 저장하지 않습니다. 이전보다 작은 thin target을 load하면 끝을 넘어 mapping된 block에 접근할 수 없습니다. 이전보다 크게 load하면 추가 block은 필요할 때 provision됩니다.

Thin target 크기 재load
이전보다 작은 target끝 이후 mapped block 접근 불가
이전보다 큰 target추가 논리 범위Write 시 필요 block provision

Table에 적은 논리 크기가 접근 가능 범위를 정하지만 pool mapping 자체의 stored size는 없습니다.

Thin target status는 mapping된 sector 수와 가장 높은 mapped sector를 보고합니다.

    <nr mapped sectors> <highest mapped sector>

Pool이 device error로 fail한 경우 status는 `Fail`만 포함하며 userspace recovery tool을 사용해야 합니다. `<nr mapped sectors>`가 0이면 highest mapped sector가 없으므로 `<highest mapped sector>` 값은 지정되지 않습니다.

thin status
상태출력
정상, mapping 있음`<nr mapped sectors> <highest mapped sector>`
정상, mapped sectors = 0Highest 값은 unspecified
Pool failed`Fail`

Mapping 존재 여부와 pool failure에 따라 출력 의미가 달라집니다.