示例#1
0
/***********************************************************************
 * The task function of send task
 * Form:     static void pofdp_send_raw_task(void *arg)
 * Input:    NONE
 * Output:   NONE
 * Return:   VOID
 * Discribe: This is the task function of send task, which is infinite
 *           loop running. It reads the send queue to get the packet data
 *           and the sending port infomation. Then it sends the packet
 *           out by binding the socket to the local physical net port
 *           spicified in the port infomation.
 * NOTE:     This task will be terminated if any ERRORs occur.
 ***********************************************************************/
static uint32_t pofdp_send_raw_task(void *arg){
    struct pofdp_packet *dpp = malloc(sizeof *dpp);
    struct   sockaddr_ll sll;
    int      sock;

    /* Create socket. */
    if((sock = socket(PF_PACKET, SOCK_RAW, POF_HTONS(ETH_P_ALL))) == -1){
        POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_CREATE_SOCKET_FAILURE, g_upward_xid++);

        /* Delay 0.1s to send error message upward to the Controller. */
        pofbf_task_delay(100);
        terminate_handler();
    }
    memset(&sll, 0, sizeof(struct sockaddr_ll));

    while(1){

        /* Read the message from the queue. */
        if(pofbf_queue_read(g_pofdp_send_q_id, dpp, sizeof *dpp, POF_WAIT_FOREVER) != POF_OK){
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_READ_MSG_QUEUE_FAILURE, g_upward_xid++);

            /* Delay 0.1s to send error message upward to the Controller. */
            pofbf_task_delay(100);
            terminate_handler();
        }

        /* Send the packet data out through the port. */
        sll.sll_ifindex = dpp->output_port_id;
        sll.sll_family = AF_PACKET;
        sll.sll_protocol = POF_HTONS(ETH_P_ALL);
        if(sendto(sock, dpp->buf_out, dpp->output_whole_len, 0, (struct sockaddr *)&sll, sizeof(sll)) == -1){
			free(dpp->buf_out);
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_SEND_MSG_FAILURE, g_upward_xid++);

            /* Delay 0.1s to send error message upward to the Controller. */
            pofbf_task_delay(100);
            terminate_handler();
        }
		free(dpp->buf_out);
    }

    close(sock);
    return POF_OK;
}
示例#2
0
void
sighandler(int sig, short event, void *arg)
{
	switch (sig) {
	case SIGTERM:
	case SIGINT:
		(void)event_loopexit(NULL);
        terminate_handler();
	}
}
示例#3
0
static uint32_t pofsc_performance_after_ctrl_disconn(){
#if (POF_PERFORM_AFTER_CTRL_DISCONN == POF_AFTER_CTRL_DISCONN_SHUT_DOWN)
    terminate_handler();
#elif (POF_PERFORM_AFTER_CTRL_DISCONN == POF_AFTER_CTRL_DISCONN_RECONN)
    pofsc_conn_desc.conn_status.state = POFCS_CHANNEL_INVALID;
	if(pof_auto_clear()){
		poflr_clear_resource();
	}
#endif // POF_PERFORM_AFTER_CTRL_DISCONN
    return POF_OK;
}
示例#4
0
/***********************************************************************
 * The endless function which control module is running.
 * Form:     static void pofsc_wait_exit()
 * Input:    NONE
 * Output:   NONE
 * Return:   VOID
 * Discribe: After all of the initialization function, the main task will
 *           keep running in this function until "quit" is inputed by
 *           user command line.
 ***********************************************************************/
static uint32_t pofsc_wait_exit(){
    char s[20];
#ifdef POF_COMMAND_ON
    sleep(1);
    pof_runing_command(s, 20);
#else // POF_COMMAND_ON
    char s_quit[] = "quit";
    fgets(s,20,stdin);
    while(memcmp(s,s_quit,sizeof(s_quit)-1) != 0){
        printf("Pleas input 'quit' to quit!\n");
        fgets(s,20,stdin);
    }
#endif
    terminate_handler();
    return POF_OK;
}
示例#5
0
/***********************************************************************
 * The task function of the datapath task
 * Form:     static void pofdp_main_task(void *arg_ptr)
 * Input:    NONE
 * Output:   NONE
 * Return:   VOID
 * Discribe: This is the main function of the datapath task, which is
 *           infinite loop running. It receive the RAW packet, and forward.
 *           The next RAW packet will be not proceeded until the forward
 *           process of the last packet is over.
 * NOTE:     The datapath task will be terminated if some ERROR occurs
 *           during the receive process and the datapath process.
 ***********************************************************************/
static uint32_t pofdp_main_task(void *arg_ptr){
    uint8_t recv_buf[POFDP_PACKET_RAW_MAX_LEN] = {0};
	struct pofdp_packet dpp[1] = {0};
	struct pof_instruction first_ins[1] = {0};
    uint32_t len_B = 0, port_id = 0;
    uint32_t ret;

	/* Set GOTO_TABLE instruction to go to the first flow table. */
	set_goto_first_table_instruction(first_ins);

    while(1){
        /* Receive raw packet through local physical OpenFlow-enabled ports. */
        ret = pofdp_recv_raw(dpp);
        if(ret != POF_OK){
            POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret);
            /* Delay 0.1s to send error message upward to the Controller. */
            pofbf_task_delay(100);
            terminate_handler();
        }

        /* Check the packet length. */
        if(dpp->ori_len > POFDP_PACKET_RAW_MAX_LEN){
			free_packet_data(dpp);
            POF_ERROR_HANDLE_NO_RETURN_NO_UPWARD(POFET_SOFTWARE_FAILED, POF_PACKET_LEN_ERROR);
            continue;
        }

		/* Check whether the first flow table exist. */
		if(POF_OK != poflr_check_flow_table_exist(POFDP_FIRST_TABLE_ID)){
			POF_DEBUG_CPRINT_FL(1,RED,"Received a packet, but the first flow table does NOT exist.");
			free_packet_data(dpp);
			continue;
		}

        /* Forward the packet. */
        ret = pofdp_forward(dpp, first_ins);
        POF_CHECK_RETVALUE_NO_RETURN_NO_UPWARD(ret);

		free_packet_data(dpp);
        POF_DEBUG_CPRINT_FL(1,GREEN,"one packet_raw has been processed!\n");
    }
    return POF_OK;
}
示例#6
0
/***********************************************************************
 * The task function for connection and state machine task.
 * Form:     void pofsc_main_task(void *arg_ptr)
 * Input:    NONE
 * Output:   NONE
 * Return:   VOID
 * Discribe: This task function keeps running the state machine of Soft
 *           Switch. The Soft Switch always works on one of states.
 *           Before the POFCS_CHANNEL_RUN state, this function
 *           builds the connection with the Cntroller by sending and
 *           receiving the "Hello" packet, replying the requests from the
 *           Controller, and so on. During the POFCS_CHANNEL_RUN state,
 *           it receive OpenFlow messages from the Controller and send
 *           them to the other modules to handle.
 ***********************************************************************/
static uint32_t pofsc_main_task(void *arg_ptr){
    pofsc_dev_conn_desc *conn_desc_ptr = (pofsc_dev_conn_desc *)&pofsc_conn_desc;
    pof_header          *head_ptr, head;
    int total_len = 0, tmp_len, left_len, rcv_len = 0, process_len = 0, packet_len = 0;
    int socket_fd;
    uint32_t ret;

    /* Clear error record. */
    pofsc_protocol_error.type = 0xffff;

    /* State machine of the control module in Soft Switch. */
    while(1)
    {
        if(conn_desc_ptr->conn_status.state != POFCS_CHANNEL_RUN && !conn_desc_ptr->conn_retry_count){
            POF_DEBUG_CPRINT_FL(1,BLUE, ">>Openflow Channel State: %s", pofsc_state_str[conn_desc_ptr->conn_status.state]);
        }

        switch(conn_desc_ptr->conn_status.state){
            case POFCS_CHANNEL_INVALID:

                /* Create openflow channel socket. */
                ret = pofsc_create_socket(&socket_fd);
                if(ret == POF_OK){
                    conn_desc_ptr->sfd = socket_fd;
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_CONNECTING;
                }else{
                    POF_ERROR_CPRINT_FL(1,RED,">>Create socket FAIL!");
                    terminate_handler();
                }
                break;

            case POFCS_CHANNEL_CONNECTING:
                /* Connect controller. */
				if(!conn_desc_ptr->conn_retry_count){
					POF_PRINT(1,GREEN,">>Connecting to POFController...\n");
				}
                ret = pofsc_connect(conn_desc_ptr->sfd, conn_desc_ptr->controller_ip, conn_desc_ptr->controller_port);
                if(ret == POF_OK){
                    POF_DEBUG_CPRINT_FL(1,GREEN,">>Connect to controler SUC! %s: %u", \
                                        pofsc_controller_ip_addr, POF_CONTROLLER_PORT_NUM);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_CONNECTED;
					conn_desc_ptr->conn_retry_count = 0;
                }else{
					if(!conn_desc_ptr->conn_retry_count){
						POF_DEBUG_CPRINT_FL(1,RED,">>Connect to controler FAIL!");
					}
                    /* Delay several seconds. */
                    pofbf_task_delay(conn_desc_ptr->conn_retry_interval * 1000);
                    conn_desc_ptr->conn_retry_count++;
                    conn_desc_ptr->conn_status.last_error = (uint8_t)(POF_CONNECT_SERVER_FAILURE); /**/
                    conn_desc_ptr->sfd = 0;
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                }
                break;

            case POFCS_CHANNEL_CONNECTED:
                /* Send hello to controller. Hello message has no body. */
                pofsc_build_header(&head, \
                                   POFT_HELLO, \
                                   sizeof(pof_header), \
                                   g_upward_xid++);
                /* send hello message. */
                ret = pofsc_send(conn_desc_ptr->sfd, (char*)&head, sizeof(pof_header));
                if(ret == POF_OK){
                    conn_desc_ptr->conn_status.state = POFCS_HELLO;
                }else{
                    POF_ERROR_CPRINT_FL(1,RED,"Send HELLO FAIL!");
                }

                break;

            case POFCS_HELLO:
                /* Receive hello from controller. */
                total_len = 0;
                left_len = 0;
                rcv_len = 0;
                process_len = 0;
                ret = pofsc_recv(conn_desc_ptr->sfd, conn_desc_ptr->recv_buf , POF_RECV_BUF_MAX_SIZE, &total_len);
                if(ret == POF_OK){
                    POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie HELLO packet SUC!");
					poflr_clear_resource();
                    conn_desc_ptr->conn_status.state = POFCS_REQUEST_FEATURE;
                }else{
                    POF_ERROR_CPRINT_FL(1,RED,"Recv HELLO FAILE!");
                    break;
                }
                rcv_len += total_len;

                /* Parse. */
                head_ptr = (pof_header *)conn_desc_ptr->recv_buf;
                while(total_len < POF_NTOHS(head_ptr->length)){
                    ret = pofsc_recv(conn_desc_ptr->sfd, conn_desc_ptr->recv_buf  + rcv_len, POF_RECV_BUF_MAX_SIZE -rcv_len,  &tmp_len);
                    if(ret != POF_OK){
                        POF_ERROR_CPRINT_FL(1,RED,"Recv HELLO FAILE!");
                        break;
                    }

                    total_len += tmp_len;
                    rcv_len += tmp_len;
                }

                if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){
                    break;
                }

                /* Check any error. */
                if(head_ptr->version > POF_VERSION){
                    POF_ERROR_CPRINT_FL(1,RED,"Version of recv-packet is higher than support!");
                    pofsc_set_error(POFET_HELLO_FAILED, POFHFC_INCOMPATIBLE);
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                }else if(head_ptr->type != POFT_HELLO){
                    POF_ERROR_CPRINT_FL(1,RED,"Type of recv-packet is not HELLO, which we want to recv!");
                    pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE);
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                }

                process_len += POF_NTOHS(head_ptr->length);
                left_len = rcv_len - process_len;
                if(left_len == 0){
                    rcv_len = 0;
                    process_len = 0;
                }
                break;

            case POFCS_REQUEST_FEATURE:
                /* Wait to receive feature request from controller. */
                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){
                    ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf  + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len);
                    if(ret == POF_OK){
                        conn_desc_ptr->conn_status.state = POFCS_SET_CONFIG;
                    }else{
                        POF_ERROR_CPRINT_FL(1,RED,"Feature request FAIL!");
                        break;
                    }

                    rcv_len += total_len;
                    total_len += left_len;

                    head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len);
                    while(total_len < POF_NTOHS(head_ptr->length)){
                        ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf  + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len);
                        if(ret != POF_OK){
                            POF_ERROR_CPRINT_FL(1,RED,"Feature request FAIL!");
                            break;
                        }
                        total_len += tmp_len;
                        rcv_len += tmp_len;
                    }
                }

                if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){
                    break;
                }

                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);

                /* Check any error. */
                if(head_ptr->type != POFT_FEATURES_REQUEST){
                    pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE);
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                    break;
                }

                POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie FEATURE_REQUEST packet SUC!");
                conn_desc_ptr->conn_status.state = POFCS_SET_CONFIG;
                packet_len = POF_NTOHS(head_ptr->length);

                ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len);

                if(ret != POF_OK){
                    POF_ERROR_CPRINT_FL(1,RED,"Features request FAIL!");
                    terminate_handler();
                    break;
                }

                process_len += packet_len;
                left_len = rcv_len - process_len;
                if(left_len == 0){
                    rcv_len = 0;
                    process_len = 0;
                }

                break;

            case POFCS_SET_CONFIG:
                /* Receive set_config message from controller. */
                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){
                    ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf  + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len);
                    if(ret == POF_OK){
                        conn_desc_ptr->conn_status.state = POFCS_REQUEST_GET_CONFIG;
                    }else{
                        POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!");
                        break;
                    }

                    rcv_len += total_len;
                    total_len += left_len;

                    head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len);
                    while(total_len < POF_NTOHS(head_ptr->length)){
                        ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf  + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len);
                        if(ret != POF_OK){
                            POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!");
                            break;
                        }
                        total_len += tmp_len;
                        rcv_len += tmp_len;
                    }
                }

                if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){
                    break;
                }

                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);

                /* Check any error. */
                if(head_ptr->version > POF_VERSION){
                    POF_ERROR_CPRINT_FL(1,RED,"Version of recv-packet is higher than support!");
                    pofsc_set_error(POFET_BAD_REQUEST, POFHFC_INCOMPATIBLE);
                    POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!");
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                    break;
                }else if(head_ptr->type != POFT_SET_CONFIG){
                    POF_ERROR_CPRINT_FL(1,RED,"Type of recv-packet is not SET_CONFIG, which we want to recv!");
                    pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE);
                    POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!");
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                    break;
                }

                POF_DEBUG_CPRINT_FL(1,BLUE,">>Recevie SET_CONFIG packet SUC!");
                conn_desc_ptr->conn_status.state = POFCS_REQUEST_GET_CONFIG;
                packet_len = POF_NTOHS(head_ptr->length);

                ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len);

                if(ret != POF_OK){
                    POF_ERROR_CPRINT_FL(1,RED,"Set config FAIL!");
                    terminate_handler();
                    break;
                }

                process_len += packet_len;
                left_len = rcv_len - process_len;

                if(left_len == 0){
                    rcv_len = 0;
                    process_len = 0;
                }
                break;

            case POFCS_REQUEST_GET_CONFIG:
                /* Wait to receive feature request from controller. */
                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                if(!((left_len >= sizeof(pof_header)) && (left_len >= POF_NTOHS(head_ptr->length)))){
                    ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf  + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len);
                    if(ret == POF_OK){
                        conn_desc_ptr->conn_status.state = POFCS_CHANNEL_RUN;
                    }else{
                        POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!");
                        break;
                    }

                    rcv_len += total_len;
                    total_len += left_len;

                    head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len);
                    while(total_len < POF_NTOHS(head_ptr->length)){
                        ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf  + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len);
                        if(ret != POF_OK){
                            POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!");
                            break;
                        }

                        total_len += tmp_len;
                        rcv_len += tmp_len;
                    }
                }

                if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){
                    break;
                }

                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                /* Check any error. */
                if(head_ptr->type != POFT_GET_CONFIG_REQUEST){
                    pofsc_set_error(POFET_BAD_REQUEST, POFBRC_BAD_TYPE);
                    POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!");
                    close(conn_desc_ptr->sfd);
                    conn_desc_ptr->conn_status.state = POFCS_CHANNEL_INVALID;
                    break;
                }

                POF_DEBUG_CPRINT_FL(1,GREEN,">>Recevie GET_CONFIG_REQUEST packet SUC!");
                packet_len = POF_NTOHS(head_ptr->length);

                ret = pof_parse_msg_from_controller(conn_desc_ptr->recv_buf + process_len);
                if(ret != POF_OK){
                    POF_ERROR_CPRINT_FL(1,RED,"Get config FAIL!");
                    terminate_handler();
                    break;
                }

                process_len += packet_len;
                left_len = rcv_len - process_len;

                if(left_len == 0){
                    rcv_len = 0;
                    process_len = 0;
                }

				sleep(1);
                conn_desc_ptr->conn_status.state = POFCS_CHANNEL_RUN;
				POF_PRINT(1,GREEN,">>Connect to POFController successfully!\n");

                break;

            case POFCS_CHANNEL_RUN:
                /* Wait to receive feature request from controller. */
                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                if(!((left_len >= sizeof(pof_header))&&(left_len >= POF_NTOHS(head_ptr->length)))){
                    /* Resv_buf has no space, so should move the left data to the head of the buf. */
                    if(POF_RECV_BUF_MAX_SIZE == rcv_len){
                        memcpy(conn_desc_ptr->recv_buf,  conn_desc_ptr->recv_buf  + process_len, left_len);
                        rcv_len = left_len;
                        process_len = 0;
                    }
                    ret = pofsc_recv(conn_desc_ptr->sfd, (conn_desc_ptr->recv_buf  + rcv_len), POF_RECV_BUF_MAX_SIZE - rcv_len, &total_len);
                    if(ret != POF_OK){
                        break;
                    }

                    rcv_len += total_len;
                    total_len += left_len;

                    head_ptr = (pof_header *)(conn_desc_ptr->recv_buf + process_len);
                    while(total_len < POF_NTOHS(head_ptr->length)){
                        ret = pofsc_recv(conn_desc_ptr->sfd, ((conn_desc_ptr->recv_buf  + rcv_len)), POF_RECV_BUF_MAX_SIZE-rcv_len ,&tmp_len);
                        if(ret != POF_OK){
                            break;
                        }
                    total_len += tmp_len;
                    rcv_len += tmp_len;
                    }
                }

                if(conn_desc_ptr->conn_status.state == POFCS_CHANNEL_INVALID){
                    break;
                }

                head_ptr = (pof_header *)(conn_desc_ptr->recv_buf  + process_len);
                packet_len = POF_NTOHS(head_ptr->length);
                /* Handle the message. Echo messages will be processed here and other messages will be forwarded to LUP. */
                ret = pofsc_run_process(conn_desc_ptr->recv_buf + process_len, packet_len);

                process_len += packet_len;
                left_len = rcv_len - process_len;

                if(left_len == 0){
                    rcv_len = 0;
                    process_len = 0;
                }
                break;

            default:
                conn_desc_ptr->conn_status.last_error = (uint8_t)POF_WRONG_CHANNEL_STATE;
                break;
        }

        /* If any error is detected, reply to controller immediately. */
        if(pofsc_protocol_error.type != 0xffff){
            tmp_len = 0;
            /* Build error message. */
            (void)pofsc_build_error_msg(conn_desc_ptr->send_buf, (uint16_t*)&tmp_len);

            /* Write error message in queue for sending. */
            ret = pofbf_queue_write(pofsc_send_q_id, conn_desc_ptr->send_buf, (uint32_t)tmp_len, POF_WAIT_FOREVER);
            POF_CHECK_RETVALUE_TERMINATE(ret);
        }
    }
    return;
}
示例#7
0
文件: main.c 项目: gaoxiaojun/mpmc
int main(int argc, char **argv) {

	char linebuf[MAXLINE];
	char input_file[MAXLINE];
	system_t *system;
	time_t t = time(NULL);
	struct tm tm = *localtime(&t);

	/* set the default rank */
	rank = 0; size = 1;

	/* check args */
	if(argc < 2) usage(argv[0]);

	/* start up the MPI chain */
#ifdef MPI
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
#endif /* MPI */
	
	if( !rank ) {
		sprintf(linebuf, "MPMC (Massively Parallel Monte Carlo) r%d - 2012-2017 GNU Public License\n", VERSION);
		output(linebuf);
		sprintf(linebuf, "MAIN: processes started on %d cores @ %d-%d-%d %d:%d:%d\n", size, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
		output(linebuf);
	}
	
#ifndef MPI
	FILE *procfile;
	FILE *host;
	char nodename[MAXLINE];
	char cpu[MAXLINE];
	struct stat info;

	// These system calls were causing a fork() that does not play nice with some
	// MPI implementations (causing some processes to never end... )
	
	/* Collect and output hostname & processor info */
	if(access("/proc/cpuinfo",R_OK)!=-1) {                                          // Linux
		host = popen("hostname","r");
		fgets(nodename, MAXLINE, host);
		sprintf(linebuf, "MAIN: Job running on node -> %s", nodename);
		output(linebuf);
		pclose(host);
		
		procfile = fopen("/proc/cpuinfo", "r");
		while (!feof(procfile)) {
			fgets(cpu, MAXLINE, procfile);
			if(strncasecmp(cpu,"model name",10)==0) {
			sprintf(linebuf, "MAIN: CPU -> %s", cpu);
			output(linebuf);
			break;
		}
	}
	fclose(procfile);
	} else if (stat("/Applications",&info)==0) {                                  // Mac OS
		output("MAIN: Mac OS detected\n");
		host = popen("hostname", "r");
		fgets(nodename, MAXLINE, host);
		sprintf(linebuf, "MAIN: Job running on node -> %s", nodename);
		output(linebuf);
		pclose(host);
		
		procfile = popen("sysctl -n machdep.cpu.brand_string","r");
		fgets(cpu, MAXLINE, procfile);
		sprintf(linebuf, "MAIN: CPU -> %s", cpu);
		output(linebuf);
		pclose(procfile);
	}
#endif // !MPI

	/* get the config file arg */
	strcpy(input_file, argv[1]);
	sprintf(linebuf, "MAIN: running parameters found in %s\n", input_file);
	output(linebuf);

	/* read the input files and setup the simulation */
	system = setup_system(input_file);
	if(!system) {
		error("MAIN: could not initialize the simulation\n");
		die(1);
	} else {
		output("MAIN: the simulation has been initialized\n");
	}
	
	/* install the signal handler to catch SIGTERM cleanly */
	terminate_handler(-1, system);
	signal(SIGTERM, ((void *)(terminate_handler)));
	signal(SIGUSR1, ((void *)(terminate_handler)));
	signal(SIGUSR2, ((void *)(terminate_handler)));
	output("MAIN: signal handler installed\n");

	/* allocate space for the statistics */
	system->nodestats = calloc(1, sizeof(nodestats_t));
	memnullcheck(system->nodestats,sizeof(nodestats_t), __LINE__-1, __FILE__);
	system->avg_nodestats = calloc(1, sizeof(avg_nodestats_t));
	memnullcheck(system->avg_nodestats,sizeof(avg_nodestats_t), __LINE__-1, __FILE__);
	system->observables = calloc(1, sizeof(observables_t));
	memnullcheck(system->observables,sizeof(observables_t), __LINE__-1, __FILE__);
	system->avg_observables = calloc(1, sizeof(avg_observables_t));
	memnullcheck(system->avg_observables,sizeof(avg_observables_t), __LINE__-1, __FILE__);
	system->checkpoint = calloc(1, sizeof(checkpoint_t));
	memnullcheck(system->checkpoint,sizeof(checkpoint_t), __LINE__-1, __FILE__);
	system->checkpoint->observables = calloc(1, sizeof(observables_t));
	memnullcheck(system->checkpoint->observables,sizeof(observables_t), __LINE__-1, __FILE__);
	system->grids = calloc(1,sizeof(grid_t));
	memnullcheck(system->grids,sizeof(grid_t), __LINE__-1, __FILE__);
	system->grids->histogram = calloc(1,sizeof(histogram_t));
	memnullcheck(system->grids->histogram,sizeof(histogram_t), __LINE__-1, __FILE__);
	system->grids->avg_histogram = calloc(1,sizeof(histogram_t));
	memnullcheck(system->grids->avg_histogram,sizeof(histogram_t), __LINE__-1, __FILE__);

	/* if polarization active, allocate the necessary matrices */
	if(system->polarization && !system->cuda && !system->polar_zodid)
		thole_resize_matrices(system);

	/* if histogram calculation flag is set, allocate grid */
	if(system->calc_hist){
		setup_histogram(system);
		allocate_histogram_grid(system);
	}

	/* seed the rng if neccessary */
	if ( system->ensemble != ENSEMBLE_TE && system->ensemble != ENSEMBLE_REPLAY )
		seed_rng(system, rank);

#ifdef MPI
	MPI_Barrier(MPI_COMM_WORLD);
	sprintf(linebuf, "MAIN: all %d cores are in sync\n", size);
	output(linebuf);
#endif /* MPI */

	/* start the MC simulation */
	if(system->ensemble == ENSEMBLE_UVT) {
		output("MAIN: *******************************************************\n");
		output("MAIN: *** starting Grand Canonical Monte Carlo simulation ***\n");
		output("MAIN: *******************************************************\n");
	} else if(system->ensemble == ENSEMBLE_NVT) {
		output("MAIN: *************************************************\n");
		output("MAIN: *** starting Canonical Monte Carlo simulation ***\n");
		output("MAIN: *************************************************\n");
	} else if(system->ensemble == ENSEMBLE_NVE) {
		output("MAIN: ******************************************************\n");
		output("MAIN: *** starting Microcanonical Monte Carlo simulation ***\n");
		output("MAIN: ******************************************************\n");
	} else if(system->ensemble == ENSEMBLE_SURF) {	/* surface run */
		output("MAIN: *****************************************************\n");
		output("MAIN: *** starting potential energy surface calculation ***\n");
		output("MAIN: *****************************************************\n");
	} else if(system->ensemble == ENSEMBLE_REPLAY) {	/* surface fitting run */
		output("MAIN: **********************************\n");
		output("MAIN: *** starting trajectory replay ***\n");
		output("MAIN: **********************************\n");
	} else if(system->ensemble == ENSEMBLE_SURF_FIT) {	/* surface fitting run */
		output("MAIN: *************************************************************\n");
		output("MAIN: *** starting potential energy surface fitting calculation ***\n");
		output("MAIN: *************************************************************\n");
	} else if(system->ensemble == ENSEMBLE_TE) {	/* surface fitting run */
		output("MAIN: *************************************************\n");
		output("MAIN: *** starting single-point energy calculation  ***\n");
		output("MAIN: *************************************************\n");
	}



	if(system->ensemble == ENSEMBLE_SURF) { /* surface */
		if(surface(system) < 0) {
			error("MAIN: surface module failed on error, exiting\n");
			die(1);
		}
	}
	
	
	else if(system->ensemble == ENSEMBLE_SURF_FIT) { /* surface fitting */
	    
		if( system->surf_fit_arbitrary_configs ) {
			if( surface_fit_arbitrary( system ) < 0 ) {
				error("MAIN: surface fitting module (for arbitrary configurations) failed on error, exiting\n");
				die(1);
			}
		}
		else if(surface_fit(system) < 0) {
			error("MAIN: surface fitting module failed on error, exiting\n");
			die(1);
		}
	}
	
	
	else if(system->ensemble == ENSEMBLE_REPLAY) { /* replay trajectory and recalc energies, etc. */
		if(replay_trajectory(system) < 0) {
			error("MAIN: trajectory replay failed, exiting\n");
			die(1);
		}
	}
	
	
	else if(system->ensemble == ENSEMBLE_TE) {
		if(calculate_te(system) < 0) {
			error("MAIN: single-point energy calculation failed, exiting\n");
			die(1);
		}
	}
	
	
	else { //else run monte carlo
		if(mc(system) < 0) {
			error("MAIN: MC failed on error, exiting\n");
			die(1);
		}
	}



	/* cleanup */
	output("MAIN: freeing all data structures....");
	cleanup(system);
	output("...done\n");

	output("MAIN: simulation exiting successfully\n\n");
	die(0);

	return 0;
}
示例#8
0
/***********************************************************************
 * The task function of receive task
 * Form:     static void pofdp_recv_raw_task(void *arg_ptr)
 * Input:    port infomation
 * Output:   NONE
 * Return:   VOID
 * Discribe: This is the task function of receive task, which is infinite
 *           loop running. It receives RAW packet by binding socket to the
 *           local physical net port spicified in the port infomation.
 *           After filtering, the packet data and port infomation will be
 *           assembled with format of struct pofdp_packet, and be send
 *           into the receive queue. The only parameter arg_ptr is the
 *           pointer of the local physical net port infomation which has
 *           been assembled with format of struct pof_port.
 * NOTE:     This task will be terminated if any ERRORs occur.
 *           If the openflow function of this physical port is disable,
 *           it will be still loop running but nothing will be received.
 ***********************************************************************/
static uint32_t pofdp_recv_raw_task(void *arg_ptr){
    pof_port *port_ptr = (pof_port *)arg_ptr;
    struct pofdp_packet *dpp = malloc(sizeof *dpp);
    struct   sockaddr_ll sockadr, from;
    uint32_t from_len, len_B;
    uint8_t  buf[POFDP_PACKET_RAW_MAX_LEN];
    int      sock;

    from_len = sizeof(struct sockaddr_ll);

    /* Create socket, and bind it to the specific port. */
    if((sock = socket(AF_PACKET, SOCK_RAW, POF_HTONS(ETH_P_ALL))) == -1){
        POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_CREATE_SOCKET_FAILURE, g_upward_xid++);
        /* Delay 0.1s to send error message upward to the Controller. */
        pofbf_task_delay(100);
        terminate_handler();
    }

    sockadr.sll_family = AF_PACKET;
    sockadr.sll_protocol = POF_HTONS(ETH_P_ALL);
    sockadr.sll_ifindex = port_ptr->port_id;

    if(bind(sock, (struct sockaddr *)&sockadr, sizeof(struct sockaddr_ll)) != 0){
       POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_BIND_SOCKET_FAILURE, g_upward_xid++);
        /* Delay 0.1s to send error message upward to the Controller. */
        pofbf_task_delay(100);
        terminate_handler();
    }

    /* Receive the raw packet through the specific port. */
    while(1){
		pthread_testcancel();

        /* Receive the raw packet. */
        if((len_B = recvfrom(sock, buf, POFDP_PACKET_RAW_MAX_LEN, 0, (struct sockaddr *)&from, &from_len)) <=0){
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_RECEIVE_MSG_FAILURE, g_upward_xid++);
            continue;
        }

        /* Check whether the OpenFlow-enabled of the port is on or not. */
        if(port_ptr->of_enable == POFLR_PORT_DISABLE){
            continue;
        }

        /* Check the packet length. */
        if(len_B > POF_MTU_LENGTH){
            POF_DEBUG_CPRINT_FL(1,RED,"The packet received is longer than MTU. DROP!");
            continue;
        }

        /* Filter the received raw packet by some rules. */
        if(pofdp_packet_raw_filter(buf, port_ptr) != POF_OK){
            continue;
        }
		
        /* Store packet data, length, received port infomation into the message queue. */
		memset(dpp, 0, sizeof *dpp);
        dpp->ori_port_id = port_ptr->port_id;
		malloc_packet_data(dpp, len_B);
        memcpy(dpp->buf, buf, len_B);

        if(pofbf_queue_write(g_pofdp_recv_q_id, dpp, sizeof *dpp, POF_WAIT_FOREVER) != POF_OK){
            POF_ERROR_HANDLE_NO_RETURN_UPWARD(POFET_SOFTWARE_FAILED, POF_WRITE_MSG_QUEUE_FAILURE, g_upward_xid++);
			free_packet_data(dpp);

            pofbf_task_delay(100);
            terminate_handler();
        }
    }

    close(sock);
    return POF_OK;
}