mxlnd.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 938 行 · 第 1/3 页

C
938
字号
mxlnd_free_hosts(void){        struct kmx_host         *host   = NULL;        struct kmx_host         *next   = NULL;        list_for_each_entry_safe(host, next, &kmxlnd_data.kmx_hosts, mxh_list) {                list_del_init(&host->mxh_list);                mxlnd_host_free(host);        }        return;}#define xstr(s) #s#define str(s) xstr(s)#define MXLND_MAX_BOARD 4       /* we expect hosts to have fewer NICs than this */#define MXLND_MAX_EP_ID 16      /* we expect hosts to have less than this endpoints *//* this parses a line that consists of: *  * IP              HOSTNAME           BOARD        ENDPOINT ID * 169.192.0.113   mds01              0            3 *  * By default MX uses the alias (short hostname). If you override * it using mx_hostname to use the FQDN or some other name, the hostname * here must match exactly. *//* MX_MAX_HOSTNAME_LEN = 80. See myriexpress.h */intmxlnd_parse_line(char *line){        int             i               = 0;        int             ret             = 0;        int             len             = 0;        u32             ip[4]           = { 0, 0, 0, 0 };        char            hostname[MX_MAX_HOSTNAME_LEN];        u32             board           = -1;        u32             ep_id           = -1;        struct kmx_host *host           = NULL;        if (line == NULL) return -1;        len = strlen(line);        if (len == 0) return -1;        /* convert tabs to spaces */        for (i = 0; i < len; i++) {                if (line[i] == '\t') line[i] = ' ';        }        memset(&hostname, 0 , sizeof(hostname));        ret = sscanf(line, "%d.%d.%d.%d %" str(MX_MAX_HOSTNAME_LEN) "s %d %d",                      &ip[0], &ip[1], &ip[2], &ip[3], hostname, &board, &ep_id);        if (ret != 7) {                return -1;        }        /* check for valid values */        /* we assume a valid IP address (all <= 255), number of NICs,         * and number of endpoint IDs */        if (ip[0] > 255 || ip [1] > 255 || ip[2] > 255 || ip[3] > 255 ||            board > MXLND_MAX_BOARD || ep_id > MXLND_MAX_EP_ID) {                CDEBUG(D_NETERROR, "Illegal value in \"%s\". Ignoring "                                   "this host.\n", line);                return -1;        }        ret = mxlnd_host_alloc(&host);        if (ret != 0) return -1;        host->mxh_addr = ((ip[0]<<24)|(ip[1]<<16)|(ip[2]<<8)|ip[3]);        len = strlen(hostname);        MXLND_ALLOC(host->mxh_hostname, len + 1);        if (host->mxh_hostname == NULL) {                mxlnd_host_free(host);                return -ENOMEM;        }        memset(host->mxh_hostname, 0, len + 1);        strncpy(host->mxh_hostname, hostname, len);        host->mxh_board = board;        host->mxh_ep_id = ep_id;        spin_lock(&kmxlnd_data.kmx_hosts_lock);        list_add_tail(&host->mxh_list, &kmxlnd_data.kmx_hosts);        spin_unlock(&kmxlnd_data.kmx_hosts_lock);        return 0;}voidmxlnd_print_hosts(void){#if MXLND_DEBUG        struct kmx_host         *host   = NULL;        list_for_each_entry(host, &kmxlnd_data.kmx_hosts, mxh_list) {                int             ip[4];                u32             addr    = host->mxh_addr;                ip[0] = (addr >> 24) & 0xff;                ip[1] = (addr >> 16) & 0xff;                ip[2] = (addr >>  8) & 0xff;                ip[3] = addr & 0xff;                CDEBUG(D_NET, "\tip= %d.%d.%d.%d\n\thost= %s\n\tboard= %d\n\tep_id= %d\n\n",                            ip[0], ip[1], ip[2], ip[3],                            host->mxh_hostname, host->mxh_board, host->mxh_ep_id);        }#endif        return;}#define MXLND_BUFSIZE (PAGE_SIZE - 1)intmxlnd_parse_hosts(char *filename){        int             ret             = 0;        s32             size            = 0;        s32             bufsize         = MXLND_BUFSIZE;        s32             allocd          = 0;        loff_t          offset          = 0;        struct file     *filp           = NULL;        struct inode    *inode          = NULL;        char            *buf            = NULL;        s32             buf_off         = 0;        char            *sep            = NULL;        char            *line           = NULL;        if (filename == NULL) return -1;        filp = filp_open(filename, O_RDONLY, 0);        if (IS_ERR(filp)) {                CERROR("filp_open() failed for %s\n", filename);                return -1;        }        inode = filp->f_dentry->d_inode;        if (!S_ISREG(inode->i_mode)) {                CERROR("%s is not a regular file\n", filename);                return -1;        }        size = (s32) inode->i_size;        if (size < MXLND_BUFSIZE) bufsize = size;        allocd = bufsize;        MXLND_ALLOC(buf, allocd + 1);        if (buf == NULL) {                CERROR("Cannot allocate buf\n");                filp_close(filp, current->files);                return -1;        }        while (offset < size) {                memset(buf, 0, bufsize + 1);                ret = kernel_read(filp, (unsigned long) offset, buf, (unsigned long) bufsize);                if (ret < 0) {                        CDEBUG(D_NETERROR, "kernel_read() returned %d - closing %s\n", ret, filename);                        filp_close(filp, current->files);                        MXLND_FREE(buf, allocd + 1);                        return -1;                }                if (ret < bufsize) bufsize = ret;                buf_off = 0;                while (buf_off < bufsize) {                        sep = strchr(buf + buf_off, '\n');                        if (sep != NULL) {                                /* we have a line */                                line = buf + buf_off;                                *sep = '\0';                                ret = mxlnd_parse_line(line);                                if (ret != 0 && strlen(line) != 0) {                                        CDEBUG(D_NETERROR, "Failed to parse \"%s\". Ignoring this host.\n", line);                                }                                buf_off += strlen(line) + 1;                        } else {                                /* last line or we need to read more */                                line = buf + buf_off;                                ret = mxlnd_parse_line(line);                                if (ret != 0) {                                        bufsize -= strlen(line) + 1;                                }                                buf_off += strlen(line) + 1;                        }                }                offset += bufsize;                bufsize = MXLND_BUFSIZE;        }        MXLND_FREE(buf, allocd + 1);        filp_close(filp, current->files);        mxlnd_print_hosts();        return 0;}/** * mxlnd_init_mx - open the endpoint, set out ID, register the EAGER callback * @ni - the network interface * * Returns 0 on success, -1 on failure */intmxlnd_init_mx(lnet_ni_t *ni){        int                     ret     = 0;        int                     found   = 0;        mx_return_t             mxret;        mx_endpoint_addr_t      addr;        u32                     board   = *kmxlnd_tunables.kmx_board;        u32                     ep_id   = *kmxlnd_tunables.kmx_ep_id;        u64                     nic_id  = 0LL;        struct kmx_host         *host   = NULL;        mxret = mx_init();        if (mxret != MX_SUCCESS) {                CERROR("mx_init() failed with %s (%d)\n", mx_strerror(mxret), mxret);                return -1;        }        ret = mxlnd_parse_hosts(*kmxlnd_tunables.kmx_hosts);        if (ret != 0) {                if (*kmxlnd_tunables.kmx_hosts != NULL) {                        CERROR("mxlnd_parse_hosts(%s) failed\n", *kmxlnd_tunables.kmx_hosts);                }                mx_finalize();                return -1;        }        list_for_each_entry(host, &kmxlnd_data.kmx_hosts, mxh_list) {                if (strcmp(host->mxh_hostname, system_utsname.nodename) == 0) {                        /* override the defaults and module parameters with                          * the info from the hosts file */                        board = host->mxh_board;                        ep_id = host->mxh_ep_id;                        kmxlnd_data.kmx_localhost = host;                        CDEBUG(D_NET, "my hostname is %s board %d ep_id %d\n", kmxlnd_data.kmx_localhost->mxh_hostname, kmxlnd_data.kmx_localhost->mxh_board, kmxlnd_data.kmx_localhost->mxh_ep_id);                        found = 1;                        break;                }        }        if (found == 0) {                CERROR("no host entry found for localhost\n");                mx_finalize();                return -1;        }        mxret = mx_open_endpoint(board, ep_id, MXLND_MSG_MAGIC,                                  NULL, 0, &kmxlnd_data.kmx_endpt);        if (mxret != MX_SUCCESS) {                CERROR("mx_open_endpoint() failed with %d\n", mxret);                mx_finalize();                return -1;        }        mx_get_endpoint_addr(kmxlnd_data.kmx_endpt, &addr);        mx_decompose_endpoint_addr(addr, &nic_id, &ep_id);        LASSERT(host != NULL);        ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), host->mxh_addr);        CDEBUG(D_NET, "My NID is 0x%llx\n", ni->ni_nid);        /* this will catch all unexpected receives. */        mxret = mx_register_unexp_handler(kmxlnd_data.kmx_endpt,                                          (mx_unexp_handler_t) mxlnd_unexpected_recv,                                          NULL);        if (mxret != MX_SUCCESS) {                CERROR("mx_register_unexp_callback() failed with %s\n",                          mx_strerror(mxret));                mx_close_endpoint(kmxlnd_data.kmx_endpt);                mx_finalize();                return -1;        }        mxret = mx_set_request_timeout(kmxlnd_data.kmx_endpt, NULL, MXLND_COMM_TIMEOUT/HZ*1000);        if (mxret != MX_SUCCESS) {                CERROR("mx_set_request_timeout() failed with %s\n",                         mx_strerror(mxret));                mx_close_endpoint(kmxlnd_data.kmx_endpt);                mx_finalize();                return -1;        }        return 0;}/** * mxlnd_thread_start - spawn a kernel thread with this function * @fn - function pointer * @arg - pointer to the parameter data * * Returns 0 on success and a negative value on failure */intmxlnd_thread_start(int (*fn)(void *arg), void *arg){        int     pid = 0;        int     i   = (int) ((long) arg);        atomic_inc(&kmxlnd_data.kmx_nthreads);        init_completion(&kmxlnd_data.kmx_completions[i]);        pid = kernel_thread (fn, arg, 0);        if (pid < 0) {                CERROR("kernel_thread() failed with %d\n", pid);                atomic_dec(&kmxlnd_data.kmx_nthreads);        }        return pid;}

⌨️ 快捷键说明

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