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