void list_disk_geometry(struct fdisk_context *cxt) { char *id = NULL; uint64_t bytes = cxt->total_sectors * cxt->sector_size; char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE | SIZE_SUFFIX_3LETTER, bytes); fdisk_colon(cxt, _("Disk %s: %s, %ju bytes, %ju sectors"), cxt->dev_path, strsz, bytes, (uintmax_t) cxt->total_sectors); free(strsz); if (fdisk_require_geometry(cxt) || fdisk_context_use_cylinders(cxt)) fdisk_colon(cxt, _("Geometry: %d heads, %llu sectors/track, %llu cylinders"), cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders); fdisk_colon(cxt, _("Units: %s of %d * %ld = %ld bytes"), fdisk_context_get_unit(cxt, PLURAL), fdisk_context_get_units_per_sector(cxt), cxt->sector_size, fdisk_context_get_units_per_sector(cxt) * cxt->sector_size); fdisk_colon(cxt, _("Sector size (logical/physical): %lu bytes / %lu bytes"), cxt->sector_size, cxt->phy_sector_size); fdisk_colon(cxt, _("I/O size (minimum/optimal): %lu bytes / %lu bytes"), cxt->min_io_size, cxt->io_size); if (cxt->alignment_offset) fdisk_colon(cxt, _("Alignment offset: %lu bytes"), cxt->alignment_offset); if (fdisk_dev_has_disklabel(cxt)) fdisk_colon(cxt, _("Disklabel type: %s"), cxt->label->name); if (fdisk_get_disklabel_id(cxt, &id) == 0 && id) fdisk_colon(cxt, _("Disk identifier: %s"), id); }
/* * @str: "cylinder" or "sector". * * This is pure shit, unfortunately for example Sun addresses begin of the * partition by cylinders... */ int fdisk_context_set_unit(struct fdisk_context *cxt, const char *str) { assert(cxt); cxt->display_in_cyl_units = 0; if (!str) return 0; if (strcmp(str, "cylinder") == 0 || strcmp(str, "cylinders") == 0) cxt->display_in_cyl_units = 1; else if (strcmp(str, "sector") == 0 || strcmp(str, "sectors") == 0) cxt->display_in_cyl_units = 0; DBG(CONTEXT, dbgprint("display unit: %s", fdisk_context_get_unit(cxt, 0))); return 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; }
static int sun_add_partition( struct fdisk_context *cxt, size_t n, struct fdisk_parttype *t) { struct sun_disklabel *sunlabel = self_disklabel(cxt); uint32_t starts[SUN_MAXPARTITIONS], lens[SUN_MAXPARTITIONS]; struct sun_partition *part = &sunlabel->partitions[n]; struct sun_info *info = &sunlabel->vtoc.infos[n]; uint32_t start, stop, stop2; int whole_disk = 0, sys = t ? t->type : SUN_TAG_LINUX_NATIVE; struct fdisk_ask *ask; int rc; char mesg[256]; size_t i; unsigned int first, last; if (part->num_sectors && be16_to_cpu(info->id) != SUN_TAG_UNASSIGNED) { fdisk_info(cxt, _("Partition %zu is already defined. Delete " "it before re-adding it."), n + 1); return -EINVAL; } fetch_sun(cxt, starts, lens, &start, &stop); if (stop <= start) { if (n == 2) whole_disk = 1; else { fdisk_info(cxt, _("Other partitions already cover the " "whole disk. Delete some/shrink them before retry.")); 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 (whole_disk) { fdisk_ask_number_set_low(ask, 0); /* minimal */ fdisk_ask_number_set_default(ask, 0); /* default */ fdisk_ask_number_set_high(ask, 0); /* maximal */ } else { fdisk_ask_number_set_low(ask, fdisk_scround(cxt, start)); /* minimal */ fdisk_ask_number_set_default(ask, fdisk_scround(cxt, start)); /* default */ fdisk_ask_number_set_high(ask, fdisk_scround(cxt, stop)); /* maximal */ } rc = fdisk_do_ask(cxt, ask); first = fdisk_ask_number_get_result(ask); fdisk_free_ask(ask); if (rc) return rc; if (fdisk_context_use_cylinders(cxt)) first *= fdisk_context_get_units_per_sector(cxt); else { /* Starting sector has to be properly aligned */ int cs = cxt->geom.heads * cxt->geom.sectors; int x = first % cs; if (x) { fdisk_info(cxt, _("Aligning the first sector from %u to %u " "to be on cylinder boundary."), first, first + cs - x); first += cs - x; } } if (n == 2 && first != 0) fdisk_warnx(cxt, _("It is highly recommended that the " "third partition covers the whole disk " "and is of type `Whole disk'")); /* ewt asks to add: "don't start a partition at cyl 0" However, [email protected] 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 < cxt->label->nparts_max; i++) if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) break; if (i < cxt->label->nparts_max && !whole_disk) { if (n == 2 && !first) { whole_disk = 1; break; } fdisk_warnx(cxt, _("Sector %d is already allocated"), first); } else break; } stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors; /* ancient */ stop2 = stop; for (i = 0; i < cxt->label->nparts_max; i++) { if (starts[i] > first && starts[i] < stop) stop = starts[i]; } 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); if (whole_disk) { fdisk_ask_number_set_low(ask, fdisk_scround(cxt, stop2)); /* minimal */ fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop2)); /* default */ fdisk_ask_number_set_high(ask, fdisk_scround(cxt, stop2)); /* maximal */ fdisk_ask_number_set_base(ask, 0); } else if (n == 2 && !first) { fdisk_ask_number_set_low(ask, fdisk_scround(cxt, first)); /* minimal */ fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop2)); /* default */ fdisk_ask_number_set_high(ask, fdisk_scround(cxt, stop2)); /* maximal */ fdisk_ask_number_set_base(ask, fdisk_scround(cxt, first)); } else { fdisk_ask_number_set_low(ask, fdisk_scround(cxt, first)); /* minimal */ fdisk_ask_number_set_default(ask, fdisk_scround(cxt, stop)); /* default */ fdisk_ask_number_set_high(ask, fdisk_scround(cxt, stop)); /* 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); fdisk_free_ask(ask); if (rc) return rc; if (fdisk_context_use_cylinders(cxt)) last *= fdisk_context_get_units_per_sector(cxt); if (n == 2 && !first) { if (last >= stop2) { whole_disk = 1; last = stop2; } else if (last > stop) { fdisk_warnx(cxt, _("You haven't covered the whole disk with the 3rd partition, but your value\n" "%lu %s covers some other partition. Your entry has been changed\n" "to %lu %s"), (unsigned long) fdisk_scround(cxt, last), fdisk_context_get_unit(cxt, SINGULAR), (unsigned long) fdisk_scround(cxt, stop), fdisk_context_get_unit(cxt, SINGULAR)); last = stop; } } else if (!whole_disk && last > stop) last = stop; if (whole_disk) sys = SUN_TAG_WHOLEDISK; set_sun_partition(cxt, n, first, last, sys); cxt->label->nparts_cur = count_used_partitions(cxt); return 0; }