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 + -
显示快捷键?