€•ÌúŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ,/translations/zh_CN/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/zh_TW/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/it_IT/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ja_JP/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ko_KR/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/pt_BR/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/sp_SP/driver-api/md/md-cluster”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ MD Cluster”h]”hŒ MD Cluster”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒF/var/lib/git/docbuild/linux/Documentation/driver-api/md/md-cluster.rst”h´KubhŒ paragraph”“”)�”}”(hŒqThe cluster MD is a shared-device RAID for a cluster, it supports two levels: raid1 and raid10 (limited support).”h]”hŒqThe cluster MD is a shared-device RAID for a cluster, it supports two levels: raid1 and raid10 (limited support).”…”�”}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ1. On-disk format”h]”hŒ1. On-disk format”…”�”}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÛh²hh³hÊh´K ubhÌ)�”}”(hŒ»Separate write-intent-bitmaps are used for each cluster node. The bitmaps record all writes that may have been started on that node, and may not yet have finished. The on-disk layout is::”h]”hŒºSeparate write-intent-bitmaps are used for each cluster node. The bitmaps record all writes that may have been started on that node, and may not yet have finished. The on-disk layout is:”…”�”}”(hhìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hhÛh²hubhŒ literal_block”“”)�”}”(hX™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] | | |”h]”hX™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] | | |”…”�”}”hhüsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1húh³hÊh´KhhÛh²hubhÌ)�”}”(hŒŒDuring "normal" functioning we assume the filesystem ensures that only one node writes to any given block at a time, so a write request will”h]”hŒ�During “normalâ€� functioning we assume the filesystem ensures that only one node writes to any given block at a time, so a write request will”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhŒ block_quote”“”)�”}”(hŒƒ- set the appropriate bit (if not already set) - commit the write to all mirrors - schedule the bit to be cleared after a timeout. ”h]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ,set the appropriate bit (if not already set)”h]”hÌ)�”}”(hj)h]”hŒ,set the appropriate bit (if not already set)”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj'ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"ubj&)�”}”(hŒcommit the write to all mirrors”h]”hÌ)�”}”(hj@h]”hŒcommit the write to all mirrors”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"ubj&)�”}”(hŒ0schedule the bit to be cleared after a timeout. ”h]”hÌ)�”}”(hŒ/schedule the bit to be cleared after a timeout.”h]”hŒ/schedule the bit to be cleared after a timeout.”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjUubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj"ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j h³hÊh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KhhÛh²hubhÌ)�”}”(hŒ�Reads are just handled normally. It is up to the filesystem to ensure one node doesn't read from a location where another node (or the same node) is writing.”h]”hŒŸReads are just handled normally. It is up to the filesystem to ensure one node doesn’t read from a location where another node (or the same node) is writing.”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubeh}”(h]”Œon-disk-format”ah ]”h"]”Œ1. on-disk format”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubh¶)�”}”(hhh]”(h»)�”}”(hŒ2. DLM Locks for management”h]”hŒ2. DLM Locks for management”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj‘h²hh³hÊh´K$ubhÌ)�”}”(hŒ8There are three groups of locks for managing the device:”h]”hŒ8There are three groups of locks for managing the device:”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K&hj‘h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ%2.1 Bitmap lock resource (bm_lockres)”h]”hŒ%2.1 Bitmap lock resource (bm_lockres)”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj°h²hh³hÊh´K)ubj)�”}”(hXÄThe bm_lockres protects individual node bitmaps. They are named in the form bitmap000 for node 1, bitmap001 for node 2 and so on. When a node joins the cluster, it acquires the lock in PW mode and it stays so during the lifetime the node is part of the cluster. The lock resource number is based on the slot number returned by the DLM subsystem. Since DLM starts node count from one and bitmap slots start from zero, one is subtracted from the DLM slot number to arrive at the bitmap slot number. The LVB of the bitmap lock for a particular node records the range of sectors that are being re-synced by that node. No other node may write to those sectors. This is used when a new nodes joins the cluster. ”h]”(hÌ)�”}”(hXðThe bm_lockres protects individual node bitmaps. They are named in the form bitmap000 for node 1, bitmap001 for node 2 and so on. When a node joins the cluster, it acquires the lock in PW mode and it stays so during the lifetime the node is part of the cluster. The lock resource number is based on the slot number returned by the DLM subsystem. Since DLM starts node count from one and bitmap slots start from zero, one is subtracted from the DLM slot number to arrive at the bitmap slot number.”h]”hXðThe bm_lockres protects individual node bitmaps. They are named in the form bitmap000 for node 1, bitmap001 for node 2 and so on. When a node joins the cluster, it acquires the lock in PW mode and it stays so during the lifetime the node is part of the cluster. The lock resource number is based on the slot number returned by the DLM subsystem. Since DLM starts node count from one and bitmap slots start from zero, one is subtracted from the DLM slot number to arrive at the bitmap slot number.”…”�”}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K+hjÁubhÌ)�”}”(hŒÑThe LVB of the bitmap lock for a particular node records the range of sectors that are being re-synced by that node. No other node may write to those sectors. This is used when a new nodes joins the cluster.”h]”hŒÑThe LVB of the bitmap lock for a particular node records the range of sectors that are being re-synced by that node. No other node may write to those sectors. This is used when a new nodes joins the cluster.”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K4hjÁubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K+hj°h²hubeh}”(h]”Œbitmap-lock-resource-bm-lockres”ah ]”h"]”Œ%2.1 bitmap lock resource (bm_lockres)”ah$]”h&]”uh1hµhj‘h²hh³hÊh´K)ubh¶)�”}”(hhh]”(h»)�”}”(hŒ2.2 Message passing locks”h]”hŒ2.2 Message passing locks”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjïh²hh³hÊh´K:ubj)�”}”(hX Each node has to communicate with other nodes when starting or ending resync, and for metadata superblock updates. This communication is managed through three locks: "token", "message", and "ack", together with the Lock Value Block (LVB) of one of the "message" lock. ”h]”hÌ)�”}”(hX Each node has to communicate with other nodes when starting or ending resync, and for metadata superblock updates. This communication is managed through three locks: "token", "message", and "ack", together with the Lock Value Block (LVB) of one of the "message" lock.”h]”hXEach node has to communicate with other nodes when starting or ending resync, and for metadata superblock updates. This communication is managed through three locks: “tokenâ€�, “messageâ€�, and “ackâ€�, together with the Lock Value Block (LVB) of one of the “messageâ€� lock.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kh²hh³hÊh´Kmubj)�”}”(hX� A failed or spare device is being removed from the array. The slot-number of the device is included in the message. 3.1.5 RE_ADD: A failed device is being re-activated - the assumption is that it has been determined to be working again. 3.1.6 BITMAP_NEEDS_SYNC: If a node is stopped locally but the bitmap isn't clean, then another node is informed to take the ownership of resync. ”h]”(j)�”}”(hŒtA failed or spare device is being removed from the array. The slot-number of the device is included in the message. ”h]”hÌ)�”}”(hŒsA failed or spare device is being removed from the array. The slot-number of the device is included in the message.”h]”hŒsA failed or spare device is being removed from the array. The slot-number of the device is included in the message.”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KohjSubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KohjOubhÌ)�”}”(hŒ 3.1.5 RE_ADD:”h]”hŒ 3.1.5 RE_ADD:”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KrhjOubj)�”}”(hŒkA failed device is being re-activated - the assumption is that it has been determined to be working again. ”h]”hÌ)�”}”(hŒjA failed device is being re-activated - the assumption is that it has been determined to be working again.”h]”hŒjA failed device is being re-activated - the assumption is that it has been determined to be working again.”…”�”}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kthjyubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KthjOubhÌ)�”}”(hŒ3.1.6 BITMAP_NEEDS_SYNC:”h]”hŒ3.1.6 BITMAP_NEEDS_SYNC:”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KwhjOubj)�”}”(hŒxIf a node is stopped locally but the bitmap isn't clean, then another node is informed to take the ownership of resync. ”h]”hÌ)�”}”(hŒwIf a node is stopped locally but the bitmap isn't clean, then another node is informed to take the ownership of resync.”h]”hŒyIf a node is stopped locally but the bitmap isn’t clean, then another node is informed to take the ownership of resync.”…”�”}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KyhjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KyhjOubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Kohj>h²hubeh}”(h]”Œremove”ah ]”h"]”Œ 3.1.4 remove”ah$]”h&]”uh1hµhj‚h²hh³hÊh´Kmubeh}”(h]”Œ message-types”ah ]”h"]”Œ3.1 message types”ah$]”h&]”uh1hµhjYh²hh³hÊh´KPubh¶)�”}”(hhh]”(h»)�”}”(hŒ3.2 Communication mechanism”h]”hŒ3.2 Communication mechanism”…”�”}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÍh²hh³hÊh´K~ubj)�”}”(hŒpThe DLM LVB is used to communicate within nodes of the cluster. There are three resources used for the purpose: ”h]”hÌ)�”}”(hŒoThe DLM LVB is used to communicate within nodes of the cluster. There are three resources used for the purpose:”h]”hŒoThe DLM LVB is used to communicate within nodes of the cluster. There are three resources used for the purpose:”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K€hjÞubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K€hjÍh²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ 3.2.1 token”h]”hŒ 3.2.1 token”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjöh²hh³hÊh´K„ubj)�”}”(hŒ{The resource which protects the entire communication system. The node having the token resource is allowed to communicate. ”h]”hÌ)�”}”(hŒzThe resource which protects the entire communication system. The node having the token resource is allowed to communicate.”h]”hŒzThe resource which protects the entire communication system. The node having the token resource is allowed to communicate.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K…hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K…hjöh²hubeh}”(h]”Œtoken”ah ]”h"]”Œ 3.2.1 token”ah$]”h&]”uh1hµhjÍh²hh³hÊh´K„ubh¶)�”}”(hhh]”(h»)�”}”(hŒ 3.2.2 message”h]”hŒ 3.2.2 message”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj'h²hh³hÊh´KŠubj)�”}”(hŒ9The lock resource which carries the data to communicate. ”h]”hÌ)�”}”(hŒ8The lock resource which carries the data to communicate.”h]”hŒ8The lock resource which carries the data to communicate.”…”�”}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K‹hj8ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K‹hj'h²hubeh}”(h]”Œmessage”ah ]”h"]”Œ 3.2.2 message”ah$]”h&]”uh1hµhjÍh²hh³hÊh´KŠubh¶)�”}”(hhh]”(h»)�”}”(hŒ 3.2.3 ack”h]”hŒ 3.2.3 ack”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjXh²hh³hÊh´KŽubj)�”}”(hŒÃThe resource, acquiring which means the message has been acknowledged by all nodes in the cluster. The BAST of the resource is used to inform the receiving node that a node wants to communicate. ”h]”hÌ)�”}”(hŒÂThe resource, acquiring which means the message has been acknowledged by all nodes in the cluster. The BAST of the resource is used to inform the receiving node that a node wants to communicate.”h]”hŒÂThe resource, acquiring which means the message has been acknowledged by all nodes in the cluster. The BAST of the resource is used to inform the receiving node that a node wants to communicate.”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K�hjiubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K�hjXh²hubhÌ)�”}”(hŒThe algorithm is:”h]”hŒThe algorithm is:”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K•hjXh²hubj)�”}”(hX¿1. receive status - all nodes have concurrent-reader lock on "ack":: sender receiver receiver "ack":CR "ack":CR "ack":CR 2. sender get EX on "token", sender get EX on "message":: sender receiver receiver "token":EX "ack":CR "ack":CR "message":EX "ack":CR Sender checks that it still needs to send a message. Messages received or other events that happened while waiting for the "token" may have made this message inappropriate or redundant. 3. sender writes LVB sender down-convert "message" from EX to CW sender try to get EX of "ack" :: [ 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 4. triggered by grant of EX on "ack" (indicating all receivers have processed message) sender down-converts "ack" from EX to CR sender releases "message" sender releases "token" :: receiver upconvert to PR on "message" receiver get CR of "ack" receiver release "message" sender receiver receiver "ack":CR "ack":CR "ack":CR ”h]”hŒenumerated_list”“”)�”}”(hhh]”(j&)�”}”(hŒÍreceive status - all nodes have concurrent-reader lock on "ack":: sender receiver receiver "ack":CR "ack":CR "ack":CR ”h]”(hÌ)�”}”(hŒAreceive status - all nodes have concurrent-reader lock on "ack"::”h]”hŒDreceive status - all nodes have concurrent-reader lock on “ackâ€�:”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K—hj˜ubhû)�”}”(hŒ�sender receiver receiver "ack":CR "ack":CR "ack":CR”h]”hŒ�sender receiver receiver "ack":CR "ack":CR "ack":CR”…”�”}”hjªsbah}”(h]”h ]”h"]”h$]”h&]”j j uh1húh³hÊh´K™hj˜ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j%hj•ubj&)�”}”(hX™sender get EX on "token", sender get EX on "message":: sender receiver receiver "token":EX "ack":CR "ack":CR "message":EX "ack":CR Sender checks that it still needs to send a message. Messages received or other events that happened while waiting for the "token" may have made this message inappropriate or redundant. ”h]”(hÌ)�”}”(hŒ6sender get EX on "token", sender get EX on "message"::”h]”hŒ=sender get EX on “tokenâ€�, sender get EX on “messageâ€�:”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kœhj¾ubhû)�”}”(hŒ•sender receiver receiver "token":EX "ack":CR "ack":CR "message":EX "ack":CR”h]”hŒ•sender receiver receiver "token":EX "ack":CR "ack":CR "message":EX "ack":CR”…”�”}”hjÐsbah}”(h]”h ]”h"]”h$]”h&]”j j uh1húh³hÊh´KŸhj¾ubhÌ)�”}”(hŒ¹Sender checks that it still needs to send a message. Messages received or other events that happened while waiting for the "token" may have made this message inappropriate or redundant.”h]”hŒ½Sender checks that it still needs to send a message. Messages received or other events that happened while waiting for the “tokenâ€� may have made this message inappropriate or redundant.”…”�”}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¤hj¾ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j%hj•ubj&)�”}”(hXõsender writes LVB sender down-convert "message" from EX to CW sender try to get EX of "ack" :: [ 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 ”h]”(hÌ)�”}”(hŒsender writes LVB”h]”hŒsender writes LVB”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¨hjòubhÌ)�”}”(hŒ+sender down-convert "message" from EX to CW”h]”hŒ/sender down-convert “messageâ€� from EX to CW”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KªhjòubhÌ)�”}”(hŒsender try to get EX of "ack"”h]”hŒ!sender try to get EX of “ackâ€�”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¬hjòubhû)�”}”(hX… [ 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”h]”hX… [ 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”…”�”}”hj sbah}”(h]”h ]”h"]”h$]”h&]”j j uh1húh³hÊh´K°hjòubeh}”(h]”h ]”h"]”h$]”h&]”uh1j%hj•ubj&)�”}”(hXìtriggered by grant of EX on "ack" (indicating all receivers have processed message) sender down-converts "ack" from EX to CR sender releases "message" sender releases "token" :: receiver upconvert to PR on "message" receiver get CR of "ack" receiver release "message" sender receiver receiver "ack":CR "ack":CR "ack":CR ”h]”(hÌ)�”}”(hŒStriggered by grant of EX on "ack" (indicating all receivers have processed message)”h]”hŒWtriggered by grant of EX on “ackâ€� (indicating all receivers have processed message)”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¿hj4ubhÌ)�”}”(hŒ(sender down-converts "ack" from EX to CR”h]”hŒ,sender down-converts “ackâ€� from EX to CR”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÂhj4ubhÌ)�”}”(hŒsender releases "message"”h]”hŒsender releases “messageâ€�”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÄhj4ubhÌ)�”}”(hŒsender releases "token"”h]”hŒsender releases “tokenâ€�”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÆhj4ubhû)�”}”(hX. receiver upconvert to PR on "message" receiver get CR of "ack" receiver release "message" sender receiver receiver "ack":CR "ack":CR "ack":CR”h]”hX. receiver upconvert to PR on "message" receiver get CR of "ack" receiver release "message" sender receiver receiver "ack":CR "ack":CR "ack":CR”…”�”}”hjpsbah}”(h]”h ]”h"]”h$]”h&]”j j uh1húh³hÊh´KÊhj4ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j%hj•ubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1j“hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K—hjXh²hubeh}”(h]”Œack”ah ]”h"]”Œ 3.2.3 ack”ah$]”h&]”uh1hµhjÍh²hh³hÊh´KŽubeh}”(h]”Œcommunication-mechanism”ah ]”h"]”Œ3.2 communication mechanism”ah$]”h&]”uh1hµhjYh²hh³hÊh´K~ubeh}”(h]”Œ communication”ah ]”h"]”Œ3. communication”ah$]”h&]”uh1hµhh·h²hh³hÊh´KIubh¶)�”}”(hhh]”(h»)�”}”(hŒ4. Handling Failures”h]”hŒ4. Handling Failures”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj­h²hh³hÊh´KÓubh¶)�”}”(hhh]”(h»)�”}”(hŒ4.1 Node Failure”h]”hŒ4.1 Node Failure”…”�”}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj¾h²hh³hÊh´KÖubj)�”}”(hXüWhen a node fails, the DLM informs the cluster with the slot number. The node starts a cluster recovery thread. The cluster recovery thread: - acquires the bitmap lock of the failed node - opens the bitmap - reads the bitmap of the failed node - copies the set bitmap to local node - cleans the bitmap of the failed node - releases bitmap lock of the failed node - initiates resync of the bitmap on the current node md_check_recovery is invoked within recover_bitmaps, then md_check_recovery -> metadata_update_start/finish, it will lock the communication by lock_comm. Which means when one node is resyncing it blocks all other nodes from writing anywhere on the array. The resync process is the regular md resync. However, in a clustered environment when a resync is performed, it needs to tell other nodes of the areas which are suspended. Before a resync starts, the node send out RESYNCING with the (lo,hi) range of the area which needs to be suspended. Each node maintains a suspend_list, which contains the list of ranges which are currently suspended. On receiving RESYNCING, the node adds the range to the suspend_list. Similarly, when the node performing resync finishes, it sends RESYNCING with an empty range to other nodes and other nodes remove the corresponding entry from the suspend_list. A helper function, ->area_resyncing() can be used to check if a particular I/O range should be suspended or not. ”h]”(hÌ)�”}”(hŒŒWhen a node fails, the DLM informs the cluster with the slot number. The node starts a cluster recovery thread. The cluster recovery thread:”h]”hŒŒWhen a node fails, the DLM informs the cluster with the slot number. The node starts a cluster recovery thread. The cluster recovery thread:”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KØhjÏubj)�”}”(hX,- acquires the bitmap lock of the failed node - opens the bitmap - reads the bitmap of the failed node - copies the set bitmap to local node - cleans the bitmap of the failed node - releases bitmap lock of the failed node - initiates resync of the bitmap on the current node md_check_recovery is invoked within recover_bitmaps, then md_check_recovery -> metadata_update_start/finish, it will lock the communication by lock_comm. Which means when one node is resyncing it blocks all other nodes from writing anywhere on the array. ”h]”j!)�”}”(hhh]”(j&)�”}”(hŒ3acquires the bitmap lock of the failed node”h]”hÌ)�”}”(hjêh]”hŒ3acquires the bitmap lock of the failed node”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÜhjèubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hŒopens the bitmap”h]”hÌ)�”}”(hjh]”hŒopens the bitmap”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÝhjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hŒ#reads the bitmap of the failed node”h]”hÌ)�”}”(hjh]”hŒ#reads the bitmap of the failed node”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÞhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hŒ#copies the set bitmap to local node”h]”hÌ)�”}”(hj/h]”hŒ#copies the set bitmap to local node”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kßhj-ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hŒ$cleans the bitmap of the failed node”h]”hÌ)�”}”(hjFh]”hŒ$cleans the bitmap of the failed node”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KàhjDubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hŒ/releases bitmap lock of the failed node”h]”hÌ)�”}”(hj]h]”hŒ/releases bitmap lock of the failed node”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Káhj[ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubj&)�”}”(hX2initiates resync of the bitmap on the current node md_check_recovery is invoked within recover_bitmaps, then md_check_recovery -> metadata_update_start/finish, it will lock the communication by lock_comm. Which means when one node is resyncing it blocks all other nodes from writing anywhere on the array. ”h]”hÌ)�”}”(hX1initiates resync of the bitmap on the current node md_check_recovery is invoked within recover_bitmaps, then md_check_recovery -> metadata_update_start/finish, it will lock the communication by lock_comm. Which means when one node is resyncing it blocks all other nodes from writing anywhere on the array.”h]”hX1initiates resync of the bitmap on the current node md_check_recovery is invoked within recover_bitmaps, then md_check_recovery -> metadata_update_start/finish, it will lock the communication by lock_comm. Which means when one node is resyncing it blocks all other nodes from writing anywhere on the array.”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kâhjrubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjåubeh}”(h]”h ]”h"]”h$]”h&]”jsjtuh1j h³hÊh´KÜhjáubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KÜhjÏubhÌ)�”}”(hXzThe resync process is the regular md resync. However, in a clustered environment when a resync is performed, it needs to tell other nodes of the areas which are suspended. Before a resync starts, the node send out RESYNCING with the (lo,hi) range of the area which needs to be suspended. Each node maintains a suspend_list, which contains the list of ranges which are currently suspended. On receiving RESYNCING, the node adds the range to the suspend_list. Similarly, when the node performing resync finishes, it sends RESYNCING with an empty range to other nodes and other nodes remove the corresponding entry from the suspend_list.”h]”hXzThe resync process is the regular md resync. However, in a clustered environment when a resync is performed, it needs to tell other nodes of the areas which are suspended. Before a resync starts, the node send out RESYNCING with the (lo,hi) range of the area which needs to be suspended. Each node maintains a suspend_list, which contains the list of ranges which are currently suspended. On receiving RESYNCING, the node adds the range to the suspend_list. Similarly, when the node performing resync finishes, it sends RESYNCING with an empty range to other nodes and other nodes remove the corresponding entry from the suspend_list.”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KéhjÏubhÌ)�”}”(hŒpA helper function, ->area_resyncing() can be used to check if a particular I/O range should be suspended or not.”h]”hŒpA helper function, ->area_resyncing() can be used to check if a particular I/O range should be suspended or not.”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KôhjÏubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KØhj¾h²hubeh}”(h]”Œ node-failure”ah ]”h"]”Œ4.1 node failure”ah$]”h&]”uh1hµhj­h²hh³hÊh´KÖubeh}”(h]”Œhandling-failures”ah ]”h"]”Œ4. handling failures”ah$]”h&]”uh1hµhh·h²hh³hÊh´KÓubh¶)�”}”(hhh]”(h»)�”}”(hŒ4.2 Device Failure”h]”hŒ4.2 Device Failure”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÈh²hh³hÊh´Køubj)�”}”(hŒåDevice failures are handled and communicated with the metadata update routine. When a node detects a device failure it does not allow any further writes to that device until the failure has been acknowledged by all other nodes. ”h]”hÌ)�”}”(hŒäDevice failures are handled and communicated with the metadata update routine. When a node detects a device failure it does not allow any further writes to that device until the failure has been acknowledged by all other nodes.”h]”hŒäDevice failures are handled and communicated with the metadata update routine. When a node detects a device failure it does not allow any further writes to that device until the failure has been acknowledged by all other nodes.”…”�”}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KúhjÙubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KúhjÈh²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ5. Adding a new Device”h]”hŒ5. Adding a new Device”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjñh²hh³hÊh´Mubj)�”}”(hX®For adding a new device, it is necessary that all nodes "see" the new device to be added. For this, the following algorithm is used: 1. Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD) 2. Node 1 sends a NEWDISK message with uuid and slot number 3. Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule) 4. In userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID="" 5. Other nodes issue either of the following depending on whether the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK) 6. Other nodes drop lock on "no-new-devs" (CR) if device is found 7. Node 1 attempts EX lock on "no-new-dev" 8. If node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk as SpareLocal 9. If not (get "no-new-dev" lock), it fails the operation and sends METADATA_UPDATED. 10. Other nodes get the information whether a disk is added or not by the following METADATA_UPDATED. ”h]”(hÌ)�”}”(hŒ„For adding a new device, it is necessary that all nodes "see" the new device to be added. For this, the following algorithm is used:”h]”hŒˆFor adding a new device, it is necessary that all nodes “seeâ€� the new device to be added. For this, the following algorithm is used:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhjubj)�”}”(hX1. Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD) 2. Node 1 sends a NEWDISK message with uuid and slot number 3. Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule) 4. In userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID="" 5. Other nodes issue either of the following depending on whether the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK) 6. Other nodes drop lock on "no-new-devs" (CR) if device is found 7. Node 1 attempts EX lock on "no-new-dev" 8. If node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk as SpareLocal 9. If not (get "no-new-dev" lock), it fails the operation and sends METADATA_UPDATED. 10. Other nodes get the information whether a disk is added or not by the following METADATA_UPDATED. ”h]”j”)�”}”(hhh]”(j&)�”}”(hŒ�Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD)”h]”hÌ)�”}”(hŒ�Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD)”h]”hŒ�Node 1 issues mdadm --manage /dev/mdX --add /dev/sdYY which issues ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CLUSTER_ADD)”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒ8Node 1 sends a NEWDISK message with uuid and slot number”h]”hÌ)�”}”(hj5h]”hŒ8Node 1 sends a NEWDISK message with uuid and slot number”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj3ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒ_Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule)”h]”hÌ)�”}”(hŒ_Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule)”h]”hŒ_Other nodes issue kobject_uevent_env with uuid and slot number (Steps 4,5 could be a udev rule)”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MhjJubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒPIn userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID=""”h]”hÌ)�”}”(hŒPIn userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID=""”h]”hŒTIn userspace, the node searches for the disk, perhaps using blkid -t SUB_UUID=â€�â€�”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M hjbubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒÍOther nodes issue either of the following depending on whether the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK)”h]”hÌ)�”}”(hŒÍOther nodes issue either of the following depending on whether the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK)”h]”hŒÍOther nodes issue either of the following depending on whether the disk was found: ioctl(ADD_NEW_DISK with disc.state set to MD_DISK_CANDIDATE and disc.number set to slot number) ioctl(CLUSTERED_DISK_NACK)”…”�”}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M hjzubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒ>Other nodes drop lock on "no-new-devs" (CR) if device is found”h]”hÌ)�”}”(hj”h]”hŒBOther nodes drop lock on “no-new-devsâ€� (CR) if device is found”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj’ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒ'Node 1 attempts EX lock on "no-new-dev"”h]”hÌ)�”}”(hj«h]”hŒ+Node 1 attempts EX lock on “no-new-devâ€�”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj©ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒYIf node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk as SpareLocal”h]”hÌ)�”}”(hŒYIf node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk as SpareLocal”h]”hŒYIf node 1 gets the lock, it sends METADATA_UPDATED after unmarking the disk as SpareLocal”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MhjÀubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒRIf not (get "no-new-dev" lock), it fails the operation and sends METADATA_UPDATED.”h]”hÌ)�”}”(hŒRIf not (get "no-new-dev" lock), it fails the operation and sends METADATA_UPDATED.”h]”hŒVIf not (get “no-new-devâ€� lock), it fails the operation and sends METADATA_UPDATED.”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MhjØubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubj&)�”}”(hŒbOther nodes get the information whether a disk is added or not by the following METADATA_UPDATED. ”h]”hÌ)�”}”(hŒaOther nodes get the information whether a disk is added or not by the following METADATA_UPDATED.”h]”hŒaOther nodes get the information whether a disk is added or not by the following METADATA_UPDATED.”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhjðubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hjubeh}”(h]”h ]”h"]”h$]”h&]”jŠj‹jŒhj�jŽuh1j“hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mhjñh²hubeh}”(h]”Œadding-a-new-device”ah ]”h"]”Œ5. adding a new device”ah$]”h&]”uh1hµhjÈh²hh³hÊh´Mubeh}”(h]”Œdevice-failure”ah ]”h"]”Œ4.2 device failure”ah$]”h&]”uh1hµhh·h²hh³hÊh´Køubh¶)�”}”(hhh]”(h»)�”}”(hŒ6. Module interface”h]”hŒ6. Module interface”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj*h²hh³hÊh´Mubj)�”}”(hŒŽThere are 17 call-backs which the md core can make to the cluster module. Understanding these can give a good overview of the whole process. ”h]”hÌ)�”}”(hŒ�There are 17 call-backs which the md core can make to the cluster module. Understanding these can give a good overview of the whole process.”h]”hŒ�There are 17 call-backs which the md core can make to the cluster module. Understanding these can give a good overview of the whole process.”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj;ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mhj*h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.1 join(nodes) and leave()”h]”hŒ6.1 join(nodes) and leave()”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjSh²hh³hÊh´M"ubj)�”}”(hŒñThese are called when an array is started with a clustered bitmap, and when the array is stopped. join() ensures the cluster is available and initializes the various resources. Only the first 'nodes' nodes in the cluster can use the array. ”h]”hÌ)�”}”(hŒðThese are called when an array is started with a clustered bitmap, and when the array is stopped. join() ensures the cluster is available and initializes the various resources. Only the first 'nodes' nodes in the cluster can use the array.”h]”hŒôThese are called when an array is started with a clustered bitmap, and when the array is stopped. join() ensures the cluster is available and initializes the various resources. Only the first ‘nodes’ nodes in the cluster can use the array.”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M$hjdubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´M$hjSh²hubeh}”(h]”Œjoin-nodes-and-leave”ah ]”h"]”Œ6.1 join(nodes) and leave()”ah$]”h&]”uh1hµhj*h²hh³hÊh´M"ubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.2 slot_number()”h]”hŒ6.2 slot_number()”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj„h²hh³hÊh´M*ubj)�”}”(hŒ[Reports the slot number advised by the cluster infrastructure. Range is from 0 to nodes-1. ”h]”hÌ)�”}”(hŒZReports the slot number advised by the cluster infrastructure. Range is from 0 to nodes-1.”h]”hŒZReports the slot number advised by the cluster infrastructure. Range is from 0 to nodes-1.”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M,hj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´M,hj„h²hubeh}”(h]”Œ slot-number”ah ]”h"]”Œ6.2 slot_number()”ah$]”h&]”uh1hµhj*h²hh³hÊh´M*ubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.3 resync_info_update()”h]”hŒ6.3 resync_info_update()”…”�”}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjµh²hh³hÊh´M0ubj)�”}”(hŒÐThis updates the resync range that is stored in the bitmap lock. The starting point is updated as the resync progresses. The end point is always the end of the array. It does *not* send a RESYNCING message. ”h]”hÌ)�”}”(hŒÏThis updates the resync range that is stored in the bitmap lock. The starting point is updated as the resync progresses. The end point is always the end of the array. It does *not* send a RESYNCING message.”h]”(hŒ°This updates the resync range that is stored in the bitmap lock. The starting point is updated as the resync progresses. The end point is always the end of the array. It does ”…”�”}”(hjÊh²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ*not*”h]”hŒnot”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÒhjÊubhŒ send a RESYNCING message.”…”�”}”(hjÊh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M2hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´M2hjµh²hubeh}”(h]”Œresync-info-update”ah ]”h"]”Œ6.3 resync_info_update()”ah$]”h&]”uh1hµhj*h²hh³hÊh´M0ubh¶)�”}”(hhh]”(h»)�”}”(hŒ#6.4 resync_start(), resync_finish()”h]”hŒ#6.4 resync_start(), resync_finish()”…”�”}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjúh²hh³hÊh´M8ubj)�”}”(hXNThese are called when resync/recovery/reshape starts or stops. They update the resyncing range in the bitmap lock and also send a RESYNCING message. resync_start reports the whole array as resyncing, resync_finish reports none of it. resync_finish() also sends a BITMAP_NEEDS_SYNC message which allows some other node to take over. ”h]”(hÌ)�”}”(hŒêThese are called when resync/recovery/reshape starts or stops. They update the resyncing range in the bitmap lock and also send a RESYNCING message. resync_start reports the whole array as resyncing, resync_finish reports none of it.”h]”hŒêThese are called when resync/recovery/reshape starts or stops. They update the resyncing range in the bitmap lock and also send a RESYNCING message. resync_start reports the whole array as resyncing, resync_finish reports none of it.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M:hj ubhÌ)�”}”(hŒaresync_finish() also sends a BITMAP_NEEDS_SYNC message which allows some other node to take over.”h]”hŒaresync_finish() also sends a BITMAP_NEEDS_SYNC message which allows some other node to take over.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M?hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´M:hjúh²hubeh}”(h]”Œresync-start-resync-finish”ah ]”h"]”Œ#6.4 resync_start(), resync_finish()”ah$]”h&]”uh1hµhj*h²hh³hÊh´M8ubh¶)�”}”(hhh]”(h»)�”}”(hŒO6.5 metadata_update_start(), metadata_update_finish(), metadata_update_cancel()”h]”hŒO6.5 metadata_update_start(), metadata_update_finish(), metadata_update_cancel()”…”�”}”(hj< h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj9 h²hh³hÊh´MCubj)�”}”(hXmetadata_update_start is used to get exclusive access to the metadata. If a change is still needed once that access is gained, metadata_update_finish() will send a METADATA_UPDATE message to all other nodes, otherwise metadata_update_cancel() can be used to release the lock. ”h]”hÌ)�”}”(hXmetadata_update_start is used to get exclusive access to the metadata. If a change is still needed once that access is gained, metadata_update_finish() will send a METADATA_UPDATE message to all other nodes, otherwise metadata_update_cancel() can be used to release the lock.”h]”hXmetadata_update_start is used to get exclusive access to the metadata. If a change is still needed once that access is gained, metadata_update_finish() will send a METADATA_UPDATE message to all other nodes, otherwise metadata_update_cancel() can be used to release the lock.”…”�”}”(hjN h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MEhjJ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´MEhj9 h²hubeh}”(h]”ŒCmetadata-update-start-metadata-update-finish-metadata-update-cancel”ah ]”h"]”ŒO6.5 metadata_update_start(), metadata_update_finish(), metadata_update_cancel()”ah$]”h&]”uh1hµhj*h²hh³hÊh´MCubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.6 area_resyncing()”h]”hŒ6.6 area_resyncing()”…”�”}”(hjm h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjj h²hh³hÊh´MLubj)�”}”(hX²This combines two elements of functionality. Firstly, it will check if any node is currently resyncing anything in a given range of sectors. If any resync is found, then the caller will avoid writing or read-balancing in that range. Secondly, while node recovery is happening it reports that all areas are resyncing for READ requests. This avoids races between the cluster-filesystem and the cluster-RAID handling a node failure. ”h]”(hÌ)�”}”(hŒ,This combines two elements of functionality.”h]”hŒ,This combines two elements of functionality.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MNhj{ ubhÌ)�”}”(hŒ¼Firstly, it will check if any node is currently resyncing anything in a given range of sectors. If any resync is found, then the caller will avoid writing or read-balancing in that range.”h]”hŒ¼Firstly, it will check if any node is currently resyncing anything in a given range of sectors. If any resync is found, then the caller will avoid writing or read-balancing in that range.”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MPhj{ ubhÌ)�”}”(hŒÅSecondly, while node recovery is happening it reports that all areas are resyncing for READ requests. This avoids races between the cluster-filesystem and the cluster-RAID handling a node failure.”h]”hŒÅSecondly, while node recovery is happening it reports that all areas are resyncing for READ requests. This avoids races between the cluster-filesystem and the cluster-RAID handling a node failure.”…”�”}”(hj› h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MUhj{ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´MNhjj h²hubeh}”(h]”Œarea-resyncing”ah ]”h"]”Œ6.6 area_resyncing()”ah$]”h&]”uh1hµhj*h²hh³hÊh´MLubh¶)�”}”(hhh]”(h»)�”}”(hŒ?6.7 add_new_disk_start(), add_new_disk_finish(), new_disk_ack()”h]”hŒ?6.7 add_new_disk_start(), add_new_disk_finish(), new_disk_ack()”…”�”}”(hjº h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj· h²hh³hÊh´M[ubj)�”}”(hXwThese are used to manage the new-disk protocol described above. When a new device is added, add_new_disk_start() is called before it is bound to the array and, if that succeeds, add_new_disk_finish() is called the device is fully added. When a device is added in acknowledgement to a previous request, or when the device is declared "unavailable", new_disk_ack() is called. ”h]”(hÌ)�”}”(hŒìThese are used to manage the new-disk protocol described above. When a new device is added, add_new_disk_start() is called before it is bound to the array and, if that succeeds, add_new_disk_finish() is called the device is fully added.”h]”hŒìThese are used to manage the new-disk protocol described above. When a new device is added, add_new_disk_start() is called before it is bound to the array and, if that succeeds, add_new_disk_finish() is called the device is fully added.”…”�”}”(hjÌ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M]hjÈ ubhÌ)�”}”(hŒˆWhen a device is added in acknowledgement to a previous request, or when the device is declared "unavailable", new_disk_ack() is called.”h]”hŒŒWhen a device is added in acknowledgement to a previous request, or when the device is declared “unavailableâ€�, new_disk_ack() is called.”…”�”}”(hjÚ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´MbhjÈ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´M]hj· h²hubeh}”(h]”Œ3add-new-disk-start-add-new-disk-finish-new-disk-ack”ah ]”h"]”Œ?6.7 add_new_disk_start(), add_new_disk_finish(), new_disk_ack()”ah$]”h&]”uh1hµhj*h²hh³hÊh´M[ubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.8 remove_disk()”h]”hŒ6.8 remove_disk()”…”�”}”(hjù h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjö h²hh³hÊh´Mgubj)�”}”(hŒThis is called when a spare or failed device is removed from the array. It causes a REMOVE message to be send to other nodes. ”h]”hÌ)�”}”(hŒ~This is called when a spare or failed device is removed from the array. It causes a REMOVE message to be send to other nodes.”h]”hŒ~This is called when a spare or failed device is removed from the array. It causes a REMOVE message to be send to other nodes.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mihj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mihjö h²hubeh}”(h]”Œ remove-disk”ah ]”h"]”Œ6.8 remove_disk()”ah$]”h&]”uh1hµhj*h²hh³hÊh´Mgubh¶)�”}”(hhh]”(h»)�”}”(hŒ6.9 gather_bitmaps()”h]”hŒ6.9 gather_bitmaps()”…”�”}”(hj* h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj' h²hh³hÊh´Mmubj)�”}”(hŒ©This sends a RE_ADD message to all other nodes and then gathers bitmap information from all bitmaps. This combined bitmap is then used to recovery the re-added device. ”h]”hÌ)�”}”(hŒ¨This sends a RE_ADD message to all other nodes and then gathers bitmap information from all bitmaps. This combined bitmap is then used to recovery the re-added device.”h]”hŒ¨This sends a RE_ADD message to all other nodes and then gathers bitmap information from all bitmaps. This combined bitmap is then used to recovery the re-added device.”…”�”}”(hj< h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mohj8 ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´Mohj' h²hubeh}”(h]”Œgather-bitmaps”ah ]”h"]”Œ6.9 gather_bitmaps()”ah$]”h&]”uh1hµhj*h²hh³hÊh´Mmubh¶)�”}”(hhh]”(h»)�”}”(hŒ06.10 lock_all_bitmaps() and unlock_all_bitmaps()”h]”hŒ06.10 lock_all_bitmaps() and unlock_all_bitmaps()”…”�”}”(hj[ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjX h²hh³hÊh´Mtubj)�”}”(hXThese are called when change bitmap to none. If a node plans to clear the cluster raid's bitmap, it need to make sure no other nodes are using the raid which is achieved by lock all bitmap locks within the cluster, and also those locks are unlocked accordingly. ”h]”hÌ)�”}”(hXThese are called when change bitmap to none. If a node plans to clear the cluster raid's bitmap, it need to make sure no other nodes are using the raid which is achieved by lock all bitmap locks within the cluster, and also those locks are unlocked accordingly.”h]”hXThese are called when change bitmap to none. If a node plans to clear the cluster raid’s bitmap, it need to make sure no other nodes are using the raid which is achieved by lock all bitmap locks within the cluster, and also those locks are unlocked accordingly.”…”�”}”(hjm h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mvhji ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´MvhjX h²hubeh}”(h]”Œ'lock-all-bitmaps-and-unlock-all-bitmaps”ah ]”h"]”Œ06.10 lock_all_bitmaps() and unlock_all_bitmaps()”ah$]”h&]”uh1hµhj*h²hh³hÊh´Mtubeh}”(h]”Œmodule-interface”ah ]”h"]”Œ6. module interface”ah$]”h&]”uh1hµhh·h²hh³hÊh´Mubh¶)�”}”(hhh]”(h»)�”}”(hŒ7. Unsupported features”h]”hŒ7. Unsupported features”…”�”}”(hj” h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj‘ h²hh³hÊh´M}ubhÌ)�”}”(hŒ?There are somethings which are not supported by cluster MD yet.”h]”hŒ?There are somethings which are not supported by cluster MD yet.”…”�”}”(hj¢ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Mhj‘ h²hubj!)�”}”(hhh]”j&)�”}”(hŒchange array_sectors.”h]”hÌ)�”}”(hjµ h]”hŒchange array_sectors.”…”�”}”(hj· h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´M�hj³ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j%hj° h²hh³hÊh´Nubah}”(h]”h ]”h"]”h$]”h&]”jsjtuh1j h³hÊh´M�hj‘ h²hubeh}”(h]”Œunsupported-features”ah ]”h"]”Œ7. unsupported features”ah$]”h&]”uh1hµhh·h²hh³hÊh´M}ubeh}”(h]”Œ md-cluster”ah ]”h"]”Œ md cluster”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jÝ jÚ jŽj‹jVjSjìjéjjjNjKjªj§jÊjÇjÙjÖj jj;j8jÂj¿j¢jŸj$j!jUjRjšj—jÅjÂj½jºj'j$jjjŽ j‹ j�j~j²j¯j÷jôj6 j3 jg jd j´ j± jó jð j$ j! jU jR j† jƒ jÕ jÒ uŒ nametypes”}”(jÝ ‰jމjV‰jì‰j‰jN‰jª‰jʉjÙ‰j ‰j;‰j‰j¢‰j$‰jU‰jš‰jʼnj½‰j'‰j‰jŽ ‰j�‰j²‰j÷‰j6 ‰jg ‰j´ ‰jó ‰j$ ‰jU ‰j† ‰jÕ ‰uh}”(jÚ h·j‹hÛjSj‘jéj°jjïjKj j§jYjÇj‚jÖj«jjÜj8j j¿j>jŸjÍj!jöjRj'j—jXjÂj­jºj¾j$jÈjjñj‹ j*j~jSj¯j„jôjµj3 jújd j9 j± jj jð j· j! jö jR j' jƒ jX jÒ j‘ uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.