📄 iscsi_init.c
字号:
else if (!strncmp(cmdline + i, KEYWORD_ISCSI_INITIATOR, sizeof(KEYWORD_ISCSI_INITIATOR) - 1)) { i += (sizeof(KEYWORD_ISCSI_INITIATOR) - 1); iscsi_initiator = cmdline + i; i += split_param(iscsi_initiator); } else if (!strncmp(cmdline + i, KEYWORD_ISCSI_TARGET, sizeof(KEYWORD_ISCSI_TARGET) - 1)) { i += (sizeof(KEYWORD_ISCSI_TARGET) - 1); p1 = cmdline + i; i += split_param(p1); while (p1) { if ((p3 = strchr(p1, ','))) *(p3++) = '\0'; if ((p_target = kmalloc(sizeof(struct iscsi_target), GFP_KERNEL))) { p_target->next = NULL; p_target->target_if = NULL; if (!strncmp(p1, "eth", 3) && (p2 = strchr(p1, ':'))) { p_target->target_if = p1; *(p2++) = '\0'; p1 = p2; } p_target->target_ip = p1; if ((p2 = strchr(p1, ':'))) { *(p2++) = '\0'; if (*p2 == '/') p2++; p_target->target_name = p2; } else p_target->target_name = NULL; /* just make sure we have the same sequence when we rollout the list */ if (iscsi_target_list) { for (p2_target = iscsi_target_list; p2_target; p2_target = p2_target->next) { /* handling comma separated lists of target IP's */ if (p2_target->target_name == NULL) p2_target->target_name = p_target->target_name; if (p2_target->next == NULL) { p2_target->next = p_target; break; } } } else iscsi_target_list = p_target; } else printk(KERN_ERR "iSCSI-init(parse_parameter): memory allocation error\n"); p1 = p3; } } else if (!strncmp(cmdline + i, KEYWORD_ISCSI_TIMEOUT, sizeof(KEYWORD_ISCSI_TIMEOUT) - 1)) { i += (sizeof(KEYWORD_ISCSI_TIMEOUT) - 1); iscsi_timeout = cmdline + i; i += split_param(iscsi_timeout); } }}static void __init parse_iscsi_config(void){ #define MAX_READ_BUF 4096 int fd, len = 0, i = 0; mm_segment_t oldfs; char *p, *pname, *pvalue; struct iscsi_param *new_param; oldfs = get_fs(); set_fs(KERNEL_DS); if ((fd = open(ISCSI_CONFIG_FILE, O_RDONLY, 0644)) != -1) { if ((iscsi_config_page = kmalloc(MAX_READ_BUF, GFP_KERNEL))) { while ((i = read(fd, iscsi_config_page + len, MAX_READ_BUF)) == MAX_READ_BUF) { if ((p = kmalloc(len + i + MAX_READ_BUF, GFP_KERNEL))) { len += i; memcpy(p, iscsi_config_page, len); kfree(iscsi_config_page); iscsi_config_page = p; } else { printk(KERN_ERR "iSCSI-init(parse_config): memory allocation error\n"); break; } } len += i; } else printk(KERN_ERR "iSCSI-init(parse_config): memory allocation error\n"); close(fd); } set_fs(oldfs); if (len > 0) { for (p = iscsi_config_page, pname = iscsi_config_page; p < (iscsi_config_page + len); p++) { if (*p == '\n') { *p = '\0'; while (*pname == ' ' || *pname == '\t') pname++; if (*pname != '#') { if ((pvalue = strchr(pname, '='))) { *(pvalue++) = '\0'; for (i = 0; iscsi_param_set[i]; i++) { if (!strcmp(pname, iscsi_param_set[i])) { if ((new_param = kmalloc(sizeof(struct iscsi_param), GFP_KERNEL))) { new_param->name = pname; new_param->value = pvalue; new_param->next = iscsi_param_list; iscsi_param_list = new_param; } else printk(KERN_ERR "iSCSI-init(parse_config): memory allocation error\n"); break; } } if (iscsi_param_set[i] == NULL) printk(KERN_ERR "iSCSI-init(parse_config): unknown parameter \"%s\"\n", pname); } } pname = p + 1; } } }}static int __init open_ctl_dev(char *devname, int devnum){ mm_segment_t oldfs; int ctlfd = -1; oldfs = get_fs(); set_fs(KERNEL_DS); if ((ctlfd = open(devname, O_RDWR, 0644)) < 0) { if (mknod(devname, (S_IFCHR | 0644), (devnum<<8))) printk(KERN_ERR "iSCSI-init(open_ctl_dev): cannot create control device %s\n", devname); else if ((ctlfd = open(devname, O_RDWR, 0644)) < 0) printk(KERN_ERR "iSCSI-init(open_ctl_dev): cannot open control device %s\n", devname); } set_fs(oldfs); return ctlfd;}static void __init close_ctl_dev(int ctlfd){ mm_segment_t oldfs; oldfs = get_fs(); set_fs(KERNEL_DS); close(ctlfd); set_fs(oldfs);}static void __init ioctl_establish_session(int control_fd, char *initiator, char *target_name, char *target_ip){ mm_segment_t oldfs; struct iscsi_session_ioctl *ioctld; struct iscsi_param *sparam; struct sockaddr_in *addr; if ((ioctld = kmalloc(sizeof(struct iscsi_session_ioctl) + sizeof(struct iscsi_portal_info), GFP_KERNEL)) == NULL) { printk(KERN_ERR "iSCSI-init(ioctl_establish_session): memory allocation error\n"); return; } memset(ioctld, 0, sizeof(struct iscsi_session_ioctl) + sizeof(struct iscsi_portal_info)); ioctld->ioctl_version = ISCSI_SESSION_IOCTL_VERSION; ioctld->config_number = 1; ioctld->update = 0; ioctld->portal.login_timeout = 15; ioctld->portal.auth_timeout = 45; ioctld->portal.active_timeout = 5; ioctld->portal.idle_timeout = 60; ioctld->portal.ping_timeout = 5; ioctld->portal.replacement_timeout = 0; ioctld->portal.abort_timeout = 10; ioctld->portal.reset_timeout = 30; ioctld->portal.initial_r2t = 0; ioctld->portal.immediate_data = 1; ioctld->portal.max_recv_data_segment_len = 128 * 1024; ioctld->portal.first_burst_len = 256 * 1024; ioctld->portal.max_burst_len = (16 * 1024 * 1024) - 1024; ioctld->portal.def_time2wait = 0; ioctld->portal.def_time2retain = 0; ioctld->portal.data_digest = ISCSI_DIGEST_NONE_CRC32C; ioctld->portal.header_digest = ISCSI_DIGEST_NONE_CRC32C; ioctld->portal.tcp_window_size = 256 * 1024; for (sparam = iscsi_param_list; sparam; sparam = sparam->next) { if (!strnicmp(sparam->name, ISCSI_CFG_USERNAME, sizeof(ISCSI_CFG_USERNAME) - 1) || !strnicmp(sparam->name, ISCSI_CFG_OUTGOINGUSERNAME, sizeof(ISCSI_CFG_OUTGOINGUSERNAME) - 1)) { strncpy(ioctld->username, sparam->value, sizeof(ioctld->username) - 1); } else if (!strnicmp(sparam->name, ISCSI_CFG_PASSWORD, sizeof(ISCSI_CFG_PASSWORD) - 1) || !strnicmp(sparam->name, ISCSI_CFG_OUTGOINGPASSWORD, sizeof(ISCSI_CFG_OUTGOINGPASSWORD) - 1)) { strncpy(ioctld->password, sparam->value, sizeof(ioctld->password) - 1); ioctld->password_length = strlen(ioctld->password); } else if (!strnicmp(sparam->name, ISCSI_CFG_INCOMINGUSERNAME, sizeof(ISCSI_CFG_INCOMINGUSERNAME) - 1)) { strncpy(ioctld->username_in, sparam->value, sizeof(ioctld->username_in) - 1); } else if (!strnicmp(sparam->name, ISCSI_CFG_INCOMINGPASSWORD, sizeof(ISCSI_CFG_INCOMINGPASSWORD) - 1)) { strncpy(ioctld->password_in, sparam->value, sizeof(ioctld->password_in) - 1); ioctld->password_length_in = strlen(ioctld->password_in); } else if (!strcmp(sparam->name, ISCSI_CFG_HEADERDIGEST)) { if (!strnicmp(sparam->value, "Never", 5) || !strnicmp(sparam->value, "No", 2) || !strnicmp(sparam->value, "None", 4)) ioctld->portal.header_digest = ISCSI_DIGEST_NONE; else if (!strnicmp(sparam->value, "Always", 6) || !strnicmp(sparam->value, "Yes", 3) || !strnicmp(sparam->value, "crc32c", 6)) ioctld->portal.header_digest = ISCSI_DIGEST_CRC32C; else if (!strnicmp(sparam->value, "Prefer-on", 9)) ioctld->portal.header_digest = ISCSI_DIGEST_CRC32C_NONE; else if (!strnicmp(sparam->value, "Prefer-off", 10)) ioctld->portal.header_digest = ISCSI_DIGEST_NONE_CRC32C; } else if (!strcmp(sparam->name, ISCSI_CFG_DATADIGEST)) { if (!strnicmp(sparam->value, "Never", 5) || !strnicmp(sparam->value, "No", 2) || !strnicmp(sparam->value, "None", 4)) ioctld->portal.data_digest = ISCSI_DIGEST_NONE; else if (!strnicmp(sparam->value, "Always", 6) || !strnicmp(sparam->value, "Yes", 3) || !strnicmp(sparam->value, "crc32c", 6)) ioctld->portal.data_digest = ISCSI_DIGEST_CRC32C; else if (!strnicmp(sparam->value, "Prefer-on", 9)) ioctld->portal.data_digest = ISCSI_DIGEST_CRC32C_NONE; else if (!strnicmp(sparam->value, "Prefer-off", 10)) ioctld->portal.data_digest = ISCSI_DIGEST_NONE_CRC32C; } else if (!strcmp(sparam->name, ISCSI_CFG_LOGINTIMEOUT)) { ioctld->portal.login_timeout = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_AUTHTIMEOUT)) { ioctld->portal.auth_timeout = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_IDLETIMEOUT)) { ioctld->portal.idle_timeout = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_CONNFAILTIMEOUT)) { ioctld->portal.replacement_timeout = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_PINGTIMEOUT)) { ioctld->portal.ping_timeout = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_INITIALR2T)) { if (!strnicmp(sparam->value, "Yes", 3)) ioctld->portal.initial_r2t = 1; } else if (!strcmp(sparam->name, ISCSI_CFG_IMMEDIATEDATA)) { if (!strnicmp(sparam->value, "No", 2)) ioctld->portal.immediate_data = 0; } else if (!strcmp(sparam->name, ISCSI_CFG_MAXRECVDATASEGLEN)) { ioctld->portal.max_recv_data_segment_len = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_FIRSTBURSTLENGTH)) { ioctld->portal.first_burst_len = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_MAXFURSTLENGTH)) { ioctld->portal.max_burst_len = atoi(sparam->value); } else if (!strcmp(sparam->name, ISCSI_CFG_TCPWINSIZE)) { ioctld->portal.tcp_window_size = atoi(sparam->value); } } addr = (struct sockaddr_in *)&ioctld->portal.addr; addr->sin_family = AF_INET; addr->sin_port = htons(ISCSI_DEFAULT_PORT); addr->sin_addr.s_addr = in_aton(target_ip); ioctld->portal.tag = PORTAL_GROUP_TAG_UNKNOWN; strcpy(ioctld->initiator_name, initiator); strncpy(ioctld->initiator_alias, system_utsname.nodename, TARGET_NAME_MAXLEN); strcpy(ioctld->target_name, target_name); ioctld->isid[0] = DRIVER_ISID_0; ioctld->isid[1] = DRIVER_ISID_1; ioctld->isid[2] = DRIVER_ISID_2; ioctld->isid[5] = 1; oldfs = get_fs(); set_fs(KERNEL_DS); if (ioctl(control_fd, ISCSI_ESTABLISH_SESSION, (unsigned long) ioctld) < 0) printk(KERN_ERR "iSCSI-init(ioctl_establish_session): ioctl failed, errno = %d\n", errno); set_fs(oldfs); kfree(ioctld);}#ifdef CONFIG_PROC_FSstatic int pnp_seq_show(struct seq_file *seq, void *v){ int i; seq_printf(seq, "#PROTO: DHCP\n"); if (pnp_domain[0]) seq_printf(seq, "domain %s\n", pnp_domain); for (i = 0; i < CONF_NAMESERVERS_MAX; i++) if (pnp_nameservers[i] != INADDR_NONE) seq_printf(seq, "nameserver %u.%u.%u.%u\n", NIPQUAD(pnp_nameservers[i])); return 0;}static int pnp_seq_open(struct inode *indoe, struct file *file){ return single_open(file, pnp_seq_show, NULL);}static struct file_operations pnp_seq_fops = { .owner = THIS_MODULE, .open = pnp_seq_open, .read = seq_read, .llseek = seq_lseek, .release = single_release,};#endif /* CONFIG_PROC_FS */static int __init iscsi_init(void){ int i, control_fd, devnum, rc = -1; unsigned long jiff; char *p1, *p2, *p3; struct iscsi_param *pprev, *pnext; struct iscsi_target *p_target, *p_target_next; struct iscsi_interface *iscsi_if, *iscsi_if_next; printk("iSCSI-init: version %s\n", version); if ((cmdline = get_cmdline())) parse_cmdline(); if (!iscsi_interface_list) { if ((iscsi_interface_list = kmalloc(sizeof(struct iscsi_interface), GFP_KERNEL))) { memset(iscsi_interface_list, 0, sizeof(struct iscsi_interface)); iscsi_interface_list->if_addr = INADDR_NONE; iscsi_interface_list->if_netmask = INADDR_NONE; iscsi_interface_list->gateway = INADDR_NONE; } else printk(KERN_ERR "iSCSI-init(iscsi_init): memory allocation error\n"); } memset(pnp_domain, 0, sizeof(pnp_domain)); for (i = 0; i < CONF_NAMESERVERS_MAX; i++) pnp_nameservers[i] = INADDR_NONE; ipconfig(); if (iscsi_interface_list) { sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(iscsi_interface_list->if_addr)); if (iscsi_interface_list->host[0]) strcpy(system_utsname.nodename, iscsi_interface_list->host); if (iscsi_interface_list->nisdomain[0]) strcpy(system_utsname.domainname, iscsi_interface_list->nisdomain); if (iscsi_interface_list->domain[0]) strncpy(pnp_domain, iscsi_interface_list->domain, sizeof(pnp_domain)); for (i = 0; i < CONF_NAMESERVERS_MAX; i++) if (iscsi_interface_list->nameservers[i] != INADDR_NONE) pnp_nameservers[i] = iscsi_interface_list->nameservers[i]; } if (!iscsi_target_list) { /* parse "option root-path" retrieved via DHCP */ for (iscsi_if = iscsi_interface_list; iscsi_if; iscsi_if = iscsi_if->next) { p1 = iscsi_if->root_path; while (p1) { if ((p3 = strchr(p1, ','))) *(p3++) = '\0'; if ((p_target = kmalloc(sizeof(struct iscsi_target), GFP_KERNEL))) { p_target->next = NULL; p_target->target_if = NULL; if (!strncmp(p1, "eth", 3) && (p2 = strchr(p1, ':'))) { p_target->target_if = p1; *(p2++) = '\0'; p1 = p2; } p_target->target_ip = p1; if ((p2 = strchr(p1, ':'))) { *(p2++) = '\0'; if (*p2 == '/') p2++; p_target->target_name = p2; if ((p1 = strchr(p2, '/'))) { *(p1++) = '\0'; if (!iscsi_initiator) iscsi_initiator = p1; } } else p_target->target_name = NULL; /* just make sure we have the same sequence when we rollout the list */ if (iscsi_target_list) { for (p_target_next = iscsi_target_list; p_target_next; p_target_next = p_target_next->next) { /* handling comma separated lists of target IP's */ if (p_target_next->target_name == NULL) p_target_next->target_name = p_target->target_name; if (p_target_next->next == NULL) { p_target_next->next = p_target; break; } } } else iscsi_target_list = p_target; } p1 = p3; } } } if (iscsi_target_list && iscsi_initiator) { parse_iscsi_config(); if ((devnum = get_ioctldev()) > 0) { printk("iSCSI-init: found control device \"%s\" with number %d\n", ISCSI_IOCTL_DEV, devnum); if ((control_fd = open_ctl_dev(ISCSI_DEVICE, devnum)) >= 0) { for (p_target = iscsi_target_list; p_target; p_target = p_target->next) { if (p_target->target_name && p_target->target_ip) { if (p_target->target_if) for (iscsi_if = iscsi_interface_list; iscsi_if; iscsi_if = iscsi_if->next) if (!strcmp(p_target->target_if, iscsi_if->dev->name)) iscsi_setup_routes(iscsi_if, in_aton(p_target->target_ip)); ioctl_establish_session(control_fd, iscsi_initiator, p_target->target_name, p_target->target_ip); } else printk(KERN_ERR "iSCSI-init: incomplete iscsi_target parameter or wrong DHCP root_path\n"); if (iscsi_timeout) jiff = jiffies + HZ*(atoi(iscsi_timeout)); else jiff = jiffies + HZ*5; while (time_before(jiffies, jiff)) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); } } rc = 0;#ifdef CONFIG_PROC_FS proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);#endif /* CONFIG_PROC_FS */ close_ctl_dev(control_fd); } } else printk(KERN_ERR "iSCSI-init: iscsi_sfnet probably isn't loaded\n"); } else printk(KERN_ERR "iSCSI-init: iscsi-target and iscsi-initiator parameters must be specified or obtained via DHCP\n"); if (cmdline) kfree(cmdline); if (iscsi_config_page) kfree(iscsi_config_page); for (pprev = iscsi_param_list, pnext = iscsi_param_list; pnext; pprev = pnext) { pnext = pnext->next; kfree(pprev); } for (p_target = iscsi_target_list, p_target_next = iscsi_target_list; p_target_next; p_target = p_target_next) { p_target_next = p_target->next; kfree(p_target); } for (iscsi_if = iscsi_interface_list; iscsi_if; iscsi_if = iscsi_if_next) { iscsi_if_next = iscsi_if->next; if (iscsi_if->root_path) kfree(iscsi_if->root_path); kfree(iscsi_if); } return rc;}static void __exit iscsi_cleanup(void){#ifdef CONFIG_PROC_FS remove_proc_entry("pnp", proc_net);#endif /* CONFIG_PROC_FS */}module_init(iscsi_init);module_exit(iscsi_cleanup);MODULE_LICENSE("GPL");MODULE_DESCRIPTION("iSCSI boot initialization module");MODULE_AUTHOR("Igor Feoktistov <ifeoktistov@users.sourceforge.net>");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -