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

📄 init.c

📁 ISCSI user client software.Client would be used to access the IPSAN server.
💻 C
字号:
/* * iSCSI driver for Linux * Copyright (C) 2002 Cisco Systems, Inc. * maintained by linux-iscsi-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * See the file COPYING included with this distribution for more details. * * $Id: init.c,v 1.12 2005/01/11 03:47:11 mikenc Exp $ * */#include <stdint.h>#include <unistd.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <sys/mount.h>#include <scsi/scsi.h>#include <linux/unistd.h>#include <errno.h>#include <dirent.h>#include "iscsi-sfnet.h"#include "iscsi-ioctl.h"#include "iscsi-network-boot.h"#define ISCSI_SYS_PATH(hostnum, val) \	sprintf(sysfs_file, "/sys/class/scsi_host/host%d/%s", hostnum, val)static inline _syscall2(int, pivot_root, const char *, one, const char *, two);static int varpart = 0, rootpart = 0;	/* default value 0 indicate complete					 * disk instead of a partition.					 */int hostnum = -1;char sysfs_file[PATH_MAX];struct scsi_idlun {	int dev_id;	int host_unique_id;};struct device_info {	int lun;	int part;};static intscan_cmdline(void){	FILE *f;	char line[512], buf[256], *res, *rbuf, *cp, *tmp = NULL;	f = fopen("/proc/cmdline", "r");	if (!f) {		printf("Cannot open control path to the driver");		exit(1);	}	rbuf = fgets(line, sizeof (buf), f);	cp = strtok(rbuf, " ");	do {		sscanf(cp, "%s", buf);		res = strchr(buf, '=');		if (res) {			*res = '\0';			tmp = res + 1;		}		if (strcasecmp(buf, "varpart") == 0) {			varpart = atoi(tmp);		}		if (strcasecmp(buf, "rootpart") == 0) {			rootpart = atoi(tmp);		}		cp = strtok(NULL, " ");	} while (cp);	fclose(f);	return 0;}static intread_sysfs_file(char *sysfs_file){	int fd;	char buf[20];	fd = open(sysfs_file, O_RDONLY);	if (fd < 0) {		printf("error in opening %s file\n", sysfs_file);		return -1;	}	memset(buf, 0, sizeof(buf));	read(fd, buf, sizeof(buf));	if (!strncmp(buf, "iscsi-sfnet", 11)) {		close(fd);		return 1;	}	close(fd);	return -1;}static voidwrite_sysfs_file(char *sysfs_file, char *cmd){	int fd;	fd = open(sysfs_file, O_WRONLY);	if (fd < 0)		printf("error in opening %s file\n", sysfs_file);	write(fd, cmd, strlen(cmd));	write(fd, "\n", 1);	close(fd);}static voidgenerate_rootdev(int *rdev_id, struct device_info *info, char *devname){	struct scsi_idlun idlun;	struct stat s;	char fname[64], buf[8], ebuf[256];	int fd, in, i;	memset(buf, 0, sizeof (buf));	for (i = 0; i <= 26; i++) {		strcpy(fname, "/dev/sd");		if (info->part != 0)			sprintf(buf, "%c%d", ('a' + (char) i), info->part);		else			sprintf(buf, "%c", ('a' + (char) i));		strcat(fname, buf);		fd = open(fname, O_RDWR);		if (fd < 0) {			if (errno == EBUSY) {				printf("%s : device busy\n", fname);				continue;			} else				break;		}		if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun) < 0) {			sprintf(ebuf, "device %s failed on scsi ioctl, skip",				fname);			perror(ebuf);			continue;		}		hostnum = idlun.dev_id >> 24 & 0xff;		ISCSI_SYS_PATH(hostnum, "proc_name");		if ((read_sysfs_file(sysfs_file) > 0) &&		    ((idlun.dev_id >> 8 & 0xff) == info->lun)) {			in = open(fname, O_RDONLY);			fstat(in, &s);			*rdev_id = s.st_rdev;			if (devname)				strcpy(devname, fname);			close(in);			break;		}	}	if (fd)		close(fd);}static intmkdevices(char *prefix){	int fd, i, major, minor;	char buf[32768], devName[128];	char old, *start, *chptr;	if ((fd = open("/proc/partitions", O_RDONLY)) < 0) {		printf("failed to open /proc/partitions: %d\n", errno);		return 1;	}	i = read(fd, buf, sizeof (buf));	if (i < 1) {		close(fd);		printf("failed to read /proc/partitions: %d\n", errno);		return 1;	}	buf[i] = '\0';	close(fd);	start = strchr(buf, '\n');	if (start) {		start++;		start = strchr(buf, '\n');	}	if (!start)		return 1;	start = start + 1;	while (*start) {		while (*start && isspace(*start))			start++;		major = strtol(start, &chptr, 10);		if (start != chptr) {			start = chptr;			while (*start && isspace(*start))				start++;			minor = strtol(start, &chptr, 10);			if (start != chptr) {				start = chptr;				while (*start && isspace(*start))					start++;				while (*start && !isspace(*start))					start++;				while (*start && isspace(*start))					start++;				if (*start) {					char *ptr, *deviceDir;					int i;					chptr = start;					while (!isspace(*chptr))						chptr++;					old = *chptr;					*chptr = '\0';					sprintf(devName, "%s/%s", prefix,						start);					unlink(devName);					ptr = devName;					i = 0;					while (*ptr)						if (*ptr++ == '/')							i++;					if (i > 2) {						deviceDir =						    alloca(strlen(devName) + 1);						strcpy(deviceDir, devName);						ptr =						    deviceDir +						    (strlen(devName) - 1);						while (*ptr != '/')							*ptr-- = '\0';						if (access(deviceDir, X_OK)						    && mkdir(deviceDir, 0644)) {							printf("cannot create "							       "directory %s: "							       "%d\n",							       deviceDir,							       errno);						}					}					if (mknod(devName, S_IFBLK | 0600,						  makedev(major, minor))) {						printf("failed to create %s\n",						       devName);					}					*chptr = old;					start = chptr;				}			}		}		start = strchr(start, '\n');		if (!*start)			return 1;		start = start + 1;	}	return 0;}static intwrite_device_number(int rdev){	FILE *f = NULL;	char buf[10];	f = fopen("/proc/sys/kernel/real-root-dev", "w");	if (!f) {		printf("Cannot open /proc/sys/kernel/real-root-dev\n");		return -1;	}	sprintf(buf, "0x%x", rdev);	fprintf(f, buf, strlen(buf));	fclose(f);	return 1;}static voidcreate_symlink(char *devname, int rootpart){	char *c, buf1[64], buf2[256], diskname[256];	int i, len;	unlink("/sysroot/dev/inbpdisk");	if (rootpart != 0) {		len = strlen(devname);		c = devname;		c += strlen(devname);		c--;		i = atoi(c);		for (;;) {			if (i == rootpart) {				memset(diskname, 0, sizeof(diskname));				strncpy(diskname, devname, c-devname);				break;			} else {				c--;				i = atoi(c);			}		}	} else {		memset(diskname, 0, sizeof(diskname));		strcpy(diskname, devname);	}	symlink(diskname, "/sysroot/dev/inbpdisk");	for (i = 1; i < 16; i++) {		sprintf(buf1, "/sysroot/dev/inbpdisk%d", i);		unlink(buf1);		sprintf(buf2, "%s%d", diskname, i);		symlink(buf2, buf1);	}}static voidgenerate_rootrc(char *rootfs, int lun){	int rdev_id = 0;	unsigned long mf;	char buf[256], devname[64];	struct device_info info = {		lun: lun,		part: rootpart,	};	memset(devname, 0, sizeof (devname));	generate_rootdev(&rdev_id, &info, devname);	if (rdev_id) {		write_device_number(rdev_id);	}	if (mknod("/dev/root", S_IFBLK | 0700, rdev_id))		printf("mknod failed: %d\n", errno);	write_device_number(256);	mf = 0;	mount("/dev/root", "/sysroot", rootfs, mf, NULL);	sprintf(buf, "- - -");	ISCSI_SYS_PATH(hostnum, "scan");	write_sysfs_file(sysfs_file, buf);	create_symlink(devname, rootpart);	umount("/sysroot");	mf = 0;	mf |= MS_RDONLY;	mount("/dev/root", "/sysroot", rootfs, mf, NULL);	if (pivot_root("/sysroot", "/sysroot/initrd"))		printf("pivotroot: pivot_root(/sysroot, /sysroot/initrd) "		       "failed: %d\n", errno);	umount("/initrd/proc");	umount("/initrd/sys");}intmain(int argc, char *argv[]){	char *rootfs = NULL;	char *varfs = NULL;	struct sapiNBP nbp;	if (argc > 1)		rootfs = argv[1];	if (argc > 2)		varfs = argv[2];	scan_cmdline();	get_inbp_info(&nbp);	while (!bring_up_network(&nbp)) {		printf("iSCSI: Error in bringing up the network interface\n");	}	establish_iscsi_network_boot_session(&nbp);	mkdevices("/dev");	generate_rootrc(rootfs, nbp.slun);	return 0;}

⌨️ 快捷键说明

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