[Ocfs2-commits] khackel commits r2800 - branches/ocfs2-1.2-cert/patches
svn-commits@oss.oracle.com
svn-commits at oss.oracle.com
Thu Mar 30 18:17:31 CST 2006
Author: khackel
Signed-off-by: smushran
Date: 2006-03-30 18:17:30 -0600 (Thu, 30 Mar 2006)
New Revision: 2800
Added:
branches/ocfs2-1.2-cert/patches/fix-death-during-recovery.patch
Modified:
branches/ocfs2-1.2-cert/patches/series
Log:
add fix-death-during-recovery.patch
Signed-off-by: smushran
Added: branches/ocfs2-1.2-cert/patches/fix-death-during-recovery.patch
===================================================================
--- branches/ocfs2-1.2-cert/patches/fix-death-during-recovery.patch 2006-03-30 02:47:42 UTC (rev 2799)
+++ branches/ocfs2-1.2-cert/patches/fix-death-during-recovery.patch 2006-03-31 00:17:30 UTC (rev 2800)
@@ -0,0 +1,189 @@
+Index: ocfs2-1.2-cert/fs/ocfs2/dlm/dlmrecovery.c
+===================================================================
+--- ocfs2-1.2-cert.orig/fs/ocfs2/dlm/dlmrecovery.c 2006-03-30 15:03:04.926952000 -0800
++++ ocfs2-1.2-cert/fs/ocfs2/dlm/dlmrecovery.c 2006-03-30 15:03:17.008100000 -0800
+@@ -503,6 +503,7 @@
+
+ status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
+ if (status < 0) {
++ /* we should never hit this anymore */
+ mlog(ML_ERROR, "error %d remastering locks for node %u, "
+ "retrying.\n", status, dlm->reco.dead_node);
+ /* yield a bit to allow any final network messages
+@@ -530,9 +531,16 @@
+ int pass = 0;
+ unsigned long long mlg;
+
+- status = dlm_init_recovery_area(dlm, dead_node);
+- if (status < 0)
+- goto leave;
++ do {
++ /* we have become recovery master. there is no escaping
++ * this, so just keep trying until we get it. */
++ status = dlm_init_recovery_area(dlm, dead_node);
++ if (status < 0) {
++ mlog(ML_ERROR, "%s: failed to alloc recovery area, "
++ "retrying\n", dlm->name);
++ msleep(1000);
++ }
++ } while (status != 0);
+
+ /* safe to access the node data list without a lock, since this
+ * process is the only one to change the list */
+@@ -549,16 +557,36 @@
+ continue;
+ }
+
+- status = dlm_request_all_locks(dlm, ndata->node_num, dead_node);
+- if (status < 0) {
+- mlog_errno(status);
+- if (dlm_is_host_down(status))
+- ndata->state = DLM_RECO_NODE_DATA_DEAD;
+- else {
+- destroy = 1;
+- goto leave;
++ do {
++ status = dlm_request_all_locks(dlm, ndata->node_num,
++ dead_node);
++ if (status < 0) {
++ mlog_errno(status);
++ if (dlm_is_host_down(status)) {
++ /* node died, ignore it for recovery */
++ status = 0;
++ ndata->state = DLM_RECO_NODE_DATA_DEAD;
++ /* wait for the domain map to catch up
++ * with the network state. */
++ wait_event_timeout(dlm->dlm_reco_thread_wq,
++ dlm_is_node_dead(dlm,
++ ndata->node_num),
++ msecs_to_jiffies(1000));
++ mlog(0, "waited 1 sec for %u, "
++ "dead? %s\n", ndata->node_num,
++ dlm_is_node_dead(dlm, ndata->node_num) ?
++ "yes" : "no");
++ } else {
++ /* -ENOMEM on the other node */
++ mlog(ML_NOTICE, "%s: node %u returned "
++ "%d during recovery, retrying "
++ "after a short wait\n",
++ dlm->name, ndata->node_num,
++ status);
++ msleep(100);
++ }
+ }
+- }
++ } while (status != 0);
+
+ switch (ndata->state) {
+ case DLM_RECO_NODE_DATA_INIT:
+@@ -570,10 +598,9 @@
+ mlog(ML_ERROR, "%s:node %u died after "
+ "requesting recovery info for node %u\n",
+ dlm->name, ndata->node_num, dead_node);
+- // start all over
+- destroy = 1;
+- status = -EAGAIN;
+- goto leave;
++ /* fine. don't need this node's info.
++ * continue without it. */
++ break;
+ case DLM_RECO_NODE_DATA_REQUESTING:
+ ndata->state = DLM_RECO_NODE_DATA_REQUESTED;
+ mlog(0, "now receiving recovery data from "
+@@ -618,28 +645,12 @@
+ BUG();
+ break;
+ case DLM_RECO_NODE_DATA_DEAD:
+- mlog(ML_NOTICE, "node %u died after "
++ mlog(0, "node %u died after "
+ "requesting recovery info for "
+ "node %u\n", ndata->node_num,
+ dead_node);
+ spin_unlock(&dlm_reco_state_lock);
+- // start all over
+- destroy = 1;
+- status = -EAGAIN;
+- /* instead of spinning like crazy here,
+- * wait for the domain map to catch up
+- * with the network state. otherwise this
+- * can be hit hundreds of times before
+- * the node is really seen as dead. */
+- wait_event_timeout(dlm->dlm_reco_thread_wq,
+- dlm_is_node_dead(dlm,
+- ndata->node_num),
+- msecs_to_jiffies(1000));
+- mlog(0, "waited 1 sec for %u, "
+- "dead? %s\n", ndata->node_num,
+- dlm_is_node_dead(dlm, ndata->node_num) ?
+- "yes" : "no");
+- goto leave;
++ break;
+ case DLM_RECO_NODE_DATA_RECEIVING:
+ case DLM_RECO_NODE_DATA_REQUESTED:
+ if (pass % 1000)
+@@ -690,7 +701,7 @@
+ jiffies, dlm->reco.dead_node,
+ dlm->node_num, dlm->reco.new_master);
+ destroy = 1;
+- status = ret;
++ status = 0;
+ /* rescan everything marked dirty along the way */
+ dlm_kick_thread(dlm, NULL);
+ break;
+@@ -703,7 +714,6 @@
+
+ }
+
+-leave:
+ if (destroy)
+ dlm_destroy_recovery_area(dlm, dead_node);
+
+@@ -862,24 +872,22 @@
+
+ if (dead_node != dlm->reco.dead_node ||
+ reco_master != dlm->reco.new_master) {
+- /* show extra debug info if the recovery state is messed */
+- mlog(ML_ERROR, "%s: bad reco state: reco(dead=%u, master=%u), "
+- "request(dead=%u, master=%u)\n",
+- dlm->name, dlm->reco.dead_node, dlm->reco.new_master,
+- dead_node, reco_master);
+- mlog(ML_ERROR, "%s: name=%.*s master=%u locks=%u/%u flags=%u "
+- "entry[0]={c=%u:%llu,l=%u,f=%u,t=%d,ct=%d,hb=%d,n=%u}\n",
+- dlm->name, mres->lockname_len, mres->lockname, mres->master,
+- mres->num_locks, mres->total_locks, mres->flags,
+- dlm_get_lock_cookie_node(mres->ml[0].cookie),
+- dlm_get_lock_cookie_seq(mres->ml[0].cookie),
+- mres->ml[0].list, mres->ml[0].flags,
+- mres->ml[0].type, mres->ml[0].convert_type,
+- mres->ml[0].highest_blocked, mres->ml[0].node);
+- BUG();
++ /* worker could have been created before the recovery master
++ * died. if so, do not continue, but do not error. */
++ if (dlm->reco.new_master == O2NM_INVALID_NODE_NUM) {
++ mlog(ML_NOTICE, "%s: will not send recovery state, "
++ "recovery master %u died, thread=(dead=%u,mas=%u)"
++ " current=(dead=%u,mas=%u)\n", dlm->name,
++ reco_master, dead_node, reco_master,
++ dlm->reco.dead_node, dlm->reco.new_master);
++ } else {
++ mlog(ML_NOTICE, "%s: reco state invalid: reco(dead=%u, "
++ "master=%u), request(dead=%u, master=%u)\n",
++ dlm->name, dlm->reco.dead_node,
++ dlm->reco.new_master, dead_node, reco_master);
++ }
++ goto leave;
+ }
+- BUG_ON(dead_node != dlm->reco.dead_node);
+- BUG_ON(reco_master != dlm->reco.new_master);
+
+ /* lock resources should have already been moved to the
+ * dlm->reco.resources list. now move items from that list
+@@ -921,7 +929,7 @@
+ reco_master, dead_node);
+ }
+ }
+-
++leave:
+ free_page((unsigned long)data);
+ }
+
Modified: branches/ocfs2-1.2-cert/patches/series
===================================================================
--- branches/ocfs2-1.2-cert/patches/series 2006-03-30 02:47:42 UTC (rev 2799)
+++ branches/ocfs2-1.2-cert/patches/series 2006-03-31 00:17:30 UTC (rev 2800)
@@ -20,3 +20,4 @@
never-purge-master.patch
reassert-vs-migration.patch
fix-remote-lock-during-reco.patch
+fix-death-during-recovery.patch
More information about the Ocfs2-commits
mailing list