ctdb_reply_error(ctdb, hdr);
break;
- case CTDB_REPLY_REDIRECT:
- ctdb->status.count.reply_redirect++;
- ctdb_reply_redirect(ctdb, hdr);
- break;
-
case CTDB_REQ_DMASTER:
ctdb->status.count.req_dmaster++;
ctdb_request_dmaster(ctdb, hdr);
send a redirect reply
*/
static void ctdb_call_send_redirect(struct ctdb_context *ctdb,
+ TDB_DATA key,
struct ctdb_req_call *c,
struct ctdb_ltdb_header *header)
{
- struct ctdb_reply_redirect *r;
-
- r = ctdb_transport_allocate(ctdb, ctdb, CTDB_REPLY_REDIRECT, sizeof(*r),
- struct ctdb_reply_redirect);
- CTDB_NO_MEMORY_FATAL(ctdb, r);
-
- r->hdr.destnode = c->hdr.srcnode;
- r->hdr.reqid = c->hdr.reqid;
- r->dmaster = header->dmaster;
-
- ctdb_queue_packet(ctdb, &r->hdr);
-
- talloc_free(r);
+
+ uint32_t lmaster = ctdb_lmaster(ctdb, &key);
+ if (ctdb->vnn == lmaster) {
+ c->hdr.destnode = header->dmaster;
+ } else {
+ c->hdr.destnode = lmaster;
+ }
+ ctdb_queue_packet(ctdb, &c->hdr);
}
/* if we are not the dmaster, then send a redirect to the
requesting node */
if (header.dmaster != ctdb->vnn) {
- ctdb_call_send_redirect(ctdb, c, &header);
+ ctdb_call_send_redirect(ctdb, call.key, c, &header);
talloc_free(data.dptr);
ctdb_ltdb_unlock(ctdb_db, call.key);
return;
}
-/*
- called when a CTDB_REPLY_REDIRECT packet comes in
-
- This packet arrives when we have sent a CTDB_REQ_CALL request and
- the node that received it is not the dmaster for the given key. We
- are given a hint as to what node to try next.
-*/
-void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
-{
- struct ctdb_reply_redirect *c = (struct ctdb_reply_redirect *)hdr;
- struct ctdb_call_state *state;
-
- state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
- if (state == NULL) {
- return;
- }
-
- if (hdr->reqid != state->reqid) {
- /* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
- return;
- }
-
- /* don't allow for too many redirects */
- if ((++state->redirect_count) % CTDB_MAX_REDIRECT == 0) {
- c->dmaster = ctdb_lmaster(ctdb, &state->call.key);
- if (state->redirect_count > ctdb->status.max_redirect_count) {
- ctdb->status.max_redirect_count = state->redirect_count;
- }
- }
-
- /* send it off again */
- state->node = ctdb->nodes[c->dmaster];
- state->c->hdr.destnode = c->dmaster;
-
- ctdb_queue_packet(ctdb, &state->c->hdr);
-}
-
/*
destroy a ctdb_call
*/
struct {
uint32_t req_call;
uint32_t reply_call;
- uint32_t reply_redirect;
uint32_t req_dmaster;
uint32_t reply_dmaster;
uint32_t reply_error;
uint32_t lockwait_calls;
uint32_t pending_lockwait_calls;
uint32_t __last_counter; /* hack for control_status_all */
- uint32_t max_redirect_count;
double max_call_latency;
double max_lockwait_latency;
};
/* arbitrary maximum timeout for ctdb operations */
#define CTDB_REQ_TIMEOUT 0
-/* max number of redirects before we ask the lmaster */
-#define CTDB_MAX_REDIRECT 2
-
/* number of consecutive calls from the same node before we give them
the record */
#define CTDB_DEFAULT_MAX_LACOUNT 7
struct ctdb_node *node;
const char *errmsg;
struct ctdb_call call;
- int redirect_count;
struct ctdb_ltdb_header header;
struct {
void (*fn)(struct ctdb_call_state *);
*/
enum ctdb_operation {
CTDB_REQ_CALL = 0,
- CTDB_REPLY_CALL = 1,
- CTDB_REPLY_REDIRECT = 2,
- CTDB_REQ_DMASTER = 3,
- CTDB_REPLY_DMASTER = 4,
- CTDB_REPLY_ERROR = 5,
- CTDB_REQ_MESSAGE = 6,
- CTDB_REQ_FINISHED = 7,
- CTDB_REQ_CONTROL = 8,
- CTDB_REPLY_CONTROL = 9,
+ CTDB_REPLY_CALL,
+ CTDB_REQ_DMASTER,
+ CTDB_REPLY_DMASTER,
+ CTDB_REPLY_ERROR,
+ CTDB_REQ_MESSAGE,
+ CTDB_REQ_FINISHED,
+ CTDB_REQ_CONTROL,
+ CTDB_REPLY_CONTROL,
/* only used on the domain socket */
CTDB_REQ_REGISTER = 1000,
- CTDB_REQ_CONNECT_WAIT = 1001,
- CTDB_REPLY_CONNECT_WAIT = 1002,
- CTDB_REQ_SHUTDOWN = 1003
+ CTDB_REQ_CONNECT_WAIT,
+ CTDB_REPLY_CONNECT_WAIT,
+ CTDB_REQ_SHUTDOWN
};
#define CTDB_MAGIC 0x43544442 /* CTDB */
uint8_t msg[1];
};
-struct ctdb_reply_redirect {
- struct ctdb_req_header hdr;
- uint32_t dmaster;
-};
-
struct ctdb_req_dmaster {
struct ctdb_req_header hdr;
uint32_t db_id;
void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
void ctdb_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
void ctdb_reply_error(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
-void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
uint32_t ctdb_lmaster(struct ctdb_context *ctdb, const TDB_DATA *key);
int ctdb_ltdb_fetch(struct ctdb_db_context *ctdb_db,
#!/bin/sh
-tests/fetch.sh || exit 1
-tests/bench.sh || exit 1
+tests/fetch.sh 4 || exit 1
+tests/bench.sh 4 || exit 1
tests/test.sh || exit 1
echo "All OK"
printf(" node_packets_recv %u\n", s->node_packets_recv);
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);
printf(" reply_dmaster %u\n", s->count.reply_dmaster);
printf(" reply_error %u\n", s->count.reply_error);
- printf(" reply_redirect %u\n", s->count.reply_redirect);
printf(" req_message %u\n", s->count.req_message);
printf(" req_finished %u\n", s->count.req_finished);
printf(" total_calls %u\n", s->total_calls);
printf(" pending_calls %u\n", s->pending_calls);
printf(" lockwait_calls %u\n", s->lockwait_calls);
printf(" pending_lockwait_calls %u\n", s->pending_lockwait_calls);
- printf(" max_redirect_count %u\n", s->max_redirect_count);
printf(" max_call_latency %.6f sec\n", s->max_call_latency);
printf(" max_lockwait_latency %.6f sec\n", s->max_lockwait_latency);
}
for (j=0;j<num_ints;j++) {
v2[j] += v1[j];
}
- status.max_redirect_count =
- MAX(status.max_redirect_count, s1.max_redirect_count);
status.max_call_latency =
MAX(status.max_call_latency, s1.max_call_latency);
status.max_lockwait_latency =