📄 device.c
字号:
if (next==name) continue; /* skip */ strtoull(name,&next,10); while (isspace(*next)) next++; name = next; while (*name && !isspace(*name)) name++; *name = 0; if (strncmp("/dev/", next, 5) != 0) name = next-5; else name = next; if (*name=='/') name++; strncpy(name, "/dev/", 5); if (verbose>=5) { printf("pf_hard_disk_scan: (%d,%d) %s\n", major, minor, name); } device = MKDEV(major, minor); Dev.delete = 0; if (stat(name, &st) < 0) { dev_open(&Dev, device, O_BYPASS); if (!warned && !nowarn) { fprintf(errstd,"Warning: '" PARTITIONS "' does not match '/dev' directory structure.\n" " Name change: '%s' -> '%s'\n%s" , name, Dev.name, slashes(name) > 3 && slashes(Dev.name) < 3 ? " The kernel was compiled with DEVFS_FS, but 'devfs=mount' was omitted\n" " as a kernel command-line boot parameter; hence, the '/dev' directory\n" " structure does not reflect DEVFS_FS device names.\n" : slashes(name) < 3 && slashes(Dev.name) > 3 ? " The kernel was compiled without DEVFS, but the '/dev' directory structure\n" " implements the DEVFS filesystem.\n" : "" ); warned++; } else if (verbose >= 1 && !nowarn) { fprintf(errstd," Name change: '%s' -> '%s'\n", name, Dev.name); } name = Dev.name; if (Dev.delete) { if (!nowarn) fprintf(errstd, "Warning: '/dev' directory structure is incomplete; device (%d, %d) is missing.\n", major, minor); cache_add(name, device); } } else cache_add(name, device); mask = has_partitions(device); dev = device & mask; /* dev is the master device */ ipart = device & P_MASK(device); /* ipart is the partition number */ #if 1 for (walk=disktab; walk; walk=walk->next) { if (walk->device == dev) { if (walk->heads == 0 /* inaccessible */) { if ((!nowarn || verbose>=2) && ipart==0 && !identify) fprintf(errstd, "Warning: bypassing VolumeID scan of drive flagged INACCESSIBLE: %s\n", name); ipart = -1; /* causes skip below */ } break; } }#endif if (mask && ipart>0) { int found; int serial; for (found=i=0; i<ndevs && !found; i++) { if (dev==vm[i].device) found = i+1; } if (!found) { DEVICE Dev2; serial = volid_get_set(dev, 0, ID_GET);#if 0/* take care of uninitialized Volume IDs with no fanfare */ if (serial==0) { serial = volid_get_set(dev, new_serial(dev), ID_SET); }#endif#if BETA_TEST if (verbose>=3) printf("**ndevs=%d\n", ndevs);#endif if (ndevs>=MAX_DEVICES) { die("More than %d hard disks are listed in '" PARTITIONS "'.\n" " Disks beyond the %dth must be marked:\n" " disk=/dev/XXXX inaccessible\n" " in the configuration file (/etc/lilo.conf).\n" , MAX_DEVICES, MAX_DEVICES); } else { GEOMETRY geo; dev_open(&Dev2,dev,O_BYPASS); vm[ndevs].device = dev; vm[ndevs].sort = SORT(dev); vm[ndevs].vol_id.kernel = serial; vm[ndevs].name = stralloc(Dev2.name); if (verbose >= 4) printf("pf: dev=%04X id=%08X name=%s\n", dev, (int)serial, Dev2.name); for (walk = disktab; walk; walk = walk->next) { if (walk->device == dev) { bios = walk->bios; vm[ndevs].dt = walk; /* record disktab link */ if (bios >= 0x80 && bios <= DEV_MASK) { vm[ndevs].bios.actual = vm[ndevs].bios.user = bios; bios &= 0x7F; if (codes & (1L<<bios)) { i = ndevs-1; bios += 0x80; while (vm[i].bios.user != bios) i--; die("Disks '%s' and '%s' are both assigned 'bios=0x%02X'", vm[ndevs].name, vm[i].name, bios); } codes |= 1L << bios; /* mark BIOS code in use */ } else if (bios != -1) die("Hard disk '%s' bios= specification out of the range [0x80..0x%02X]", Dev2.name, DEV_MASK); break; } } dev_close(&Dev2);#if 0 geo_query_dev(&geo, dev, 1);#else geo_query_dev(&geo, dev, MAJOR(dev)!=MAJOR_LOOP);#endif vm[ndevs].bios.probe = bios_device(&geo, dev); if (serial_valid(serial, DEV_MASK)) { for (i=0; i<ndevs; i++) { if (vm[i].vol_id.kernel==serial) { duplicate++; vm[i].flag |= DUPLICATE; vm[ndevs].flag |= DUPLICATE; /* mark both of them */#if 0 fprintf(errstd, "Error: %s and %s have duplicate volume IDs\n", kname[i], name);#endif } /* if */ } /* for */ } else { vm[ndevs].flag |= INVALID; invalid++; } found = ++ndevs; } /* if (open, lseek, read ) */ } /* if (!found) */ if (ipart>0 && ipart<=PART_MAX) { found--; if (part_nowrite(name) & PTW_NTFS) { vm[found].flag |= NTCAUTION; vm[found].nt[ipart-1] = NTCAUTION; ntcaution++; if (verbose>=4) printf("NT partition: %s %d %s\n", vm[found].name, ipart, name); } } } /* if (mask && (device & P_MASK(device)) ) */ } /* while (!feof()) */ if (line) free(line); fclose(pp_fd); if (verbose>=5) { int i; for (i=0; i<ndevs; i++) printf(" %04X %08X %s\n", vm[i].device, vm[i].vol_id.kernel, vm[i].name); } if (verbose>=2) printf("pf_hard_disk_scan: ndevs=%d\n", ndevs);/* now sort the volumes into canonical order */ { int i,j,k; for (j=ndevs-1; j>0; j--) for (i=0; i<j; i++) if (vm[i].sort > vm[i+1].sort) { struct VolumeMgmt temp; temp = vm[i]; vm[i] = vm[i+1]; vm[i+1] = temp; }/* now automatically treat ATARAID devices as inaccessible */ for (k=0; k<ndevs; k++)#ifdef LCF_ATARAID if (MAJOR(vm[k].device) == MAJOR_HPT370) {#if ATAKEYWORD if (!cfg_get_flag(cf_options, "ataraid") ) { if (!nowarn) fprintf(errstd, "Warning: ATARAID controller present, without \"ataraid\" keyword used.\n" " Underlying drives individually must be marked INACCESSIBLE.\n" ); } else {#endif for (j=k+1; j<ndevs; j++) { if ((i=is_ata(&vm[j], &vm[k]))<0) { if (!nowarn && !identify) fprintf(errstd, "Warning: (ATAraid driver) the kernel does not support underlying\n" " device inquiries. Each underlying drive of %s must\n" " individually be marked INACCESSIBLE.\n", vm[k].name ); j=ndevs; /* terminate loop */ } else if (i) { if (!vm[j].dt) { walk = alloc_t(DT_ENTRY); walk->device = vm[j].device; walk->cylinders = walk->heads = walk->sectors = walk->start = -1; walk->next = disktab; vm[j].dt = disktab = walk;#if BETA_TEST if (verbose >= 4) printf("Allocated DT entry for device %04X ptr=%08lx\n", vm[j].device, (long)walk);#endif } if (vm[j].dt->heads != 0) { vm[j].dt->heads = 0; if (!nowarn || verbose>=1) fprintf(errstd, "Warning: (ataraid) underlying device flagged INACCESSIBLE: %s\n", vm[j].name); } --ndevs; if (!nowarn || verbose>=1) fprintf(errstd, "Warning: bypassing VolumeID check of underlying ATARAID drive:\n" "\t%04X %08X %s\n", vm[j].device, vm[j].vol_id.kernel, vm[j].name); for (i=j; i<ndevs; i++) vm[i] = vm[i+1]; j = k; /* proper place to resume scan */ } }#if ATAKEYWORD }#endif }#else if (MAJOR(vm[k].device) == MAJOR_HPT370) { if (!nowarn) fprintf(errstd, "Warning: ATARAID controller present; underlying drives individually\n" " must be marked INACCESSIBLE.\n" );#if BETA_TEST{ int ata_fd; DEVICE dev; if ((ata_fd=dev_open(&dev, vm[k].device, O_NOACCESS) ) < 0) die("Unable to open %s",vm[k].name); if (ioctl(ata_fd, ATA_PRINT_RAID_DEBUG, NULL) < 0) die("ATA_PRINT_RAID_DEBUG not implemented"); dev_close(&dev);}#endif }#endif } /* end sort */ if (verbose>=3) { for (i=0; i<ndevs; i++) printf(" %04X %08X %s\n", vm[i].device, vm[i].vol_id.kernel, vm[i].name); printf("Resolve invalid VolumeIDs\n"); }/* now go thru and resolve any invalid VolumeIDs */ if (invalid) for (i=0; i<ndevs; i++) if (vm[i].flag & INVALID) { if (ndevs>1) winnt_check(&vm[i], 1); else if (vm[i].flag & NTCAUTION) break; dev = vm[i].device; vm[i].vol_id.kernel = volid_get_set(dev, new_serial(dev), ID_SET); vm[i].flag &= ~INVALID; } if (verbose>=3) printf("Resolve duplicate VolumeIDs\n"); /* now check for duplicates */ while (duplicate) { /* loop until there are none */ int j, k; duplicate = 0; for (j=ndevs-1; j>0; j--) { for (i=0; i<j; i++) { if (vm[i].vol_id.kernel == vm[j].vol_id.kernel) { if (vm[i].flag & vm[j].flag & NTCAUTION) { if (!winnt_check(&vm[j], 0)) k = j; else winnt_check(&vm[k=i], 1); } else if (vm[i].flag & NTCAUTION) k = j; else if (vm[j].flag & NTCAUTION) k = i; else k = j; dev = vm[k].device; vm[k].vol_id.kernel = volid_get_set(dev, new_serial(dev), ID_SET); duplicate++; } } } } /* while (duplicate) */ if (verbose>=2) { for (i=0; i<ndevs; i++) printf(" %04X %08X %s\n", vm[i].device, vm[i].vol_id.kernel, vm[i].name); } if (verbose>=2) printf("device codes (user assigned pf) = %lX\n", codes);/* mark those BIOS codes that are already used in the disk=/bios= table */ for (walk=disktab; walk; walk=walk->next) { if (walk->bios >= 0x80) { /* eliminate -1 and floppies */ if (MAJOR(walk->device)==MAJOR_MD) continue; bios = walk->bios & 0x7F; if (bios >= 8*sizeof(codes) || bios >= MAX_BIOS_DEVICES) die("BIOS code %02X is too big (device %04X)", bios+0x80, walk->device); if (codes & (1L<<bios)) { int j = -1; int k = -1; for (i=0; i<ndevs; i++) { if (vm[i].device == walk->device) j = i; else if (vm[i].bios.user == bios+0x80) k = i; }#if BETA_TEST if (verbose>=3) printf("J=%d K=%d\n", j, k);#endif if (j<0 && k>=0) { die("Devices %04X and %04X are assigned to BIOS 0x%02X", vm[k].device, walk->device, bios+0x80); } } codes |= 1L << bios; } } if (verbose>=2) printf("device codes (user assigned) = %lX\n", codes); for (i=0; i<ndevs; i++) { bios = vm[i].bios.probe; if (bios >= 0x80) { if (vm[i].bios.actual < 0x80 && !(codes & (1L<<(bios&0x7F)))) { vm[i].bios.actual = bios; bios &= 0x7F; codes |= 1L << bios; } } } if (verbose>=2) printf("device codes (BIOS assigned) = %lX\n", codes); for (bios=i=0; i<ndevs; i++) { int j; if (vm[i].bios.actual < 0x80) { while ( codes & (1L<<bios) ) bios++; if (bios < MAX_BIOS_DEVICES) { codes |= 1L<<bios; vm[i].bios.actual = 0x80+bios; if (verbose>=3) printf("Filling in '%s' = 0x%02X\n", vm[i].name, bios+0x80); } else vm[i].bios.actual = -1; } if (!vm[i].dt) { walk = alloc_t(DT_ENTRY); walk->device = vm[i].device; walk->cylinders = walk->bios = walk->heads = walk->sectors = walk->start = -1; walk->next = disktab; vm[i].dt = disktab = walk;#if BETA_TEST if (verbose >= 4) printf("Allocated DT entry for device %04X ptr=%08lx\n", vm[i].device, (long)walk);#endif } j = vm[i].dt->bios = vm[i].bios.actual; j &= 0x7F; if (j < MAX_BIOS_DEVICES) { serial_no[j] = vm[i].vol_id.kernel; device_code[j] = vm[i].device;#if BETA_TEST if (verbose >= 5) { printf("Generated: %02X %04X %08X\n", j+0x80, device_code[j], (int)serial_no[j]); }#endif } else { vm[i].dt->heads = 0; /* mark inaccessible */ if (!nowarn) { static int i=0; if (!(i++)) fprintf(errstd, "Warning: Internal implementation restriction. Boot may occur from the first\n" " %d disks only. Disks beyond the %dth will be flagged INACCESSIBLE.\n" , MAX_BIOS_DEVICES, MAX_BIOS_DEVICES); fprintf(errstd, "Warning: 'disk=%s inaccessible' is being assumed. (%04X)\n", vm[i].name, vm[i].device); } } inited = 1; } if (verbose>=2) printf("device codes (canonical) = %lX\n", codes); for (bios=8*sizeof(codes)-1; !(codes&(1L<<bios)) && bios>=0; ) bios--; if (bios > ndevs && !nowarn) fprintf(errstd,"Warning: BIOS device code 0x%02X is used (>0x%02X). It indicates more disks\n" " than those represented in '/proc/partitions' having actual partitions.\n" " Booting results may be unpredictable.\n", bios+0x80, ndevs+0x80-1); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -