void start_sched(){ INIT_SCHED(); // Mettre peut être le signal() après les new_proc selon la dernière question ? signal(SIGALRM,&commut); if(mysetjmp(SCHED_PROC)==0){ new_proc(f,BEGIN_PROC); new_proc(g,BEGIN_PROC+1); new_proc(f,BEGIN_PROC+2); new_proc(g,BEGIN_PROC+3); alarm(1); int p = election(); mylongjmp(p); } else{ // Fin d'un processus int p = election(); mylongjmp(p); } }
void main() { printf("\nEnter No. of nodes:"); scanf("%d",&n); printf("\nInitially all nodes are considered to be live!!!"); for(i=1;i<=n;i++) p[i]=1; print(); co=n; while(1) { printf("\n1.Current Coordinator\n2.Crash Coordinator\n3.Recover Node\nEnter Choice:\t"); scanf("%d",&ch); switch(ch) { case 1: printf("\nCurrent Coordinator is :%d",co); break; case 2: p[co]=0; print(); printf("\nEnter the initiator:\t"); scanf("%d",&ini); election(ini); break; case 3: print(); printf("\n Enter node to be recovered:\t"); scanf("%d",&ch); p[ch]=1; if(ch>co) election(ch); break; } } }
int main ( int argc, char** argv ) { ptr_f f_; ptr_f g_; int res; init_sched(); f_ = &f; new_proc(f_, 0); res = election(); tproc[res].p_state = SRUNNING; g_ = &f; new_proc(g_, 1); election(); return EXIT_SUCCESS; }
void commut(int no){ int p = election(); printf("\n Commutation : election %d | courant %d \n\n",p,elu); signal(SIGALRM,&commut); alarm(3); if(mysetjmp(elu) == 0) { mylongjmp(p); } else{ return; } }
/* * This is a generic message handling loop that is used both by the * master to accept messages from a client and vice versa. */ static void * msg_mng_loop(void *args) { msg_mng_loop_args *mma; int eid; int ret = 0, retr = 0; /*Number of connection retries*/ int fd, m_index; /*Index in machtab list*/ char *buffer, * cmd, * cookie, * metric, *cmd_t; struct node_struct * nd; long long ballot = -1, instance_proposed = -1, round = -1; char mes[BUF_SIZE], log_rec[BUF_SIZE]; char id[5]; pthread_t cnt_thr; nd = &node; mma = (msg_mng_loop_args *) args; fd = mma->fd; eid = mma->eid; m_index = mma ->m_index; buffer = (char *) malloc(sizeof (char) * MTR_BUF); if (buffer == NULL) { pax_log(LOG_ERR,"msg_mng_loop: malloc: %s\n", strerror(errno)); exit(-1); } if (_PAXOS_DEBUG>2)pax_log(LOG_DEBUG,"Message loop for %d\n", m_index); for (ret = 0; ret == 0;) { memset(buffer, 0, MTR_BUF); if (_PAXOS_DEBUG)pax_log(LOG_DEBUG,"Ready for next mesg\n"); ret = get_next_message(fd, buffer, BTRUE); if (_PAXOS_DEBUG>2)pax_log(LOG_DEBUG,"Get next message ret %d\n", ret); if (ret == -1 || retr > NRETR) {/*Connection lost*/ if(fd)close(fd); if (_PAXOS_DEBUG) pax_log(LOG_DEBUG,"Connection with %d lost.\n", nd->machtab[eid].id); if ((ret = machtab_rem(&node, eid, 1)) != 0) break; if (_PAXOS_DEBUG>2) machtab_print(); sleep(rand()%3); /*Triing to reestablish the connection*/ if ((ret = pthread_create(&cnt_thr, NULL, contact_group, NULL)) != 0) { pax_log(LOG_ERR,"can't create connection thread: %s\n", strerror(errno)); goto err; } if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(m_index == nd->updater_id){ nd->updating = BFALSE; } if (nd->machtab[m_index].id == nd->master_id || ((nd->current)) < QUORUM(nd)) { pax_log(LOG_ERR, "Connection with master or majority lost.\n"); nd->master_id = -1; if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } sleep(1); /*Sleep some time to wait for others to notice the same event*/ election(nd); } else if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } break; } if (ret == -2) {/*Connection timeouted*/ if (retr <= NRETR) ret = send_mes("PNG;", fd); /*Ping message*/ else { pax_log(LOG_ERR, "Ping retried %d times. Node probably dead, closing connection.\n", NRETR); goto err; } retr++; continue; } if (buffer != NULL || strlen(buffer) != 0) { strncpy(log_rec, buffer, BUF_SIZE); if (_PAXOS_DEBUG>2) pax_log(LOG_DEBUG,"Message %s received %d\n", buffer, nd->machtab[eid].id); if ((cmd = strtok_r(buffer, ";", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: Command not found\n"); continue; } if (strncmp(cmd, "SHU", 3) == 0) { if(_PAXOS_DEBUG)pax_log(LOG_DEBUG, "Shutting down\n"); exit(0); } /*Upon log - the remote node asked for log*/ if (strncmp(cmd, "LOG", 3) == 0) { if ((cmd_t = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: LOG: Command not found:\n"); continue; } if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(nd->non_voting==BTRUE){ continue; } if (update_remote_node(m_index, node)==-1) { nd->master_id = -1; if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } pax_log(LOG_DEBUG>2, "Updating remote node failed, remote node connection lost, election starting\n"); election(nd); }else if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } pax_log(LOG_DEBUG>2, "Updating started\n"); continue; } /*Upon outdated message*/ if (strncmp(cmd, "OUT", 3) == 0) { if ((cmd_t = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: OUT: Command not found:\n"); continue; } if (strncmp(cookie, "BEG", 3) == 0) {/*The transfer started*/ nd->updater_id = m_index; clear_logs(); lock_snapshotting(); pax_log(LOG_ERR, "Logs cleared:\n"); } else if (strncmp(cookie, "SSM", 3) == 0) { if ((cmd = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: OUT: Command not found:\n"); continue; } write_snapshot_mark(cookie); } else if (strncmp(cookie, "SST", 3) == 0) {/*Snapshot*/ char * met_name; if ((cmd = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: OUT: Command not found:\n"); continue; } if ((met_name = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: OUT: Command not found:\n"); continue; } write_metric_snap(met_name, cookie); }else if (strncmp(cookie, "FIN", 3) == 0) { /*The transfer finnished*/ int rt = 0; if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } rt = write_log_out_hash(); rt+= out_hash(); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } rt += process_logs(&node); unlock_snapshotting(); if (rt==0) { if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(_PAXOS_DEBUG) pax_log(LOG_DEBUG, "Voting allowed\n"); nd->updating = BFALSE; nd->non_voting = BFALSE; /*The node can vote again*/ if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } }else { if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(_PAXOS_DEBUG) pax_log(LOG_DEBUG, "Wrong update\n"); send_mes("LOG;", fd); nd->updater_id = m_index; nd->updating = BTRUE; nd->non_voting = BTRUE; /*The node can vote again*/ if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } } else write_log_out_record(cookie); continue; } /*UPON NextBallot(ballot, instance proposed)*/ /*NXB:%lld:%lld;*/ if (strncmp(cmd, "NXB", 3) == 0) { if ((cmd_t = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: NXB: Command not found:\n"); continue; } if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: NXB: Command not found:\n"); continue; } ballot = atoll(cmd_t); if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: NXB: Command not found:\n"); continue; } instance_proposed = atoll(cmd_t); round = atoll(cookie); sprintf(mes, "%lld:%lld", ballot, paxos.last_instance); if (ballot >= paxos.nextBallot) { paxos.nextBallot = ballot; if (instance_proposed == (paxos.last_instance + 1) && round == (paxos.previous_round+1)) { char * ack_mes; ack_mes = malloc((4 + sizeof (char)) * strlen(mes)); if (!ack_mes) { pax_log(LOG_ERR,"NXB response message creation: %s\n", strerror(errno)); exit(EX_OSERR); } sprintf(ack_mes, "N_A:%s;", mes); /*Acknowledge the message*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(!nd->non_voting) { send_mes(ack_mes, fd); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } free(ack_mes); } else if (instance_proposed <= paxos.last_instance) { /*Remote node is outdated*/ char * nack_mes; nack_mes = malloc((4 + sizeof (char)) * strlen(mes)); if (!nack_mes) { pax_log(LOG_ERR,"NXB response message creation: %s\n", strerror(errno)); exit(EX_OSERR); } if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } sprintf(nack_mes, "N_N:%s;", mes); /*Nack the message*/ if(!nd->non_voting) { send_mes(nack_mes, fd); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } free(nack_mes); } else if(instance_proposed > (paxos.last_instance + 1) || round > (paxos.previous_round+1)){ /*Local node is outdated*/ /*char * ack_mes;*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } nd->non_voting = BTRUE; /*The local node cannot vote*/ if (!nd->updating) { if (_PAXOS_DEBUG) pax_log(LOG_DEBUG, "NXB\n"); send_mes("LOG;", fd); nd->updater_id = m_index; nd->updating = BTRUE; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } } else { char * nack_mes; nack_mes = malloc((4 + sizeof (char)) * strlen(mes)); if (!nack_mes) { pax_log(LOG_ERR,"NXB response message creation: %s\n", strerror(errno)); exit(EX_OSERR); } if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } sprintf(nack_mes, "N_N:%s;", mes); /*Nack the message*/ if(!nd->non_voting) { send_mes(nack_mes, fd); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } free(nack_mes); } continue; } /*UPON BeginBallot(ballot, instance,round, previous_instances, metric)*/ if (strncmp(cmd, "BEB", 3) == 0) { if ((cmd_t = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: BEB: Command not found:\n"); continue; } if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: BEB: Command not found:\n"); continue; } ballot = atoll(cmd_t); if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: BEB: Command not found:\n"); continue; } instance_proposed = atoll(cmd_t); if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: BEB: Command not found:\n"); continue; } round = atoll(cmd_t); metric = strdup(cookie); sprintf(mes, "%lld:%lld:%d:", instance_proposed, ballot, m_index); if (ballot >= paxos.nextBallot) { if ((instance_proposed >= paxos.last_instance && round > paxos.previous_round)) { if (instance_proposed > (paxos.last_instance + 1) || round > (paxos.previous_round + 1)) { /*Local node is out-dated*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } nd->non_voting = BTRUE; /*Local node cannot vote*/ if(_PAXOS_DEBUG) pax_log(LOG_DEBUG, "BEB received - voting forbidden\n"); if (!nd->updating) { send_mes("LOG;", fd); nd->updater_id = m_index; nd->updating = BTRUE; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } write_log_record(log_rec, BFALSE, BFALSE); /*Begin transaction*/ if (txn_begin(nd->machtab[m_index].id - 1, instance_proposed, round, metric) != 0) { /*In the case of failure*/ sprintf(mes, "B_N:%lld:%lld:%lld:%d;", paxos.last_instance, paxos.previous_round, paxos.nextBallot, m_index); /*Nack the message*/ send_mes(mes, fd); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } continue; } pax_log(LOG_DEBUG>2, "BEB txn done\n"); if(!nd->non_voting) { sprintf(mes, "B_A:%lld:0:%lld:%d;", instance_proposed, ballot, m_index); /*Acknowledge the message*/ send_mes(mes, fd); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } } else { /*remote node is outdated*/ /*Nack the message*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(!nd->non_voting) { sprintf(mes, "B_N:%lld:%lld:%lld:%d;", paxos.last_instance, paxos.previous_round, paxos.nextBallot, m_index); send_mes(mes, fd); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } continue; } /*Ping message*/ if (strncmp(cmd, "PNG", 3) == 0) { retr = 0; } //UPON Success(round , instance, previous_instances) //SUC:%lld:%lld:%s; if (strncmp(cmd, "SUC", 3) == 0) { if ((cmd_t = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: SUC: Command not found:\n"); continue; } if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: SUC: Command not found:\n"); continue; } round = atoll(cmd_t); if ((cmd_t = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: SUC: Command not found:\n"); continue; } instance_proposed = atoll(cmd_t); if (instance_proposed >= paxos.last_instance && round > paxos.previous_round) { char mtc[MTR_BUF]; if (instance_proposed > (paxos.last_instance + 1) || round > (paxos.previous_round + 1)) { /*Local node is out-dated*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "SUC received - voting forbidden\n"); nd->non_voting = BTRUE; /*Local node cannot vote*/ if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } if (pthread_mutex_lock(&nd->mtmutex) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } paxos.last_instance = instance_proposed; paxos.previous_round = round; nd->master_id = nd->machtab[m_index].id; nd->paxos_state = 0; write_log_record(log_rec, BFALSE, BTRUE); if (txn_commit( nd->machtab[m_index].id - 1, instance_proposed, round) == NULL) { pax_log(LOG_ERR, "Local value cannot be changed to requested value. (null) value commited.\n"); pax_log(LOG_ERR, "Maybe something lost, voting forbidden.\n"); if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "SUC received - voting forbidden\n"); nd->non_voting = BTRUE; /*Local node cannot vote*/ } else { strcpy(mtc, txn_commit( nd->machtab[m_index].id - 1, instance_proposed, round)); if (strncmp(mtc, "NA", 2) != 0) {/*If not voting round*/ if (strncmp(mtc, "REM:", 4) == 0) {/*If not removing*/ if (memory_remove_local(mtc) != 0) { pax_log(LOG_ERR, "Local value cannot be changed to requested value.\n"); } } else if (memory_update_local(mtc) != 0) { pax_log(LOG_ERR, "Local metric cannot be removed.\n"); if (_PAXOS_DEBUG>2) pax_log(LOG_DEBUG,"Value updated %s\n", mtc); } } if(_PAXOS_DEBUG>2)print_db_state(); if (nd->non_voting) if (nd->master_id == nd->machtab[m_index].id && !nd->updating) { send_mes("LOG;", fd); nd->updater_id = m_index; nd->updating = BTRUE; } if (_PAXOS_DEBUG>1) pax_log(LOG_DEBUG,"Commited %s\n", txn_commit(nd->machtab[m_index].id - 1, instance_proposed, round)); } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } }else{ if (_PAXOS_DEBUG>1) pax_log(LOG_DEBUG,"SUC ignoring. Should be inst: %lld >= %lld, round: %lld > %lld\n", instance_proposed, paxos.last_instance, round, paxos.previous_round); } if (_PAXOS_DEBUG>1) pax_log(LOG_DEBUG,"New master is %d\n", nd->master_id); } /*B_A, B_N, N_A, N_N*/ /*BEB acknowlegdes and NACKs*/ if ((strncmp(cmd, "B_A", 3) == 0) || (strncmp(cmd, "B_N", 3) == 0)){ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(nd->paxos_state != 4) { if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "Not allowed BA/BN\n"); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } continue; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } sprintf(mes, "%s:%d;", cmd, m_index); /*Inform the initiate consensus thread*/ write(paxpipe[m_index][1], mes, strlen(mes) * sizeof (char)); } if ((strncmp(cmd, "N_A", 3) == 0) || (strncmp(cmd, "N_N", 3) == 0)) { if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(nd->paxos_state != 2) { if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "Not allowed NA/NN, state %d\n", nd->paxos_state); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } continue; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } sprintf(mes, "%s:%d;", cmd, m_index); /*Inform the initiate consensus thread*/ write(paxpipe[m_index][1], mes, strlen(mes) * sizeof (char)); } /*Who is the master?*/ if (strncmp(cmd, "WIM", 3) == 0) { if (pthread_mutex_lock(&nd->mtmutex) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if (nd->machtab[m_index].id == nd->master_id) { nd->master_id = -1; nd->updating = BFALSE; } sprintf(id, "%d", node.master_id); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } sprintf(mes, "MIS:%s:%lld:%lld;", id, paxos.last_instance, paxos.previous_round); send_mes(mes, fd); } /*master is id*/ /*MIS:id:inst:round;*/ if (strncmp(cmd, "MIS", 3) == 0) { long long rd, inst; if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(nd->paxos_state != 1) { if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "Not allowed MIS\n"); if (_PAXOS_DEBUG>2) pax_log(LOG_DEBUG,"State is %d.\n", (int) nd->paxos_state); if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } continue; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } if ((cmd = strtok_r(cmd, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: MIS: Command not found:\n"); continue; } if ((cmd = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: MIS: Command not found:\n"); continue; } sprintf(mes, "ID:%d;", atoi(cmd)); if ((cmd = strtok_r(cookie, ":", &cookie)) == NULL) { pax_log(LOG_ERR, "Receiver: MIS: Command not found:\n"); continue; } inst = atoll(cmd); rd = atoll(cookie); if ((inst > (paxos.last_instance) && rd > (paxos.previous_round)) || (inst == (paxos.last_instance) && rd > (paxos.previous_round))) { /*Local node is out-dated*/ if ((ret = pthread_mutex_lock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't lock mutex\n"); exit(EX_OSERR); } if(_PAXOS_DEBUG>2) pax_log(LOG_DEBUG, "MIS - voting forbidden\n"); nd->non_voting = BTRUE; /*Local node cannot vote*/ if (!nd->updating) { send_mes("LOG;", fd); nd->updater_id = m_index; nd->updating = BTRUE; } if ((ret = pthread_mutex_unlock(&nd->mtmutex)) != 0) { pax_log(LOG_ERR, "can't unlock mutex\n"); exit(EX_OSERR); } } /*Inform ask_for_master*/ write(wimpipe[m_index][1], mes, strlen(mes) * sizeof (char)); } } } err: if (_PAXOS_DEBUG>1) pax_log(LOG_DEBUG,"Connection thread exiting %d\n", m_index); if (buffer != NULL) free(buffer); free(mma); return ((void *) (uintptr_t) ret); }
/* * The timedaemons synchronize the clocks of hosts in a local area network. * One daemon runs as master, all the others as slaves. The master * performs the task of computing clock differences and sends correction * values to the slaves. * Slaves start an election to choose a new master when the latter disappears * because of a machine crash, network partition, or when killed. * A resolution protocol is used to kill all but one of the masters * that happen to exist in segments of a partitioned network when the * network partition is fixed. * * Authors: Riccardo Gusella & Stefano Zatti * * overhauled at Silicon Graphics */ int main(int argc, char *argv[]) { int on; int ret; int nflag, iflag; struct timeval ntime; struct servent *srvp; char buf[BUFSIZ], *cp, *cplim; struct ifconf ifc; struct ifreq ifreq, ifreqf, *ifr; register struct netinfo *ntp; struct netinfo *ntip; struct netinfo *savefromnet; struct netent *nentp; struct nets *nt; struct sockaddr_in server; u_short port; int c; #ifdef lint ntip = NULL; #endif on = 1; nflag = OFF; iflag = OFF; opterr = 0; while ((c = getopt(argc, argv, "Mtdn:i:F:G:P:")) != -1) { switch (c) { case 'M': Mflag = 1; break; case 't': trace = 1; break; case 'n': if (iflag) { errx(1, "-i and -n make no sense together"); } else { nflag = ON; addnetname(optarg); } break; case 'i': if (nflag) { errx(1, "-i and -n make no sense together"); } else { iflag = ON; addnetname(optarg); } break; case 'F': add_good_host(optarg,1); while (optind < argc && argv[optind][0] != '-') add_good_host(argv[optind++], 1); break; case 'd': debug = 1; break; case 'G': if (goodgroup != NULL) errx(1, "only one net group"); goodgroup = optarg; break; default: usage(); break; } } if (optind < argc) usage(); /* If we care about which machine is the master, then we must * be willing to be a master */ if (goodgroup != NULL || goodhosts != NULL) Mflag = 1; if (gethostname(hostname, sizeof(hostname) - 1) < 0) err(1, "gethostname"); self.l_bak = &self; self.l_fwd = &self; self.h_bak = &self; self.h_fwd = &self; self.head = 1; self.good = 1; if (goodhosts != NULL) /* trust ourself */ add_good_host(hostname,1); srvp = getservbyname("timed", "udp"); if (srvp == NULL) errx(1, "timed/udp: unknown service"); port = srvp->s_port; bzero(&server, sizeof(struct sockaddr_in)); server.sin_port = srvp->s_port; server.sin_family = AF_INET; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) err(1, "socket"); if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt"); if (bind(sock, (struct sockaddr*)&server, sizeof(server))) { if (errno == EADDRINUSE) warnx("time daemon already running"); else warn("bind"); exit(1); } sequence = arc4random(); /* initial seq number */ (void)gettimeofday(&ntime, NULL); /* rounds kernel variable time to multiple of 5 ms. */ ntime.tv_sec = 0; ntime.tv_usec = -((ntime.tv_usec/1000) % 5) * 1000; (void)adjtime(&ntime, (struct timeval *)0); for (nt = nets; nt; nt = nt->next) { nentp = getnetbyname(nt->name); if (nentp == NULL) { nt->net = inet_network(nt->name); if (nt->net != INADDR_NONE) nentp = getnetbyaddr(nt->net, AF_INET); } if (nentp != NULL) { nt->net = nentp->n_net; } else if (nt->net == INADDR_NONE) { errx(1, "unknown net %s", nt->name); } else if (nt->net == INADDR_ANY) { errx(1, "bad net %s", nt->name); } else { warnx("warning: %s unknown in /etc/networks", nt->name); } if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) err(1, "get interface configuration"); ntp = NULL; #define size(p) max((p).sa_len, sizeof(p)) cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ for (cp = buf; cp < cplim; cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { ifr = (struct ifreq *)cp; if (ifr->ifr_addr.sa_family != AF_INET) continue; if (!ntp) ntp = (struct netinfo*)malloc(sizeof(struct netinfo)); bzero(ntp,sizeof(*ntp)); ntp->my_addr=((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; ntp->status = NOMASTER; ifreq = *ifr; ifreqf = *ifr; if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreqf) < 0) { warn("get interface flags"); continue; } if ((ifreqf.ifr_flags & IFF_UP) == 0) continue; if ((ifreqf.ifr_flags & IFF_BROADCAST) == 0 && (ifreqf.ifr_flags & IFF_POINTOPOINT) == 0) { continue; } if (ioctl(sock, SIOCGIFNETMASK, (char *)&ifreq) < 0) { warn("get netmask"); continue; } ntp->mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; if (ifreqf.ifr_flags & IFF_BROADCAST) { if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { warn("get broadaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr; /* What if the broadcast address is all ones? * So we cannot just mask ntp->dest_addr. */ ntp->net = ntp->my_addr; ntp->net.s_addr &= ntp->mask; } else { if (ioctl(sock, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { warn("get destaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr; ntp->net = ntp->dest_addr.sin_addr; } ntp->dest_addr.sin_port = port; for (nt = nets; nt; nt = nt->next) { if (ntp->net.s_addr == htonl(nt->net)) break; } if ((nflag && !nt) || (iflag && nt)) continue; ntp->next = NULL; if (nettab == NULL) { nettab = ntp; } else { ntip->next = ntp; } ntip = ntp; ntp = NULL; } if (ntp) (void) free((char *)ntp); if (nettab == NULL) errx(1, "no network usable"); /* microseconds to delay before responding to a broadcast */ delay1 = casual(1, 100*1000); /* election timer delay in secs. */ delay2 = casual(MINTOUT, MAXTOUT); if (!debug) daemon(debug, 0); if (trace) traceon(); openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON); /* * keep returning here */ ret = setjmp(jmpenv); savefromnet = fromnet; setstatus(); if (Mflag) { switch (ret) { case 0: checkignorednets(); pickslavenet(0); break; case 1: /* Just lost our master */ if (slavenet != NULL) slavenet->status = election(slavenet); if (!slavenet || slavenet->status == MASTER) { checkignorednets(); pickslavenet(0); } else { makeslave(slavenet); /* prune extras */ } break; case 2: /* Just been told to quit */ justquit = 1; pickslavenet(savefromnet); break; } setstatus(); if (!(status & MASTER) && sock_raw != -1) { /* sock_raw is not being used now */ (void)close(sock_raw); sock_raw = -1; } if (status == MASTER) master(); else slave(); } else { if (sock_raw != -1) { (void)close(sock_raw); sock_raw = -1; } if (ret) { /* we just lost our master or were told to quit */ justquit = 1; } for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) { rmnetmachs(ntp); ntp->status = NOMASTER; } } checkignorednets(); pickslavenet(0); setstatus(); slave(); } /* NOTREACHED */ return(0); }
void test_cumulative(void) { loggers::global_logger->log( loggers::LOG_ALWAYS, "Testing ElectionCumulative\n"); knowledge::KnowledgeBase knowledge; containers::Integer agent0vote("election.president.0.agent.0->Hillary", knowledge); containers::Integer agent1vote("election.president.0.agent.1->Donald", knowledge); containers::Integer agent2vote("election.president.0.agent.2->Bernie", knowledge); containers::Integer agent3vote("election.president.0.agent.3->Hillary", knowledge); containers::Integer agent4vote("election.president.0.agent.4->Cthulhu", knowledge); containers::Integer agent5vote("election.president.0.agent.5->Hillary", knowledge); containers::Integer agent6vote("election.president.0.agent.6->Cthulhu", knowledge); elections::ElectionCumulative election( "election.president", "agent.0", &knowledge); // do a self vote for agent.0 election.vote("Hillary", 1); if (*agent0vote == 1) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing self vote: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing self vote: FAIL\n"); ++gams_fails; } if (election.has_voted("agent.0")) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing has_voted: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing has_voted: FAIL\n"); ++gams_fails; } // do votes for other agents election.vote("agent.1", "Donald", 1); election.vote("agent.2", "Bernie", 1); election.vote("agent.3", "Hillary", 1); election.vote("agent.4", "Cthulhu", 1); election.vote("agent.5", "Hillary", 1); election.vote("agent.6", "Cthulhu", 1); if (*agent1vote == 1 && *agent2vote == 1.0 && *agent3vote == 1.0 && *agent4vote == 1 && *agent5vote == 1.0 && *agent6vote == 1.0) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing all agent votes: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing all agent votes: FAIL\n"); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.0: %d\n",(int)*agent0vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.1: %d\n",(int)*agent1vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.2: %d\n",(int)*agent2vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.3: %d\n",(int)*agent3vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.4: %d\n",(int)*agent4vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.5: %d\n",(int)*agent5vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.6: %d\n",(int)*agent6vote); ++gams_fails; } elections::CandidateList leaders = election.get_leaders(2); if (leaders.size() == 2 && leaders[0] == "Hillary" && leaders[1] == "Cthulhu") { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leaders == Hillary, Cthulhu: SUCCESS\n"); } else if (leaders.size() == 2) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leader == %s, %s: FAIL\n", leaders[0].c_str(), leaders[1].c_str()); ++gams_fails; } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " %d leaders instead of 2: FAIL\n", leaders.size()); ++gams_fails; } loggers::global_logger->log( loggers::LOG_ALWAYS, " Adding second vote for agent.2...\n"); // vote twice for agent.2 election.vote("agent.2", "Cthulhu", 1); leaders = election.get_leaders(2); if (leaders.size() == 2 && leaders[0] == "Cthulhu" && leaders[1] == "Hillary") { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leaders == Cthulhu, Hillary: SUCCESS\n"); } else if (leaders.size() == 2) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leader == %s, %s: FAIL\n", leaders[0].c_str(), leaders[1].c_str()); ++gams_fails; } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " %d leaders instead of 2: FAIL\n", leaders.size()); ++gams_fails; } }
void test_plurality(void) { loggers::global_logger->log( loggers::LOG_ALWAYS, "Testing ElectionPlurality\n"); knowledge::KnowledgeBase knowledge; containers::Integer agent0vote("election.president.0.agent.0->Hillary", knowledge); containers::Integer agent1vote("election.president.0.agent.1->Donald", knowledge); containers::Integer agent2vote("election.president.0.agent.2->Bernie", knowledge); containers::Integer agent3vote("election.president.0.agent.3->Hillary", knowledge); containers::Integer agent4vote("election.president.0.agent.4->Cthulhu", knowledge); containers::Integer agent5vote("election.president.0.agent.5->Hillary", knowledge); containers::Integer agent6vote("election.president.0.agent.6->Cthulhu", knowledge); elections::ElectionPlurality election( "election.president", "agent.0", &knowledge); // do a self vote for agent.0 and try to cheat on the plurality vote election.vote("Hillary", 7); if (*agent0vote == 7) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing self vote: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing self vote: FAIL\n"); ++gams_fails; } if (election.has_voted("agent.0")) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing has_voted: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing has_voted: FAIL\n"); ++gams_fails; } // do votes for other agents election.vote("agent.1", "Donald", 1); election.vote("agent.2", "Bernie", 1); election.vote("agent.3", "Hillary", 1); election.vote("agent.4", "Cthulhu", 1); election.vote("agent.5", "Hillary", 1); election.vote("agent.6", "Cthulhu", 1); if (*agent1vote == 1 && *agent2vote == 1.0 && *agent3vote == 1.0 && *agent4vote == 1 && *agent5vote == 1.0 && *agent6vote == 1.0) { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing all agent votes: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Testing all agent votes: FAIL\n"); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.0: %d\n",(int)*agent0vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.1: %d\n",(int)*agent1vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.2: %d\n",(int)*agent2vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.3: %d\n",(int)*agent3vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.4: %d\n",(int)*agent4vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.5: %d\n",(int)*agent5vote); loggers::global_logger->log( loggers::LOG_ALWAYS, " agent.6: %d\n",(int)*agent6vote); ++gams_fails; } std::string leader = election.get_leader(); if (leader == "Hillary") { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leader == Hillary: SUCCESS\n"); } else { loggers::global_logger->log( loggers::LOG_ALWAYS, " Leader == %s: FAIL\n", leader.c_str()); ++gams_fails; } }