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

Linux 6.18.37 · Administration / Device Mapper

Device-mapper snapshot support

Changed chunk만 COW 장치에 저장하는 snapshot·fork와 persistent snapshot을 origin으로 되돌리는 background merge의 target, LVM2 구성과 완료 판정을 설명합니다.

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

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

1. 요약·해설

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

Snapshot target과 COW

snapshot.rst:1-71

snapshot-origin, snapshot과 discard 기능의 I/O routing, store 유형과 COW 용량 제약을 설명합니다.

Persistent snapshot merge

snapshot.rst:72-89

COW ownership handover, background merge, origin write 지연과 기존 snapshot의 -EIO 동작을 정리합니다.

LVM2 구성과 완료 확인

snapshot.rst:90-196

네 dm device의 배치, merge target 교체와 allocated·metadata sector 기반 완료 판정을 보여 줍니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ==============================
2 Device-mapper snapshot support
3 ==============================
4
5 Device-mapper allows you, without massive data copying:
6
7 - To create snapshots of any block device i.e. mountable, saved states of
8 the block device which are also writable without interfering with the
9 original content;
10 - To create device "forks", i.e. multiple different versions of the
11 same data stream.
12 - To merge a snapshot of a block device back into the snapshot's origin
13 device.
14
15 In the first two cases, dm copies only the chunks of data that get
16 changed and uses a separate copy-on-write (COW) block device for
17 storage.
18
19 For snapshot merge the contents of the COW storage are merged back into
20 the origin device.
21
22
23 There are three dm targets available:
24 snapshot, snapshot-origin, and snapshot-merge.
25
26 - snapshot-origin <origin>
27
28 which will normally have one or more snapshots based on it.
29 Reads will be mapped directly to the backing device. For each write, the
30 original data will be saved in the <COW device> of each snapshot to keep
31 its visible content unchanged, at least until the <COW device> fills up.
32
33
34 - snapshot <origin> <COW device> <persistent?> <chunksize>
35 [<# feature args> [<arg>]*]
36
37 A snapshot of the <origin> block device is created. Changed chunks of
38 <chunksize> sectors will be stored on the <COW device>. Writes will
39 only go to the <COW device>. Reads will come from the <COW device> or
40 from <origin> for unchanged data. <COW device> will often be
41 smaller than the origin and if it fills up the snapshot will become
42 useless and be disabled, returning errors. So it is important to monitor
43 the amount of free space and expand the <COW device> before it fills up.
44
45 <persistent?> is P (Persistent) or N (Not persistent - will not survive
46 after reboot). O (Overflow) can be added as a persistent store option
47 to allow userspace to advertise its support for seeing "Overflow" in the
48 snapshot status. So supported store types are "P", "PO" and "N".
49
50 The difference between persistent and transient is with transient
51 snapshots less metadata must be saved on disk - they can be kept in
52 memory by the kernel.
53
54 When loading or unloading the snapshot target, the corresponding
55 snapshot-origin or snapshot-merge target must be suspended. A failure to
56 suspend the origin target could result in data corruption.
57
58 Optional features:
59
60 discard_zeroes_cow - a discard issued to the snapshot device that
61 maps to entire chunks to will zero the corresponding exception(s) in
62 the snapshot's exception store.
63
64 discard_passdown_origin - a discard to the snapshot device is passed
65 down to the snapshot-origin's underlying device. This doesn't cause
66 copy-out to the snapshot exception store because the snapshot-origin
67 target is bypassed.
68
69 The discard_passdown_origin feature depends on the discard_zeroes_cow
70 feature being enabled.
71
72
73 - snapshot-merge <origin> <COW device> <persistent> <chunksize>
74 [<# feature args> [<arg>]*]
75
76 takes the same table arguments as the snapshot target except it only
77 works with persistent snapshots. This target assumes the role of the
78 "snapshot-origin" target and must not be loaded if the "snapshot-origin"
79 is still present for <origin>.
80
81 Creates a merging snapshot that takes control of the changed chunks
82 stored in the <COW device> of an existing snapshot, through a handover
83 procedure, and merges these chunks back into the <origin>. Once merging
84 has started (in the background) the <origin> may be opened and the merge
85 will continue while I/O is flowing to it. Changes to the <origin> are
86 deferred until the merging snapshot's corresponding chunk(s) have been
87 merged. Once merging has started the snapshot device, associated with
88 the "snapshot" target, will return -EIO when accessed.
89
90
91 How snapshot is used by LVM2
92 ============================
93 When you create the first LVM2 snapshot of a volume, four dm devices are used:
94
95 1) a device containing the original mapping table of the source volume;
96 2) a device used as the <COW device>;
97 3) a "snapshot" device, combining #1 and #2, which is the visible snapshot
98 volume;
99 4) the "original" volume (which uses the device number used by the original
100 source volume), whose table is replaced by a "snapshot-origin" mapping
101 from device #1.
102
103 A fixed naming scheme is used, so with the following commands::
104
105 lvcreate -L 1G -n base volumeGroup
106 lvcreate -L 100M --snapshot -n snap volumeGroup/base
107
108 we'll have this situation (with volumes in above order)::
109
110 # dmsetup table|grep volumeGroup
111
112 volumeGroup-base-real: 0 2097152 linear 8:19 384
113 volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
114 volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
115 volumeGroup-base: 0 2097152 snapshot-origin 254:11
116
117 # ls -lL /dev/mapper/volumeGroup-*
118 brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
119 brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
120 brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
121 brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
122
123
124 How snapshot-merge is used by LVM2
125 ==================================
126 A merging snapshot assumes the role of the "snapshot-origin" while
127 merging. As such the "snapshot-origin" is replaced with
128 "snapshot-merge". The "-real" device is not changed and the "-cow"
129 device is renamed to <origin name>-cow to aid LVM2's cleanup of the
130 merging snapshot after it completes. The "snapshot" that hands over its
131 COW device to the "snapshot-merge" is deactivated (unless using lvchange
132 --refresh); but if it is left active it will simply return I/O errors.
133
134 A snapshot will merge into its origin with the following command::
135
136 lvconvert --merge volumeGroup/snap
137
138 we'll now have this situation::
139
140 # dmsetup table|grep volumeGroup
141
142 volumeGroup-base-real: 0 2097152 linear 8:19 384
143 volumeGroup-base-cow: 0 204800 linear 8:19 2097536
144 volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16
145
146 # ls -lL /dev/mapper/volumeGroup-*
147 brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
148 brw------- 1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
149 brw------- 1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
150
151
152 How to determine when a merging is complete
153 ===========================================
154 The snapshot-merge and snapshot status lines end with:
155
156 <sectors_allocated>/<total_sectors> <metadata_sectors>
157
158 Both <sectors_allocated> and <total_sectors> include both data and metadata.
159 During merging, the number of sectors allocated gets smaller and
160 smaller. Merging has finished when the number of sectors holding data
161 is zero, in other words <sectors_allocated> == <metadata_sectors>.
162
163 Here is a practical example (using a hybrid of lvm and dmsetup commands)::
164
165 # lvs
166 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
167 base volumeGroup owi-a- 4.00g
168 snap volumeGroup swi-a- 1.00g base 18.97
169
170 # dmsetup status volumeGroup-snap
171 0 8388608 snapshot 397896/2097152 1560
172 ^^^^ metadata sectors
173
174 # lvconvert --merge -b volumeGroup/snap
175 Merging of volume snap started.
176
177 # lvs volumeGroup/snap
178 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
179 base volumeGroup Owi-a- 4.00g 17.23
180
181 # dmsetup status volumeGroup-base
182 0 8388608 snapshot-merge 281688/2097152 1104
183
184 # dmsetup status volumeGroup-base
185 0 8388608 snapshot-merge 180480/2097152 712
186
187 # dmsetup status volumeGroup-base
188 0 8388608 snapshot-merge 16/2097152 16
189
190 Merging has finished.
191
192 ::
193
194 # lvs
195 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
196 base volumeGroup owi-a- 4.00g
197

3. 한국어 전문 번역

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

전체 복사 없는 snapshot·fork·merge

1-20

Device Mapper는 대규모 data 복사 없이 임의 block device의 snapshot을 만들 수 있습니다. Snapshot은 mount 가능한 저장 상태이며 원본 내용에 간섭하지 않고 자체적으로 write할 수 있습니다.

같은 data stream에서 서로 다른 여러 version을 만드는 device 'fork'도 지원하고, block device snapshot을 그 snapshot의 origin device로 다시 merge할 수도 있습니다.

Snapshot과 fork에서는 변경된 data chunk만 복사해 별도의 copy-on-write(COW) block device에 저장합니다. Snapshot merge에서는 COW storage의 내용을 origin device로 되돌려 합칩니다.

Snapshot lifecycle
Origin block deviceSnapshot 생성변경 chunk만 COW 저장Writable snapshot 또는 fork
Existing snapshot COW`snapshot-merge`Origin에 변경 chunk 반영

변경분만 별도 COW에 보존하고 필요하면 그 변경분을 origin으로 merge합니다.

지원 작업
작업결과Data 이동
SnapshotMount 가능한 저장 시점변경 chunk만 COW에 저장
Fork같은 data의 여러 version각 version의 변경분만 저장
MergeSnapshot 변경분을 origin에 반영COW chunk를 origin으로 복사

전체 data copy 대신 changed chunk 단위 COW를 사용합니다.

snapshot-origin의 read와 copy-out

21-32

사용 가능한 dm target은 `snapshot`, `snapshot-origin`, `snapshot-merge` 세 가지입니다.

-  snapshot-origin <origin>

`snapshot-origin <origin>`에는 보통 하나 이상의 snapshot이 연결됩니다. Read는 backing device로 직접 mapping합니다. Write할 때는 각 snapshot에서 보이는 내용이 변하지 않도록 원래 data를 해당 snapshot의 `<COW device>`에 먼저 저장합니다. 이 보장은 최소한 COW 장치가 가득 차기 전까지 유지됩니다.

snapshot-origin I/O
I/O경로Snapshot 유지 동작
ReadBacking origin으로 직접 mapping추가 copy 없음
WriteOrigin에 새 data 기록기존 data를 각 COW로 copy-out

Origin read는 직접 통과하고 origin write는 연결된 모든 snapshot의 이전 data를 보존합니다.

Snapshot constructor, store 유형과 안전한 교체

33-57
-  snapshot <origin> <COW device> <persistent?> <chunksize>
   [<# feature args> [<arg>]*]

`<origin>` block device의 snapshot을 만듭니다. `<chunksize>` sector 크기의 변경 chunk는 `<COW device>`에 저장됩니다. Snapshot write는 COW 장치에만 기록되고, read는 변경 data이면 COW에서, 변경되지 않은 data이면 origin에서 가져옵니다.

COW 장치는 origin보다 작은 경우가 많습니다. COW가 가득 차면 snapshot은 쓸 수 없게 되고 비활성화되어 오류를 반환합니다. 따라서 free space를 감시하고 가득 차기 전에 COW 장치를 확장해야 합니다.

Snapshot read·write routing
Snapshot readChanged chunkCOW device에서 read
Snapshot readUnchanged chunkOrigin에서 read
Snapshot writeCOW device에만 writeException 갱신

Exception 존재 여부에 따라 read source를 선택하고 모든 snapshot write는 COW로 보냅니다.

`<persistent?>`는 reboot 후에도 유지되는 `P`(Persistent) 또는 유지되지 않는 `N`(Not persistent)입니다. Persistent store option에 `O`(Overflow)를 추가하면 userspace가 snapshot status의 `Overflow`를 인식할 수 있음을 알립니다. 지원 store type은 `P`, `PO`, `N`입니다.

Transient snapshot은 disk에 저장할 metadata가 더 적고 kernel memory에 유지할 수 있다는 점이 persistent snapshot과 다릅니다.

Snapshot store 유형
의미Reboot 후 유지
`P`Persistent store
`PO`Persistent + userspace Overflow 지원
`N`Transient store아니요

Reboot 지속성과 overflow status 지원 여부를 구분합니다.

Snapshot target을 load하거나 unload할 때 대응하는 `snapshot-origin` 또는 `snapshot-merge` target을 반드시 suspend해야 합니다. Origin target suspend에 실패하면 data corruption이 발생할 수 있습니다.

Snapshot discard 선택 기능

58-71

`discard_zeroes_cow`를 사용하면 snapshot device에 발행된 discard가 전체 chunk에 mapping될 때 snapshot exception store의 대응 exception을 zero 처리합니다.

`discard_passdown_origin`은 snapshot device의 discard를 snapshot-origin의 underlying device로 전달합니다. 이 경로는 `snapshot-origin` target을 우회하므로 snapshot exception store로 copy-out하지 않습니다.

`discard_passdown_origin` 기능은 `discard_zeroes_cow`가 활성화되어 있어야 사용할 수 있습니다.

Discard feature
Feature동작조건
`discard_zeroes_cow`전체 chunk discard에 대응하는 COW exception zero 처리독립 사용 가능
`discard_passdown_origin`Discard를 underlying origin으로 전달하고 copy-out 우회`discard_zeroes_cow` 필요

COW exception 정리와 origin passdown의 동작 및 의존성을 구분합니다.

Persistent COW를 origin에 background merge

72-89
-  snapshot-merge <origin> <COW device> <persistent> <chunksize>
   [<# feature args> [<arg>]*]

`snapshot-merge`는 `snapshot` target과 같은 table argument를 받지만 persistent snapshot에서만 동작합니다. 이 target은 `snapshot-origin` 역할을 맡으므로 같은 `<origin>`에 `snapshot-origin`이 남아 있는 상태로 load하면 안 됩니다.

Handover 절차를 통해 기존 snapshot의 `<COW device>`에 저장된 changed chunk를 넘겨받아 `<origin>`으로 merge합니다. Background merge가 시작되면 origin을 open할 수 있고 I/O가 흐르는 동안에도 merge를 계속합니다.

Origin에 대한 변경은 해당 chunk가 merge될 때까지 지연됩니다. Merge가 시작된 뒤 기존 `snapshot` target에 연결된 snapshot device를 접근하면 `-EIO`를 반환합니다.

snapshot-merge handover
Persistent snapshot + COWHandover`snapshot-merge`가 origin 역할 인수Changed chunk를 origin에 merge완료
Merge 중 origin write대응 chunk merge까지 지연Merge 후 write 진행
기존 snapshot device 접근`-EIO`

Snapshot의 COW ownership을 merge target으로 넘기고 origin I/O와 background merge를 조정합니다.

LVM2 snapshot의 네 dm device

90-123

LVM2 volume에서 첫 snapshot을 만들면 네 개의 dm device를 사용합니다. 첫째는 source volume의 원래 mapping table, 둘째는 `<COW device>`, 셋째는 앞의 두 장치를 결합해 사용자에게 보이는 `snapshot` volume, 넷째는 원래 source volume의 device number를 유지하면서 첫 장치를 가리키는 `snapshot-origin` mapping으로 table을 바꾼 'original' volume입니다.

LVM2 snapshot device 관계
`volumeGroup-base-real`원래 source mapping`snapshot-origin``volumeGroup-base`
`base-real` + `snap-cow``snapshot` target`volumeGroup-snap`

원본 실제 mapping과 COW를 내부 device로 분리하고 snapshot과 original volume이 이를 참조합니다.

고정 naming scheme을 사용하며 다음 명령으로 1 GiB base volume과 100 MiB snapshot을 만듭니다.

  lvcreate -L 1G -n base volumeGroup
  lvcreate -L 100M --snapshot -n snap volumeGroup/base

그 결과의 dm table과 `/dev/mapper` device는 다음과 같습니다. 출력 순서는 위에서 설명한 네 volume 순서입니다.

  # dmsetup table|grep volumeGroup

  volumeGroup-base-real: 0 2097152 linear 8:19 384
  volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
  volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
  volumeGroup-base: 0 2097152 snapshot-origin 254:11

  # ls -lL /dev/mapper/volumeGroup-*
  brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
  brw-------  1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
  brw-------  1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
  brw-------  1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
LVM2 snapshot table 해석
VolumeTarget 또는 역할참조
`volumeGroup-base-real``linear`실제 backing 영역
`volumeGroup-snap-cow``linear`COW 저장 영역
`volumeGroup-snap``snapshot``254:11` + `254:12`
`volumeGroup-base``snapshot-origin``254:11`

Table target과 device number가 네 내부·외부 volume의 연결을 보여 줍니다.

LVM2 merge 시 target 교체와 이름 변경

124-150

Merge 중에는 merging snapshot이 `snapshot-origin` 역할을 맡으므로 `snapshot-origin`을 `snapshot-merge`로 교체합니다. `-real` device는 바꾸지 않고, merge 완료 뒤 LVM2가 정리하기 쉽도록 `-cow` device를 `<origin name>-cow`로 이름 변경합니다.

COW device를 `snapshot-merge`에 넘긴 `snapshot`은 비활성화됩니다. 단, `lvchange --refresh`를 사용하는 경우는 예외입니다. Snapshot을 active 상태로 남겨도 접근 시 I/O error만 반환합니다.

LVM2 merge target 교체
`base`: snapshot-origin`lvconvert --merge``base`: snapshot-mergeMerge 완료일반 origin 복구
`snap-cow``base-cow`로 renameMerge source
`snap` snapshotDeactivate 또는 access 시 I/O error

Real mapping을 유지한 채 origin target과 COW 이름만 merge 상태에 맞게 바꿉니다.

다음 명령으로 snapshot을 origin에 merge합니다.

  lvconvert --merge volumeGroup/snap

Merge를 시작한 뒤 table과 device 이름은 다음과 같이 바뀝니다.

  # dmsetup table|grep volumeGroup

  volumeGroup-base-real: 0 2097152 linear 8:19 384
  volumeGroup-base-cow: 0 204800 linear 8:19 2097536
  volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16

  # ls -lL /dev/mapper/volumeGroup-*
  brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
  brw-------  1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
  brw-------  1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
Merge 중 LVM2 구성
VolumeMerge 중 역할
`volumeGroup-base-real`변경 없는 backing mapping
`volumeGroup-base-cow`이름을 바꾼 merge source COW
`volumeGroup-base``snapshot-merge 254:11 254:12 P 16`

Base volume이 snapshot-merge target이 되고 COW가 base 이름 아래로 이동합니다.

Merge 완료 판정식

151-162

`snapshot-merge`와 `snapshot` status line의 끝은 다음 형식입니다.

  <sectors_allocated>/<total_sectors> <metadata_sectors>

`<sectors_allocated>`와 `<total_sectors>`에는 data와 metadata가 모두 포함됩니다. Merge 중에는 allocated sector 수가 계속 감소합니다.

Data를 담은 sector 수가 0이면 merge가 끝난 것입니다. 즉 완료 조건은 `<sectors_allocated> == <metadata_sectors>`입니다.

Snapshot status 끝 필드
Field포함 내용Merge 중 변화
`sectors_allocated`Data + metadata allocated sector감소
`total_sectors`Data + metadata 전체 sector고정
`metadata_sectors`Metadata가 차지하는 sector상태에 따라 보고
완료 조건`sectors_allocated == metadata_sectors`이면 data sector가 0입니다.

Allocated 값에서 metadata만 남았는지 비교해 data merge 완료를 판단합니다.

Merge progress
Data + metadata allocatedChanged chunk mergeAllocated sector 감소Metadata만 남음Merge 완료

Allocated sector가 줄어 metadata sector와 같아지는 순간 merge가 완료됩니다.

LVM과 dmsetup을 함께 쓴 완료 예제

163-196

실제 예제는 LVM과 `dmsetup` 명령을 함께 사용합니다. 처음 snapshot은 18.97% 사용 중이고 status는 allocated/total `397896/2097152`, metadata `1560`을 보고합니다.

`lvconvert --merge -b`로 background merge를 시작하면 base volume이 merge 상태가 됩니다. 이어지는 status에서 allocated sector가 `281688`, `180480`, 마지막에는 `16`으로 감소합니다. 마지막 status의 metadata sector도 `16`이므로 완료 조건을 만족합니다.

  # lvs
    LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
    base    volumeGroup owi-a- 4.00g
    snap    volumeGroup swi-a- 1.00g base  18.97

  # dmsetup status volumeGroup-snap
  0 8388608 snapshot 397896/2097152 1560
                                    ^^^^ metadata sectors

  # lvconvert --merge -b volumeGroup/snap
    Merging of volume snap started.

  # lvs volumeGroup/snap
    LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
    base    volumeGroup Owi-a- 4.00g          17.23

  # dmsetup status volumeGroup-base
  0 8388608 snapshot-merge 281688/2097152 1104

  # dmsetup status volumeGroup-base
  0 8388608 snapshot-merge 180480/2097152 712

  # dmsetup status volumeGroup-base
  0 8388608 snapshot-merge 16/2097152 16
예제 merge 수치
단계Allocated/totalMetadata상태
Snapshot 시작`397896/2097152``1560`Merge 전
Merge 진행 1`281688/2097152``1104`진행 중
Merge 진행 2`180480/2097152``712`진행 중
마지막`16/2097152``16`완료

Status의 allocated sector가 metadata sector와 같아지는 과정을 정리합니다.

Merge가 끝나면 snapshot volume은 사라지고 base volume만 일반 LVM volume으로 남습니다.

::

  # lvs
    LV      VG          Attr   LSize Origin  Snap%  Move Log Copy%  Convert
    base    volumeGroup owi-a- 4.00g
LVM2 merge 종료 상태
Base + snapshot + COWBackground mergeAllocated data sector 0Snapshot 정리`base` volume만 유지

Snapshot과 COW가 정리되고 origin base volume만 남습니다.