Exemple #1
0
void
create_sgiinfo(struct fdisk_context *cxt) {
	/* I keep SGI's habit to write the sgilabel to the second block */
	sgilabel->directory[0].vol_file_start = SSWAP32(2);
	sgilabel->directory[0].vol_file_size = SSWAP32(sizeof(sgiinfo));
	strncpy((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8);
}
void
sgi_write_table(void) {
	sgilabel->csum = 0;
	sgilabel->csum = SSWAP32(two_s_complement_32bit_sum(
		(unsigned int*)sgilabel, 
		sizeof(*sgilabel)));
	assert(two_s_complement_32bit_sum(
		(unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
	if (lseek(fd, 0, SEEK_SET) < 0)
		fatal(unable_to_seek);
	if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
		fatal(unable_to_write);
	if (! strncmp((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
		/*
		 * keep this habit of first writing the "sgilabel".
		 * I never tested whether it works without (AN 981002).
		 */
		sgiinfo *info = fill_sgiinfo();
		int infostartblock = SSWAP32(sgilabel->directory[0].vol_file_start);
		if (lseek(fd, (off_t) infostartblock*
				SECTOR_SIZE, SEEK_SET) < 0)
			fatal(unable_to_seek);
		if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE)
			fatal(unable_to_write);
		free(info);
	}
}
static void
sgi_set_partition(int i, unsigned int start, unsigned int length, int sys) {
	sgilabel->partitions[i].id = SSWAP32(sys);
	sgilabel->partitions[i].num_sectors = SSWAP32(length);
	sgilabel->partitions[i].start_sector = SSWAP32(start);
	set_changed(i);
	if (sgi_gaps() < 0)	/* rebuild freelist */
		printf(_("Partition overlap on the disk.\n"));
	if (length)
		print_partition_size(i + 1, start, start + length, sys);
}
Exemple #4
0
static int sgi_set_partition(struct fdisk_context *cxt, int i,
			     unsigned int start, unsigned int length, int sys)
{
	sgilabel->partitions[i].id = SSWAP32(sys);
	sgilabel->partitions[i].num_sectors = SSWAP32(length);
	sgilabel->partitions[i].start_sector = SSWAP32(start);
	set_changed(i);

	if (sgi_gaps(cxt) < 0)	/* rebuild freelist */
		printf(_("Partition overlap on the disk.\n"));
	if (length)
		print_partition_size(cxt, i + 1, start, start + length, sys);

	return 0;
}
sgiinfo *
fill_sgiinfo(void)
{
	sgiinfo *info=xcalloc(1, sizeof(sgiinfo));
	info->magic=SSWAP32(SGI_INFO_MAGIC);
	info->b1=SSWAP32(-1);
	info->b2=SSWAP16(-1);
	info->b3=SSWAP16(1);
	/* You may want to replace this string !!!!!!! */
	strcpy((char *) info->scsi_string, "IBM OEM 0662S12         3 30");
	strcpy((char *) info->serial, "0000");
	info->check1816 = SSWAP16(18*256 +16);
	strcpy((char *) info->installer, "Sfx version 5.3, Oct 18, 1994");
	return info;
}
Exemple #6
0
static int sgi_set_parttype(struct fdisk_context *cxt, int i,
			    struct fdisk_parttype *t)
{
	if (i >= partitions || !t || t->type > UINT32_MAX)
		return -EINVAL;

	if (sgi_get_num_sectors(cxt, i) == 0)	/* caught already before, ... */ {
		printf(_("Sorry, only for non-empty partitions you can change the tag.\n"));
		return -EINVAL;
	}

	if ((i == 10 && t->type != ENTIRE_DISK) || (i == 8 && t->type != 0))
		printf(_("Consider leaving partition 9 as volume header (0), "
			 "and partition 11 as entire volume (6), as IRIX "
			 "expects it.\n\n"));

	if (((t->type != ENTIRE_DISK) && (t->type != SGI_VOLHDR))
	    && (sgi_get_start_sector(cxt, i) < 1)) {
		read_chars(
			_("It is highly recommended that the partition at offset 0\n"
			  "is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
			  "retrieve from its directory standalone tools like sash and fx.\n"
			  "Only the \"SGI volume\" entire disk section may violate this.\n"
			  "Type YES if you are sure about tagging this partition differently.\n"));
		if (strcmp (line_ptr, _("YES\n")))
			return 1;
	}
	sgilabel->partitions[i].id = SSWAP32(t->type);
	return 0;
}
Exemple #7
0
static unsigned int
two_s_complement_32bit_sum(unsigned int *base, int size /* in bytes */) {
	int i = 0;
	unsigned int sum = 0;

	size /= sizeof(unsigned int);
	for (i = 0; i < size; i++)
		sum -= SSWAP32(base[i]);
	return sum;
}
Exemple #8
0
static int sgi_write_disklabel(struct fdisk_context *cxt)
{
	sgiinfo *info = NULL;

	sgilabel->csum = 0;
	sgilabel->csum = SSWAP32(two_s_complement_32bit_sum(
		(unsigned int*)sgilabel,
		sizeof(*sgilabel)));
	assert(two_s_complement_32bit_sum(
		(unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
	if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
		goto err;
	if (write(cxt->dev_fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
		goto err;
	if (!strncmp((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
		/*
		 * keep this habit of first writing the "sgilabel".
		 * I never tested whether it works without (AN 981002).
		 */
		int infostartblock
			= SSWAP32(sgilabel->directory[0].vol_file_start);

		if (lseek(cxt->dev_fd, (off_t) infostartblock *
						SECTOR_SIZE, SEEK_SET) < 0)
			goto err;

		info = fill_sgiinfo();
		if (!info)
			goto err;

		if (write(cxt->dev_fd, info, SECTOR_SIZE) != SECTOR_SIZE)
			goto err;
	}

	free(info);
	return 0;
err:
	free(info);
	return -errno;
}
int
sgi_change_sysid(int i, int sys)
{
	if (sgi_get_num_sectors(i) == 0) /* caught already before, ... */ {
		printf(_("Sorry, only for non-empty partitions you can change the tag.\n"));
		return 0;
	}
	if (((sys != ENTIRE_DISK) && (sys != SGI_VOLHDR))
	    && (sgi_get_start_sector(i)<1)) {
		read_chars(
			_("It is highly recommended that the partition at offset 0\n"
			  "is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
			  "retrieve from its directory standalone tools like sash and fx.\n"
			  "Only the \"SGI volume\" entire disk section may violate this.\n"
			  "Type YES if you are sure about tagging this partition differently.\n"));
		if (strcmp (line_ptr, _("YES\n")))
			return 0;
	}
	sgilabel->partitions[i].id = SSWAP32(sys);
	return 1;
}
Exemple #10
0
static int
sgi_get_sysid(struct fdisk_context *cxt, int i)
{
	return SSWAP32(sgilabel->partitions[i].id);
}
Exemple #11
0
unsigned int
sgi_get_num_sectors(struct fdisk_context *cxt, int i) {
	return SSWAP32(sgilabel->partitions[i].num_sectors);
}
Exemple #12
0
unsigned int
sgi_get_start_sector(struct fdisk_context *cxt, int i) {
	return SSWAP32(sgilabel->partitions[i].start_sector);
}
Exemple #13
0
unsigned int
sgi_get_num_sectors(int i) {
	return SSWAP32(sgilabel->partitions[i].num_sectors);
}
Exemple #14
0
void
create_sgilabel(void)
{
	struct hd_geometry geometry;
	struct {
		unsigned int start;
		unsigned int nsect;
		int sysid;
	} old[4];
	int i=0;
	unsigned long long llsectors;
	int res; 		/* the result from the ioctl */
	int sec_fac; 		/* the sector factor */

	sec_fac = sector_size / 512;	/* determine the sector factor */

	fprintf(stderr,
		_("Building a new SGI disklabel.\n"));

	other_endian = (BYTE_ORDER == LITTLE_ENDIAN);

	res = blkdev_get_sectors(fd, &llsectors);

#ifdef HDIO_GETGEO
	if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
		heads = geometry.heads;
		sectors = geometry.sectors;
		if (res == 0) {
			/* the get device size ioctl was successful */
			unsigned long long llcyls;
			llcyls = llsectors / (heads * sectors * sec_fac);
			cylinders = llcyls;
			if (cylinders != llcyls)	/* truncated? */
				cylinders = ~0;
		} else {
			/* otherwise print error and use truncated version */
			cylinders = geometry.cylinders;
			fprintf(stderr,
				_("Warning:  BLKGETSIZE ioctl failed on %s.  "
				  "Using geometry cylinder value of %d.\n"
				  "This value may be truncated for devices"
				  " > 33.8 GB.\n"), disk_device, cylinders);
		}
	}
#endif
	for (i = 0; i < 4; i++) {
		old[i].sysid = 0;
		if (valid_part_table_flag(MBRbuffer)) {
			if (get_part_table(i)->sys_ind) {
				old[i].sysid = get_part_table(i)->sys_ind;
				old[i].start = get_start_sect(get_part_table(i));
				old[i].nsect = get_nr_sects(get_part_table(i));
				if (debug)
					printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
					       old[i].sysid, old[i].start, old[i].nsect);
			}
		}
	}

	for (i = 0; i < 4; i++)
		if (old[i].sysid) {
			printf(_("Trying to keep parameters of partitions already set.\n"));
			break;
		}

	zeroize_mbr_buffer();
	sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC);
	sgilabel->boot_part = SSWAP16(0);
	sgilabel->swap_part = SSWAP16(1);

	/* sizeof(sgilabel->boot_file) = 16 > 6 */
	memset(sgilabel->boot_file, 0, 16);
	strcpy((char *) sgilabel->boot_file, "/unix");

	sgilabel->devparam.skew			= (0);
	sgilabel->devparam.gap1			= (0);
	sgilabel->devparam.gap2			= (0);
	sgilabel->devparam.sparecyl			= (0);
	sgilabel->devparam.pcylcount		= SSWAP16(geometry.cylinders);
	sgilabel->devparam.head_vol0		= SSWAP16(0);
	sgilabel->devparam.ntrks			= SSWAP16(geometry.heads);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.cmd_tag_queue_depth	= (0);
	sgilabel->devparam.unused0			= (0);
	sgilabel->devparam.unused1			= SSWAP16(0);
	sgilabel->devparam.nsect			= SSWAP16(geometry.sectors);
	/* sectors/track */
	sgilabel->devparam.bytes			= SSWAP16(sector_size);
	sgilabel->devparam.ilfact			= SSWAP16(1);
	sgilabel->devparam.flags			= SSWAP32(TRACK_FWD|\
								  IGNORE_ERRORS|RESEEK);
	sgilabel->devparam.datarate			= SSWAP32(0);
	sgilabel->devparam.retries_on_error		= SSWAP32(1);
	sgilabel->devparam.ms_per_word		= SSWAP32(0);
	sgilabel->devparam.xylogics_gap1		= SSWAP16(0);
	sgilabel->devparam.xylogics_syncdelay	= SSWAP16(0);
	sgilabel->devparam.xylogics_readdelay	= SSWAP16(0);
	sgilabel->devparam.xylogics_gap2		= SSWAP16(0);
	sgilabel->devparam.xylogics_readgate	= SSWAP16(0);
	sgilabel->devparam.xylogics_writecont	= SSWAP16(0);
	memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15);
	memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16);
	disklabel  = SGI_LABEL;
	partitions = 16;
	volumes    = 15;
	sgi_set_entire();
	sgi_set_volhdr();
	for (i = 0; i < 4; i++) {
		if (old[i].sysid) {
			sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid);
		}
	}
}
Exemple #15
0
int
sgi_get_sysid(int i)
{
	return SSWAP32(sgilabel->partitions[i].id);
}
Exemple #16
0
static int sgi_create_disklabel(struct fdisk_context *cxt)
{
	struct hd_geometry geometry;
	struct {
		unsigned int start;
		unsigned int nsect;
		int sysid;
	} old[4];
	int i=0;
	sector_t llsectors;
	int res; 		/* the result from the ioctl */
	int sec_fac; 		/* the sector factor */

	sec_fac = cxt->sector_size / 512;	/* determine the sector factor */

	fprintf(stderr,
		_("Building a new SGI disklabel.\n"));

	other_endian = (BYTE_ORDER == LITTLE_ENDIAN);

	res = blkdev_get_sectors(cxt->dev_fd, &llsectors);

#ifdef HDIO_GETGEO
	if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0)
		err(EXIT_FAILURE, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path);

	cxt->geom.heads = geometry.heads;
	cxt->geom.sectors = geometry.sectors;
	if (res == 0) {
		/* the get device size ioctl was successful */
	        sector_t llcyls;
		llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
		cxt->geom.cylinders = llcyls;
		if (cxt->geom.cylinders != llcyls)	/* truncated? */
			cxt->geom.cylinders = ~0;
	} else {
		/* otherwise print error and use truncated version */
		cxt->geom.cylinders = geometry.cylinders;
		fprintf(stderr,
			_("Warning:  BLKGETSIZE ioctl failed on %s.  "
			  "Using geometry cylinder value of %llu.\n"
			  "This value may be truncated for devices"
			  " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders);
	}
#endif
	/*
	 * Convert old MBR to SGI label, make it DEPRECATED, this feature
	 * has to be handled in by any top-level fdisk command.
	 */
	for (i = 0; i < 4; i++) {
		old[i].sysid = 0;
		if (mbr_is_valid_magic(cxt->firstsector)) {
			if (get_part_table(i)->sys_ind) {
				old[i].sysid = get_part_table(i)->sys_ind;
				old[i].start = get_start_sect(get_part_table(i));
				old[i].nsect = get_nr_sects(get_part_table(i));
				if (debug)
					printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
					       old[i].sysid, old[i].start, old[i].nsect);
			}
		}
	}

	for (i = 0; i < 4; i++)
		if (old[i].sysid) {
			printf(_("Trying to keep parameters of partitions already set.\n"));
			break;
		}

	fdisk_zeroize_firstsector(cxt);
	sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC);
	sgilabel->boot_part = SSWAP16(0);
	sgilabel->swap_part = SSWAP16(1);

	/* sizeof(sgilabel->boot_file) = 16 > 6 */
	memset(sgilabel->boot_file, 0, 16);
	strcpy((char *) sgilabel->boot_file, "/unix");

	sgilabel->devparam.skew			= (0);
	sgilabel->devparam.gap1			= (0);
	sgilabel->devparam.gap2			= (0);
	sgilabel->devparam.sparecyl			= (0);
	sgilabel->devparam.pcylcount		= SSWAP16(geometry.cylinders);
	sgilabel->devparam.head_vol0		= SSWAP16(0);
	sgilabel->devparam.ntrks			= SSWAP16(geometry.heads);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.cmd_tag_queue_depth	= (0);
	sgilabel->devparam.unused0			= (0);
	sgilabel->devparam.unused1			= SSWAP16(0);
	sgilabel->devparam.nsect			= SSWAP16(geometry.sectors);
	/* sectors/track */
	sgilabel->devparam.bytes			= SSWAP16(cxt->sector_size);
	sgilabel->devparam.ilfact			= SSWAP16(1);
	sgilabel->devparam.flags			= SSWAP32(TRACK_FWD|\
								  IGNORE_ERRORS|RESEEK);
	sgilabel->devparam.datarate			= SSWAP32(0);
	sgilabel->devparam.retries_on_error		= SSWAP32(1);
	sgilabel->devparam.ms_per_word		= SSWAP32(0);
	sgilabel->devparam.xylogics_gap1		= SSWAP16(0);
	sgilabel->devparam.xylogics_syncdelay	= SSWAP16(0);
	sgilabel->devparam.xylogics_readdelay	= SSWAP16(0);
	sgilabel->devparam.xylogics_gap2		= SSWAP16(0);
	sgilabel->devparam.xylogics_readgate	= SSWAP16(0);
	sgilabel->devparam.xylogics_writecont	= SSWAP16(0);
	memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15);
	memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16);
	cxt->disklabel  = FDISK_DISKLABEL_SGI;
	partitions = 16;
	volumes    = 15;
	sgi_set_entire(cxt);
	sgi_set_volhdr(cxt);
	for (i = 0; i < 4; i++) {
		if (old[i].sysid) {
			sgi_set_partition(cxt, i, old[i].start, old[i].nsect, old[i].sysid);
		}
	}
	return 0;
}
Exemple #17
0
void
sgi_list_table(struct fdisk_context *cxt, int xtra) {
	int i, w;
	int kpi = 0;		/* kernel partition ID */

	w = strlen(cxt->dev_path);

	if (xtra) {
		printf(_("\nDisk %s (SGI disk label): %d heads, %llu sectors\n"
			 "%llu cylinders, %d physical cylinders\n"
			 "%d extra sects/cyl, interleave %d:1\n"
			 "%s\n"
			 "Units = %s of %d * %ld bytes\n\n"),
		       cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
		       SSWAP16(sgiparam.pcylcount),
		       (int) sgiparam.sparecyl, SSWAP16(sgiparam.ilfact),
		       (char *)sgilabel,
		       str_units(PLURAL), units_per_sector,
                       cxt->sector_size);
	} else {
		printf(_("\nDisk %s (SGI disk label): "
			 "%d heads, %llu sectors, %llu cylinders\n"
			 "Units = %s of %d * %ld bytes\n\n"),
		       cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
		       str_units(PLURAL), units_per_sector,
                       cxt->sector_size);
	}
	printf(_("----- partitions -----\n"
		 "Pt# %*s  Info     Start       End   Sectors  Id  System\n"),
	       w + 1, _("Device"));
	for (i = 0 ; i < partitions; i++) {
		if (sgi_get_num_sectors(cxt, i) || debug) {
			uint32_t start = sgi_get_start_sector(cxt, i);
			uint32_t len = sgi_get_num_sectors(cxt, i);
			struct fdisk_parttype *t = fdisk_get_partition_type(cxt, i);

			kpi++;		/* only count nonempty partitions */
			printf(
				"%2d: %s %4s %9ld %9ld %9ld  %2x  %s\n",
/* fdisk part number */   i+1,
/* device */              partname(cxt->dev_path, kpi, w+2),
/* flags */               (sgi_get_swappartition(cxt) == i) ? "swap" :
/* flags */               (sgi_get_bootpartition(cxt) == i) ? "boot" : "    ",
/* start */               (long) scround(start),
/* end */                 (long) scround(start+len)-1,
/* no odd flag on end */  (long) len,
/* type id */             t->type,
/* type name */           t->name);

			fdisk_free_parttype(t);
		}
	}
	printf(_("----- Bootinfo -----\nBootfile: %s\n"
		 "----- Directory Entries -----\n"),
	       sgilabel->boot_file);
	for (i = 0 ; i < volumes; i++) {
		if (sgilabel->directory[i].vol_file_size) {
			uint32_t start = SSWAP32(sgilabel->directory[i].vol_file_start);
			uint32_t len = SSWAP32(sgilabel->directory[i].vol_file_size);
			unsigned char *name = sgilabel->directory[i].vol_file_name;
			printf(_("%2d: %-10s sector%5u size%8u\n"),
			       i, name, (unsigned int) start,
			       (unsigned int) len);
		}
	}
}
Exemple #18
0
unsigned int
sgi_get_start_sector(int i) {
	return SSWAP32(sgilabel->partitions[i].start_sector);
}