1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-20 22:50:26 +03:00

merge from tridge

(This used to be ctdb commit 3457af559a5d54fd9eb787f18ff15d7c19271f60)
This commit is contained in:
Ronnie Sahlberg 2007-04-23 02:35:05 +10:00
commit 1bb55c1f77
4 changed files with 95 additions and 34 deletions

View File

@ -95,6 +95,7 @@ int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
}
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 @@ static void ctdb_call_send_dmaster(struct ctdb_db_context *ctdb_db,
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 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
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 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
((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 @@ void ctdb_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
}
}
/*
called when a CTDB_REPLY_DMASTER packet comes in
@ -501,28 +564,7 @@ void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
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);
}

View File

@ -225,7 +225,11 @@ int ctdb_ltdb_lock(struct ctdb_db_context *ctdb_db, TDB_DATA key)
*/
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 {

View File

@ -36,15 +36,25 @@ static void usage(void)
exit(1);
}
struct node_info {
uint32_t num_nodes;
uint32_t vnn;
};
static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
{
int *num_nodes = (int *)p;
struct node_info *info = (struct node_info *)p;
struct id {
dev_t dev;
ino_t inode;
} *id;
struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
char *keystr;
uint32_t lmaster;
int authoritative=0;
lmaster = ctdb_hash(&key) % info->num_nodes;
id = (struct id *)key.dptr;
if (key.dsize == sizeof(*id)) {
keystr = talloc_asprintf(NULL, "%llu:%llu",
@ -52,10 +62,12 @@ static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
} else {
keystr = hex_encode(NULL, key.dptr, key.dsize);
}
printf(" rec %s lmaster=%u dmaster=%u\n",
authoritative = (info->vnn == lmaster || info->vnn == h->dmaster);
printf(" rec %s lmaster=%u dmaster=%u %c\n",
keystr,
ctdb_hash(&key) % (*num_nodes),
h->dmaster);
lmaster,
h->dmaster,
authoritative?'A':' ');
talloc_free(keystr);
return 0;
}
@ -75,6 +87,7 @@ int main(int argc, const char *argv[])
int i, extra_argc = 0;
poptContext pc;
struct tdb_wrap *db;
struct node_info info;
pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
@ -107,7 +120,9 @@ int main(int argc, const char *argv[])
}
printf("db %s\n", extra_argv[i]);
tdb_traverse(db->tdb, traverse_fn, &extra_argc);
info.vnn = i;
info.num_nodes = extra_argc;
tdb_traverse(db->tdb, traverse_fn, &info);
talloc_free(db);
}

View File

@ -42,7 +42,7 @@ static void show_status(struct ctdb_status *s)
printf(" req_status %u\n", s->client.req_status);
printf(" node_packets_sent %u\n", s->node_packets_sent);
printf(" node_packets_recv %u\n", s->node_packets_recv);
printf(" req_call %u\n", s->client.req_call);
printf(" req_call %u\n", s->count.req_call);
printf(" reply_call %u\n", s->count.reply_call);
printf(" reply_redirect %u\n", s->count.reply_redirect);
printf(" req_dmaster %u\n", s->count.req_dmaster);