static void
sgi_add_partition(int n, int sys)
{
	char mesg[256];
	unsigned int first = 0, last = 0;

	if (n == 10) {
		sys = SGI_VOLUME;
	} else if (n == 8) {
		sys = 0;
	}
	if (sgi_get_num_sectors(n)) {
		printf(msg_part_already_defined, n + 1);
		return;
	}
	if ((sgi_entire() == -1) && (sys != SGI_VOLUME)) {
		printf("Attempting to generate entire disk entry automatically\n");
		sgi_set_entire();
		sgi_set_volhdr();
	}
	if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) {
		printf("The entire disk is already covered with partitions\n");
		return;
	}
	if (sgi_gaps() < 0) {
		printf("You got a partition overlap on the disk. Fix it first!\n");
		return;
	}
	snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR));
	while (1) {
		if (sys == SGI_VOLUME) {
			last = sgi_get_lastblock();
			first = read_int(0, 0, last-1, 0, mesg);
			if (first != 0) {
				printf("It is highly recommended that eleventh partition\n"
						"covers the entire disk and is of type 'SGI volume'\n");
			}
		} else {
			first = freelist[0].first;
			last  = freelist[0].last;
			first = read_int(scround(first), scround(first), scround(last)-1,
				0, mesg);
		}
		if (display_in_cyl_units)
			first *= units_per_sector;
		else
			first = first; /* align to cylinder if you know how ... */
		if (!last )
			last = isinfreelist(first);
		if (last != 0)
			break;
		printf("You will get a partition overlap on the disk. "
				"Fix it first!\n");
	}
	snprintf(mesg, sizeof(mesg), " Last %s", str_units(SINGULAR));
	last = read_int(scround(first), scround(last)-1, scround(last)-1,
			scround(first), mesg)+1;
	if (display_in_cyl_units)
		last *= units_per_sector;
	else
		last = last; /* align to cylinder if You know how ... */
	if ( (sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock() ) )
		printf("It is highly recommended that eleventh partition\n"
			"covers the entire disk and is of type 'SGI volume'\n");
	sgi_set_partition(n, first, last-first, sys);
}
static void
create_sgilabel(void)
{
	struct hd_geometry geometry;
	struct {
		unsigned int start;
		unsigned int nsect;
		int sysid;
	} old[4];
	int i = 0;
	long longsectors;               /* the number of sectors on the device */
	int res;                        /* the result from the ioctl */
	int sec_fac;                    /* the sector factor */

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

	printf(msg_building_new_label, "SGI disklabel");

	sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN);
	res = ioctl(fd, BLKGETSIZE, &longsectors);
	if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
		heads = geometry.heads;
		sectors = geometry.sectors;
		if (res == 0) {
			/* the get device size ioctl was successful */
			cylinders = longsectors / (heads * sectors);
			cylinders /= sec_fac;
		} else {
			/* otherwise print error and use truncated version */
			cylinders = geometry.cylinders;
			printf(
"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);
		}
	}
	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));
				printf("Trying to keep parameters of partition %d\n", i);
				if (debug)
					printf("ID=%02x\tSTART=%d\tLENGTH=%d\n",
				old[i].sysid, old[i].start, old[i].nsect);
			}
		}
	}

	memset(MBRbuffer, 0, sizeof(MBRbuffer));
	/* fields with '//' are already zeroed out by memset above */

	sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC);
	//sgilabel->boot_part = SGI_SSWAP16(0);
	sgilabel->swap_part = SGI_SSWAP16(1);

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

	//sgilabel->devparam.skew                     = (0);
	//sgilabel->devparam.gap1                     = (0);
	//sgilabel->devparam.gap2                     = (0);
	//sgilabel->devparam.sparecyl                 = (0);
	sgilabel->devparam.pcylcount                = SGI_SSWAP16(geometry.cylinders);
	//sgilabel->devparam.head_vol0                = SGI_SSWAP16(0);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.ntrks                    = SGI_SSWAP16(geometry.heads);
	//sgilabel->devparam.cmd_tag_queue_depth      = (0);
	//sgilabel->devparam.unused0                  = (0);
	//sgilabel->devparam.unused1                  = SGI_SSWAP16(0);
	/* sectors/track */
	sgilabel->devparam.nsect                    = SGI_SSWAP16(geometry.sectors);
	sgilabel->devparam.bytes                    = SGI_SSWAP16(512);
	sgilabel->devparam.ilfact                   = SGI_SSWAP16(1);
	sgilabel->devparam.flags                    = SGI_SSWAP32(TRACK_FWD|
							IGNORE_ERRORS|RESEEK);
	//sgilabel->devparam.datarate                 = SGI_SSWAP32(0);
	sgilabel->devparam.retries_on_error         = SGI_SSWAP32(1);
	//sgilabel->devparam.ms_per_word              = SGI_SSWAP32(0);
	//sgilabel->devparam.xylogics_gap1            = SGI_SSWAP16(0);
	//sgilabel->devparam.xylogics_syncdelay       = SGI_SSWAP16(0);
	//sgilabel->devparam.xylogics_readdelay       = SGI_SSWAP16(0);
	//sgilabel->devparam.xylogics_gap2            = SGI_SSWAP16(0);
	//sgilabel->devparam.xylogics_readgate        = SGI_SSWAP16(0);
	//sgilabel->devparam.xylogics_writecont       = SGI_SSWAP16(0);
	//memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 );
	//memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partinfo)*16 );
	current_label_type = label_sgi;
	partitions = 16;
	sgi_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);
		}
	}
}
Example #3
0
static int sgi_add_partition(struct fdisk_context *cxt,
		size_t n,
		struct fdisk_parttype *t)
{
	struct fdisk_sgi_label *sgi;
	char mesg[256];
	unsigned int first = 0, last = 0;
	struct fdisk_ask *ask;
	int sys = t ? t->type : SGI_TYPE_XFS;
	int rc;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_disklabel(cxt, SGI));

	if (n == 10)
		sys = SGI_TYPE_ENTIRE_DISK;
	else if (n == 8)
		sys = 0;

	sgi = self_label(cxt);

	if (sgi_get_num_sectors(cxt, n)) {
		fdisk_warnx(cxt, _("Partition %zd is already defined.  Delete "
			 "it before re-adding it."), n + 1);
		return -EINVAL;
	}
	if (sgi_entire(cxt) == -1 &&  sys != SGI_TYPE_ENTIRE_DISK) {
		fdisk_info(cxt, _("Attempting to generate entire disk entry automatically."));
		sgi_set_entire(cxt);
		sgi_set_volhdr(cxt);
	}
	if (sgi_gaps(cxt) == 0 && sys != SGI_TYPE_ENTIRE_DISK) {
		fdisk_warnx(cxt, _("The entire disk is already covered with partitions."));
		return -EINVAL;
	}
	if (sgi_gaps(cxt) < 0) {
		fdisk_warnx(cxt, _("You got a partition overlap on the disk. Fix it first!"));
		return -EINVAL;
	}

	snprintf(mesg, sizeof(mesg), _("First %s"),
			fdisk_context_get_unit(cxt, SINGULAR));
	for (;;) {
		ask = fdisk_new_ask();
		if (!ask)
			return -ENOMEM;

		fdisk_ask_set_query(ask, mesg);
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);

		if (sys == SGI_TYPE_ENTIRE_DISK) {
			last = sgi_get_lastblock(cxt);
			fdisk_ask_number_set_low(ask,     0);	/* minimal */
			fdisk_ask_number_set_default(ask, 0);	/* default */
			fdisk_ask_number_set_high(ask, last - 1); /* maximal */
		} else {
			first = sgi->freelist[0].first;
			last  = sgi->freelist[0].last;
			fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
			fdisk_ask_number_set_default(ask, fdisk_scround(cxt, first));	/* default */
			fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, last) - 1); /* maximal */
		}
		rc = fdisk_do_ask(cxt, ask);
		first = fdisk_ask_number_get_result(ask);
		fdisk_free_ask(ask);

		if (rc)
			return rc;

		if (first && sys == SGI_TYPE_ENTIRE_DISK)
			fdisk_info(cxt, _("It is highly recommended that "
					"eleventh partition covers the entire "
					"disk and is of type `SGI volume'"));

		if (fdisk_context_use_cylinders(cxt))
			first *= fdisk_context_get_units_per_sector(cxt);
		/*else
			first = first; * align to cylinder if you know how ... */
		if (!last)
			last = is_in_freelist(cxt, first);
		if (last == 0)
			fdisk_warnx(cxt, _("You will get a partition overlap "
				"on the disk. Fix it first!"));
		else
			break;
	}

	snprintf(mesg, sizeof(mesg),
		 _("Last %s or +%s or +size{K,M,G,T,P}"),
		 fdisk_context_get_unit(cxt, SINGULAR),
		 fdisk_context_get_unit(cxt, PLURAL));

	ask = fdisk_new_ask();
	if (!ask)
		return -ENOMEM;

	fdisk_ask_set_query(ask, mesg);
	fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET);

	fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
	fdisk_ask_number_set_default(ask, fdisk_scround(cxt, last) - 1);/* default */
	fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, last) - 1);/* maximal */
	fdisk_ask_number_set_base(ask,    fdisk_scround(cxt, first));

	if (fdisk_context_use_cylinders(cxt))
		fdisk_ask_number_set_unit(ask,
			     cxt->sector_size *
			     fdisk_context_get_units_per_sector(cxt));
	else
		fdisk_ask_number_set_unit(ask,cxt->sector_size);

	rc = fdisk_do_ask(cxt, ask);
	last = fdisk_ask_number_get_result(ask) + 1;

	fdisk_free_ask(ask);
	if (rc)
		return rc;

	if (fdisk_context_use_cylinders(cxt))
		last *= fdisk_context_get_units_per_sector(cxt);

	if (sys == SGI_TYPE_ENTIRE_DISK
	    && (first != 0 || last != sgi_get_lastblock(cxt)))
		fdisk_info(cxt, _("It is highly recommended that eleventh "
			"partition covers the entire disk and is of type "
			"`SGI volume'"));

	sgi_set_partition(cxt, n, first, last - first, sys);
	cxt->label->nparts_cur = count_used_partitions(cxt);

	return 0;
}
Example #4
0
static int sgi_create_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_sgi_label *sgi;
	struct sgi_disklabel *sgilabel;
	struct hd_geometry geometry;
	sector_t llsectors;
	int res; 		/* the result from the ioctl */
	int sec_fac; 		/* the sector factor */

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_disklabel(cxt, SGI));

	sec_fac = cxt->sector_size / 512;	/* determine the sector factor */
	res = blkdev_get_sectors(cxt->dev_fd, &llsectors);

#ifdef HDIO_GETGEO
	/* TODO: it seems unnecessary, geometry is already set in the context */
	if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0) {
		fdisk_warn(cxt, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path);
		return -1;
	}
	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;
		fdisk_warnx(cxt,
			_("Warning:  BLKGETSIZE ioctl failed on %s.  "
			  "Using geometry cylinder value of %llu."
			  "This value may be truncated for devices"
			  " > 33.8 GB."), cxt->dev_path, cxt->geom.cylinders);
	}
#endif
	fdisk_zeroize_firstsector(cxt);
	sgi = (struct fdisk_sgi_label *) cxt->label;
	sgi->header = (struct sgi_disklabel *) cxt->firstsector;

	sgilabel = sgi->header;

	sgilabel->magic = cpu_to_be32(SGI_LABEL_MAGIC);
	sgilabel->root_part_num = cpu_to_be16(0);
	sgilabel->swap_part_num = cpu_to_be16(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	= cpu_to_be16(geometry.cylinders);
	sgilabel->devparam.head_vol0	= cpu_to_be16(0);
	sgilabel->devparam.ntrks	= cpu_to_be16(geometry.heads);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.cmd_tag_queue_depth	= (0);
	sgilabel->devparam.unused0			= (0);
	sgilabel->devparam.unused1	= cpu_to_be16(0);
	sgilabel->devparam.nsect	= cpu_to_be16(geometry.sectors);
	/* sectors/track */
	sgilabel->devparam.bytes	= cpu_to_be16(cxt->sector_size);
	sgilabel->devparam.ilfact	= cpu_to_be16(1);
	sgilabel->devparam.flags	= cpu_to_be32(
			SGI_DEVPARAM_TRACK_FWD
			| SGI_DEVPARAM_IGNORE_ERRORS
			| SGI_DEVPARAM_RESEEK);
	sgilabel->devparam.datarate	= cpu_to_be32(0);
	sgilabel->devparam.retries_on_error	= cpu_to_be32(1);
	sgilabel->devparam.ms_per_word		= cpu_to_be32(0);
	sgilabel->devparam.xylogics_gap1	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_syncdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_gap2	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readgate	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_writecont	= cpu_to_be16(0);

	memset(&(sgilabel->volume), 0,
			sizeof(struct sgi_volume) * SGI_MAXVOLUMES);
	memset(&(sgilabel->partitions), 0,
			sizeof(struct sgi_partition) * SGI_MAXPARTITIONS);
	cxt->label->nparts_max = SGI_MAXPARTITIONS;
	sgi_set_entire(cxt);
	sgi_set_volhdr(cxt);

	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
			_("Created a new SGI disklabel."));
	return 0;
}
Example #5
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;
}
Example #6
0
static int sgi_add_partition(struct fdisk_context *cxt, int n,
			     struct fdisk_parttype *t)
{
	char mesg[256];
	unsigned int first=0, last=0;
	int sys = t ? t->type : SGI_XFS;

	if (n == 10)
		sys = SGI_VOLUME;
	else if (n == 8)
		sys = 0;

	if (sgi_get_num_sectors(cxt, n)) {
		printf(_("Partition %d is already defined.  Delete "
			 "it before re-adding it.\n"), n + 1);
		return -EINVAL;
	}
	if ((sgi_entire(cxt) == -1)
	    &&  (sys != SGI_VOLUME)) {
		printf(_("Attempting to generate entire disk entry automatically.\n"));
		sgi_set_entire(cxt);
		sgi_set_volhdr(cxt);
	}
	if ((sgi_gaps(cxt) == 0) &&  (sys != SGI_VOLUME)) {
		printf(_("The entire disk is already covered with partitions.\n"));
		return -EINVAL;
	}
	if (sgi_gaps(cxt) < 0) {
		printf(_("You got a partition overlap on the disk. Fix it first!\n"));
		return -EINVAL;
	}
	snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
	for (;;) {
		if (sys == SGI_VOLUME) {
			last = sgi_get_lastblock(cxt);
			first = read_int(cxt, 0, 0, last-1, 0, mesg);
			if (first != 0) {
				printf(_("It is highly recommended that eleventh partition\n"
					 "covers the entire disk and is of type `SGI volume'\n"));
			}
		} else {
			first = freelist[0].first;
			last  = freelist[0].last;
			first = read_int(cxt, scround(first), scround(first), scround(last)-1,
					 0, mesg);
		}
		if (display_in_cyl_units)
			first *= units_per_sector;
		/*else
			first = first; * align to cylinder if you know how ... */
		if (!last)
			last = isinfreelist(first);
		if (last == 0) {
			printf(_("You will get a partition overlap on the disk. "
				 "Fix it first!\n"));
		} else
			break;
	}
	snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR));
	last = read_int(cxt, scround(first), scround(last)-1, scround(last)-1,
			scround(first), mesg)+1;
	if (display_in_cyl_units)
		last *= units_per_sector;
	/*else
		last = last; * align to cylinder if You know how ... */
	if ((sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock(cxt)))
		printf(_("It is highly recommended that eleventh partition\n"
			 "covers the entire disk and is of type `SGI volume'\n"));
	sgi_set_partition(cxt, n, first, last-first, sys);

	return 0;
}
Example #7
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);
		}
	}
}
Example #8
0
static int sgi_create_disklabel(struct fdisk_context *cxt)
{
	struct fdisk_sgi_label *sgi;
	struct sgi_disklabel *sgilabel;
	int rc;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, SGI));

#ifdef HDIO_GETGEO
	if (cxt->geom.heads && cxt->geom.sectors) {
		fdisk_sector_t llsectors;

		if (blkdev_get_sectors(cxt->dev_fd, (unsigned long long *) &llsectors) == 0) {
			/* the get device size ioctl was successful */
			fdisk_sector_t llcyls;
			int sec_fac = cxt->sector_size / 512;

			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 */
			fdisk_warnx(cxt,
				_("BLKGETSIZE ioctl failed on %s. "
				  "Using geometry cylinder value of %llu. "
				  "This value may be truncated for devices "
				  "> 33.8 GB."), cxt->dev_path, cxt->geom.cylinders);
		}
	}
#endif
	rc = fdisk_init_firstsector_buffer(cxt, 0, 0);
	if (rc)
		return rc;

	sgi = (struct fdisk_sgi_label *) cxt->label;
	sgi->header = (struct sgi_disklabel *) cxt->firstsector;

	sgilabel = sgi->header;

	sgilabel->magic = cpu_to_be32(SGI_LABEL_MAGIC);
	sgilabel->root_part_num = cpu_to_be16(0);
	sgilabel->swap_part_num = cpu_to_be16(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	= cpu_to_be16(cxt->geom.cylinders);
	sgilabel->devparam.head_vol0	= cpu_to_be16(0);
	sgilabel->devparam.ntrks	= cpu_to_be16(cxt->geom.heads);
	/* tracks/cylinder (heads) */
	sgilabel->devparam.cmd_tag_queue_depth	= (0);
	sgilabel->devparam.unused0			= (0);
	sgilabel->devparam.unused1	= cpu_to_be16(0);
	sgilabel->devparam.nsect	= cpu_to_be16(cxt->geom.sectors);
	/* sectors/track */
	sgilabel->devparam.bytes	= cpu_to_be16(cxt->sector_size);
	sgilabel->devparam.ilfact	= cpu_to_be16(1);
	sgilabel->devparam.flags	= cpu_to_be32(
			SGI_DEVPARAM_TRACK_FWD
			| SGI_DEVPARAM_IGNORE_ERRORS
			| SGI_DEVPARAM_RESEEK);
	sgilabel->devparam.datarate	= cpu_to_be32(0);
	sgilabel->devparam.retries_on_error	= cpu_to_be32(1);
	sgilabel->devparam.ms_per_word		= cpu_to_be32(0);
	sgilabel->devparam.xylogics_gap1	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_syncdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readdelay	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_gap2	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_readgate	= cpu_to_be16(0);
	sgilabel->devparam.xylogics_writecont	= cpu_to_be16(0);

	memset(&(sgilabel->volume), 0,
			sizeof(struct sgi_volume) * SGI_MAXVOLUMES);
	memset(&(sgilabel->partitions), 0,
			sizeof(struct sgi_partition) * SGI_MAXPARTITIONS);
	cxt->label->nparts_max = SGI_MAXPARTITIONS;

	/* don't create default layout when a script defined */
	if (!cxt->script) {
		sgi_set_entire(cxt);
		sgi_set_volhdr(cxt);
	}
	cxt->label->nparts_cur = count_used_partitions(cxt);

	fdisk_info(cxt, _("Created a new SGI disklabel."));
	return 0;
}
Example #9
0
static int sgi_add_partition(struct fdisk_context *cxt,
			     struct fdisk_partition *pa,
			     size_t *partno)
{
	struct fdisk_sgi_label *sgi;
	char mesg[256];
	unsigned int first = 0, last = 0;
	struct fdisk_ask *ask;
	int sys = pa && pa->type ? pa->type->code : SGI_TYPE_XFS;
	int rc;
	size_t n;

	assert(cxt);
	assert(cxt->label);
	assert(fdisk_is_label(cxt, SGI));

	rc = fdisk_partition_next_partno(pa, cxt, &n);
	if (rc)
		return rc;
	if (n == 10)
		sys = SGI_TYPE_ENTIRE_DISK;
	else if (n == 8)
		sys = 0;

	sgi = self_label(cxt);

	if (sgi_get_num_sectors(cxt, n)) {
		fdisk_warnx(cxt, _("Partition %zu is already defined.  "
				   "Delete it before re-adding it."), n + 1);
		return -EINVAL;
	}
	if (!cxt->script && sgi_entire(cxt) == -1 &&  sys != SGI_TYPE_ENTIRE_DISK) {
		fdisk_info(cxt, _("Attempting to generate entire disk entry automatically."));
		sgi_set_entire(cxt);
		sgi_set_volhdr(cxt);
	}
	if (sgi_gaps(cxt) == 0 && sys != SGI_TYPE_ENTIRE_DISK) {
		fdisk_warnx(cxt, _("The entire disk is already covered with partitions."));
		return -EINVAL;
	}
	if (sgi_gaps(cxt) < 0) {
		fdisk_warnx(cxt, _("You got a partition overlap on the disk. Fix it first!"));
		return -EINVAL;
	}

	if (sys == SGI_TYPE_ENTIRE_DISK) {
		first = 0;
		last = sgi_get_lastblock(cxt);
	} else {
		first = sgi->freelist[0].first;
		last  = sgi->freelist[0].last;
	}

	/* first sector */
	if (pa && pa->start_follow_default)
		;
	else if (pa && fdisk_partition_has_start(pa)) {
		first = pa->start;
		last = is_in_freelist(cxt, first);

		if (sys != SGI_TYPE_ENTIRE_DISK && !last)
			return -ERANGE;
	} else {
		snprintf(mesg, sizeof(mesg), _("First %s"),
				fdisk_get_unit(cxt, FDISK_SINGULAR));
		ask = fdisk_new_ask();
		if (!ask)
			return -ENOMEM;

		fdisk_ask_set_query(ask, mesg);
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);

		fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
		fdisk_ask_number_set_default(ask, fdisk_scround(cxt, first));	/* default */
		fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, last) - 1); /* maximal */

		rc = fdisk_do_ask(cxt, ask);
		first = fdisk_ask_number_get_result(ask);
		fdisk_unref_ask(ask);

		if (rc)
			return rc;
		if (fdisk_use_cylinders(cxt))
			first *= fdisk_get_units_per_sector(cxt);
	}

	if (first && sys == SGI_TYPE_ENTIRE_DISK)
		fdisk_info(cxt, _("It is highly recommended that the "
				  "eleventh partition covers the entire "
				  "disk and is of type 'SGI volume'."));
	if (!last)
		last = is_in_freelist(cxt, first);

	/* last sector */
	if (pa && pa->end_follow_default)
		last -= 1ULL;
	else if (pa && fdisk_partition_has_size(pa)) {
		if (first + pa->size - 1ULL > last)
			return -ERANGE;
		last = first + pa->size - 1ULL;
	} else {
		snprintf(mesg, sizeof(mesg),
			 _("Last %s or +%s or +size{K,M,G,T,P}"),
			 fdisk_get_unit(cxt, FDISK_SINGULAR),
			 fdisk_get_unit(cxt, FDISK_PLURAL));

		ask = fdisk_new_ask();
		if (!ask)
			return -ENOMEM;

		fdisk_ask_set_query(ask, mesg);
		fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET);

		fdisk_ask_number_set_low(ask,     fdisk_scround(cxt, first));	/* minimal */
		fdisk_ask_number_set_default(ask, fdisk_scround(cxt, last) - 1);/* default */
		fdisk_ask_number_set_high(ask,    fdisk_scround(cxt, last) - 1);/* maximal */
		fdisk_ask_number_set_base(ask,    fdisk_scround(cxt, first));

		if (fdisk_use_cylinders(cxt))
			fdisk_ask_number_set_unit(ask,
				     cxt->sector_size *
				     fdisk_get_units_per_sector(cxt));
		else
			fdisk_ask_number_set_unit(ask,cxt->sector_size);

		rc = fdisk_do_ask(cxt, ask);
		last = fdisk_ask_number_get_result(ask) + 1;

		fdisk_unref_ask(ask);
		if (rc)
			return rc;
		if (fdisk_use_cylinders(cxt))
			last *= fdisk_get_units_per_sector(cxt);
	}

	if (sys == SGI_TYPE_ENTIRE_DISK
	    && (first != 0 || last != sgi_get_lastblock(cxt)))
		fdisk_info(cxt, _("It is highly recommended that the "
				  "eleventh partition covers the entire "
				  "disk and is of type 'SGI volume'."));

	set_partition(cxt, n, first, last - first, sys);
	cxt->label->nparts_cur = count_used_partitions(cxt);
	if (partno)
		*partno = n;
	return 0;
}