Documentation/driver-api/md/md-cluster.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

MD Cluster

Clustered raid1·raid10의 node별 bitmap, DLM lock·LVB broadcast, failure recovery와 device 추가 callback protocol을 설명합니다.

Source pathDocumentation/driver-api/md/md-cluster.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

md-cluster.rst:1-385

Cluster MD는 node별 write-intent bitmap과 DLM resource를 조합해 shared RAID를 운영합니다. `token/message/ack` handshake로 metadata와 resync 상태를 모든 node에 동기화하고, node failure 때 failed bitmap을 인계해 resync하며, 새 disk는 모든 node가 발견·승인한 뒤에만 array에 편입합니다.

핵심 안전성 경계는 filesystem의 block-level write serialization, bitmap lock LVB의 resync range, 모든 receiver가 처리할 때까지 기다리는 `ack` barrier입니다. Module callback은 이 protocol을 MD core의 resync, metadata update, disk add/remove lifecycle에 연결합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ==========
2 MD Cluster
3 ==========
4
5 The cluster MD is a shared-device RAID for a cluster, it supports
6 two levels: raid1 and raid10 (limited support).
7
8
9 1. On-disk format
10 =================
11
12 Separate write-intent-bitmaps are used for each cluster node.
13 The bitmaps record all writes that may have been started on that node,
14 and may not yet have finished. The on-disk layout is::
15
16 0 4k 8k 12k
17 -------------------------------------------------------------------
18 | idle | md super | bm super [0] + bits |
19 | bm bits[0, contd] | bm super[1] + bits | bm bits[1, contd] |
20 | bm super[2] + bits | bm bits [2, contd] | bm super[3] + bits |
21 | bm bits [3, contd] | | |
22
23 During "normal" functioning we assume the filesystem ensures that only
24 one node writes to any given block at a time, so a write request will
25
26 - set the appropriate bit (if not already set)
27 - commit the write to all mirrors
28 - schedule the bit to be cleared after a timeout.
29
30 Reads are just handled normally. It is up to the filesystem to ensure
31 one node doesn't read from a location where another node (or the same
32 node) is writing.
33
34
35 2. DLM Locks for management
36 ===========================
37
38 There are three groups of locks for managing the device:
39
40 2.1 Bitmap lock resource (bm_lockres)
41 -------------------------------------
42
43 The bm_lockres protects individual node bitmaps. They are named in
44 the form bitmap000 for node 1, bitmap001 for node 2 and so on. When a
45 node joins the cluster, it acquires the lock in PW mode and it stays
46 so during the lifetime the node is part of the cluster. The lock
47 resource number is based on the slot number returned by the DLM
48 subsystem. Since DLM starts node count from one and bitmap slots
49 start from zero, one is subtracted from the DLM slot number to arrive
50 at the bitmap slot number.
51
52 The LVB of the bitmap lock for a particular node records the range
53 of sectors that are being re-synced by that node. No other
54 node may write to those sectors. This is used when a new nodes
55 joins the cluster.
56
57 2.2 Message passing locks
58 -------------------------
59
60 Each node has to communicate with other nodes when starting or ending
61 resync, and for metadata superblock updates. This communication is
62 managed through three locks: "token", "message", and "ack", together
63 with the Lock Value Block (LVB) of one of the "message" lock.
64
65 2.3 new-device management
66 -------------------------
67
68 A single lock: "no-new-dev" is used to coordinate the addition of
69 new devices - this must be synchronized across the array.
70 Normally all nodes hold a concurrent-read lock on this device.
71
72 3. Communication
73 ================
74
75 Messages can be broadcast to all nodes, and the sender waits for all
76 other nodes to acknowledge the message before proceeding. Only one
77 message can be processed at a time.
78
79 3.1 Message Types
80 -----------------
81
82 There are six types of messages which are passed:
83
84 3.1.1 METADATA_UPDATED
85 ^^^^^^^^^^^^^^^^^^^^^^
86
87 informs other nodes that the metadata has
88 been updated, and the node must re-read the md superblock. This is
89 performed synchronously. It is primarily used to signal device
90 failure.
91
92 3.1.2 RESYNCING
93 ^^^^^^^^^^^^^^^
94 informs other nodes that a resync is initiated or
95 ended so that each node may suspend or resume the region. Each
96 RESYNCING message identifies a range of the devices that the
97 sending node is about to resync. This overrides any previous
98 notification from that node: only one ranged can be resynced at a
99 time per-node.
100
101 3.1.3 NEWDISK
102 ^^^^^^^^^^^^^
103
104 informs other nodes that a device is being added to
105 the array. Message contains an identifier for that device. See
106 below for further details.
107
108 3.1.4 REMOVE
109 ^^^^^^^^^^^^
110
111 A failed or spare device is being removed from the
112 array. The slot-number of the device is included in the message.
113
114 3.1.5 RE_ADD:
115
116 A failed device is being re-activated - the assumption
117 is that it has been determined to be working again.
118
119 3.1.6 BITMAP_NEEDS_SYNC:
120
121 If a node is stopped locally but the bitmap
122 isn't clean, then another node is informed to take the ownership of
123 resync.
124
125 3.2 Communication mechanism
126 ---------------------------
127
128 The DLM LVB is used to communicate within nodes of the cluster. There
129 are three resources used for the purpose:
130
131 3.2.1 token
132 ^^^^^^^^^^^
133 The resource which protects the entire communication
134 system. The node having the token resource is allowed to
135 communicate.
136
137 3.2.2 message
138 ^^^^^^^^^^^^^
139 The lock resource which carries the data to communicate.
140
141 3.2.3 ack
142 ^^^^^^^^^
143
144 The resource, acquiring which means the message has been
145 acknowledged by all nodes in the cluster. The BAST of the resource
146 is used to inform the receiving node that a node wants to
147 communicate.
148
149 The algorithm is:
150
151 1. receive status - all nodes have concurrent-reader lock on "ack"::
152
153 sender receiver receiver
154 "ack":CR "ack":CR "ack":CR
155
156 2. sender get EX on "token",
157 sender get EX on "message"::
158
159 sender receiver receiver
160 "token":EX "ack":CR "ack":CR
161 "message":EX
162 "ack":CR
163
164 Sender checks that it still needs to send a message. Messages
165 received or other events that happened while waiting for the
166 "token" may have made this message inappropriate or redundant.
167
168 3. sender writes LVB
169
170 sender down-convert "message" from EX to CW
171
172 sender try to get EX of "ack"
173
174 ::
175
176 [ wait until all receivers have *processed* the "message" ]
177
178 [ triggered by bast of "ack" ]
179 receiver get CR on "message"
180 receiver read LVB
181 receiver processes the message
182 [ wait finish ]
183 receiver releases "ack"
184 receiver tries to get PR on "message"
185
186 sender receiver receiver
187 "token":EX "message":CR "message":CR
188 "message":CW
189 "ack":EX
190
191 4. triggered by grant of EX on "ack" (indicating all receivers
192 have processed message)
193
194 sender down-converts "ack" from EX to CR
195
196 sender releases "message"
197
198 sender releases "token"
199
200 ::
201
202 receiver upconvert to PR on "message"
203 receiver get CR of "ack"
204 receiver release "message"
205
206 sender receiver receiver
207 "ack":CR "ack":CR "ack":CR
208
209
210 4. Handling Failures
211 ====================
212
213 4.1 Node Failure
214 ----------------
215
216 When a node fails, the DLM informs the cluster with the slot
217 number. The node starts a cluster recovery thread. The cluster
218 recovery thread:
219
220 - acquires the bitmap<number> lock of the failed node
221 - opens the bitmap
222 - reads the bitmap of the failed node
223 - copies the set bitmap to local node
224 - cleans the bitmap of the failed node
225 - releases bitmap<number> lock of the failed node
226 - initiates resync of the bitmap on the current node
227 md_check_recovery is invoked within recover_bitmaps,
228 then md_check_recovery -> metadata_update_start/finish,
229 it will lock the communication by lock_comm.
230 Which means when one node is resyncing it blocks all
231 other nodes from writing anywhere on the array.
232
233 The resync process is the regular md resync. However, in a clustered
234 environment when a resync is performed, it needs to tell other nodes
235 of the areas which are suspended. Before a resync starts, the node
236 send out RESYNCING with the (lo,hi) range of the area which needs to
237 be suspended. Each node maintains a suspend_list, which contains the
238 list of ranges which are currently suspended. On receiving RESYNCING,
239 the node adds the range to the suspend_list. Similarly, when the node
240 performing resync finishes, it sends RESYNCING with an empty range to
241 other nodes and other nodes remove the corresponding entry from the
242 suspend_list.
243
244 A helper function, ->area_resyncing() can be used to check if a
245 particular I/O range should be suspended or not.
246
247 4.2 Device Failure
248 ==================
249
250 Device failures are handled and communicated with the metadata update
251 routine. When a node detects a device failure it does not allow
252 any further writes to that device until the failure has been
253 acknowledged by all other nodes.
254
255 5. Adding a new Device
256 ----------------------
257
258 For adding a new device, it is necessary that all nodes "see" the new
259 device to be added. For this, the following algorithm is used:
260
261 1. Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues
262 ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD)
263 2. Node 1 sends a NEWDISK message with uuid and slot number
264 3. Other nodes issue kobject_uevent_env with uuid and slot number
265 (Steps 4,5 could be a udev rule)
266 4. In userspace, the node searches for the disk, perhaps
267 using blkid -t SUB_UUID=""
268 5. Other nodes issue either of the following depending on whether
269 the disk was found:
270 ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and
271 disc.number set to slot number)
272 ioctl(CLUSTERED_DISK_NACK)
273 6. Other nodes drop lock on "no-new-devs" (CR) if device is found
274 7. Node 1 attempts EX lock on "no-new-dev"
275 8. If node 1 gets the lock, it sends METADATA_UPDATED after
276 unmarking the disk as SpareLocal
277 9. If not (get "no-new-dev" lock), it fails the operation and sends
278 METADATA_UPDATED.
279 10. Other nodes get the information whether a disk is added or not
280 by the following METADATA_UPDATED.
281
282 6. Module interface
283 ===================
284
285 There are 17 call-backs which the md core can make to the cluster
286 module. Understanding these can give a good overview of the whole
287 process.
288
289 6.1 join(nodes) and leave()
290 ---------------------------
291
292 These are called when an array is started with a clustered bitmap,
293 and when the array is stopped. join() ensures the cluster is
294 available and initializes the various resources.
295 Only the first 'nodes' nodes in the cluster can use the array.
296
297 6.2 slot_number()
298 -----------------
299
300 Reports the slot number advised by the cluster infrastructure.
301 Range is from 0 to nodes-1.
302
303 6.3 resync_info_update()
304 ------------------------
305
306 This updates the resync range that is stored in the bitmap lock.
307 The starting point is updated as the resync progresses. The
308 end point is always the end of the array.
309 It does *not* send a RESYNCING message.
310
311 6.4 resync_start(), resync_finish()
312 -----------------------------------
313
314 These are called when resync/recovery/reshape starts or stops.
315 They update the resyncing range in the bitmap lock and also
316 send a RESYNCING message. resync_start reports the whole
317 array as resyncing, resync_finish reports none of it.
318
319 resync_finish() also sends a BITMAP_NEEDS_SYNC message which
320 allows some other node to take over.
321
322 6.5 metadata_update_start(), metadata_update_finish(), metadata_update_cancel()
323 -------------------------------------------------------------------------------
324
325 metadata_update_start is used to get exclusive access to
326 the metadata. If a change is still needed once that access is
327 gained, metadata_update_finish() will send a METADATA_UPDATE
328 message to all other nodes, otherwise metadata_update_cancel()
329 can be used to release the lock.
330
331 6.6 area_resyncing()
332 --------------------
333
334 This combines two elements of functionality.
335
336 Firstly, it will check if any node is currently resyncing
337 anything in a given range of sectors. If any resync is found,
338 then the caller will avoid writing or read-balancing in that
339 range.
340
341 Secondly, while node recovery is happening it reports that
342 all areas are resyncing for READ requests. This avoids races
343 between the cluster-filesystem and the cluster-RAID handling
344 a node failure.
345
346 6.7 add_new_disk_start(), add_new_disk_finish(), new_disk_ack()
347 ---------------------------------------------------------------
348
349 These are used to manage the new-disk protocol described above.
350 When a new device is added, add_new_disk_start() is called before
351 it is bound to the array and, if that succeeds, add_new_disk_finish()
352 is called the device is fully added.
353
354 When a device is added in acknowledgement to a previous
355 request, or when the device is declared "unavailable",
356 new_disk_ack() is called.
357
358 6.8 remove_disk()
359 -----------------
360
361 This is called when a spare or failed device is removed from
362 the array. It causes a REMOVE message to be send to other nodes.
363
364 6.9 gather_bitmaps()
365 --------------------
366
367 This sends a RE_ADD message to all other nodes and then
368 gathers bitmap information from all bitmaps. This combined
369 bitmap is then used to recovery the re-added device.
370
371 6.10 lock_all_bitmaps() and unlock_all_bitmaps()
372 ------------------------------------------------
373
374 These are called when change bitmap to none. If a node plans
375 to clear the cluster raid's bitmap, it need to make sure no other
376 nodes are using the raid which is achieved by lock all bitmap
377 locks within the cluster, and also those locks are unlocked
378 accordingly.
379
380 7. Unsupported features
381 =======================
382
383 There are somethings which are not supported by cluster MD yet.
384
385 - change array_sectors.
386

3. 한국어 전문 번역

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

MD Cluster 개요

1-8

Cluster MD는 cluster가 함께 사용하는 shared-device RAID입니다. 지원 RAID level은 `raid1`과 제한적으로 지원되는 `raid10`입니다.

Cluster MD 지원 범위
항목내용
Device modelCluster node가 함께 쓰는 shared device
지원 levelraid1
제한 지원raid10

문서가 전제로 삼는 공유 RAID 구성입니다.

1. On-disk format

9-34

각 cluster node는 별도의 write-intent bitmap을 사용합니다. Bitmap에는 그 node에서 시작했지만 아직 끝나지 않았을 수 있는 모든 write가 기록됩니다.

디스크는 첫 4 KiB를 비워 두고 다음 4 KiB에 MD superblock을 둡니다. 이후 각 node의 `bm super[n]`과 bitmap bit를 이어 배치합니다. 아래 원문 block과 구조화 표는 같은 layout을 나타냅니다.

0                    4k                     8k                    12k
-------------------------------------------------------------------
| idle                | md super            | bm super [0] + bits |
| bm bits[0, contd]   | bm super[1] + bits  | bm bits[1, contd]   |
| bm super[2] + bits  | bm bits [2, contd]  | bm super[3] + bits  |
| bm bits [3, contd]  |                     |                     |
4 KiB 단위 on-disk 배치
Offset내용
0 KiBidle
4 KiBmd super
8 KiBbm super[0] + bits
12 KiBbm bits[0, contd]
16 KiBbm super[1] + bits
20 KiBbm bits[1, contd]
24 KiBbm super[2] + bits
28 KiBbm bits[2, contd]
32 KiBbm super[3] + bits
36 KiBbm bits[3, contd]

원문 ASCII layout을 offset 순서대로 구조화했습니다.

정상 동작 중에는 filesystem이 임의의 block을 한 번에 한 node만 쓰도록 보장한다고 가정합니다. Write request는 필요한 bit를 set하고, 모든 mirror에 write를 commit한 뒤 timeout 후 해당 bit를 clear하도록 예약합니다.

Read는 일반 방식으로 처리합니다. 다른 node 또는 같은 node가 쓰고 있는 location을 동시에 읽지 않도록 보장하는 책임은 filesystem에 있습니다.

2. DLM lock과 bitmap lock resource

35-56

Device 관리를 위한 lock은 bitmap lock resource, message passing lock, new-device management lock의 세 group으로 나뉩니다.

DLM management lock group
GroupResource역할
Bitmapbitmap000, bitmap001, ...Node별 bitmap과 resync range 보호
Message passingtoken, message, ackResync 및 metadata update broadcast
New deviceno-new-devArray 전체의 device 추가 직렬화

Cluster MD가 관리 목적으로 사용하는 세 lock group입니다.

`bm_lockres`는 개별 node bitmap을 보호합니다. Node 1은 `bitmap000`, node 2는 `bitmap001`처럼 이름을 붙입니다. Node가 cluster에 join하면 PW mode로 lock을 얻고 cluster member인 동안 유지합니다.

Lock resource number는 DLM subsystem이 돌려주는 slot number에 기반합니다. DLM node count는 1부터 시작하고 bitmap slot은 0부터 시작하므로 DLM slot number에서 1을 빼 bitmap slot number를 얻습니다.

특정 node의 bitmap lock LVB는 그 node가 resync 중인 sector range를 기록합니다. 다른 node는 그 sector에 쓸 수 없습니다. 이 정보는 새 node가 cluster에 join할 때 사용됩니다.

Node bitmap lock lifecycle
Node가 cluster joinDLM slot number 획득slot - 1로 bitmap slot 계산bitmapNNN을 PW mode로 획득LVB에 resync sector range 기록Membership 동안 lock 유지

DLM slot을 bitmap slot과 lock resource로 변환하는 흐름입니다.

2.2 Message passing과 2.3 new-device lock

57-71

각 node는 resync 시작·종료 및 metadata superblock update 때 다른 node와 통신해야 합니다. 이 통신은 `token`, `message`, `ack` 세 lock과 `message` lock 하나의 Lock Value Block(LVB)으로 관리합니다.

새 device 추가는 `no-new-dev` 단일 lock으로 조정하며 array 전체에서 synchronize해야 합니다. 평상시에는 모든 node가 이 resource에 concurrent-read lock을 보유합니다.

3. Communication

72-78

Message는 모든 node에 broadcast할 수 있습니다. Sender는 진행하기 전에 다른 모든 node가 message를 acknowledge할 때까지 기다립니다. 동시에 처리할 수 있는 message는 하나뿐입니다.

3.1 Message types

79-124

Cluster MD가 전달하는 message type은 여섯 가지입니다.

`METADATA_UPDATED`는 metadata가 바뀌었으므로 각 node가 MD superblock을 다시 읽어야 함을 알립니다. 동기적으로 처리하며 주로 device failure를 signal하는 데 사용합니다.

`RESYNCING`은 resync 시작 또는 종료를 알려 각 node가 해당 region을 suspend하거나 resume하게 합니다. Message에는 sender가 resync하려는 device range가 들어가며, 같은 node가 이전에 보낸 notification을 대체합니다. Node별로 한 번에 하나의 range만 resync할 수 있습니다.

`NEWDISK`는 device가 array에 추가되고 있음을 알리며 그 device identifier를 담습니다. `REMOVE`는 failed 또는 spare device의 제거를 알리며 device slot number를 담습니다.

`RE_ADD`는 다시 정상 동작한다고 판단한 failed device를 reactivate합니다. `BITMAP_NEEDS_SYNC`는 node가 local에서 stop했지만 bitmap이 clean하지 않을 때 다른 node가 resync ownership을 넘겨받도록 알립니다.

Cluster MD message type
TypePayload 또는 의미수신 node 동작
METADATA_UPDATEDMetadata 변경MD superblock 재읽기
RESYNCINGResync range 또는 empty rangeRegion suspend 또는 resume
NEWDISKDevice identifier새 device 탐색·후보 등록
REMOVEDevice slot numberFailed/spare device 제거
RE_ADD복구된 deviceDevice reactivate 준비
BITMAP_NEEDS_SYNCDirty bitmap ownership다른 node가 resync 인계

여섯 message의 payload와 효과를 정리했습니다.

3.2 Communication mechanism

125-148

Cluster node 사이 통신에는 DLM LVB와 `token`, `message`, `ack` 세 resource를 사용합니다.

`token`은 전체 통신 system을 보호합니다. Token resource를 가진 node만 통신할 수 있습니다. `message` lock resource는 실제 전달 data를 담습니다.

`ack` resource의 획득은 cluster의 모든 node가 message를 acknowledge했다는 뜻입니다. 이 resource의 BAST는 어떤 node가 통신하려 한다는 사실을 receiver에 알립니다.

통신 resource 역할
ResourceLock/LVB 역할
token전체 communication 직렬화, 보유 node만 송신
messageLVB를 통해 payload 전달
ack모든 receiver의 처리 완료 barrier
ack BASTReceiver에 sender의 통신 의도 통지

직렬화, payload 전달, 완료 확인을 각 resource가 분담합니다.

3.2 Communication algorithm

149-209

초기 receive 상태에서는 모든 node가 `ack`에 concurrent-reader(CR) lock을 갖습니다.

sender                         receiver                 receiver
"ack":CR                       "ack":CR                 "ack":CR

Sender는 먼저 `token`과 `message`에 exclusive(EX) lock을 얻습니다. `token`을 기다리는 동안 받은 message나 다른 event 때문에 원래 message가 부적절하거나 중복이 되었을 수 있으므로, 이 시점에 여전히 보낼 필요가 있는지 다시 확인합니다.

sender                        receiver                 receiver
"token":EX                    "ack":CR                 "ack":CR
"message":EX
"ack":CR

Sender는 `message` LVB에 payload를 쓰고 `message`를 EX에서 concurrent-write(CW)로 down-convert한 다음 `ack`의 EX 획득을 시도합니다. `ack` BAST를 받은 receiver는 `message` CR을 얻어 LVB를 읽고 message를 처리한 뒤 `ack`를 release하고 `message` PR을 시도합니다.

 [ wait until all receivers have *processed* the "message" ]

                                  [ triggered by bast of "ack" ]
                                  receiver get CR on "message"
                                  receiver read LVB
                                  receiver processes the message
                                  [ wait finish ]
                                  receiver releases "ack"
                                  receiver tries to get PR on "message"

sender                         receiver                  receiver
"token":EX                     "message":CR              "message":CR
"message":CW
"ack":EX

모든 receiver가 message를 처리하면 sender에게 `ack` EX가 grant됩니다. Sender는 `ack`를 EX에서 CR로 down-convert하고 `message`, `token`을 release합니다. Receiver는 `message`를 PR로 up-convert하고 `ack` CR을 다시 얻은 뒤 `message`를 release하여 초기 상태로 돌아갑니다.

                            receiver upconvert to PR on "message"
                            receiver get CR of "ack"
                            receiver release "message"

sender                      receiver                   receiver
"ack":CR                    "ack":CR                   "ack":CR
DLM broadcast handshake
모든 node: ack CRSender: token EX 획득Sender: message EX 획득 후 필요성 재검사Sender: LVB 기록, message EX→CWSender: ack EX 요청Receiver: BAST 수신, message CR로 LVB 읽기Receiver: message 처리 후 ack release모든 처리 완료로 sender ack EX grantSender: ack EX→CR, message·token releaseReceiver: ack CR 복구, message release

원문 lock state ASCII sequence를 하나의 처리 흐름으로 재구성했습니다.

Algorithm 단계별 주요 lock state
단계SenderReceiver
초기ack:CRack:CR
송신권 확보token:EX, message:EX, ack:CRack:CR
처리 대기token:EX, message:CW, ack:EX 요청message:CR, ack release
완료ack:CR, message/token releaseack:CR, message release

Sender와 receiver의 핵심 상태를 비교합니다.

4.1 Node failure

210-246

Node가 fail하면 DLM이 cluster에 slot number를 알리고 node는 cluster recovery thread를 시작합니다. 이 thread는 failed node의 `bitmap<number>` lock을 얻고 bitmap을 열어 읽은 뒤 set bit를 local node로 복사합니다. 이어 failed node bitmap을 clean하고 lock을 release한 다음 현재 node에서 그 bitmap의 resync를 시작합니다.

`recover_bitmaps` 안에서 `md_check_recovery`가 호출되고, `md_check_recovery -> metadata_update_start/finish`가 이어져 `lock_comm`으로 communication을 잠급니다. 따라서 한 node가 resync하는 동안 다른 모든 node의 array 전체 write가 block됩니다.

Resync 자체는 일반 MD resync이지만 clustered environment에서는 suspend할 area를 다른 node에 알려야 합니다. 시작 전 `(lo,hi)` range를 담은 `RESYNCING`을 보내고, 각 node는 받은 range를 `suspend_list`에 추가합니다. 완료 node가 empty range의 `RESYNCING`을 보내면 다른 node가 해당 entry를 제거합니다.

Helper function `->area_resyncing()`은 특정 I/O range를 suspend해야 하는지 검사합니다.

Failed node bitmap recovery
DLM이 failed slot 통지Failed node bitmap lock 획득Bitmap open·readSet bit를 local bitmap에 복사Failed bitmap clean·lock releaseRESYNCING(lo,hi) broadcast각 node suspend_list 갱신MD resync 수행RESYNCING(empty) broadcastSuspend entry 제거

DLM failure 통지부터 resync 종료까지의 순서입니다.

4.2 Device failure

247-254

Device failure는 metadata update routine으로 처리하고 전파합니다. 어떤 node가 device failure를 감지하면 다른 모든 node가 failure를 acknowledge할 때까지 그 device에 더 이상 write하지 못하게 합니다.

5. Adding a new device

255-281

새 device를 추가하려면 모든 node가 그 device를 볼 수 있어야 합니다. Node 1의 `mdadm --manage /dev/mdX --add /dev/sdYY`는 `disc.state=MD_DISK_CLUSTER_ADD`인 `ioctl(ADD_NEW_DISK)`를 발생시킵니다.

Node 1은 uuid와 slot number를 담은 `NEWDISK`를 보냅니다. 다른 node는 같은 정보를 넣어 `kobject_uevent_env`를 발생시키고, userspace에서 `blkid -t SUB_UUID=""` 같은 방법으로 disk를 찾습니다. 이 두 단계는 udev rule로 구현할 수 있습니다.

Disk를 찾은 node는 `disc.state=MD_DISK_CANDIDATE`, `disc.number=slot number`인 `ioctl(ADD_NEW_DISK)`를 실행하고, 찾지 못한 node는 `ioctl(CLUSTERED_DISK_NACK)`를 실행합니다.

Device를 찾은 다른 node는 `no-new-devs`의 CR lock을 내려놓습니다. Node 1은 `no-new-dev` EX lock을 시도합니다. Lock을 얻으면 disk의 `SpareLocal` 표시를 제거한 뒤 `METADATA_UPDATED`를 보내고, 얻지 못하면 operation을 fail시킨 뒤 역시 `METADATA_UPDATED`를 보냅니다. 다른 node는 뒤따르는 message로 추가 성공 여부를 알게 됩니다.

New device cluster protocol
Node 1: mdadm --addADD_NEW_DISK(MD_DISK_CLUSTER_ADD)NEWDISK(uuid, slot) broadcast다른 node: uevent와 userspace disk 탐색Found: MD_DISK_CANDIDATE / Not found: CLUSTERED_DISK_NACKFound node가 no-new-devs CR dropNode 1이 no-new-dev EX 시도성공: SpareLocal 해제 / 실패: operation failMETADATA_UPDATED broadcast모든 node가 결과 반영

모든 node가 새 disk를 확인하고 동의하는 절차입니다.

6. Module interface와 join·leave

282-296

MD core가 cluster module에 호출할 수 있는 callback은 17개입니다. 이 interface를 이해하면 전체 처리 흐름을 파악할 수 있습니다.

Clustered bitmap으로 array를 시작할 때 `join(nodes)`가, array를 stop할 때 `leave()`가 호출됩니다. `join()`은 cluster 가용성을 확인하고 여러 resource를 initialize합니다. Cluster의 처음 `nodes`개 node만 array를 사용할 수 있습니다.

6.2 slot_number()

297-302

`slot_number()`는 cluster infrastructure가 알려 준 slot number를 보고합니다. 범위는 0부터 `nodes-1`까지입니다.

6.3 resync_info_update()

303-310

`resync_info_update()`는 bitmap lock에 저장된 resync range를 갱신합니다. Resync 진행에 따라 시작점은 이동하지만 끝점은 항상 array의 끝입니다. 이 callback 자체는 `RESYNCING` message를 보내지 않습니다.

6.4 resync_start()와 resync_finish()

311-321

`resync_start()`와 `resync_finish()`는 resync, recovery 또는 reshape가 시작하거나 멈출 때 호출됩니다. 두 callback은 bitmap lock의 resyncing range를 갱신하고 `RESYNCING` message도 보냅니다.

`resync_start()`는 array 전체가 resync 중이라고 보고하고 `resync_finish()`는 resync 중인 영역이 없다고 보고합니다. `resync_finish()`는 다른 node가 작업을 넘겨받을 수 있도록 `BITMAP_NEEDS_SYNC`도 보냅니다.

6.5 Metadata update callback

322-330

`metadata_update_start()`는 metadata에 exclusive access를 얻는 데 사용합니다. Access를 얻은 뒤에도 변경이 필요하면 `metadata_update_finish()`가 다른 모든 node에 `METADATA_UPDATE` message를 보냅니다. 변경이 필요 없으면 `metadata_update_cancel()`로 lock을 release합니다.

6.6 area_resyncing()

331-345

`area_resyncing()`은 두 기능을 결합합니다. 첫째, 어느 node든 주어진 sector range의 일부를 resync 중인지 검사합니다. Resync를 찾으면 caller는 그 range에서 write 또는 read-balancing을 피합니다.

둘째, node recovery 중에는 READ request에 대해 모든 area가 resync 중이라고 보고합니다. 이로써 node failure를 처리하는 cluster filesystem과 cluster RAID 사이의 race를 피합니다.

area_resyncing() 결정
Sector range와 request type 입력어느 node가 range를 resync 중인가?예: write·read-balancing 회피아니오: node recovery 중 READ인가?예: 전체 area resyncing으로 보고아니오: normal I/O 허용

I/O가 resync 또는 recovery와 충돌하지 않도록 판단합니다.

6.7 New disk callback

346-357

`add_new_disk_start()`, `add_new_disk_finish()`, `new_disk_ack()`는 앞에서 설명한 new-disk protocol을 관리합니다. 새 device를 array에 bind하기 전에 `add_new_disk_start()`를 호출하고, 성공했다면 device가 완전히 추가된 뒤 `add_new_disk_finish()`를 호출합니다.

이전 request에 대한 acknowledge로 device가 추가되었거나 device를 unavailable로 선언할 때 `new_disk_ack()`를 호출합니다.

New disk callback 시점
Callback호출 시점
add_new_disk_start()Device를 array에 bind하기 전
add_new_disk_finish()Start 성공 후 device가 완전히 추가됨
new_disk_ack()요청에 응답해 추가 또는 unavailable 선언

새 device protocol의 callback boundary입니다.

6.8 remove_disk()와 6.9 gather_bitmaps()

358-370

`remove_disk()`는 spare 또는 failed device를 array에서 제거할 때 호출되며 다른 node에 `REMOVE` message를 보냅니다.

`gather_bitmaps()`는 다른 모든 node에 `RE_ADD` message를 보낸 뒤 모든 bitmap의 정보를 모읍니다. 결합한 bitmap은 다시 추가한 device를 recover하는 데 사용합니다.

6.10 모든 bitmap lock

371-379

`lock_all_bitmaps()`와 `unlock_all_bitmaps()`는 bitmap을 none으로 바꿀 때 호출됩니다. 어떤 node가 cluster RAID bitmap을 clear하려면 다른 node가 RAID를 사용하지 않는지 확인해야 합니다. 이를 위해 cluster 안의 모든 bitmap lock을 잠그고 작업 후 그 lock을 모두 해제합니다.

7. Unsupported features

380-385

Cluster MD가 아직 지원하지 않는 기능이 있으며, 이 문서가 명시하는 항목은 `array_sectors` 변경입니다.