* [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down
@ 2016-03-02 7:56 Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 1/6] ocfs2: o2hb: add negotiate timer Junxiao Bi
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
Hi Mark,
This serial 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
---
Changes from V1:
- code style fix.
Junxiao Bi (6):
ocfs2: o2hb: add negotiate timer
ocfs2: o2hb: add NEGO_TIMEOUT message
ocfs2: o2hb: add NEGOTIATE_APPROVE message
ocfs2: o2hb: add some user/debug log
ocfs2: o2hb: don't negotiate if last hb fail
ocfs2: o2hb: fix hb hung time
fs/ocfs2/cluster/heartbeat.c | 180 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 174 insertions(+), 6 deletions(-)
Thanks,
Junxiao.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 1/6] ocfs2: o2hb: add negotiate timer
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 2/6] ocfs2: o2hb: add NEGO_TIMEOUT message Junxiao Bi
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
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.
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 51 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index a76b9ea7722e..59982b34b7a5 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -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. */
@@ -320,7 +324,7 @@ static void o2hb_write_timeout(struct work_struct *work)
o2quo_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)
@@ -338,11 +342,49 @@ static void o2hb_arm_write_timeout(struct o2hb_region *reg)
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)
@@ -1033,7 +1075,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
/* 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:
@@ -1115,7 +1157,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++)
@@ -1764,6 +1806,7 @@ static ssize_t o2hb_region_dev_store(struct config_item *item,
}
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
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 2/6] ocfs2: o2hb: add NEGO_TIMEOUT message
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 1/6] ocfs2: o2hb: add negotiate timer Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 3/6] ocfs2: o2hb: add NEGOTIATE_APPROVE message Junxiao Bi
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
This message is sent to master node when non-master nodes's negotiate
timer expired. Master node records these nodes in a bitmap which is used
to do write timeout timer re-queue decision.
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 66 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 59982b34b7a5..39547d7090d3 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -280,6 +280,10 @@ struct o2hb_region {
* being checked because we temporarily have to zero out the
* crc field. */
struct o2hb_disk_heartbeat_block *hr_tmp_block;
+
+ /* Message key for negotiate timeout message. */
+ unsigned int hr_key;
+ struct list_head hr_handler_list;
};
struct o2hb_bio_wait_ctxt {
@@ -288,6 +292,14 @@ struct o2hb_bio_wait_ctxt {
int wc_error;
};
+enum {
+ O2HB_NEGO_TIMEOUT_MSG = 1,
+};
+
+struct o2hb_nego_msg {
+ u8 node_num;
+};
+
static void o2hb_write_timeout(struct work_struct *work)
{
int failed, quorum;
@@ -356,6 +368,24 @@ static void o2hb_disarm_timeout(struct o2hb_region *reg)
cancel_delayed_work_sync(®->hr_nego_timeout_work);
}
+static int o2hb_send_nego_msg(int key, int type, u8 target)
+{
+ struct o2hb_nego_msg msg;
+ int status, ret;
+
+ msg.node_num = o2nm_this_node();
+again:
+ ret = o2net_send_message(type, key, &msg, sizeof(msg),
+ target, &status);
+
+ if (ret == -EAGAIN || ret == -ENOMEM) {
+ msleep(100);
+ goto again;
+ }
+
+ return ret;
+}
+
static void o2hb_nego_timeout(struct work_struct *work)
{
unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
@@ -383,8 +413,24 @@ static void o2hb_nego_timeout(struct work_struct *work)
/* approve negotiate timeout request. */
} else {
/* negotiate timeout with master node. */
+ o2hb_send_nego_msg(reg->hr_key, O2HB_NEGO_TIMEOUT_MSG,
+ master_node);
}
+}
+
+static int o2hb_nego_timeout_handler(struct o2net_msg *msg, u32 len, void *data,
+ void **ret_data)
+{
+ struct o2hb_region *reg = data;
+ struct o2hb_nego_msg *nego_msg;
+ nego_msg = (struct o2hb_nego_msg *)msg->buf;
+ if (nego_msg->node_num < O2NM_MAX_NODES)
+ set_bit(nego_msg->node_num, reg->hr_nego_node_bitmap);
+ else
+ mlog(ML_ERROR, "got nego timeout message from bad node.\n");
+
+ return 0;
}
static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)
@@ -1494,6 +1540,7 @@ static void o2hb_region_release(struct config_item *item)
list_del(®->hr_all_item);
spin_unlock(&o2hb_live_lock);
+ o2net_unregister_handler_list(®->hr_handler_list);
kfree(reg);
}
@@ -2040,13 +2087,30 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
config_item_init_type_name(®->hr_item, name, &o2hb_region_type);
+ /* this is the same way to generate msg key as dlm, for local heartbeat,
+ * name is also the same, so make initial crc value different to avoid
+ * message key conflict.
+ */
+ reg->hr_key = crc32_le(reg->hr_region_num + O2NM_MAX_REGIONS,
+ name, strlen(name));
+ INIT_LIST_HEAD(®->hr_handler_list);
+ ret = o2net_register_handler(O2HB_NEGO_TIMEOUT_MSG, reg->hr_key,
+ sizeof(struct o2hb_nego_msg),
+ o2hb_nego_timeout_handler,
+ reg, NULL, ®->hr_handler_list);
+ if (ret)
+ goto free;
+
ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
if (ret) {
config_item_put(®->hr_item);
- goto free;
+ goto unregister_handler;
}
return ®->hr_item;
+
+unregister_handler:
+ o2net_unregister_handler_list(®->hr_handler_list);
free:
kfree(reg);
return ERR_PTR(ret);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 3/6] ocfs2: o2hb: add NEGOTIATE_APPROVE message
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 1/6] ocfs2: o2hb: add negotiate timer Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 2/6] ocfs2: o2hb: add NEGO_TIMEOUT message Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 4/6] ocfs2: o2hb: add some user/debug log Junxiao Bi
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
This message is used to re-queue write timeout timer and negotiate timer
when all nodes suffer a write hung to storage, this makes node not fence
self if storage down.
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 39547d7090d3..9ac01dcd1feb 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -294,6 +294,7 @@ struct o2hb_bio_wait_ctxt {
enum {
O2HB_NEGO_TIMEOUT_MSG = 1,
+ O2HB_NEGO_APPROVE_MSG = 2,
};
struct o2hb_nego_msg {
@@ -389,7 +390,7 @@ again:
static void o2hb_nego_timeout(struct work_struct *work)
{
unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
- int master_node;
+ int master_node, i;
struct o2hb_region *reg;
reg = container_of(work, struct o2hb_region, hr_nego_timeout_work.work);
@@ -411,6 +412,17 @@ static void o2hb_nego_timeout(struct work_struct *work)
}
/* approve negotiate timeout request. */
+ o2hb_arm_timeout(reg);
+
+ i = -1;
+ while ((i = find_next_bit(live_node_bitmap,
+ O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
+ if (i == master_node)
+ continue;
+
+ o2hb_send_nego_msg(reg->hr_key,
+ O2HB_NEGO_APPROVE_MSG, i);
+ }
} else {
/* negotiate timeout with master node. */
o2hb_send_nego_msg(reg->hr_key, O2HB_NEGO_TIMEOUT_MSG,
@@ -433,6 +445,13 @@ static int o2hb_nego_timeout_handler(struct o2net_msg *msg, u32 len, void *data,
return 0;
}
+static int o2hb_nego_approve_handler(struct o2net_msg *msg, u32 len, void *data,
+ void **ret_data)
+{
+ o2hb_arm_timeout(data);
+ return 0;
+}
+
static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)
{
atomic_set(&wc->wc_num_reqs, 1);
@@ -2101,6 +2120,13 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
if (ret)
goto free;
+ ret = o2net_register_handler(O2HB_NEGO_APPROVE_MSG, reg->hr_key,
+ sizeof(struct o2hb_nego_msg),
+ o2hb_nego_approve_handler,
+ reg, NULL, ®->hr_handler_list);
+ if (ret)
+ goto unregister_handler;
+
ret = o2hb_debug_region_init(reg, o2hb_debug_dir);
if (ret) {
config_item_put(®->hr_item);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 4/6] ocfs2: o2hb: add some user/debug log
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
` (2 preceding siblings ...)
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 3/6] ocfs2: o2hb: add NEGOTIATE_APPROVE message Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 5/6] ocfs2: o2hb: don't negotiate if last hb fail Junxiao Bi
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 9ac01dcd1feb..9f4a02ed85fd 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -292,6 +292,8 @@ struct o2hb_bio_wait_ctxt {
int wc_error;
};
+#define O2HB_NEGO_TIMEOUT_MS (O2HB_MAX_WRITE_TIMEOUT_MS/2)
+
enum {
O2HB_NEGO_TIMEOUT_MSG = 1,
O2HB_NEGO_APPROVE_MSG = 2,
@@ -359,7 +361,7 @@ static void o2hb_arm_timeout(struct o2hb_region *reg)
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);
+ msecs_to_jiffies(O2HB_NEGO_TIMEOUT_MS));
memset(reg->hr_nego_node_bitmap, 0, sizeof(reg->hr_nego_node_bitmap));
}
@@ -390,7 +392,7 @@ again:
static void o2hb_nego_timeout(struct work_struct *work)
{
unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
- int master_node, i;
+ int master_node, i, ret;
struct o2hb_region *reg;
reg = container_of(work, struct o2hb_region, hr_nego_timeout_work.work);
@@ -399,7 +401,12 @@ static void o2hb_nego_timeout(struct work_struct *work)
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 (!test_bit(master_node, reg->hr_nego_node_bitmap)) {
+ printk(KERN_NOTICE "o2hb: node %d hb write hung for %ds on region %s (%s).\n",
+ o2nm_this_node(), O2HB_NEGO_TIMEOUT_MS/1000,
+ config_item_name(®->hr_item), reg->hr_dev_name);
+ 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
@@ -411,6 +418,8 @@ static void o2hb_nego_timeout(struct work_struct *work)
return;
}
+ printk(KERN_NOTICE "o2hb: all nodes hb write hung, maybe region %s (%s) is down.\n",
+ config_item_name(®->hr_item), reg->hr_dev_name);
/* approve negotiate timeout request. */
o2hb_arm_timeout(reg);
@@ -420,13 +429,23 @@ static void o2hb_nego_timeout(struct work_struct *work)
if (i == master_node)
continue;
- o2hb_send_nego_msg(reg->hr_key,
+ mlog(ML_HEARTBEAT, "send NEGO_APPROVE msg to node %d\n", i);
+ ret = o2hb_send_nego_msg(reg->hr_key,
O2HB_NEGO_APPROVE_MSG, i);
+ if (ret)
+ mlog(ML_ERROR, "send NEGO_APPROVE msg to node %d fail %d\n",
+ i, ret);
}
} else {
/* negotiate timeout with master node. */
- o2hb_send_nego_msg(reg->hr_key, O2HB_NEGO_TIMEOUT_MSG,
- master_node);
+ printk(KERN_NOTICE "o2hb: node %d hb write hung for %ds on region %s (%s), negotiate timeout with node %d.\n",
+ o2nm_this_node(), O2HB_NEGO_TIMEOUT_MS/1000, config_item_name(®->hr_item),
+ reg->hr_dev_name, master_node);
+ ret = o2hb_send_nego_msg(reg->hr_key, O2HB_NEGO_TIMEOUT_MSG,
+ master_node);
+ if (ret)
+ mlog(ML_ERROR, "send NEGO_TIMEOUT msg to node %d fail %d\n",
+ master_node, ret);
}
}
@@ -437,6 +456,8 @@ static int o2hb_nego_timeout_handler(struct o2net_msg *msg, u32 len, void *data,
struct o2hb_nego_msg *nego_msg;
nego_msg = (struct o2hb_nego_msg *)msg->buf;
+ printk(KERN_NOTICE "o2hb: receive negotiate timeout message from node %d on region %s (%s).\n",
+ nego_msg->node_num, config_item_name(®->hr_item), reg->hr_dev_name);
if (nego_msg->node_num < O2NM_MAX_NODES)
set_bit(nego_msg->node_num, reg->hr_nego_node_bitmap);
else
@@ -448,7 +469,11 @@ static int o2hb_nego_timeout_handler(struct o2net_msg *msg, u32 len, void *data,
static int o2hb_nego_approve_handler(struct o2net_msg *msg, u32 len, void *data,
void **ret_data)
{
- o2hb_arm_timeout(data);
+ struct o2hb_region *reg = data;
+
+ printk(KERN_NOTICE "o2hb: negotiate timeout approved by master node on region %s (%s).\n",
+ config_item_name(®->hr_item), reg->hr_dev_name);
+ o2hb_arm_timeout(reg);
return 0;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 5/6] ocfs2: o2hb: don't negotiate if last hb fail
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
` (3 preceding siblings ...)
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 4/6] ocfs2: o2hb: add some user/debug log Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 6/6] ocfs2: o2hb: fix hb hung time Junxiao Bi
2016-05-23 21:50 ` [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Andrew Morton
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
Sometimes io error is returned when storage is down for a while. Like for
iscsi device, stroage is made offline when session timeout, and this will
make all io return -EIO. For this case, nodes shouldn't do negotiate
timeout but should fence self. So let nodes fence self when
o2hb_do_disk_heartbeat return an error, this is the same behavior with
o2hb without negotiate timer.
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 9f4a02ed85fd..c040fc3dd605 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -284,6 +284,9 @@ struct o2hb_region {
/* Message key for negotiate timeout message. */
unsigned int hr_key;
struct list_head hr_handler_list;
+
+ /* last hb status, 0 for success, other value for error. */
+ int hr_last_hb_status;
};
struct o2hb_bio_wait_ctxt {
@@ -396,6 +399,12 @@ static void o2hb_nego_timeout(struct work_struct *work)
struct o2hb_region *reg;
reg = container_of(work, struct o2hb_region, hr_nego_timeout_work.work);
+ /* don't negotiate timeout if last hb failed since it is very
+ * possible io failed. Should let write timeout fence self.
+ */
+ if (reg->hr_last_hb_status)
+ return;
+
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);
@@ -1229,6 +1238,7 @@ static int o2hb_thread(void *data)
before_hb = ktime_get_real();
ret = o2hb_do_disk_heartbeat(reg);
+ reg->hr_last_hb_status = ret;
after_hb = ktime_get_real();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] [PATCH V2 6/6] ocfs2: o2hb: fix hb hung time
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
` (4 preceding siblings ...)
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 5/6] ocfs2: o2hb: don't negotiate if last hb fail Junxiao Bi
@ 2016-03-02 7:56 ` Junxiao Bi
2016-05-23 21:50 ` [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Andrew Morton
6 siblings, 0 replies; 9+ messages in thread
From: Junxiao Bi @ 2016-03-02 7:56 UTC (permalink / raw)
To: ocfs2-devel
hr_last_timeout_start should be set as the last time where hb is still OK.
When hb write timeout, hung time will be (jiffies -
hr_last_timeout_start).
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Ryan Ding <ryan.ding@oracle.com>
Cc: Gang He <ghe@suse.com>
Cc: rwxybh <rwxybh@126.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/cluster/heartbeat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index c040fc3dd605..8ec85cac894e 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -357,7 +357,6 @@ static void o2hb_arm_timeout(struct o2hb_region *reg)
spin_unlock(&o2hb_live_lock);
}
cancel_delayed_work(®->hr_write_timeout_work);
- reg->hr_last_timeout_start = jiffies;
schedule_delayed_work(®->hr_write_timeout_work,
msecs_to_jiffies(O2HB_MAX_WRITE_TIMEOUT_MS));
@@ -1175,6 +1174,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
if (own_slot_ok) {
o2hb_set_quorum_device(reg);
o2hb_arm_timeout(reg);
+ reg->hr_last_timeout_start = jiffies;
}
bail:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
` (5 preceding siblings ...)
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 6/6] ocfs2: o2hb: fix hb hung time Junxiao Bi
@ 2016-05-23 21:50 ` Andrew Morton
2016-05-23 23:40 ` Mark Fasheh
6 siblings, 1 reply; 9+ messages in thread
From: Andrew Morton @ 2016-05-23 21:50 UTC (permalink / raw)
To: ocfs2-devel
On Wed, 2 Mar 2016 15:56:06 +0800 Junxiao Bi <junxiao.bi@oracle.com> wrote:
>
> Hi Mark,
>
> This serial 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
Guys, can we please do a quick triple-check on this series? I'd like
to unload them this week. Thanks.
I'll send out the current version in a few secs.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down
2016-05-23 21:50 ` [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Andrew Morton
@ 2016-05-23 23:40 ` Mark Fasheh
0 siblings, 0 replies; 9+ messages in thread
From: Mark Fasheh @ 2016-05-23 23:40 UTC (permalink / raw)
To: ocfs2-devel
On Mon, May 23, 2016 at 02:50:10PM -0700, Andrew Morton wrote:
> On Wed, 2 Mar 2016 15:56:06 +0800 Junxiao Bi <junxiao.bi@oracle.com> wrote:
>
> >
> > Hi Mark,
> >
> > This serial 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
>
> Guys, can we please do a quick triple-check on this series? I'd like
> to unload them this week. Thanks.
>
> I'll send out the current version in a few secs.
I'll go through them and give my review.
Thanks,
--Mark
--
Mark Fasheh
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-05-23 23:40 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-02 7:56 [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 1/6] ocfs2: o2hb: add negotiate timer Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 2/6] ocfs2: o2hb: add NEGO_TIMEOUT message Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 3/6] ocfs2: o2hb: add NEGOTIATE_APPROVE message Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 4/6] ocfs2: o2hb: add some user/debug log Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 5/6] ocfs2: o2hb: don't negotiate if last hb fail Junxiao Bi
2016-03-02 7:56 ` [Ocfs2-devel] [PATCH V2 6/6] ocfs2: o2hb: fix hb hung time Junxiao Bi
2016-05-23 21:50 ` [Ocfs2-devel] ocfs2: o2hb: not fence self if storage down Andrew Morton
2016-05-23 23:40 ` Mark Fasheh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).