geometry.c

来自「LINUX lilo-22.7 源代码。」· C语言 代码 · 共 1,345 行 · 第 1/3 页

C
1,345
字号
	    die("LVM IOP %d not supported for booting\n", iop);	close(lvmfd);	lvmfd = dev_open(&dev, lbm->lv_dev, O_RDONLY);	if (lvmfd < 0)	    die("can't open LVM block device %#x\n", lbm->lv_dev);	last_dev = lbm->lv_dev;    }    if (ioctl(lvmfd, LV_BMAP, lbm) < 0) {	perror(__FUNCTION__);	pdie("LV_BMAP error or ioctl unsupported, can't have image in LVM.\n");    }}#endif#ifdef LCF_EVMSvoid evms_bmap(struct evms_get_bmap_t *ebm){                                      DEVICE dev;    static int evms_fd = -1;    static dev_t evms_last_dev = 0;    if (ebm->dev != evms_last_dev) {        char evms_blk[] = "/dev/evms/block_device";        struct evms_version_t evms_ver;        // Open the EVMS device        if (evms_fd != -1)            close(evms_fd);        evms_fd = open(evms_blk, O_RDONLY);        if (evms_fd < 0)            die("Can't open EVMS block device %s.\n", evms_blk);        // Get EVMS ioctl version number.        if (ioctl(evms_fd, EVMS_GET_IOCTL_VERSION, &evms_ver) < 0)            die("EVMS_GET_IOCTL_VERSION failed on %s.\n", evms_blk);        // Check that the ioctl version is >= 7.1.0        if (evms_ver.major < 7 ||            (evms_ver.major == 7 && evms_ver.minor < 1))            die("EVMS ioctl version %d.%d.%d does not support booting.\n",                evms_ver.major, evms_ver.minor, evms_ver.patch);        close(evms_fd);        evms_fd = dev_open(&dev, ebm->dev, O_RDONLY);        if (evms_fd < 0)            die("Can't open EVMS block device %#x\n", ebm->dev);        evms_last_dev = ebm->dev;    }    if (ioctl(evms_fd, EVMS_GET_BMAP, ebm) < 0) {        perror(__FUNCTION__);        pdie("EVMS_GET_BMAP error or ioctl unsupported. Can't have image on EVMS volume.\n");    }}#endifvoid geo_query_dev(GEOMETRY *geo,int device,int all){    DEVICE dev;    int fd,get_all,major;    struct floppy_struct fdprm;    struct hd_geometry hdprm;    if (verbose>=5) printf("geo_query_dev: device=%04X\n", device);#if 0/*  Werner's original */    get_all = all || MAJOR(device) != MAJOR_FD; */#else/* simplify the condition -- JRC 2003-06-04 */    get_all = all;#endif    if (!MAJOR(device))	die("Trying to map files from unnamed device 0x%04x (NFS/RAID mirror down ?)",device);    if (device == MAJMIN_RAM)	die("Trying to map files from your RAM disk. "	  "Please check -r option or ROOT environment variable.");    if (get_all) {	fd = dev_open(&dev,device,O_NOACCESS);    }    else {	fd = -1; /* pacify GCC */	geo->heads = geo->cylinders = geo->sectors = 1;	geo->start = 0;	geo->device = -1;    }    switch ((major=MAJOR(device))) {	case MAJOR_FD:	    geo->device = device & 3;	    if (!get_all) break;	    if (ioctl(fd,FDGETPRM,&fdprm) < 0)		die("geo_query_dev FDGETPRM (dev 0x%04x): %s",device,		  strerror(errno));	    geo->heads = fdprm.head;	    geo->cylinders = fdprm.track;	    geo->sectors = fdprm.sect;	    geo->start = 0;	    break;	case MAJOR_HD:	case MAJOR_IDE2:	case MAJOR_IDE3:	case MAJOR_IDE4:#ifdef MAJOR_IDE5	case MAJOR_IDE5:#endif	case MAJOR_IDE6:	case MAJOR_IDE7:	case MAJOR_IDE8:	case MAJOR_IDE9:	case MAJOR_IDE10:	case MAJOR_ESDI:	case MAJOR_XT:	case MAJOR_ACORN:	MASK63:	    geo->device = 0x80 + (MINOR(device) >> 6) +		    (MAJOR(device) == MAJOR_HD ? 0 : last_dev(MAJOR_HD,64));	    if (!get_all) break;	    if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)		die("geo_query_dev HDIO_GETGEO (dev 0x%04x): %s",device,		  strerror(errno));	    geo->heads = hdprm.heads;	    geo->cylinders = hdprm.cylinders;	    geo->sectors = hdprm.sectors;	    geo->start = hdprm.start;	    break;	case MAJOR_SD:	case MAJOR_SD2:	case MAJOR_SD3:	case MAJOR_SD4:	case MAJOR_SD5:	case MAJOR_SD6:	case MAJOR_SD7:	case MAJOR_SD8:	MASK15:	    geo->device = 0x80 + last_dev(MAJOR_HD,64) + (MINOR(device) >> 4);	    if (!get_all) break;	    if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)		die("geo_query_dev HDIO_GETGEO (dev 0x%04x): %s",device,		  strerror(errno));	    if (all && !hdprm.sectors)		die("HDIO_REQ not supported for your SCSI controller. Please "		  "use a DISK section");	    geo->heads = hdprm.heads;	    geo->cylinders = hdprm.cylinders;	    geo->sectors = hdprm.sectors;	    geo->start = hdprm.start;	    break;	case MAJOR_DAC960:	case MAJOR_DAC960+1:	case MAJOR_DAC960+2:	case MAJOR_DAC960+3:	case MAJOR_DAC960+4:	case MAJOR_DAC960+5:	case MAJOR_DAC960+6:	case MAJOR_DAC960+7:	case MAJOR_IBM_iSER:	MASK7:	    geo->device = 0x80 + last_dev(MAJOR_HD,64) + (MINOR(device) >> 3);	    if (!get_all) break;	    if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)		die("geo_query_dev HDIO_GETGEO (dev 0x%04x): %s",device,		  strerror(errno));	    if (all && !hdprm.sectors)		die("HDIO_REQ not supported for your DAC960/IBM controller. "		  "Please use a DISK section");	    geo->heads = hdprm.heads;	    geo->cylinders = hdprm.cylinders;	    geo->sectors = hdprm.sectors;	    geo->start = hdprm.start;	    break;	case MAJOR_AMI_HYP:	case MAJOR_HPT370:	case MAJOR_EXPR:	case MAJOR_EXPR+1:	case MAJOR_EXPR+2:	case MAJOR_EXPR+3:	case MAJOR_FTL:	case MAJOR_NFTL:	case MAJOR_DOC:	case MAJOR_SMART2+0:	case MAJOR_SMART2+1:	case MAJOR_SMART2+2:	case MAJOR_SMART2+3:	case MAJOR_SMART2+4:	case MAJOR_SMART2+5:	case MAJOR_SMART2+6:	case MAJOR_SMART2+7:	case MAJOR_CISS+0:	case MAJOR_CISS+1:	case MAJOR_CISS+2:	case MAJOR_CISS+3:	case MAJOR_CISS+4:	case MAJOR_CISS+5:	case MAJOR_CISS+6:	case MAJOR_CISS+7:	case MAJOR_I2O:	case MAJOR_I2O+1:	case MAJOR_I2O+2:	case MAJOR_I2O+3:	case MAJOR_I2O+4:	case MAJOR_I2O+5:	case MAJOR_I2O+6:	case MAJOR_I2O+7:	    geo->device = 0x80 + last_dev(MAJOR_HD,64) + (MINOR(device) >> 4);	    if (!get_all) break;	    if (ioctl(fd,HDIO_GETGEO,&hdprm) < 0)		die("geo_query_dev HDIO_GETGEO (dev 0x%04x): %s",device,		  strerror(errno));	    if (all && !hdprm.sectors)		die("HDIO_REQ not supported for your Array controller. Please "		  "use a DISK section");	    geo->heads = hdprm.heads;	    geo->cylinders = hdprm.cylinders;	    geo->sectors = hdprm.sectors;	    geo->start = hdprm.start;	    break;	default:	    if (max_partno[major] && major==MAJOR_LOOP) break;	    if (max_partno[major] == 63)  goto MASK63;	    if (max_partno[major] == 15)  goto MASK15;	    if (max_partno[major] == 7)   goto MASK7;	    	    if (MAJOR(device)>=120 && MAJOR(device)<=127)		die("Linux experimental device 0x04x needs to be defined.\n"		    "Check 'man lilo.conf' under 'disk=' and 'max-partitions='", device);	    else die("Sorry, don't know how to handle device 0x%04x",device);    }    if (get_all) dev_close(&dev);    if (verbose>=5) printf("exit geo_query_dev\n");}int is_first(int device){    DT_ENTRY *walk;    for (walk = disktab; walk; walk = walk->next)	if (walk->device == device) break;    if (!walk && !old_disktab)	for (walk = disktab; walk; walk = walk->next)	    if (walk->device == (device & D_MASK(device))) break;    if (walk && !walk->heads)	die("Device 0x%04X: Configured as inaccessible.\n",device);    if (walk && walk->bios != -1) return !(walk->bios & 0x7f);    switch (MAJOR(device)) {	case MAJOR_FD:	    return !(device & 3);	case MAJOR_HD:	    return !(MINOR(device) >> 6);	case MAJOR_IDE2:	case MAJOR_IDE3:	case MAJOR_IDE4:#ifdef MAJOR_IDE5	case MAJOR_IDE5:#endif	case MAJOR_IDE6:	case MAJOR_IDE7:	case MAJOR_IDE8:	case MAJOR_IDE9:	case MAJOR_IDE10:	case MAJOR_ESDI:	case MAJOR_XT:	    return MINOR(device) >> 6 ? 0 : !last_dev(MAJOR_HD,64);	case MAJOR_SD:	case MAJOR_SD2:	case MAJOR_SD3:	case MAJOR_SD4:	case MAJOR_SD5:	case MAJOR_SD6:	case MAJOR_SD7:	case MAJOR_SD8:	case MAJOR_AMI_HYP:	case MAJOR_HPT370:	case MAJOR_EXPR+0:	case MAJOR_EXPR+1:	case MAJOR_EXPR+2:	case MAJOR_EXPR+3:	case MAJOR_NFTL:	case MAJOR_DOC:	case MAJOR_SMART2+0:	case MAJOR_SMART2+1:	case MAJOR_SMART2+2:	case MAJOR_SMART2+3:	case MAJOR_SMART2+4:	case MAJOR_SMART2+5:	case MAJOR_SMART2+6:	case MAJOR_SMART2+7:	case MAJOR_CISS+0:	case MAJOR_CISS+1:	case MAJOR_CISS+2:	case MAJOR_CISS+3:	case MAJOR_CISS+4:	case MAJOR_CISS+5:	case MAJOR_CISS+6:	case MAJOR_CISS+7:	case MAJOR_I2O:	case MAJOR_I2O+1:	case MAJOR_I2O+2:	case MAJOR_I2O+3:	case MAJOR_I2O+4:	case MAJOR_I2O+5:	case MAJOR_I2O+6:	case MAJOR_I2O+7:	    return MINOR(device) >> 4 ? 0 : !last_dev(MAJOR_HD,64);	case MAJOR_DAC960:	case MAJOR_DAC960+1:	case MAJOR_DAC960+2:	case MAJOR_DAC960+3:	case MAJOR_DAC960+4:	case MAJOR_DAC960+5:	case MAJOR_DAC960+6:	case MAJOR_DAC960+7:	case MAJOR_IBM_iSER:	    return MINOR(device) >> 3 ? 0 : !last_dev(MAJOR_HD,64);	default:	    return 1; /* user knows what (s)he's doing ... I hope */    }}void geo_get(GEOMETRY *geo,int device,int user_device,int all){    DT_ENTRY *walk;    int inherited,keep_cyls,is_raid=0;    if (verbose>=5) printf("geo_get: device %04X, all=%d\n", device, all);#ifdef LCF_LVM    /*     * Find underlying device (PV) for LVM.  It is OK if the underlying PV is     * really an MD RAID1 device, because the geometry of the RAID1 device is     * exactly the same as the underlying disk, so FIBMAP and LV_BMAP should     * return the correct block numbers regardless of MD.     *     * We do a quick test to see if the LVM LV_BMAP ioctl is working correctly.     * It should map the two blocks with the same difference as they were input,     * with a constant offset from their original block numbers.  If this is not     * the case then LV_BMAP is not working correctly (some widely distributed     * kernels did not have working LV_BMAP support, some just oops here).     */    if (MAJOR(device) == MAJOR_LVM)    {	struct lv_bmap lbmA, lbmB;#define DIFF 255	lbmA.lv_dev = lbmB.lv_dev = device;	lbmA.lv_block = 0;	lbmB.lv_block = DIFF;	lvm_bmap(&lbmA);	lvm_bmap(&lbmB);	if (lbmB.lv_block - lbmA.lv_block != DIFF)	    die("This version of LVM does not support boot LVs");	device = geo->base_dev = lbmA.lv_dev;    }#endif#ifdef LCF_EVMS    if (MAJOR(device) == MAJOR_EVMS) {        struct evms_get_bmap_t ebm;                ebm.rsector = 0;        ebm.dev = device;        ebm.status = 0;                evms_bmap(&ebm);                device = geo->base_dev = ebm.dev;    }#endif    /* Find underlying device for MD RAID */    if (MAJOR(device) == MD_MAJOR) {        char mdxxx[16];	int md_fd;/*	int pass;	*/	struct md_version md_version_info;	md_array_info_t md_array_info;	md_disk_info_t md_disk_info;	int raid_limit;	sprintf(mdxxx, "/dev/md%d", MINOR(device));	if ((md_fd=open(mdxxx,O_NOACCESS)) < 0)	{	    sprintf(mdxxx, "/dev/md/%d", MINOR(device));	    if ((md_fd=open(mdxxx,O_NOACCESS)) < 0)		die("Unable to open %s", mdxxx);	}	if (ioctl(md_fd,RAID_VERSION,&md_version_info) < 0)	    die("Unable to get RAID version on %s", mdxxx);	if (md_version_info.major > 0)	    die("Raid major versions > 0 are not supported");	if (md_version_info.minor < 90)	    die("Raid versions < 0.90 are not supported");		if (ioctl(md_fd,GET_ARRAY_INFO,&md_array_info) < 0)	    die("Unable to get RAID info on %s", mdxxx);	if ((md_array_info.major_version != md_version_info.major) &&		(md_array_info.minor_version != md_version_info.minor))	    die("Inconsistent Raid version information on %s", mdxxx);	if (md_array_info.level != 1)	    die("Only RAID1 devices are supported for boot images");	raid_limit = md_array_info.raid_disks + md_array_info.spare_disks;	/* version 22.7 */#if 1	is_raid = (device==boot_dev_nr);	md_disk_info.number = raid_index;	if (ioctl(md_fd,GET_DISK_INFO,&md_disk_info) < 0)	    die("GET_DISK_INFO: %s", mdxxx);	device = MKDEV(md_disk_info.major, md_disk_info.minor);#else		/* prior to 22.7 */{int pass;   	for (pass = 0; pass < raid_limit; pass++) {	    md_disk_info.number = pass;	    if (ioctl(md_fd,GET_DISK_INFO,&md_disk_info) < 0)#if BETA_TEST	    {		printf("(raid) GET_DISK_INFO: failed for pass=%d\n", pass);		continue;	    }#else	        die("GET_DISK_INFO: %s", mdxxx);#endif	    if (!(md_disk_info.state & (1 << MD_DISK_FAULTY))) {#if 1		is_raid = (device==boot_dev_nr);#else/* this change may be in error; the correct comparison is == */		is_raid = (device!=boot_dev_nr);#endif	        device = MKDEV(md_disk_info.major, md_disk_info.minor);		break;	    }	}}#endif	/* end of code prior to version 22.7 */	close(md_fd);

⌨️ 快捷键说明

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