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);
  }
  
  
}
Esempio n. 2
0
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;
		}
	}
}
Esempio n. 3
0
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;
  }
  
}                                                                                                                                                                   
Esempio n. 5
0
File: msg.c Progetto: CESNET/torque
/*
 * 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);
}
Esempio n. 6
0
/*
 * 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);
}
Esempio n. 7
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;
  }
}
Esempio n. 8
0
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;
  }
}