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