ocfs2: o2hb: add negotiate timer
PATCH 1/6 ocfs2: o2hb: add negotiate timer
From: Junxiao Bi <[email protected]>
Subject: ocfs2: o2hb: add negotiate timer
This series of patches is to fix the issue that when storage down, all nodes will fence self due to write timeout.
With this patch set, all nodes will keep going until storage back online, except if the following issue happens, then all nodes will do as before to fence self.
1. io error got
2. network between nodes down
3. nodes panic
This patch (of 6):
When storage down, all nodes will fence self due to write timeout. The negotiate timer is designed to avoid this, with it node will wait until storage up again.
Negotiate timer working in the following way:
1. The timer expires before write timeout timer, its timeout is half of write timeout now. It is re-queued along with write timeout timer. If expires, it will send NEGO_TIMEOUT message to master node(node with lowest node number). This message does nothing but marks a bit in a bitmap recording which nodes are negotiating timeout on master node.
2. If storage down, nodes will send this message to master node, then when master node finds its bitmap including all online nodes, it sends NEGO_APPROVL message to all nodes one by one, this message will re-queue write timeout timer and negotiate timer. For any node doesn't receive this message or meets some issue when handling this message, it will be fenced. If storage up at any time, o2hb_thread will run and re-queue all the timer, nothing will be affected by these two steps.
---
fs/ocfs2/cluster/heartbeat.c | 51 ++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-)
fs/ocfs2/cluster/heartbeat.c renamed from fs/ocfs2/cluster/heartbeat.c~ocfs2-o2hb-add-negotiate-timer +47 -4
@@ -272,6 +272,10 @@ struct o2hb_region {struct delayed_work hr_write_timeout_work;unsigned long hr_last_timeout_start; +/* negotiate timer, used to negotiate extending hb timeout. */ +struct delayed_work hr_nego_timeout_work; +unsigned long hr_nego_node_bitmap[BITS_TO_LONGS (O2NM_MAX_NODES )]; +/* Used during o2hb_check_slot to hold a copy of the block * being checked because we temporarily have to zero out the * crc field. */
@@ -319,7 +323,7 @@ static void o2hb_write_timeout(struct woo2quo_disk_timeout (); } -static void o2hb_arm_write_timeout (struct o2hb_region *reg) +static void o2hb_arm_timeout (struct o2hb_region *reg) {/* Arm writeout only after thread reaches steady state */ if (atomic_read (®->hr_steady_iterations) !=0 )
@@ -337,11 +341,49 @@ static void o2hb_arm_write_timeout(struc reg->hr_last_timeout_start = jiffies;schedule_delayed_work (®->hr_write_timeout_work,msecs_to_jiffies (O2HB_MAX_WRITE_TIMEOUT_MS )); + +cancel_delayed_work (®->hr_nego_timeout_work); +/* negotiate timeout must be less than write timeout. */ +schedule_delayed_work (®->hr_nego_timeout_work, +msecs_to_jiffies (O2HB_MAX_WRITE_TIMEOUT_MS )/2 ); +memset (reg->hr_nego_node_bitmap,0 ,sizeof (reg->hr_nego_node_bitmap)); } -static void o2hb_disarm_write_timeout (struct o2hb_region *reg) +static void o2hb_disarm_timeout (struct o2hb_region *reg) {cancel_delayed_work_sync (®->hr_write_timeout_work); +cancel_delayed_work_sync (®->hr_nego_timeout_work); +} + +static void o2hb_nego_timeout (struct work_struct *work) +{ +unsigned long live_node_bitmap[BITS_TO_LONGS (O2NM_MAX_NODES )]; +int master_node; +struct o2hb_region *reg; + + reg = container_of(work, struct o2hb_region, hr_nego_timeout_work.work); +o2hb_fill_node_map (live_node_bitmap,sizeof (live_node_bitmap)); +/* lowest node as master node to make negotiate decision. */ + master_node =find_next_bit (live_node_bitmap,O2NM_MAX_NODES ,0 ); + +if (master_node ==o2nm_this_node ()) { +set_bit (master_node, reg->hr_nego_node_bitmap); +if (memcmp (reg->hr_nego_node_bitmap, live_node_bitmap, +sizeof (reg->hr_nego_node_bitmap))) { +/* check negotiate bitmap every second to do timeout +* approve decision. +*/ +schedule_delayed_work (®->hr_nego_timeout_work, +msecs_to_jiffies (1000 )); + +return ; + } + +/* approve negotiate timeout request. */ + }else { +/* negotiate timeout with master node. */ + } + }static inline void o2hb_bio_wait_init (struct o2hb_bio_wait_ctxt *wc)
@@ -1032,7 +1074,7 @@ static int o2hb_do_disk_heartbeat(struct/* Skip disarming the timeout if own slot has stale/bad data */ if (own_slot_ok) {o2hb_set_quorum_device (reg); -o2hb_arm_write_timeout (reg); +o2hb_arm_timeout (reg); } bail:
@@ -1114,7 +1156,7 @@ static int o2hb_thread(void *data) } } -o2hb_disarm_write_timeout (reg); +o2hb_disarm_timeout (reg);/* unclean stop is only used in very bad situation */ for (i =0 ; !reg->hr_unclean_stop && i < reg->hr_blocks; i++)
@@ -1762,6 +1804,7 @@ static ssize_t o2hb_region_dev_store(str }INIT_DELAYED_WORK (®->hr_write_timeout_work, o2hb_write_timeout); +INIT_DELAYED_WORK (®->hr_nego_timeout_work, o2hb_nego_timeout);/* * A node is considered live after it has beat LIVE_THRESHOLD
_
PATCH 1/6 ocfs2: o2hb: add negotiate timer
Quoted 2 lines · Andrew Morton
From: Junxiao Bi <[email protected]>
Subject: ocfs2: o2hb: add negotiate timer
Thank you for the well written patch description by the way.
Quoted 17 lines
This series of patches is to fix the issue that when storage down, all nodes will fence self due to write timeout.
With this patch set, all nodes will keep going until storage back online, except if the following issue happens, then all nodes will do as before to fence self.
1. io error got
2. network between nodes down
3. nodes panicThis patch (of 6):
When storage down, all nodes will fence self due to write timeout. The negotiate timer is designed to avoid this, with it node will wait until storage up again.
Quoted 7 lines
Negotiate timer working in the following way:
1. The timer expires before write timeout timer, its timeout is half of write timeout now. It is re-queued along with write timeout timer. If expires, it will send
NEGO_TIMEOUTmessage to master node(node with lowest node number). This message does nothing but marks a bit in a bitmap recording which nodes are negotiating timeout on master node.
I went through the patch series, and generally feel that the code is well written and straight forward. I have two issues regarding how this operates. Otherwise, I like the general direction this is taking.
The first is easy - we're updating the o2cb network protocol and need to bump the protocol version otherwise a node that doesn't speak these new messages could mount and even be selected as the 'master' without actually being able to participate in this scheme.
My other concern is whether the notion of 'lowest node' can change if one comes online while the cluster is negotiating this timeout. Obviously in the case where all the disks are unplugged this couldn't happen because a new node couldn't begin to heartbeat.
What about a situation where only some nodes are negotiating this timeout? On the ones which have no disk access, lowest node number still won't change since they can't read the new heartbeats. On those with stable access though, can't this value change? How does that effect this algorithm?
Thanks,
--Mark
--
Mark Fasheh
PATCH 1/6 ocfs2: o2hb: add negotiate timer
Quoted 37 lines · Mark Fasheh
Quoted 2 lines · Andrew Morton
From: Junxiao Bi <[email protected]>
Subject: ocfs2: o2hb: add negotiate timerThank you for the well written patch description by the way.
Quoted 17 lines
This series of patches is to fix the issue that when storage down, all nodes will fence self due to write timeout.
With this patch set, all nodes will keep going until storage back online, except if the following issue happens, then all nodes will do as before to fence self.
1. io error got
2. network between nodes down
3. nodes panicThis patch (of 6):
When storage down, all nodes will fence self due to write timeout. The negotiate timer is designed to avoid this, with it node will wait until storage up again.
Quoted 7 lines
Negotiate timer working in the following way:
1. The timer expires before write timeout timer, its timeout is half of write timeout now. It is re-queued along with write timeout timer. If expires, it will send
NEGO_TIMEOUTmessage to master node(node with lowest node number). This message does nothing but marks a bit in a bitmap recording which nodes are negotiating timeout on master node.I went through the patch series, and generally feel that the code is well written and straight forward. I have two issues regarding how this operates. Otherwise, I like the general direction this is taking.
Quoted 4 lines
The first is easy - we're updating the o2cb network protocol and need to bump the protocol version otherwise a node that doesn't speak these new messages could mount and even be selected as the 'master' without actually being able to participate in this scheme.
Right. Will add this.
Quoted 7 lines
My other concern is whether the notion of 'lowest node' can change if one comes online while the cluster is negotiating this timeout. Obviously in the case where all the disks are unplugged this couldn't happen because a new node couldn't begin to heartbeat.
Yes.
Quoted 6 lines
What about a situation where only some nodes are negotiating this timeout? On the ones which have no disk access, lowest node number still won't change since they can't read the new heartbeats. On those with stable access though, can't this value change? How does that effect this algorithm?
The lowest node can change for good nodes, but didn't affect the algorithm. Because only bad nodes sent NEGO_TIMEOUT message while good nodes not, so the original lowest node will never receive NEGO_TIMEOUT messages from all nodes, then it will not approve the timeout, at last bad nodes will fence self and good nodes keep alive.
Thanks,
Junxiao.
Quoted 7 lines
Thanks,
--Mark--
Mark Fasheh
PATCH 1/6 ocfs2: o2hb: add negotiate timer
Quoted 11 lines · Junxiao Bi
Quoted 9 lines · Mark Fasheh
I went through the patch series, and generally feel that the code is well written and straight forward. I have two issues regarding how this operates. Otherwise, I like the general direction this is taking.
The first is easy - we're updating the o2cb network protocol and need to bump the protocol version otherwise a node that doesn't speak these new messages could mount and even be selected as the 'master' without actually being able to participate in this scheme.
Right. Will add this.
Great, thanks!
Quoted 14 lines
Quoted 7 lines
My other concern is whether the notion of 'lowest node' can change if one comes online while the cluster is negotiating this timeout. Obviously in the case where all the disks are unplugged this couldn't happen because a new node couldn't begin to heartbeat.
Yes.
Quoted 6 lines
What about a situation where only some nodes are negotiating this timeout? On the ones which have no disk access, lowest node number still won't change since they can't read the new heartbeats. On those with stable access though, can't this value change? How does that effect this algorithm?
Quoted 5 lines
The lowest node can change for good nodes, but didn't affect the algorithm. Because only bad nodes sent
NEGO_TIMEOUTmessage while good nodes not, so the original lowest node will never receiveNEGO_TIMEOUTmessages from all nodes, then it will not approve the timeout, at last bad nodes will fence self and good nodes keep alive.
Ok, in that case you can put:
on the patches I've seen (this series). We don't want it to go upstream until your patch to bump the protocol version though so please cc me on that patch and the others.
Thanks,
--Mark
--
Mark Fasheh