Esempio n. 1
0
static void handle_response (CcnetProcessor *processor,
                             char *code, char *code_msg,
                             char *content, int clen)
{
    SeafileSendcommitV3Proc *proc = (SeafileSendcommitV3Proc *)processor;
    TransferTask *task = proc->tx_task;
    if (task->state != TASK_STATE_NORMAL) {
        ccnet_processor_done (processor, TRUE);
        return;
    }

    switch (processor->state) {
    case INIT:
        if (memcmp (code, SC_OK, 3) == 0) {
            processor->state = SEND_OBJECT;
            send_commits (processor, task->head);
            return;
        }
        break;
    case SEND_OBJECT:
        if (memcmp (code, SC_ACK, 3) == 0) {
            send_one_commit (processor);
            return;
        }
        break;
    default:
        g_return_if_reached ();
    }

    g_warning ("Bad response: %s %s.\n", code, code_msg);
    if (memcmp (code, SC_ACCESS_DENIED, 3) == 0)
        transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED);
    ccnet_processor_done (processor, FALSE);
}
Esempio n. 2
0
static void handle_response (CcnetProcessor *processor,
                             char *code, char *code_msg,
                             char *content, int clen)
{
    SeafileSendcommitV2Proc *proc = (SeafileSendcommitV2Proc *)processor;
    TransferTask *task = proc->tx_task;
    if (task->state != TASK_STATE_NORMAL) {
        /* TODO: not tested yet */
        ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN,
                                     NULL, 0);
        ccnet_processor_done (processor, TRUE);
        return;
    }

    switch (processor->state) {
    case INIT:
        if (memcmp (code, SC_OK, 3) == 0) {
            processor->state = SEND_OBJECT;
            send_commits (processor, task->head);
        } else {
            seaf_warning ("Bad response: %s %s.\n", code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case SEND_OBJECT:
        seaf_warning ("[sendcommit] Bad response in state SEND_OBJECT: %s %s\n",
                   code, code_msg);
        ccnet_processor_done (processor, FALSE);
        break;
    default:
        g_return_if_reached ();
    }
}
Esempio n. 3
0
static void handle_response (CcnetProcessor *processor,
                             char *code, char *code_msg,
                             char *content, int clen)
{
    SeafileSendcommitV3Proc *proc = (SeafileSendcommitV3Proc *)processor;
    TransferTask *task = proc->tx_task;
    if (task->state != TASK_STATE_NORMAL) {
        ccnet_processor_done (processor, TRUE);
        return;
    }

    switch (processor->state) {
    case INIT:
        if (memcmp (code, SC_OK, 3) == 0) {
            processor->state = SEND_OBJECT;
            send_commits (processor, task->head);
        } else {
            g_warning ("Bad response: %s %s.\n", code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    case SEND_OBJECT:
        if (memcmp (code, SC_ACK, 3) == 0) {
            send_one_commit (processor);
        } else {
            g_warning ("[sendcommit] Bad response in state SEND_OBJECT: %s %s\n",
                       code, code_msg);
            ccnet_processor_done (processor, FALSE);
        }
        break;
    default:
        g_assert (0);
    }
}
Esempio n. 4
0
static void handle_update (CcnetProcessor *processor,
                           char *code, char *code_msg,
                           char *content, int clen)
{
    if (strncmp(code, SC_GET_OBJECT, 3) == 0) {
        send_commits (processor, content, clen);
    } else if (strncmp(code, SC_END, 3) == 0) {
        ccnet_processor_done (processor, TRUE);
    } else {
        g_warning ("[putcommit] Bad response: %s %s\n", code, code_msg);
        ccnet_processor_done (processor, FALSE);
    }
}
Esempio n. 5
0
static int paxos_handle_msg(struct worker_msg *m, void *v)
{
	struct node_data *me = (struct node_data*)v;
	struct mmm_propose *mprop;
	struct mmm_do_timeout *mtimeo;
	struct mmm_accept *macc; 
	struct mmm_reject *mrej; 
	struct mmm_commit *mcom; 
	struct mmm_commit_resp *mresp;
	int i;

	pthread_mutex_lock(&g_start_lock);
	while (g_start == 0)
		pthread_cond_wait(&g_start_cond, &g_start_lock);
	pthread_mutex_unlock(&g_start_lock);

	switch (m->ty) {
	case MMM_DO_PROPOSE:
		if ((me->state != NODE_STATE_INIT) ||
				!node_is_dead(me, me->leader)) {
			if (g_verbose)
				fprintf(stderr, "%d: ignoring do_propose\n", me->id);
			break;
		}
		reset_remotes(me->remotes);
		me->prop_pseq  = me->seen_pseq = outbid(me->seen_pseq, me->id);
		me->prop_leader = me->id;
		for (i = 0; i < g_num_nodes; ++i) {
			if (i == me->id)
				continue;
			mprop = xcalloc(1, sizeof(struct mmm_propose));
			mprop->base.ty = MMM_PROPOSE;
			mprop->src = me->id;
			mprop->prop_leader = me->id;
			mprop->prop_pseq = me->prop_pseq;
			if (worker_sendmsg_or_free(g_nodes[i], mprop)) {
				fprintf(stderr, "%d: declaring node %d as failed\n", me->id, i);
				me->remotes[i] = REMOTE_STATE_FAILED;
			}
			else {
				if (g_verbose)
					fprintf(stderr, "%d: sent MMM_PROPOSE to "
						"node %d\n", me->id, i);
				me->remotes[i] = REMOTE_STATE_NO_RESP;
			}
		}
		mtimeo = xcalloc(1, sizeof(struct mmm_do_timeout));
		mtimeo->base.ty = MMM_DO_TIMEOUT;
		mtimeo->prop_pseq = me->prop_pseq;
		worker_sendmsg_deferred_ms(g_nodes[me->id], mtimeo, 1000);
		me->state = NODE_STATE_PROPOSING;
		break;
	case MMM_DO_TIMEOUT:
		mtimeo = (struct mmm_do_timeout*)m;
		if ((mtimeo->prop_pseq != me->prop_pseq) ||
		    		(me->state != NODE_STATE_PROPOSING)) {
			if (g_verbose) {
				fprintf(stderr, "%d: ignoring timeout for defunct "
					"pseq 0x%"PRIx64"\n", me->id, mtimeo->prop_pseq);
			}
			break;
		}
		abandon_proposal(me, "because of timeout");
		break;
	case MMM_PROPOSE:
		mprop = (struct mmm_propose *)m;
		if ((!node_is_dead(me, me->leader)) || 
				    (mprop->prop_pseq <= me->seen_pseq)) {
			struct mmm_reject *mrej;

			mrej = xcalloc(1, sizeof(struct mmm_reject));
			mrej->base.ty = MMM_REJECT;
			mrej->src = me->id;
			mrej->seen_pseq = me->seen_pseq;
			if (worker_sendmsg_or_free(g_nodes[mprop->src], mrej)) {
				me->remotes[mprop->src] = REMOTE_STATE_FAILED;
			}
			if (g_verbose)
				fprintf(stderr, "%d: rejected proposal (mprop->leader = %d, "
					"mprop->seen_pseq = 0x%"PRIx64 ") from %d "
					"(me->leader = %d, me->seen_pseq = 0x%"PRIx64")\n",
					me->id, mprop->prop_leader, mprop->prop_pseq,
					mprop->src, me->leader, me->seen_pseq);
		}
		else {
			macc = xcalloc(1, sizeof(struct mmm_accept));
			if (me->prop_leader == -1) {
				macc->prop_leader = -1;
				macc->seen_pseq = 0;
			}
			else {
				macc->prop_leader = me->prop_leader;
				macc->seen_pseq = me->seen_pseq;
			}
			me->prop_leader = mprop->prop_leader;
			me->seen_pseq = mprop->prop_pseq;
			macc->base.ty = MMM_ACCEPT;
			macc->src = me->id;
			if (worker_sendmsg_or_free(g_nodes[mprop->src], macc)) {
				me->remotes[mprop->src] = REMOTE_STATE_FAILED;
			}
			if (me->state != NODE_STATE_INIT) {
				if (g_verbose) {
					fprintf(stderr, "%d: giving up on proposing "
						"because node %d had a proposal with a "
						"higher sequence number\n",
						me->id, mprop->src);
				}
				me->state = NODE_STATE_INIT;
			}
		}
		break;
	case MMM_ACCEPT:
		macc = (struct mmm_accept *)m;
		if (check_acceptor_resp(me, MMM_ACCEPT, macc->src))
			break;
		if (g_verbose) {
			fprintf(stderr, "%d: got MMM_ACCEPT (prop_leader=%d) from %d\n",
				me->id, macc->prop_leader, macc->src);
		}
		me->remotes[macc->src] = REMOTE_STATE_ACCEPTED;
		if (!have_majority_of_acceptors(me))
			break;
		send_commits(me);
		me->state = NODE_STATE_COMMITTING;
		break;
	case MMM_REJECT:
		mrej = (struct mmm_reject *)m;
		if (check_acceptor_resp(me, MMM_REJECT, mrej->src))
			break;
		if (g_verbose) {
			fprintf(stderr, "%d: got MMM_REJECT (seen_pseq=0x%"
				PRIx64") from %d\n", me->id, mrej->seen_pseq, mrej->src);
		}
		me->remotes[mrej->src] = REMOTE_STATE_REJECTED;
		if (cannot_have_majority_of_acceptors(me))
			abandon_proposal(me, " because of too much rejection");
		break;
	case MMM_COMMIT:
		mcom = (struct mmm_commit*)m;
		mresp = xcalloc(1, sizeof(struct mmm_commit));
		mresp->base.ty = MMM_COMMIT_RESP;
		mresp->src = me->id;
		mresp->prop_pseq = mcom->prop_pseq;
		if ((me->state != NODE_STATE_INIT) ||
				(mcom->prop_leader != me->prop_leader) ||
				(mcom->prop_pseq < me->prop_pseq)) {
			mresp->ack = 0;
		}
		else {
			mresp->ack = 1;
			accept_leader(me, mcom->prop_leader);
		}
		if (g_verbose) {
			fprintf(stderr, "%d: sending commit %s back to %d\n",
				me->id, (mresp->ack ? "ACK" : "NACK"), mcom->src);
		}
		if (worker_sendmsg_or_free(g_nodes[mcom->src], mresp)) {
			me->remotes[mcom->src] = REMOTE_STATE_FAILED;
		}
		break;
	case MMM_COMMIT_RESP:
		mresp = (struct mmm_commit_resp *)m;
		if (check_commit_resp(me, mresp))
			break;
		if (!mresp->ack) {
			me->remotes[mresp->src] = REMOTE_STATE_REJECTED;
			break;
		}
		me->remotes[mresp->src] = REMOTE_STATE_ACCEPTED;
		if (!have_majority_of_acceptors(me))
			break;
		accept_leader(me, me->prop_leader);
		if (g_verbose)
			fprintf(stderr, "%d: considering protocol "
				"terminated\n", me->id);
		break;
	default:
		fprintf(stderr, "%d: invalid message type %d\n", me->id, m->ty);
		abort();
		break;
	}
	return 0;
}