Example #1
0
BOOL
v2v_stream_recv(struct v2v_stream *stream, void *buf, size_t buf_size,
                size_t *_bytes_received)
{
    struct queued_message *qm;
    size_t bytes_received;
    size_t bytes_this_time;
    HANDLE handles[2];
    DWORD status;

    v2v_nc2_request_fast_receive(stream->channel);
    handles[0] = stream->receive_event;
    handles[1] = stream->control_event;
    for (bytes_received = 0;
            bytes_received < buf_size;
            bytes_received += bytes_this_time) {
        if (!stream->recv_state.current_message) {
            while (!get_next_message(stream)) {
                if (bytes_received != 0 ||
                        GetLastError() != ERROR_NO_MORE_ITEMS)
                    goto out;
                status = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
                if (status == WAIT_OBJECT_0 + 1 && remote_disconnect(stream)) {
                    SetLastError(ERROR_VC_DISCONNECTED);
                    goto out;
                }
            }
        }
        qm = stream->recv_state.current_message;
        bytes_this_time = MIN(qm->size - qm->bytes_already_used,
                              buf_size - bytes_received);
        memcpy( (void *)((ULONG_PTR)buf + bytes_received),
                (const void *)((ULONG_PTR)qm->payload +
                               qm->bytes_already_used),
                bytes_this_time);
        qm->bytes_already_used += bytes_this_time;
        if (qm->bytes_already_used == qm->size) {
            release_queued_message(stream, qm);
            stream->recv_state.current_message = NULL;
        }
    }
out:
    v2v_nc2_cancel_fast_receive(stream->channel);
    *_bytes_received = bytes_received;
    if (bytes_received == 0)
        return FALSE;
    else
        return TRUE;
}
Example #2
0
File: msg.c Project: 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);
}
Example #3
0
// processing the file_name by removing its \t and spaces at the head
// and attach the file handler with the class
// Return 0 if successful
// Return non zero if fail
int Traffic_source::set_trace_file(char * file_name) {

  trace_file_empty = false;

    string str_file(file_name);
    // lets rip off any space or table key at the beginning of the file_name
    rip_off_space_and_table(str_file);
    trace_file.open(str_file.c_str());

    trace_file_loop_cnt = 0;

    if (!trace_file.is_open() || !trace_file.good())
        return -1;

    // let's preparse the file to get the period, and also verify the trace_file
    period = 0;
    int prev_time = -1;
    char input_line[MAX_LINE];
    char * sub_string;
    while (trace_file.getline(input_line, MAX_LINE, '\n')) {
        // line starting with "#" are coomments
        if (input_line[0] == '#')
            continue;

        if (strstr(input_line, "PERIOD")) {
            sub_string = strstr(input_line, "PERIOD");
            sub_string += strlen("PERIOD");

            if (!sscanf(sub_string, "%d", &period)) {
                trace_file.close();
                cerr << ERRO_BAD_TRACE_FILE << str_file << endl;
                return -1;
            }
            assert(period > 0);
            continue;
        }

        // otherwise, the line should contain 3 integers in the format
        // of:
        // timestamp     destination     message_size
        int timestamp;
        unsigned int destination, message_size;
        istringstream istr(input_line, istringstream::in);
        istr >> timestamp >> destination >> message_size;
        period = max(timestamp+1, period);
        if (timestamp <= prev_time) {
            trace_file.close();
            cerr << ERRO_BAD_TRACE_FILE << str_file << endl;
            return -1;
        }
        prev_time = timestamp;
        continue;
    }

 //   assert(period > 0);

    if (prev_time == -1) {
      // the trace file does not contain any messages
      cout << WARN_EMPTY_TRACE_FILE << str_file << endl;
      trace_file_empty = true;
      return 0;
    }

    // rewind the trace file and pre-fetch one message
    trace_file.clear();
    trace_file.seekg(0, ios::beg);
    trace_file.clear();
    get_next_message(pre_fetched_message);

    return 0;
}
Example #4
0
void Traffic_source::tick(void) {
    if (trace_file.is_open()) {
        // if we have a trace file, read and generate packet using 
        // the trace file

      if (!trace_file_empty) {
        if (pre_fetched_message.timestamp == net_clock.get_clock()) { // % period) {
            // time to do send the message in the pre-fetched message
            generate_packets(pre_fetched_message);
            Message a_message;
            do {
                get_next_message(a_message);
                if (a_message.timestamp == net_clock.get_clock()) // % period) 
                    generate_packets(a_message);
                else
                    pre_fetched_message = a_message;
            } while (a_message.timestamp == net_clock.get_clock()); // % period);

            // the last message is the one which is not ready to fire yet,
            // we should save it as the pre_fetched_message
            pre_fetched_message = a_message;
        }
      }
    }
    else if (on_off_model)  {
      if (next_generation_time == net_clock.get_clock())  { // Time to generate new message
	// Decide the destination address
	unsigned int dst_id = id;
	if (packet_to_destination_rate) {
	  dst_id = get_destination_customized();
        }
        else if (traffic_mode == uniform) {
	  dst_id = get_destination_uniform();
        }
        else if (traffic_mode == transpose1) {
	  dst_id = get_destination_transpose1();
        }
        else if (traffic_mode == transpose2) {
	  dst_id = get_destination_transpose2();
        }
        else if (traffic_mode == hotspot) {
	  dst_id = get_destination_hotspot();
        }
        else {
	  cerr << ERRO_TRAFFIC_PATTEN_NOT_SUPPORTED;
	  return;
        }

        if ( (dst_id != id) && (total_pkt_sent < pkt_to_sent) ) {
	  bool pkt_generated = 0;
	  if (buffer.empty_slots() >= on_period) { // Finite source buffer
	    // Source flow control implemented here
	    if (param.flow_control) {
	      pRouter localRouter = param.network->get_router(pos);     // Find the local router
	      pIn_port localPort = localRouter->get_in_port(local);     // get the local port
	      int acceptable = localPort->get_total_acceptable();
	 
	      if (acceptable > param.availability_thresh) {
		generate_a_packet(dst_id,on_period);
		pkt_generated = 1;
		total_pkt_sent ++;
	      }
	      //      if (id == 6 || id == 8 || id == 10 || id == 15)
	      //	printf("At %d acceptable:%d \n",id,acceptable);
	    }  // Flow control
	    else {
	      generate_a_packet(dst_id,on_period);
	      pkt_generated = 1;
	      total_pkt_sent ++;
	    }
	  } // buffer.empty_slots
          // Compute the next generate time
	  if (!pkt_generated) {
	    next_generation_time ++;
	    param.gen_delay ++;
	  }
	  else {
	    int wait_time = (int) (-log(drand48())*wait_period);
	    if (wait_time <= 0)
	      wait_time = 0;
	    next_generation_time =  net_clock.get_clock() + on_period + off_period + wait_time;
	    // printf("Next generation time for %d is %d \n",id,next_generation_time);
	    // printf("Empty slots not sufficient \n");
	  }
	} // (dst_id != id)
	//	else {
	//  //printf("At %d, total pkt sent is %d at time %d\n",id,total_pkt_sent, net_clock.get_clock());
	//  param.on_off_complete_time =  net_clock.get_clock();
	//}   
      } // if(next_generation...
    } // else if (on_off_model
    
    else if (drand48() < packet_generating_rate) {  // mimic possion arrival
        unsigned int dst_id = id;

        // if this node has customized rate table, use this one instead of 
        // global traffic mode setup
        if (packet_to_destination_rate) {
            dst_id = get_destination_customized();
        }
        else if (traffic_mode == uniform) {
            dst_id = get_destination_uniform();
        }
        else if (traffic_mode == transpose1) {
            dst_id = get_destination_transpose1();
        }
        else if (traffic_mode == transpose2) {
            dst_id = get_destination_transpose2();
        }
        else if (traffic_mode == hotspot) {
            dst_id = get_destination_hotspot();
        }
        else {
            cerr << ERRO_TRAFFIC_PATTEN_NOT_SUPPORTED;
            return;
        }
        if (dst_id != id)
            generate_a_packet(dst_id);
    }

    // as a sender, do sending
    if (can_send()) 
      send();
}