fdisksunlabel.c
来自「Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分」· C语言 代码 · 共 747 行 · 第 1/2 页
C
747 行
unsigned short csum = 0; while(ush < (unsigned short *)(&sunlabel->csum)) csum ^= *ush++; sunlabel->csum = csum; } set_all_unchanged(); set_changed(0); get_boot(create_empty_sun);}voidtoggle_sunflags(int i, unsigned char mask) { if (sunlabel->infos[i].flags & mask) sunlabel->infos[i].flags &= ~mask; else sunlabel->infos[i].flags |= mask; set_changed(i);}static voidfetch_sun(unsigned int *starts, unsigned int *lens, unsigned int *start, unsigned int *stop) { int i, continuous = 1; *start = 0; *stop = cylinders * heads * sectors; for (i = 0; i < partitions; i++) { if (sunlabel->partitions[i].num_sectors && sunlabel->infos[i].id && sunlabel->infos[i].id != WHOLE_DISK) { starts[i] = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; lens[i] = SSWAP32(sunlabel->partitions[i].num_sectors); if (continuous) { if (starts[i] == *start) *start += lens[i]; else if (starts[i] + lens[i] >= *stop) *stop = starts[i]; else continuous = 0; /* There will be probably more gaps than one, so lets check afterwards */ } } else { starts[i] = 0; lens[i] = 0; } }}static unsigned int *verify_sun_starts;static intverify_sun_cmp(int *a, int *b) { if (*a == -1) return 1; if (*b == -1) return -1; if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1; return -1;}voidverify_sun(void) { unsigned int starts[8], lens[8], start, stop; int i,j,k,starto,endo; int array[8]; verify_sun_starts = starts; fetch_sun(starts,lens,&start,&stop); for (k = 0; k < 7; k++) { for (i = 0; i < 8; i++) { if (k && (lens[i] % (heads * sectors))) { printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1); } if (lens[i]) { for (j = 0; j < i; j++) if (lens[j]) { if (starts[j] == starts[i]+lens[i]) { starts[j] = starts[i]; lens[j] += lens[i]; lens[i] = 0; } else if (starts[i] == starts[j]+lens[j]){ lens[j] += lens[i]; lens[i] = 0; } else if (!k) { if (starts[i] < starts[j]+lens[j] && starts[j] < starts[i]+lens[i]) { starto = starts[i]; if (starts[j] > starto) starto = starts[j]; endo = starts[i]+lens[i]; if (starts[j]+lens[j] < endo) endo = starts[j]+lens[j]; printf(_("Partition %d overlaps with others in " "sectors %d-%d\n"), i+1, starto, endo); } } } } } } for (i = 0; i < 8; i++) { if (lens[i]) array[i] = i; else array[i] = -1; } qsort(array,SIZE(array),sizeof(array[0]), (int (*)(const void *,const void *)) verify_sun_cmp); if (array[0] == -1) { printf(_("No partitions defined\n")); return; } stop = cylinders * heads * sectors; if (starts[array[0]]) printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]); for (i = 0; i < 7 && array[i+1] != -1; i++) { printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]); } start = starts[array[i]]+lens[array[i]]; if (start < stop) printf(_("Unused gap - sectors %d-%d\n"),start,stop);}voidadd_sun_partition(int n, int sys) { unsigned int start, stop, stop2; unsigned int starts[8], lens[8]; int whole_disk = 0; char mesg[256]; int i, first, last; if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) { printf(_("Partition %d is already defined. Delete " "it before re-adding it.\n"), n + 1); return; } fetch_sun(starts,lens,&start,&stop); if (stop <= start) { if (n == 2) whole_disk = 1; else { printf(_("Other partitions already cover the whole disk.\nDelete " "some/shrink them before retry.\n")); return; } } snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR)); for (;;) { if (whole_disk) first = read_int(0, 0, 0, 0, mesg); else first = read_int(scround(start), scround(stop)+1, scround(stop), 0, mesg); if (display_in_cyl_units) first *= units_per_sector; else /* Starting sector has to be properly aligned */ first = (first + heads * sectors - 1) / (heads * sectors); if (n == 2 && first != 0) printf ("\It is highly recommended that the third partition covers the whole disk\n\and is of type `Whole disk'\n"); /* ewt asks to add: "don't start a partition at cyl 0" However, edmundo@rano.demon.co.uk writes: "In addition to having a Sun partition table, to be able to boot from the disc, the first partition, /dev/sdX1, must start at cylinder 0. This means that /dev/sdX1 contains the partition table and the boot block, as these are the first two sectors of the disc. Therefore you must be careful what you use /dev/sdX1 for. In particular, you must not use a partition starting at cylinder 0 for Linux swap, as that would overwrite the partition table and the boot block. You may, however, use such a partition for a UFS or EXT2 file system, as these file systems leave the first 1024 bytes undisturbed. */ /* On the other hand, one should not use partitions starting at block 0 in an md, or the label will be trashed. */ for (i = 0; i < partitions; i++) if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) break; if (i < partitions && !whole_disk) { if (n == 2 && !first) { whole_disk = 1; break; } printf(_("Sector %d is already allocated\n"), first); } else break; } stop = cylinders * heads * sectors; stop2 = stop; for (i = 0; i < partitions; i++) { if (starts[i] > first && starts[i] < stop) stop = starts[i]; } snprintf(mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"), str_units(SINGULAR)); if (whole_disk) last = read_int(scround(stop2), scround(stop2), scround(stop2), 0, mesg); else if (n == 2 && !first) last = read_int(scround(first), scround(stop2), scround(stop2), scround(first), mesg); else last = read_int(scround(first), scround(stop), scround(stop), scround(first), mesg); if (display_in_cyl_units) last *= units_per_sector; if (n == 2 && !first) { if (last >= stop2) { whole_disk = 1; last = stop2; } else if (last > stop) { printf ( _("You haven't covered the whole disk with the 3rd partition, but your value\n" "%d %s covers some other partition. Your entry has been changed\n" "to %d %s\n"), scround(last), str_units(SINGULAR), scround(stop), str_units(SINGULAR)); last = stop; } } else if (!whole_disk && last > stop) last = stop; if (whole_disk) sys = WHOLE_DISK; set_sun_partition(n, first, last, sys);}voidsun_delete_partition(int i) { unsigned int nsec; if (i == 2 && sunlabel->infos[i].id == WHOLE_DISK && !sunlabel->partitions[i].start_cylinder && (nsec = SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders) printf(_("If you want to maintain SunOS/Solaris compatibility, " "consider leaving this\n" "partition as Whole disk (5), starting at 0, with %u " "sectors\n"), nsec); sunlabel->infos[i].id = 0; sunlabel->partitions[i].num_sectors = 0;}voidsun_change_sysid(int i, int sys) { if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) { read_chars( _("It is highly recommended that the partition at offset 0\n" "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" "there may destroy your partition table and bootblock.\n" "Type YES if you're very sure you would like that partition\n" "tagged with 82 (Linux swap): ")); if (strcmp (line_ptr, _("YES\n"))) return; } switch (sys) { case SUNOS_SWAP: case LINUX_SWAP: /* swaps are not mountable by default */ sunlabel->infos[i].flags |= 0x01; break; default: /* assume other types are mountable; user can change it anyway */ sunlabel->infos[i].flags &= ~0x01; break; } sunlabel->infos[i].id = sys;}voidsun_list_table(int xtra) { int i, w; char *type; w = strlen(disk_device); if (xtra) printf( _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n" "%d cylinders, %d alternate cylinders, %d physical cylinders\n" "%d extra sects/cyl, interleave %d:1\n" "%s\n" "Units = %s of %d * 512 bytes\n\n"), disk_device, heads, sectors, SSWAP16(sunlabel->rspeed), cylinders, SSWAP16(sunlabel->nacyl), SSWAP16(sunlabel->pcylcount), SSWAP16(sunlabel->sparecyl), SSWAP16(sunlabel->ilfact), (char *)sunlabel, str_units(PLURAL), units_per_sector); else printf( _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n" "Units = %s of %d * 512 bytes\n\n"), disk_device, heads, sectors, cylinders, str_units(PLURAL), units_per_sector); printf(_("%*s Flag Start End Blocks Id System\n"), w + 1, _("Device")); for (i = 0 ; i < partitions; i++) { if (sunlabel->partitions[i].num_sectors) { __u32 start = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors; __u32 len = SSWAP32(sunlabel->partitions[i].num_sectors); printf( "%s %c%c %9ld %9ld %9ld%c %2x %s\n",/* device */ partname(disk_device, i+1, w),/* flags */ (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ', (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',/* start */ (long) scround(start),/* end */ (long) scround(start+len),/* odd flag on end */ (long) len / 2, len & 1 ? '+' : ' ',/* type id */ sunlabel->infos[i].id,/* type name */ (type = partition_type(sunlabel->infos[i].id)) ? type : _("Unknown")); } }}voidsun_set_alt_cyl(void) { sunlabel->nacyl = SSWAP16(read_int(0,SSWAP16(sunlabel->nacyl), 65535, 0, _("Number of alternate cylinders")));}voidsun_set_ncyl(int cyl) { sunlabel->ncyl = SSWAP16(cyl);}voidsun_set_xcyl(void) { sunlabel->sparecyl = SSWAP16(read_int(0, SSWAP16(sunlabel->sparecyl), sectors, 0, _("Extra sectors per cylinder")));}voidsun_set_ilfact(void) { sunlabel->ilfact = SSWAP16(read_int(1, SSWAP16(sunlabel->ilfact), 32, 0, _("Interleave factor")));}voidsun_set_rspeed(void) { sunlabel->rspeed = SSWAP16(read_int(1, SSWAP16(sunlabel->rspeed), 100000, 0, _("Rotation speed (rpm)")));}voidsun_set_pcylcount(void) { sunlabel->pcylcount = SSWAP16(read_int(0, SSWAP16(sunlabel->pcylcount), 65535, 0, _("Number of physical cylinders")));}voidsun_write_table(void) { unsigned short *ush = (unsigned short *)sunlabel; unsigned short csum = 0; while(ush < (unsigned short *)(&sunlabel->csum)) csum ^= *ush++; sunlabel->csum = csum; if (lseek(fd, 0, SEEK_SET) < 0) fatal(unable_to_seek); if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE) fatal(unable_to_write);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?