コード例 #1
0
ファイル: sgi.c プロジェクト: TacheR/util-linux
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;
}
コード例 #2
0
ファイル: sgi.c プロジェクト: Distrotech/util-linux
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;
}