Exemple #1
0
/* fdisk_get_partition() backend */
static int sgi_get_partition(struct fdisk_context *cxt, size_t n, struct fdisk_partition *pa)
{
	uint64_t start, len;

	pa->used = sgi_get_num_sectors(cxt, n) > 0;
	if (!pa->used)
		return 0;

	start = sgi_get_start_sector(cxt, n);
	len = sgi_get_num_sectors(cxt, n);

	pa->type = sgi_get_parttype(cxt, n);
	pa->size = len;
	pa->start = start;
	pa->end = start + len - (len ? 1 : 0);

	if (pa->type && pa->type->type == SGI_TYPE_ENTIRE_DISK)
		pa->wholedisk = 1;

	pa->attrs = sgi_get_swappartition(cxt) == (int) n ? "swap" :
		    sgi_get_bootpartition(cxt) == (int) n ? "boot" : NULL;
	if (pa->attrs)
		pa->attrs = strdup(pa->attrs);

	return 0;
}
Exemple #2
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 #3
0
static int compare_start(struct fdisk_context *cxt,
			 const void *x, const void *y)
{
	/*
	 * sort according to start sectors and prefers largest partition: entry
	 * zero is entire disk entry
	 */
	unsigned int i = *(int *) x;
	unsigned int j = *(int *) y;
	unsigned int a = sgi_get_start_sector(cxt, i);
	unsigned int b = sgi_get_start_sector(cxt, j);
	unsigned int c = sgi_get_num_sectors(cxt, i);
	unsigned int d = sgi_get_num_sectors(cxt, j);

	if (a == b)
		return (d > c) ? 1 : (d == c) ? 0 : -1;
	return (a > b) ? 1 : -1;
}
static int
compare_start(int *x, int *y) {
	/*
	 * sort according to start sectors
	 * and prefers largest partition:
	 * entry zero is entire disk entry
	 */
	unsigned int i = *x;
	unsigned int j = *y;
	unsigned int a = sgi_get_start_sector(i);
	unsigned int b = sgi_get_start_sector(j);
	unsigned int c = sgi_get_num_sectors(i);
	unsigned int d = sgi_get_num_sectors(j);

	if (a == b)
		return (d > c) ? 1 : (d == c) ? 0 : -1;
	return (a > b) ? 1 : -1;
}
Exemple #5
0
static size_t count_used_partitions(struct fdisk_context *cxt)
{
	size_t i, ct = 0;

	for (i = 0; i < cxt->label->nparts_max; i++)
		ct += sgi_get_num_sectors(cxt, i) > 0;

	return ct;
}
Exemple #6
0
static void
sgi_set_entire(struct fdisk_context *cxt) {
	int n;

	for (n=10; n<partitions; n++) {
		if (!sgi_get_num_sectors(cxt, n)) {
			sgi_set_partition(cxt, n, 0, sgi_get_lastblock(cxt), SGI_VOLUME);
			break;
		}
	}
}
Exemple #7
0
static int sgi_partition_is_used(
		struct fdisk_context *cxt,
		size_t i)
{
	assert(cxt);
	assert(fdisk_is_disklabel(cxt, SGI));

	if (i >= cxt->label->nparts_max)
		return 0;
	return sgi_get_num_sectors(cxt, i) ? 1 : 0;
}
Exemple #8
0
static void sgi_set_entire(struct fdisk_context *cxt)
{
	size_t n;

	for (n = 10; n < cxt->label->nparts_max; n++) {
		if (!sgi_get_num_sectors(cxt, n)) {
			sgi_set_partition(cxt, n, 0, sgi_get_lastblock(cxt), SGI_TYPE_ENTIRE_DISK);
			break;
		}
	}
}
static void
sgi_set_entire(void) {
	int n;

	for (n=10; n<partitions; n++) {
		if (!sgi_get_num_sectors(n)) {
			sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME);
			break;
		}
	}
}
Exemple #10
0
static void sgi_set_volhdr(struct fdisk_context *cxt)
{
	size_t n;

	for (n = 8; n < cxt->label->nparts_max; n++) {
		if (!sgi_get_num_sectors(cxt, n)) {
			/* Choose same default volume header size as IRIX fx uses. */
			if (4096 < sgi_get_lastblock(cxt))
				sgi_set_partition(cxt, n, 0, 4096, SGI_TYPE_VOLHDR);
			break;
		}
	}
}
Exemple #11
0
static int sgi_set_partition(struct fdisk_context *cxt,
		size_t i,
		struct fdisk_partition *pa)
{
	struct sgi_disklabel *sgilabel;

	if (i >= cxt->label->nparts_max)
		return -EINVAL;

	sgilabel = self_disklabel(cxt);

	if (pa->type) {
		struct fdisk_parttype *t = pa->type;

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

		if ((i == 10 && t->code != SGI_TYPE_ENTIRE_DISK)
		    || (i == 8 && t->code != 0))
			fdisk_info(cxt, _("Consider leaving partition 9 as volume header (0), "
					  "and partition 11 as entire volume (6), "
					  "as IRIX expects it."));

		if (cxt->script == NULL
		    && ((t->code != SGI_TYPE_ENTIRE_DISK) && (t->code != SGI_TYPE_VOLHDR))
		    && (sgi_get_start_sector(cxt, i) < 1)) {
			int yes = 0;
			fdisk_ask_yesno(cxt,
				_("It is highly recommended that the partition at offset 0 "
				  "is of type \"SGI volhdr\", the IRIX system will rely on it to "
				  "retrieve from its directory standalone tools like sash and fx. "
				  "Only the \"SGI volume\" entire disk section may violate this. "
				  "Are you sure about tagging this partition differently?"), &yes);
			if (!yes)
				return 1;
		}

		sgilabel->partitions[i].type = cpu_to_be32(t->code);
	}

	if (fdisk_partition_has_start(pa))
		sgilabel->partitions[i].first_block = cpu_to_be32(pa->start);
	if (fdisk_partition_has_size(pa))
		sgilabel->partitions[i].num_blocks = cpu_to_be32(pa->size);

	fdisk_label_set_changed(cxt->label, 1);
	return 0;
}
Exemple #12
0
static
void
sgi_set_volhdr(void)
{
	int n;

	for (n=8; n<partitions; n++) {
		if (!sgi_get_num_sectors(n)) {
			/*
			 * Choose same default volume header size
			 * as IRIX fx uses.
			 */
			if (4096 < sgi_get_lastblock())
				sgi_set_partition(n, 0, 4096, SGI_VOLHDR);
			break;
		}
	}
}
Exemple #13
0
static
void
sgi_set_volhdr(struct fdisk_context *cxt)
{
	int n;

	for (n=8; n<partitions; n++) {
		if (!sgi_get_num_sectors(cxt, n)) {
			/*
			 * Choose same default volume header size
			 * as IRIX fx uses.
			 */
			if (4096 < sgi_get_lastblock(cxt))
				sgi_set_partition(cxt, n, 0, 4096, SGI_VOLHDR);
			break;
		}
	}
}
static void
sgi_set_volhdr(void)
{
	int n;

	for (n = 8; n < partitions; n++) {
	if (!sgi_get_num_sectors(n)) {
		/*
		 * 5 cylinders is an arbitrary value I like
		 * IRIX 5.3 stored files in the volume header
		 * (like sash, symmon, fx, ide) with ca. 3200
		 * sectors.
		 */
		if (heads * sectors * 5 < sgi_get_lastblock())
			sgi_set_partition(n, 0, heads * sectors * 5, SGI_VOLHDR);
			break;
		}
	}
}
Exemple #15
0
static int sgi_get_partition_status(
		struct fdisk_context *cxt,
		size_t i,
		int *status)
{

	assert(cxt);
	assert(fdisk_is_disklabel(cxt, SGI));

	if (!status || i >= cxt->label->nparts_max)
		return -EINVAL;

	*status = FDISK_PARTSTAT_NONE;

	if (sgi_get_num_sectors(cxt, i))
		*status = FDISK_PARTSTAT_USED;

	return 0;
}
static void
sgi_change_sysid(int i, int sys)
{
	if (sgi_get_num_sectors(i) == 0 ) { /* caught already before, ... */
		printf("Sorry you may change the Tag of non-empty partitions\n");
		return;
	}
	if ((sys != SGI_ENTIRE_DISK) && (sys != SGI_VOLHDR)
	 && (sgi_get_start_sector(i) < 1)
	) {
		read_maybe_empty(
			"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") != 0)
			return;
	}
	sgilabel->partitions[i].id = SGI_SSWAP32(sys);
}
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 int
verify_sgi(int verbose)
{
	int Index[16];      /* list of valid partitions */
	int sortcount = 0;  /* number of used partitions, i.e. non-zero lengths */
	int entire = 0, i = 0;
	unsigned int start = 0;
	long long gap = 0;      /* count unused blocks */
	unsigned int lastblock = sgi_get_lastblock();

	clearfreelist();
	for (i = 0; i < 16; i++) {
		if (sgi_get_num_sectors(i) != 0) {
			Index[sortcount++] = i;
			if (sgi_get_sysid(i) == SGI_ENTIRE_DISK) {
				if (entire++ == 1) {
					if (verbose)
						printf("More than one entire disk entry present\n");
				}
			}
		}
	}
	if (sortcount == 0) {
		if (verbose)
			printf("No partitions defined\n");
		return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1;
	}
	qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start);
	if (sgi_get_sysid(Index[0]) == SGI_ENTIRE_DISK) {
		if ((Index[0] != 10) && verbose)
			printf("IRIX likes when Partition 11 covers the entire disk\n");
		if ((sgi_get_start_sector(Index[0]) != 0) && verbose)
			printf("The entire disk partition should start "
				"at block 0,\n"
				"not at diskblock %d\n",
				sgi_get_start_sector(Index[0]));
		if (debug)      /* I do not understand how some disks fulfil it */
			if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose)
				printf("The entire disk partition is only %d diskblock large,\n"
					"but the disk is %d diskblocks long\n",
					sgi_get_num_sectors(Index[0]), lastblock);
			lastblock = sgi_get_num_sectors(Index[0]);
	} else {
		if (verbose)
			printf("One Partition (#11) should cover the entire disk\n");
		if (debug > 2)
			printf("sysid=%d\tpartition=%d\n",
				sgi_get_sysid(Index[0]), Index[0]+1);
	}
	for (i = 1, start = 0; i < sortcount; i++) {
		int cylsize = sgi_get_nsect() * sgi_get_ntrks();

		if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) {
			if (debug)      /* I do not understand how some disks fulfil it */
				if (verbose)
					printf("Partition %d does not start on cylinder boundary\n",
						Index[i]+1);
		}
		if (sgi_get_num_sectors(Index[i]) % cylsize != 0) {
			if (debug)      /* I do not understand how some disks fulfil it */
				if (verbose)
					printf("Partition %d does not end on cylinder boundary\n",
						Index[i]+1);
		}
		/* We cannot handle several "entire disk" entries. */
		if (sgi_get_sysid(Index[i]) == SGI_ENTIRE_DISK) continue;
		if (start > sgi_get_start_sector(Index[i])) {
			if (verbose)
				printf("Partitions %d and %d overlap by %d sectors\n",
					Index[i-1]+1, Index[i]+1,
					start - sgi_get_start_sector(Index[i]));
			if (gap > 0) gap = -gap;
			if (gap == 0) gap = -1;
		}
		if (start < sgi_get_start_sector(Index[i])) {
			if (verbose)
				printf("Unused gap of %8u sectors - sectors %8u-%8u\n",
					sgi_get_start_sector(Index[i]) - start,
					start, sgi_get_start_sector(Index[i])-1);
			gap += sgi_get_start_sector(Index[i]) - start;
			add2freelist(start, sgi_get_start_sector(Index[i]));
		}
		start = sgi_get_start_sector(Index[i])
			   + sgi_get_num_sectors(Index[i]);
		if (debug > 1) {
			if (verbose)
				printf("%2d:%12d\t%12d\t%12d\n", Index[i],
					sgi_get_start_sector(Index[i]),
					sgi_get_num_sectors(Index[i]),
					sgi_get_sysid(Index[i]));
		}
	}
	if (start < lastblock) {
		if (verbose)
			printf("Unused gap of %8u sectors - sectors %8u-%8u\n",
				lastblock - start, start, lastblock-1);
		gap += lastblock - start;
		add2freelist(start, lastblock);
	}
	/*
	 * Done with arithmetics
	 * Go for details now
	 */
	if (verbose) {
		if (!sgi_get_num_sectors(sgi_get_bootpartition())) {
			printf("\nThe boot partition does not exist\n");
		}
		if (!sgi_get_num_sectors(sgi_get_swappartition())) {
			printf("\nThe swap partition does not exist\n");
		} else {
			if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP)
			 && (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP))
				printf("\nThe swap partition has no swap type\n");
		}
		if (sgi_check_bootfile("/unix"))
			printf("\tYou have chosen an unusual boot file name\n");
	}
	return (gap > 0) ? 1 : (gap == 0) ? 0 : -1;
}
static void
sgi_list_table(int xtra)
{
	int i, w, wd;
	int kpi = 0;                /* kernel partition ID */

	if (xtra) {
		printf("\nDisk %s (SGI disk label): %d heads, %d sectors\n"
			"%d 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, cylinders,
			SGI_SSWAP16(sgiparam.pcylcount),
			SGI_SSWAP16(sgiparam.sparecyl),
			SGI_SSWAP16(sgiparam.ilfact),
			(char *)sgilabel,
			str_units(PLURAL), units_per_sector);
	} else {
		printf("\nDisk %s (SGI 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 );
	}

	w = strlen(disk_device);
	wd = sizeof("Device") - 1;
	if (w < wd)
	w = wd;

	printf("----- partitions -----\n"
		"Pt# %*s  Info     Start       End   Sectors  Id  System\n",
		w + 2, "Device");
	for (i = 0 ; i < partitions; i++) {
		if (sgi_get_num_sectors(i) || debug ) {
			uint32_t start = sgi_get_start_sector(i);
			uint32_t len = sgi_get_num_sectors(i);
			kpi++;              /* only count nonempty partitions */
			printf(
			"%2d: %s %4s %9ld %9ld %9ld  %2x  %s\n",
/* fdisk part number */	i+1,
/* device */            partname(disk_device, kpi, w+3),
/* flags */             (sgi_get_swappartition() == i) ? "swap" :
/* flags */             (sgi_get_bootpartition() == i) ? "boot" : "    ",
/* start */             (long) scround(start),
/* end */               (long) scround(start+len)-1,
/* no odd flag on end */(long) len,
/* type id */           sgi_get_sysid(i),
/* type name */         partition_type(sgi_get_sysid(i)));
		}
	}
	printf("----- Bootinfo -----\nBootfile: %s\n"
		"----- Directory Entries -----\n",
		sgilabel->boot_file);
	for (i = 0 ; i < sgi_volumes; i++) {
		if (sgilabel->directory[i].vol_file_size) {
			uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start);
			uint32_t len = SGI_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, (char*)name, (unsigned int) start, (unsigned int) len);
		}
	}
}
Exemple #20
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;
}
Exemple #21
0
static int verify_disklabel(struct fdisk_context *cxt, int verbose)
{
	int Index[SGI_MAXPARTITIONS];	/* list of valid partitions */
	int sortcount = 0;		/* number of used partitions, i.e. non-zero lengths */
	int entire = 0, i = 0;
	unsigned int start = 0;
	long long gap = 0;	/* count unused blocks */
	unsigned int lastblock = sgi_get_lastblock(cxt);

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

	clear_freelist(cxt);
	memset(Index, 0, sizeof(Index));

	for (i=0; i < SGI_MAXPARTITIONS; i++) {
		if (sgi_get_num_sectors(cxt, i) != 0) {
			Index[sortcount++] = i;
			if (sgi_get_sysid(cxt, i) == SGI_TYPE_ENTIRE_DISK
			    && entire++ == 1) {
				if (verbose)
					fdisk_info(cxt, _("More than one entire "
						"disk entry present."));
			}
		}
	}
	if (sortcount == 0) {
		if (verbose)
			fdisk_info(cxt, _("No partitions defined"));
		return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1;
	}

	sort(Index, sortcount, sizeof(Index[0]), cxt, compare_start);

	if (sgi_get_sysid(cxt, Index[0]) == SGI_TYPE_ENTIRE_DISK) {
		if (verbose && Index[0] != 10)
			fdisk_info(cxt, _("IRIX likes when Partition 11 "
					  "covers the entire disk."));

		if (verbose && sgi_get_start_sector(cxt, Index[0]) != 0)
			fdisk_info(cxt, _("The entire disk partition should "
				"start at block 0, not at diskblock %d."),
			       sgi_get_start_sector(cxt, Index[0]));

		if (verbose && sgi_get_num_sectors(cxt, Index[0]) != lastblock)
			DBG(LABEL, dbgprint(
				"entire disk partition=%ds, but disk=%ds",
				sgi_get_num_sectors(cxt, Index[0]),
				lastblock));
		lastblock = sgi_get_num_sectors(cxt, Index[0]);
	} else if (verbose) {
		fdisk_info(cxt, _("Partition 11 should cover the entire disk."));
		DBG(LABEL, dbgprint("sysid=%d\tpartition=%d",
			       sgi_get_sysid(cxt, Index[0]), Index[0]+1));
	}
	for (i=1, start=0; i<sortcount; i++) {
		int cylsize = sgi_get_nsect(cxt) * sgi_get_ntrks(cxt);

		if (verbose && cylsize
		    && (sgi_get_start_sector(cxt, Index[i]) % cylsize) != 0)
			DBG(LABEL, dbgprint("partition %d does not start on "
					"cylinder boundary.", Index[i]+1));

		if (verbose && cylsize
		    && sgi_get_num_sectors(cxt, Index[i]) % cylsize != 0)
			DBG(LABEL, dbgprint("partition %d does not end on "
					"cylinder boundary.", Index[i]+1));

		/* We cannot handle several "entire disk" entries. */
		if (sgi_get_sysid(cxt, Index[i]) == SGI_TYPE_ENTIRE_DISK)
			continue;
		if (start > sgi_get_start_sector(cxt, Index[i])) {
			if (verbose)
				fdisk_info(cxt, _("The Partition %d and %d overlap "
					  "by %d sectors."),
				       Index[i-1]+1, Index[i]+1,
				       start - sgi_get_start_sector(cxt, Index[i]));
			if (gap >  0) gap = -gap;
			if (gap == 0) gap = -1;
		}
		if (start < sgi_get_start_sector(cxt, Index[i])) {
			if (verbose)
				fdisk_info(cxt, _("Unused gap of %8u sectors "
					    "- sectors %8u-%u"),
				       sgi_get_start_sector(cxt, Index[i]) - start,
				       start, sgi_get_start_sector(cxt, Index[i])-1);
			gap += sgi_get_start_sector(cxt, Index[i]) - start;
			add_to_freelist(cxt, start,
					sgi_get_start_sector(cxt, Index[i]));
		}
		start = sgi_get_start_sector(cxt, Index[i])
			+ sgi_get_num_sectors(cxt, Index[i]);
		/* Align free space on cylinder boundary */
		if (cylsize && start % cylsize)
			start += cylsize - (start % cylsize);

		DBG(LABEL, dbgprint("%2d:%12d\t%12d\t%12d", Index[i],
				       sgi_get_start_sector(cxt, Index[i]),
				       sgi_get_num_sectors(cxt, Index[i]),
				       sgi_get_sysid(cxt, Index[i])));
	}
	if (start < lastblock) {
		if (verbose)
			fdisk_info(cxt, _("Unused gap of %8u sectors - sectors %8u-%u"),
				lastblock - start, start, lastblock-1);
		gap += lastblock - start;
		add_to_freelist(cxt, start, lastblock);
	}
	/*
	 * Done with arithmetics. Go for details now
	 */
	if (verbose) {
		if (sgi_get_bootpartition(cxt) < 0
		    || !sgi_get_num_sectors(cxt, sgi_get_bootpartition(cxt)))
			fdisk_info(cxt, _("The boot partition does not exist."));

		if (sgi_get_swappartition(cxt) < 0
		    || !sgi_get_num_sectors(cxt, sgi_get_swappartition(cxt)))
			fdisk_info(cxt, _("The swap partition does not exist."));

		else if (sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != SGI_TYPE_SWAP
		    && sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != MBR_LINUX_SWAP_PARTITION)
			fdisk_info(cxt, _("The swap partition has no swap type."));

		if (sgi_check_bootfile(cxt, "/unix"))
			fdisk_info(cxt, _("You have chosen an unusual boot "
					  "file name."));
	}

	return (gap > 0) ? 1 : (gap == 0) ? 0 : -1;
}
Exemple #22
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 #23
0
static int sgi_list_table(struct fdisk_context *cxt)
{
	struct tt *tb = NULL;
	struct sgi_disklabel *sgilabel = self_disklabel(cxt);
	struct sgi_device_parameter *sgiparam = &sgilabel->devparam;
	size_t i, used;
	char *p;
	int rc;

	if (fdisk_context_display_details(cxt))
		fdisk_colon(cxt, _(
			"Label geometry: %d heads, %llu sectors\n"
			"                %llu cylinders, %d physical cylinders\n"
			"                %d extra sects/cyl, interleave %d:1\n"),
			cxt->geom.heads, cxt->geom.sectors,
			cxt->geom.cylinders, be16_to_cpu(sgiparam->pcylcount),
			(int) sgiparam->sparecyl, be16_to_cpu(sgiparam->ilfact));

	/*
	 * Partitions
	 */
	tb = tt_new_table(TT_FL_FREEDATA);
	if (!tb)
		return -ENOMEM;

	tt_define_column(tb, _("Pt#"),      3, TT_FL_RIGHT);
	tt_define_column(tb, _("Device"), 0.2, 0);
	tt_define_column(tb, _("Info"),     2, 0);
	tt_define_column(tb, _("Start"),    9, TT_FL_RIGHT);
	tt_define_column(tb, _("End"),      9, TT_FL_RIGHT);
	tt_define_column(tb, _("Sectors"),  9, TT_FL_RIGHT);
	tt_define_column(tb, _("Id"),       2, TT_FL_RIGHT);
	tt_define_column(tb, _("System"), 0.2, TT_FL_TRUNC);

	for (i = 0, used = 1; i < cxt->label->nparts_max; i++) {
		uint32_t start, len;
		struct fdisk_parttype *t;
		struct tt_line *ln;

		if (sgi_get_num_sectors(cxt, i) == 0)
			continue;

		ln = tt_add_line(tb, NULL);
		if (!ln)
			continue;
		start = sgi_get_start_sector(cxt, i);
		len = sgi_get_num_sectors(cxt, i);
		t = fdisk_get_partition_type(cxt, i);

		if (asprintf(&p, "%zu:", i + 1) > 0)
			tt_line_set_data(ln, 0, p);	/* # */
		p = fdisk_partname(cxt->dev_path, used++);
		if (p)
			tt_line_set_data(ln, 1, p);	/* Device */

		p = sgi_get_swappartition(cxt) == (int) i ? "swap" :
		    sgi_get_bootpartition(cxt) == (int) i ? "boot" : NULL;
		if (p)
			tt_line_set_data(ln, 2, strdup(p));	/* Info */

		if (asprintf(&p, "%ju", (uintmax_t) fdisk_scround(cxt, start)) > 0)
			tt_line_set_data(ln, 3, p);	/* Start */
		if (asprintf(&p, "%ju",	(uintmax_t) fdisk_scround(cxt, start + len) - 1) > 0)
			tt_line_set_data(ln, 4, p);	/* End */
		if (asprintf(&p, "%ju",	(uintmax_t) len) > 0)
			tt_line_set_data(ln, 5, p);	/* Sectors*/
		if (asprintf(&p, "%2x", t->type) > 0)
			tt_line_set_data(ln, 6, p);	/* type ID */
		if (t->name)
			tt_line_set_data(ln, 7, strdup(t->name)); /* type Name */
		fdisk_free_parttype(t);
	}

	rc = fdisk_print_table(cxt, tb);
	tt_free_table(tb);
	if (rc)
		return rc;

	/*
	 * Volumes
	 */
	tb = tt_new_table(TT_FL_FREEDATA);
	if (!tb)
		return -ENOMEM;

	tt_define_column(tb, _("#"),       3, TT_FL_RIGHT);
	tt_define_column(tb, _("Name"),  0.2, 0);
	tt_define_column(tb, _("Sector"),  2, TT_FL_RIGHT);
	tt_define_column(tb, _("Size"),    9, TT_FL_RIGHT);

	for (i = 0, used = 0; i < SGI_MAXVOLUMES; i++) {
		struct tt_line *ln;
		uint32_t start = be32_to_cpu(sgilabel->volume[i].block_num),
			 len = be32_to_cpu(sgilabel->volume[i].num_bytes);
		if (!len)
			continue;
		ln = tt_add_line(tb, NULL);
		if (!ln)
			continue;
		if (asprintf(&p, "%zu:", i) > 0)
			tt_line_set_data(ln, 0, p);		/* # */
		if (*sgilabel->volume[i].name)
			tt_line_set_data(ln, 1,
				strndup((char *) sgilabel->volume[i].name,
				        sizeof(sgilabel->volume[i].name)));	/* Name */
		if (asprintf(&p, "%ju", (uintmax_t) start) > 0)
			tt_line_set_data(ln, 2, p);	/* Sector */
		if (asprintf(&p, "%ju",	(uintmax_t) len) > 0)
			tt_line_set_data(ln, 3, p);	/* Size */
		used++;
	}

	if (used)
		rc = fdisk_print_table(cxt, tb);
	tt_free_table(tb);

	fdisk_colon(cxt, _("Bootfile: %s"), sgilabel->boot_file);

	return rc;
}
Exemple #24
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;
}
Exemple #25
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;
}