⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iscsi_init.c

📁 iscsi-init LINUX boot
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (servers > CONF_NAMESERVERS_MAX)		    servers = CONF_NAMESERVERS_MAX;		for (i = 0; i < servers; i++) {		    if (iscsi_if->nameservers[i] == INADDR_NONE)			memcpy(&(iscsi_if->nameservers[i]), ext + 1 + 4*i, 4);		}		break;	case 12:	/* Host name */		iscsi_bootp_string(iscsi_if->host, ext + 1, *ext, sizeof(iscsi_if->host));		break;	case 15:	/* Domain name (DNS) */		iscsi_bootp_string(iscsi_if->domain, ext + 1, *ext, sizeof(iscsi_if->domain));		break;	case 17:	/* Root path */		if (iscsi_if->root_path)		    kfree(iscsi_if->root_path);		if ((iscsi_if->root_path = kmalloc((*ext) + 1, GFP_ATOMIC)))		    iscsi_bootp_string(iscsi_if->root_path, ext + 1, *ext, *ext + 1);		else		    printk(KERN_ERR "iSCSI-init(iscsi_do_bootp_ext): memory allocation error\n");		break;	case 40:	/* NIS Domain name (_not_ DNS) */		iscsi_bootp_string(iscsi_if->nisdomain, ext + 1, *ext, sizeof(iscsi_if->nisdomain));		break;    }}/* *  Receive BOOTP reply. */static int __init iscsi_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt){    struct bootp_pkt *b;    struct iphdr *h;    struct iscsi_device *d;    int len, mt;    u8 *end, *ext, *opt;    u32 server_id;    /* Perform verifications before taking the lock.  */    if (skb->pkt_type == PACKET_OTHERHOST)	goto drop;    if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)	return NET_RX_DROP;    if (!pskb_may_pull(skb, sizeof(struct iphdr) + sizeof(struct udphdr)))	goto drop;    b = (struct bootp_pkt *) skb->nh.iph;    h = &b->iph;    if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)	goto drop;    /* Fragments are not supported */    if (h->frag_off & htons(IP_OFFSET | IP_MF)) {	if (net_ratelimit())	    printk(KERN_ERR "iSCSI-init(iscsi_bootp_recv): ignoring fragmented reply.\n");	goto drop;    }    if (skb->len < ntohs(h->tot_len))	goto drop;    if (ip_fast_csum((char *) h, h->ihl))	goto drop;    if (b->udph.source != htons(67) || b->udph.dest != htons(68))	goto drop;    if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))	goto drop;    len = ntohs(b->udph.len) - sizeof(struct udphdr);    if (len < 300)	goto drop;    /* Ok the front looks good, make sure we can get at the rest.  */    if (!pskb_may_pull(skb, skb->len))	goto drop;    b = (struct bootp_pkt*) skb->nh.iph;    h = &b->iph;    /* One reply at a time, please. */    spin_lock(&bootp_recv_lock);    /* Find the iscsi_device that the packet arrived on */    d = iscsi_device_list;    while (d && d->dev != dev)	d = d->next;    if (!d || d->iscsi_if->bootp_got_reply == 1)	goto drop_unlock;    /* Is it a reply to our BOOTP request? */    if (b->op != BOOTP_REPLY || b->xid != d->xid) {	if (net_ratelimit())	    printk(KERN_ERR "iSCSI-init(iscsi_bootp_recv): Reply not for us, op[%x] xid[%x]\n", b->op, b->xid);	goto drop_unlock;    }    /* Parse extensions */    if (!memcmp(b->exten, iscsi_bootp_cookie, 4)) { /* Check magic cookie */	end = (u8 *) b + ntohs(b->iph.tot_len);	server_id = INADDR_NONE;	mt = 0;	ext = &b->exten[4];	while (ext < end && *ext != 0xff) {	    opt = ext++;	    if (*opt == 0)	/* Padding */		continue;	    ext += *ext + 1;	    if (ext >= end)		break;	    switch (*opt) {		case 53:	/* Message type */		    if (opt[1])			mt = opt[2];		    break;		case 54:	/* Server ID (IP address) */		    if (opt[1] >= 4)			memcpy(&server_id, opt + 2, 4);		    break;	    }	}	switch (mt) {	    case DHCPOFFER:		/* While in the process of accepting one offer,		 * ignore all others.		 */		if (d->iscsi_if->if_addr != INADDR_NONE)		    goto drop_unlock;		/* Let's accept that offer. */		d->iscsi_if->if_addr = b->your_ip;		d->iscsi_if->servaddr = server_id;		/* The DHCP indicated server address takes		 * precedence over the bootp header one if		 * they are different.		 */		if ((server_id != INADDR_NONE) && (b->server_ip != server_id))		    b->server_ip = d->iscsi_if->servaddr;		break;	    case DHCPACK:		/* Yeah! */		break;	    default:		/* Urque.  Forget it*/		d->iscsi_if->if_addr = INADDR_NONE;		d->iscsi_if->servaddr = INADDR_NONE;		goto drop_unlock;	}	d->iscsi_if->bootp_msgtype = mt;	ext = &b->exten[4];	while (ext < end && *ext != 0xff) {	    opt = ext++;	    if (*opt == 0)	/* Padding */		continue;	    ext += *ext + 1;	    if (ext < end)		iscsi_do_bootp_ext(opt, d->iscsi_if);	}    }    d->iscsi_if->if_addr = b->your_ip;    if (server_id == INADDR_NONE)	d->iscsi_if->servaddr = b->server_ip;    else	d->iscsi_if->servaddr = server_id;    if (d->iscsi_if->gateway == INADDR_NONE && b->relay_ip)	d->iscsi_if->gateway = b->relay_ip;    if (d->iscsi_if->nameservers[0] == INADDR_NONE)	d->iscsi_if->nameservers[0] = d->iscsi_if->servaddr;    d->iscsi_if->bootp_got_reply = 1;drop_unlock:    /* Show's over.  Nothing to see here.  */    spin_unlock(&bootp_recv_lock);drop:    /* Throw the packet out. */    kfree_skb(skb);    return 0;}	static int __init iscsi_dynamic(struct iscsi_interface *iscsi_if){    int retries = CONF_SEND_RETRIES;    struct iscsi_device *d;    unsigned long start_jiffies, timeout, jiff;    if (!iscsi_device_list) {	printk(KERN_ERR "iSCSI-init(iscsi_dynamic): no suitable device found.\n");	return -1;    }    iscsi_bootp_init();    /*     * Send requests and wait, until we get an answer. This loop     * seems to be a terrible waste of CPU time, but actually there is     * only one process running at all, so we don't need to use any     * scheduler functions.     */    printk("iSCSI-init: sending DHCP requests .");    start_jiffies = jiffies;    d = iscsi_device_list;    get_random_bytes(&timeout, sizeof(timeout));    timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);    iscsi_if->bootp_got_reply = 0;    for(;;) {	iscsi_bootp_send_if(d, jiffies - start_jiffies);	jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);	while (time_before(jiffies, jiff) && !(iscsi_if->bootp_got_reply)) {	    set_current_state(TASK_UNINTERRUPTIBLE);	    schedule_timeout(1);	}	/* DHCP isn't done until we get a DHCPACK. */	if (iscsi_if->bootp_got_reply) {	    if (iscsi_if->bootp_msgtype == DHCPACK) {		iscsi_if->dev = d->dev;		printk(" OK\n");		break;	    }	    else {		iscsi_if->bootp_got_reply = 0;		printk(".");		continue;	    }	}	if ((d = d->next))	    continue;	if (!(--retries)) {	    printk(" timed out!\n");	    break;	}	d = iscsi_device_list;	timeout = timeout CONF_TIMEOUT_MULT;	if (timeout > CONF_TIMEOUT_MAX)	    timeout = CONF_TIMEOUT_MAX;	printk(".");    }    iscsi_bootp_cleanup();    if (!(iscsi_if->bootp_got_reply))	return -1;    printk("iSCSI-init: got DHCP answer from %u.%u.%u.%u, my address is %u.%u.%u.%u\n", NIPQUAD(iscsi_if->servaddr), NIPQUAD(iscsi_if->if_addr));    return 0;}static int __init ipconfig(void){    struct iscsi_device *d;    struct iscsi_interface *iscsi_if;    int retries, i;    for (iscsi_if = iscsi_interface_list; iscsi_if; iscsi_if = iscsi_if->next) {	for (i = 0; i < CONF_NAMESERVERS_MAX; i++)	    iscsi_if->nameservers[i] = INADDR_NONE;	if (iscsi_open_devs(iscsi_if) < 0)	    return -1;	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(CONF_POST_OPEN);	if (iscsi_if->if_addr == INADDR_NONE) {	    retries = CONF_OPEN_RETRIES;	    while (iscsi_dynamic(iscsi_if) < 0 && retries--) {		iscsi_close_devs(iscsi_if);		set_current_state(TASK_UNINTERRUPTIBLE);		schedule_timeout(CONF_PRE_OPEN);		printk(KERN_ERR "iSCSI-init(ipconfig): reopening network devices...\n");		if (iscsi_open_devs(iscsi_if) < 0)		    return -1;		set_current_state(TASK_UNINTERRUPTIBLE);		schedule_timeout(CONF_POST_OPEN);	    }	    if (iscsi_if->dev == NULL) {		if (iscsi_if->if_name)		    printk(KERN_ERR "iSCSI-init(ipconfig): auto-configuration of network for %s failed.\n", iscsi_if->if_name);		else		    printk(KERN_ERR "iSCSI-init(ipconfig): auto-configuration of network failed.\n");	    }	}	else {	    for (d = iscsi_device_list; d; d = d->next)		if (d->iscsi_if == iscsi_if)		    iscsi_if->dev = d->dev;	}	if (iscsi_if->dev) {	    if (iscsi_setup_if(iscsi_if) == 0) {		if (iscsi_if->gateway != INADDR_NONE)		    iscsi_setup_routes(iscsi_if, 0);		printk("iSCSI-init: network interface %s complete:\n", iscsi_if->dev->name);		printk("            addr=%u.%u.%u.%u", NIPQUAD(iscsi_if->if_addr));		printk(", mask=%u.%u.%u.%u", NIPQUAD(iscsi_if->if_netmask));		if (iscsi_if->gateway != INADDR_NONE)		    printk(", gw=%u.%u.%u.%u", NIPQUAD(iscsi_if->gateway));		if (iscsi_if->host[0]) {		    printk("\n            host=%s", iscsi_if->host);		    if (iscsi_if->domain[0])			printk(", domain=%s", iscsi_if->domain);		    if (iscsi_if->nisdomain[0])			printk(", nis-domain=%s", iscsi_if->nisdomain);		}		else {		    if (iscsi_if->domain[0]) {			printk("\n            domain=%s", iscsi_if->domain);			if (iscsi_if->nisdomain[0])			    printk(", nis-domain=%s", iscsi_if->nisdomain);		    }		}		printk("\n");		if (iscsi_if->nameservers[0] != INADDR_NONE) {		    printk("            nameservers=%u.%u.%u.%u", NIPQUAD(iscsi_if->nameservers[0]));		    for (i = 1; i < CONF_NAMESERVERS_MAX; i++)			if (iscsi_if->nameservers[i] != INADDR_NONE)			    printk(", %u.%u.%u.%u", NIPQUAD(iscsi_if->nameservers[i]));		    printk("\n");		}		if (iscsi_if->root_path)		    printk("            root-path=%s\n", iscsi_if->root_path);	    }	}	iscsi_close_devs(iscsi_if);    }    return 0;}static char* __init get_cmdline(void){    struct proc_dir_entry *d;    char *p, *page, *start = NULL;    ssize_t n = 0, count = PROC_BLOCK_SIZE;    loff_t pos = 0;    int eof = 0;    for (d = proc_root.subdir; d; d = d->next) {	if (!strcmp(d->name, "cmdline")) {	    if (!(page = (char*) __get_free_page(GFP_KERNEL))) {		printk(KERN_ERR "iSCSI-init(get_cmdline): page allocation error\n");		return NULL;	    }	    if (d->get_info)		n = d->get_info(page, &start, pos, count);	    else	    if (d->read_proc)		n = d->read_proc(page, &start, pos, count, &eof, d->data);	    else {		printk(KERN_ERR "iSCSI-init(get_cmdline): no methods available in proc_dir_entry\n");		return NULL;	    }	    if ((p = kmalloc(n + 1, GFP_KERNEL))) {		*(page + n) = '\0';		strcpy(p, page);	    } else		printk(KERN_ERR "iSCSI-init(get_cmdline): memory allocation error\n");	    free_page((unsigned long) page);	    return p;	}    }    printk(KERN_ERR "iSCSI-init(get_cmdline): no proc_dir_entry found for \"/proc/cmdline\"\n");    return NULL;}static int __init get_ioctldev(void){    struct proc_dir_entry *d;    char *page, *start = NULL, *p, *line;    char devname[sizeof(ISCSI_IOCTL_DEV) + 12];    ssize_t n = 0, count = PROC_BLOCK_SIZE;    loff_t pos = 0;    int eof = 0, devnum = 0;    for (d = proc_root.subdir; d; d = d->next) {	if (!strcmp(d->name, "devices")) {	    if (!(page = (char*) __get_free_page(GFP_KERNEL))) {		printk(KERN_ERR "iSCSI-init(get_ioctldev): page allocation error\n");		return -1;	    }	    if (d->get_info)		n = d->get_info(page, &start, pos, count);	    else	    if (d->read_proc)		n = d->read_proc(page, &start, pos, count, &eof, d->data);	    else {		printk(KERN_ERR "iSCSI-init(get_ioctldev): no methods available in proc_dir_entry\n");		return -1;	    }	    for (p = page, line = page; p < (page + n); p++) {		if (*p == '\n') {		    *p = '\0';		    if (strlen(line) < sizeof(devname) && sscanf(line, "%d %s", &devnum, devname) == 2) {			if (!strcmp(devname, ISCSI_IOCTL_DEV))			    break;		    }		    devnum = 0;		    line = p + 1;		}	    }	    free_page((unsigned long) page);	    if (!devnum)		printk(KERN_ERR "iSCSI-init(get_ioctldev): no device \"%s\" was found in \"/proc/devices\"\n", ISCSI_IOCTL_DEV);	    return devnum;	}    }    printk(KERN_ERR "iSCSI-init(get_ioctldev): no proc_dir_entry found for \"/proc/devices\"\n");    return -1;}static int __init atoi(const char *s){    int i = 0;    while (isdigit(*s))	i = i*10 + *(s++) - '0';    return i;}                                                                                    					static int __init split_param(char *arg){    int paramlen;    for (paramlen = 0; *(arg + paramlen) && !isspace(*(arg + paramlen)); paramlen++);    *(arg + paramlen) = '\0';    return paramlen;}static void __init parse_cmdline(void){    #define KEYWORD_ISCSI_INTERFACE	"iscsi-if="    #define KEYWORD_ISCSI_INITIATOR	"iscsi-initiator="    #define KEYWORD_ISCSI_TARGET	"iscsi-target="    #define KEYWORD_ISCSI_TIMEOUT	"iscsi-timeout="    int i, cmdlen;    char *p1, *p2, *p3, *p4, *p5;    struct iscsi_target *p_target, *p2_target;    struct iscsi_interface *p_interface, *p2_interface;    cmdlen = strlen(cmdline);    for (i = 0; i < cmdlen; i++) {	if (!strncmp(cmdline + i, KEYWORD_ISCSI_INTERFACE, sizeof(KEYWORD_ISCSI_INTERFACE) - 1)) {	    i += (sizeof(KEYWORD_ISCSI_INTERFACE) - 1);	    p4 = cmdline + i;	    i += split_param(p4);	    while (p4) {		if ((p5 = strchr(p4, ',')))		    *(p5++) = '\0';		if ((p_interface = kmalloc(sizeof(struct iscsi_interface), GFP_KERNEL))) {		    memset(p_interface, 0, sizeof(struct iscsi_interface));		    p_interface->if_addr = INADDR_NONE;		    p_interface->if_netmask = INADDR_NONE;		    p_interface->gateway = INADDR_NONE;		    p_interface->if_name = p4;		    if ((p1 = strchr(p4, ':')) && (p2 = strchr(p1 + 1, ':'))) {	    		if ((p3 = strchr(p2 + 1, ':'))) {			    *(p3++) = '\0';			    p_interface->gateway = in_aton(p3);			}			*(p1++) = '\0', *(p2++) = '\0';			p_interface->if_addr = in_aton(p1);			p_interface->if_netmask = in_aton(p2);		    }		    /* just make sure we have the same sequence when we rollout the list */		    if (iscsi_interface_list) {			for (p2_interface = iscsi_interface_list; p2_interface; p2_interface = p2_interface->next) {			    if (p2_interface->next == NULL) {				p2_interface->next = p_interface;				break;			    }			}		    }		    else			iscsi_interface_list = p_interface;		}		else		    printk(KERN_ERR "iSCSI-init(parse_parameter): memory allocation error\n");		p4 = p5;	    }	}

⌨️ 快捷键说明

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