Exemple #1
0
/** Try to get the ticket for the local site.
 * */
int do_grant_ticket(struct ticket_config *tk, int options)
{
	int rv;

	tk_log_info("granting ticket");

	if (tk->leader == local)
		return RLT_SUCCESS;
	if (is_owned(tk))
		return RLT_OVERGRANT;

	set_future_time(&tk->delay_commit, tk->term_duration + tk->acquire_after);

	if (options & OPT_IMMEDIATE) {
		tk_log_warn("granting ticket immediately! If there are "
				"unreachable sites, _hope_ you are sure that they don't "
				"have the ticket!");
		time_reset(&tk->delay_commit);
	}

	rv = acquire_ticket(tk, OR_ADMIN);
	if (rv) {
		time_reset(&tk->delay_commit);
		return rv;
	} else {
		return RLT_MORE;
	}
}
Exemple #2
0
/** Try to get the ticket for the local site.
 * */
int do_grant_ticket(struct ticket_config *tk, int options)
{
	int rv;

	tk_log_info("granting ticket");

	if (tk->leader == local)
		return RLT_SUCCESS;
	if (is_owned(tk)) {
		if (is_manual(tk) && (options & OPT_IMMEDIATE)) {
			/* -F flag has been used while granting a manual ticket.
			 * The ticket will be granted and may end up being granted
			 * on multiple sites */
			tk_log_warn("manual ticket forced to be granted! be aware that "
					"you may end up having two sites holding the same manual "
					"ticket! revoke the ticket from the unnecessary site!");
		} else {
			return RLT_OVERGRANT;
		}
	}

	set_future_time(&tk->delay_commit, tk->term_duration + tk->acquire_after);

	if (options & OPT_IMMEDIATE) {
		tk_log_warn("granting ticket immediately! If there are "
				"unreachable sites, _hope_ you are sure that they don't "
				"have the ticket!");
		time_reset(&tk->delay_commit);
	}

	rv = acquire_ticket(tk, OR_ADMIN);
	if (rv) {
		time_reset(&tk->delay_commit);
		return rv;
	} else {
		return RLT_MORE;
	}
}
Exemple #3
0
static void set_ticket_expiry(struct ticket_config *tk,
		int duration)
{
	set_future_time(&tk->term_expires, duration);
}
Exemple #4
0
int new_election(struct ticket_config *tk,
	struct booth_site *preference, int update_term, cmd_reason_t reason)
{
	struct booth_site *new_leader;

	if (local->type != SITE)
		return 0;

	if ((is_reason(OR_TKT_LOST, tk) || is_reason(OR_STEPDOWN, tk)) &&
			check_attr_prereq(tk, GRANT_AUTO)) {
		tk_log_info("attribute prerequisite not met, "
			"not starting elections");
		return 0;
	}

	/* elections were already started, but not yet finished/timed out */
	if (is_time_set(&tk->election_end) && !is_past(&tk->election_end))
		return 1;

	if (ANYDEBUG) {
		int tdiff;
		if (is_time_set(&tk->election_end)) {
			tdiff = -time_left(&tk->election_end);
			tk_log_debug("starting elections, previous finished since " intfmt(tdiff));
		} else {
			tk_log_debug("starting elections");
		}
		tk_log_debug("elections caused by %s %s",
				state_to_string(reason),
				reason == OR_AGAIN ? state_to_string(tk->election_reason) : "" );
	}

	/* §5.2 */
	/* If there was _no_ answer, don't keep incrementing the term number
	 * indefinitely. If there was no peer, there'll probably be no one
	 * listening now either. However, we don't know if we were
	 * invoked due to a timeout (caller does).
	 */
	/* increment the term only if either the current term was
	 * valid or if there was a tie (in that case update_term > 1)
	 */
	if ((update_term > 1) ||
		(update_term && tk->last_valid_tk &&
			tk->last_valid_tk->current_term >= tk->current_term)) {
		/* save the previous term, we may need to send out the
		 * MY_INDEX message */
		if (tk->state != ST_CANDIDATE) {
			save_committed_tkt(tk);
		}
		tk->current_term++;
	}

	set_future_time(&tk->election_end, tk->timeout);
	tk->in_election = 1;

	tk_log_info("starting new election (term=%d)",
			tk->current_term);
	clear_election(tk);

	if(preference)
		new_leader = preference;
	else
		new_leader = (local->type == SITE) ? local : NULL;
	record_vote(tk, local, new_leader);
	tk->voted_for = new_leader;

	set_state(tk, ST_CANDIDATE);

	/* some callers may want just to repeat on timeout */
	if (reason == OR_AGAIN) {
		reason = tk->election_reason;
	} else {
		tk->election_reason = reason;
	}

	ticket_broadcast(tk, OP_REQ_VOTE, OP_VOTE_FOR, RLT_SUCCESS, reason);
	add_random_delay(tk);
	return 0;
}