Rev 181: fixed the reverse of the last bug - handle the case when
the new dmaster is the lmaster in http://samba.org/~tridge/ctdb
tridge at samba.org
tridge at samba.org
Sun Apr 22 16:19:49 GMT 2007
------------------------------------------------------------
revno: 181
revision-id: tridge at samba.org-20070422161949-l7agikqiawx4ah1b
parent: tridge at samba.org-20070422145309-2hanalfdwko2p6gn
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Sun 2007-04-22 18:19:49 +0200
message:
fixed the reverse of the last bug - handle the case when the new dmaster is the lmaster
modified:
common/ctdb_call.c ctdb_call.c-20061128065342-to93h6eejj5kon81-1
common/ctdb_ltdb.c ctdb_ltdb.c-20061128065342-to93h6eejj5kon81-2
=== modified file 'common/ctdb_call.c'
--- a/common/ctdb_call.c 2007-04-22 12:26:45 +0000
+++ b/common/ctdb_call.c 2007-04-22 16:19:49 +0000
@@ -95,6 +95,7 @@
}
if (c->new_data) {
+ /* XXX check that we always have the lock here? */
if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
talloc_free(c);
@@ -292,6 +293,50 @@
talloc_free(r);
}
+/*
+ called when a CTDB_REPLY_DMASTER packet comes in, or when the lmaster
+ gets a CTDB_REQUEST_DMASTER for itself. We become the dmaster.
+
+ must be called with the chainlock held. This function releases the chainlock
+*/
+static void ctdb_become_dmaster(struct ctdb_context *ctdb,
+ uint32_t reqid, TDB_DATA data)
+{
+ struct ctdb_call_state *state;
+ struct ctdb_db_context *ctdb_db;
+
+ state = idr_find_type(ctdb->idr, reqid, struct ctdb_call_state);
+ if (state == NULL) {
+ return;
+ }
+
+ ctdb_db = state->ctdb_db;
+
+ DEBUG(2,("vnn %u dmaster response %08x\n",
+ ctdb->vnn, ctdb_hash(&state->call.key)));
+
+ /* we're now the dmaster - update our local ltdb with new header
+ and data */
+ state->header.dmaster = ctdb->vnn;
+
+ if (ctdb_ltdb_store(ctdb_db, state->call.key, &state->header, data) != 0) {
+ ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
+ return;
+ }
+
+ ctdb_call_local(ctdb_db, &state->call, &state->header, &data, ctdb->vnn);
+
+ ctdb_ltdb_unlock(ctdb_db, state->call.key);
+
+ talloc_steal(state, state->call.reply_data.dptr);
+
+ state->state = CTDB_CALL_DONE;
+ if (state->async.fn) {
+ state->async.fn(state);
+ }
+}
+
+
/*
called when a CTDB_REQ_DMASTER packet comes in
@@ -331,17 +376,32 @@
DEBUG(2,(__location__ " deferring ctdb_request_dmaster\n"));
return;
}
-
+
+ if (ctdb_lmaster(ctdb, &key) != ctdb->vnn) {
+ DEBUG(0,("vnn %u dmaster request to non-lmaster lmaster=%u\n",
+ ctdb->vnn, ctdb_lmaster(ctdb, &key)));
+ ctdb_fatal(ctdb, "ctdb_req_dmaster to non-lmaster");
+ }
+
+ DEBUG(2,("vnn %u dmaster request on %08x for %u from %u\n",
+ ctdb->vnn, ctdb_hash(&key), c->dmaster, c->hdr.srcnode));
+
/* its a protocol error if the sending node is not the current dmaster */
if (header.dmaster != hdr->srcnode) {
- DEBUG(0,("vnn=%u dmaster request non-master %u dmaster=%u\n",
- ctdb->vnn, hdr->srcnode, header.dmaster));
+ DEBUG(0,("vnn %u dmaster request non-master %u dmaster=%u key %08x\n",
+ ctdb->vnn, hdr->srcnode, header.dmaster, ctdb_hash(&key)));
ctdb_fatal(ctdb, "ctdb_req_dmaster from non-master");
return;
}
- ctdb_send_dmaster_reply(ctdb_db, &header, key, data, c->dmaster, hdr->reqid);
- ctdb_ltdb_unlock(ctdb_db, key);
+ /* check if the new dmaster is the lmaster, in which case we
+ skip the dmaster reply */
+ if (c->dmaster == ctdb->vnn) {
+ ctdb_become_dmaster(ctdb, hdr->reqid, data);
+ } else {
+ ctdb_send_dmaster_reply(ctdb_db, &header, key, data, c->dmaster, hdr->reqid);
+ ctdb_ltdb_unlock(ctdb_db, key);
+ }
}
@@ -404,6 +464,8 @@
((header.laccessor == c->hdr.srcnode
&& header.lacount >= ctdb->max_lacount)
|| (c->flags&CTDB_IMMEDIATE_MIGRATION)) ) {
+ DEBUG(2,("vnn %u starting migration of %08x to %u\n",
+ ctdb->vnn, ctdb_hash(&call.key), c->hdr.srcnode));
ctdb_call_send_dmaster(ctdb_db, c, &header, &call.key, &data);
talloc_free(data.dptr);
ctdb_ltdb_unlock(ctdb_db, call.key);
@@ -466,6 +528,7 @@
}
}
+
/*
called when a CTDB_REPLY_DMASTER packet comes in
@@ -501,28 +564,7 @@
data.dptr = c->data;
data.dsize = c->datalen;
- talloc_steal(state, c);
-
- /* we're now the dmaster - update our local ltdb with new header
- and data */
- state->header.dmaster = ctdb->vnn;
-
- if (ctdb_ltdb_store(ctdb_db, state->call.key, &state->header, data) != 0) {
- ctdb_ltdb_unlock(ctdb_db, state->call.key);
- ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
- return;
- }
-
- ctdb_call_local(ctdb_db, &state->call, &state->header, &data, ctdb->vnn);
-
- ctdb_ltdb_unlock(ctdb_db, state->call.key);
-
- talloc_steal(state, state->call.reply_data.dptr);
-
- state->state = CTDB_CALL_DONE;
- if (state->async.fn) {
- state->async.fn(state);
- }
+ ctdb_become_dmaster(ctdb, hdr->reqid, data);
}
=== modified file 'common/ctdb_ltdb.c'
--- a/common/ctdb_ltdb.c 2007-04-19 08:31:49 +0000
+++ b/common/ctdb_ltdb.c 2007-04-22 16:19:49 +0000
@@ -225,7 +225,11 @@
*/
int ctdb_ltdb_unlock(struct ctdb_db_context *ctdb_db, TDB_DATA key)
{
- return tdb_chainunlock(ctdb_db->ltdb->tdb, key);
+ int ret = tdb_chainunlock(ctdb_db->ltdb->tdb, key);
+ if (ret != 0) {
+ DEBUG(0,("tdb_chainunlock failed\n"));
+ }
+ return ret;
}
struct lock_fetch_state {
More information about the samba-cvs
mailing list