btl_tcp_component.c

来自「MPI stands for the Message Passing Inter」· C语言 代码 · 共 642 行 · 第 1/2 页

C
642
字号
 * (1) all interfaces specified by the user * (2) all available interfaces  * (3) all available interfaces except for those excluded by the user */static int mca_btl_tcp_component_create_instances(void){    int if_count = opal_ifcount();    int if_index;    char **include;    char **exclude;    char **argv;    if(if_count <= 0)        return OMPI_ERROR;    /* allocate memory for btls */    mca_btl_tcp_component.tcp_btls = (mca_btl_tcp_module_t **)malloc(if_count * sizeof(mca_btl_tcp_module_t*));    if(NULL == mca_btl_tcp_component.tcp_btls)        return OMPI_ERR_OUT_OF_RESOURCE;    /* if the user specified an interface list - use these exclusively */    argv = include = opal_argv_split(mca_btl_tcp_component.tcp_if_include,',');    while(argv && *argv) {        char* if_name = *argv;        int if_index = opal_ifnametoindex(if_name);        if(if_index < 0) {            BTL_ERROR(("invalid interface \"%s\"", if_name));        } else {            mca_btl_tcp_create(if_index, if_name);        }        argv++;    }    opal_argv_free(include);    if(mca_btl_tcp_component.tcp_num_btls)        return OMPI_SUCCESS;    /* if the interface list was not specified by the user, create      * a BTL for each interface that was not excluded.    */    exclude = opal_argv_split(mca_btl_tcp_component.tcp_if_exclude,',');    for(if_index = opal_ifbegin(); if_index >= 0; if_index = opal_ifnext(if_index)) {        char if_name[32];        opal_ifindextoname(if_index, if_name, sizeof(if_name));        /* check to see if this interface exists in the exclude list */        if(opal_ifcount() > 1) {            argv = exclude;            while(argv && *argv) {                if(strncmp(*argv,if_name,strlen(*argv)) == 0)                    break;                argv++;            }            /* if this interface was not found in the excluded list - create a BTL */            if(argv == 0 || *argv == 0) {                mca_btl_tcp_create(if_index, if_name);            }        } else {            mca_btl_tcp_create(if_index, if_name);        }    }    opal_argv_free(exclude);    return OMPI_SUCCESS;}/* * Create a listen socket and bind to all interfaces */static int mca_btl_tcp_component_create_listen(void){    int flags;    struct sockaddr_in inaddr;     opal_socklen_t addrlen;    /* create a listen socket for incoming connections */    mca_btl_tcp_component.tcp_listen_sd = socket(AF_INET, SOCK_STREAM, 0);    if(mca_btl_tcp_component.tcp_listen_sd < 0) {        BTL_ERROR(("socket() failed with errno=%d", opal_socket_errno));        return OMPI_ERROR;    }    mca_btl_tcp_set_socket_options(mca_btl_tcp_component.tcp_listen_sd);                                                                                                          /* bind to all addresses and dynamically assigned port */    memset(&inaddr, 0, sizeof(inaddr));    inaddr.sin_family = AF_INET;    inaddr.sin_addr.s_addr = INADDR_ANY;    inaddr.sin_port = 0;                                                                                                          if(bind(mca_btl_tcp_component.tcp_listen_sd, (struct sockaddr*)&inaddr, sizeof(inaddr)) < 0) {        BTL_ERROR(("bind() failed with errno=%d", opal_socket_errno));        return OMPI_ERROR;    }                                                                                                          /* resolve system assignend port */    addrlen = sizeof(struct sockaddr_in);    if(getsockname(mca_btl_tcp_component.tcp_listen_sd, (struct sockaddr*)&inaddr, &addrlen) < 0) {        BTL_ERROR(("getsockname() failed with errno=%d", opal_socket_errno));        return OMPI_ERROR;    }    mca_btl_tcp_component.tcp_listen_port = inaddr.sin_port;    /* setup listen backlog to maximum allowed by kernel */    if(listen(mca_btl_tcp_component.tcp_listen_sd, SOMAXCONN) < 0) {        BTL_ERROR(("listen() failed with errno=%d", opal_socket_errno));        return OMPI_ERROR;    }    /* set socket up to be non-blocking, otherwise accept could block */    if((flags = fcntl(mca_btl_tcp_component.tcp_listen_sd, F_GETFL, 0)) < 0) {        BTL_ERROR(("fcntl(F_GETFL) failed with errno=%d", opal_socket_errno));        return OMPI_ERROR;    } else {        flags |= O_NONBLOCK;        if(fcntl(mca_btl_tcp_component.tcp_listen_sd, F_SETFL, flags) < 0) {            BTL_ERROR(("fcntl(F_SETFL) failed with errno=%d", opal_socket_errno));            return OMPI_ERROR;        }    }    /* register listen port */    opal_event_set(        &mca_btl_tcp_component.tcp_recv_event,        mca_btl_tcp_component.tcp_listen_sd,         OPAL_EV_READ|OPAL_EV_PERSIST,         mca_btl_tcp_component_recv_handler,         0);    opal_event_add(&mca_btl_tcp_component.tcp_recv_event,0);    return OMPI_SUCCESS;}/* *  Register TCP module addressing information. The MCA framework *  will make this available to all peers.  */static int mca_btl_tcp_component_exchange(void){     int rc=0;     size_t i=0;     size_t size = mca_btl_tcp_component.tcp_num_btls * sizeof(mca_btl_tcp_addr_t);     if(mca_btl_tcp_component.tcp_num_btls != 0) {         mca_btl_tcp_addr_t *addrs = (mca_btl_tcp_addr_t *)malloc(size);         for(i=0; i<mca_btl_tcp_component.tcp_num_btls; i++) {             struct mca_btl_tcp_module_t* btl = mca_btl_tcp_component.tcp_btls[i];             addrs[i].addr_inet    = btl->tcp_ifaddr.sin_addr;             addrs[i].addr_port    = mca_btl_tcp_component.tcp_listen_port;             addrs[i].addr_inuse   = 0;         }         rc =  mca_pml_base_modex_send(&mca_btl_tcp_component.super.btl_version, addrs, size);         free(addrs);     }     return rc;}/* *  TCP module initialization: *  (1) read interface list from kernel and compare against module parameters *      then create a BTL instance for selected interfaces *  (2) setup TCP listen socket for incoming connection attempts *  (3) register BTL parameters with the MCA */mca_btl_base_module_t** mca_btl_tcp_component_init(int *num_btl_modules,                                                    bool enable_progress_threads,                                                   bool enable_mpi_threads){    mca_btl_base_module_t **btls;    *num_btl_modules = 0;    /* initialize free lists */    ompi_free_list_init( &mca_btl_tcp_component.tcp_frag_eager,                         sizeof (mca_btl_tcp_frag_eager_t) +                          mca_btl_tcp_module.super.btl_eager_limit,                         OBJ_CLASS (mca_btl_tcp_frag_eager_t),                         mca_btl_tcp_component.tcp_free_list_num,                         mca_btl_tcp_component.tcp_free_list_max,                         mca_btl_tcp_component.tcp_free_list_inc,                         NULL );                                                                                                                                      ompi_free_list_init( &mca_btl_tcp_component.tcp_frag_max,                         sizeof (mca_btl_tcp_frag_max_t) +                          mca_btl_tcp_module.super.btl_max_send_size,                         OBJ_CLASS (mca_btl_tcp_frag_max_t),                         mca_btl_tcp_component.tcp_free_list_num,                         mca_btl_tcp_component.tcp_free_list_max,                         mca_btl_tcp_component.tcp_free_list_inc,                         NULL );                                                                                                                                      ompi_free_list_init( &mca_btl_tcp_component.tcp_frag_user,                         sizeof (mca_btl_tcp_frag_user_t),                         OBJ_CLASS (mca_btl_tcp_frag_user_t),                         mca_btl_tcp_component.tcp_free_list_num,                         mca_btl_tcp_component.tcp_free_list_max,                         mca_btl_tcp_component.tcp_free_list_inc,                         NULL );                                                                                                                                      /* create a BTL TCP module for selected interfaces */    if(mca_btl_tcp_component_create_instances() != OMPI_SUCCESS)        return 0;    /* create a TCP listen socket for incoming connection attempts */    if(mca_btl_tcp_component_create_listen() != OMPI_SUCCESS)        return 0;    /* publish TCP parameters with the MCA framework */    if(mca_btl_tcp_component_exchange() != OMPI_SUCCESS)        return 0;    btls = (mca_btl_base_module_t **)malloc(mca_btl_tcp_component.tcp_num_btls *                   sizeof(mca_btl_base_module_t*));    if(NULL == btls)        return NULL;    memcpy(btls, mca_btl_tcp_component.tcp_btls, mca_btl_tcp_component.tcp_num_btls*sizeof(mca_btl_tcp_module_t*));    *num_btl_modules = mca_btl_tcp_component.tcp_num_btls;    return btls;}/* *  TCP module control */int mca_btl_tcp_component_control(int param, void* value, size_t size){    return OMPI_SUCCESS;}/* *  Called by mca_btl_tcp_component_recv() when the TCP listen *  socket has pending connection requests. Accept incoming *  requests and queue for completion of the connection handshake.*/static void mca_btl_tcp_component_accept(void){    while(true) {        opal_socklen_t addrlen = sizeof(struct sockaddr_in);        struct sockaddr_in addr;        mca_btl_tcp_event_t *event;        int sd = accept(mca_btl_tcp_component.tcp_listen_sd, (struct sockaddr*)&addr, &addrlen);        if(sd < 0) {            if(opal_socket_errno == EINTR)                continue;            if(opal_socket_errno != EAGAIN && opal_socket_errno != EWOULDBLOCK)                BTL_ERROR(("accept() failed with errno %d.", opal_socket_errno));            return;        }        mca_btl_tcp_set_socket_options(sd);        /* wait for receipt of peers process identifier to complete this connection */                 event = OBJ_NEW(mca_btl_tcp_event_t);        opal_event_set(&event->event, sd, OPAL_EV_READ, mca_btl_tcp_component_recv_handler, event);        opal_event_add(&event->event, 0);    }}/* * Event callback when there is data available on the registered  * socket to recv. */static void mca_btl_tcp_component_recv_handler(int sd, short flags, void* user){    orte_process_name_t guid;    struct sockaddr_in addr;    int retval;    mca_btl_tcp_proc_t* btl_proc;    opal_socklen_t addr_len = sizeof(addr);    mca_btl_tcp_event_t *event = (mca_btl_tcp_event_t *)user;    /* accept new connections on the listen socket */    if(mca_btl_tcp_component.tcp_listen_sd == sd) {        mca_btl_tcp_component_accept();        return;    }    OBJ_RELEASE(event);    /* recv the process identifier */    retval = recv(sd, (char *)&guid, sizeof(guid), 0);    if(retval != sizeof(guid)) {        CLOSE_THE_SOCKET(sd);        return;    }    ORTE_PROCESS_NAME_NTOH(guid);    /* now set socket up to be non-blocking */    if((flags = fcntl(sd, F_GETFL, 0)) < 0) {        BTL_ERROR(("fcntl(F_GETFL) failed with errno=%d", opal_socket_errno));    } else {        flags |= O_NONBLOCK;        if(fcntl(sd, F_SETFL, flags) < 0) {            BTL_ERROR(("fcntl(F_SETFL) failed with errno=%d", opal_socket_errno));        }    }       /* lookup the corresponding process */    btl_proc = mca_btl_tcp_proc_lookup(&guid);    if(NULL == btl_proc) {        BTL_ERROR(("errno=%d",errno));        CLOSE_THE_SOCKET(sd);        return;    }    /* lookup peer address */    if(getpeername(sd, (struct sockaddr*)&addr, &addr_len) != 0) {        BTL_ERROR(("getpeername() failed with errno=%d", opal_socket_errno));        CLOSE_THE_SOCKET(sd);        return;    }    /* are there any existing peer instances will to accept this connection */    if(mca_btl_tcp_proc_accept(btl_proc, &addr, sd) == false) {        CLOSE_THE_SOCKET(sd);        return;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?