fdisk: add fdisk_set_partition_type()

- remove all label specific partition type stuff from fdisk.c to
   label files
 - add new fdisk_set_partition_type() to API

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2012-09-26 13:30:44 +02:00
parent 010186f2a2
commit 02460b8aae
8 changed files with 160 additions and 123 deletions

View File

@ -128,7 +128,6 @@ char *line_ptr, /* interactive input */
int nowarn = 0, /* no warnings for fdisk -l/-s */
dos_compatible_flag = 0, /* disabled by default */
dos_changed = 0,
partitions = 4; /* maximum partition + 1 */
unsigned int user_cylinders, user_heads, user_sectors;
@ -846,7 +845,7 @@ static void delete_partition(struct fdisk_context *cxt, int partnum)
printf(_("Partition %d is deleted\n"), partnum + 1);
}
static void change_sysid(struct fdisk_context *cxt)
static void change_partition_type(struct fdisk_context *cxt)
{
int i;
struct fdisk_parttype *t, *org_t;
@ -859,71 +858,23 @@ static void change_sysid(struct fdisk_context *cxt)
if (!t)
printf(_("Partition %d does not exist yet!\n"), i + 1);
else while (1) {
else do {
t = read_partition_type(cxt);
if (!t && disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
printf(_("Type 0 means free space to many systems\n"
"(but not to Linux). Having partitions of\n"
"type 0 is probably unwise. You can delete\n"
"a partition using the `d' command.\n"));
/* break; */
}
if (!t)
continue;
if (disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
if (IS_EXTENDED (t->type) != IS_EXTENDED (t->type)) {
printf(_("You cannot change a partition into"
" an extended one or vice versa\n"
"Delete it first.\n"));
break;
}
if (fdisk_set_partition_type(cxt, i, t) == 0) {
ptes[i].changed = 1;
printf (_("Changed type of partition '%s' to '%s'\n"),
org_t ? org_t->name : _("Unknown"),
t ? t->name : _("Unknown"));
} else {
printf (_("Type of partition %d is unchanged: %s\n"),
i + 1,
org_t ? org_t->name : _("Unknown"));
}
/* TODO: add set_partition_type(cxt, npart, type) API */
if (t->type < 256) {
if (disklabel == SUN_LABEL && i == 2 && t->type != SUN_TAG_BACKUP)
printf(_("Consider leaving partition 3 "
"as Whole disk (5),\n"
"as SunOS/Solaris expects it and "
"even Linux likes it.\n\n"));
if (disklabel == SGI_LABEL && ((i == 10 && t->type != ENTIRE_DISK)
|| (i == 8 && t->type != 0)))
printf(_("Consider leaving partition 9 "
"as volume header (0),\nand "
"partition 11 as entire volume (6), "
"as IRIX expects it.\n\n"));
if (t == org_t)
goto nochange;
if (disklabel == SUN_LABEL) {
ptes[i].changed = sun_change_sysid(cxt, i, t->type);
} else
if (disklabel == SGI_LABEL) {
ptes[i].changed = sgi_change_sysid(cxt, i, t->type);
} else {
ptes[i].part_table->sys_ind = t->type;
ptes[i].changed = 1;
}
if (ptes[i].changed)
printf (_("Changed type of partition '%s' to '%s'\n"),
org_t ? org_t->name : _("Unknown"),
t ? t->name : _("Unknown"));
else {
nochange:
printf (_("Type of partition %d is unchanged: %s\n"),
i + 1,
org_t ? org_t->name : _("Unknown"));
}
if (is_dos_partition(t->type) || is_dos_partition(t->type))
dos_changed = 1;
break;
}
}
break;
} while (1);
fdisk_free_parttype(t);
fdisk_free_parttype(org_t);
@ -1398,12 +1349,6 @@ reread_partition_table(struct fdisk_context *cxt, int leave) {
errno);
}
if (dos_changed)
printf(
_("\nWARNING: If you have created or modified any DOS 6.x\n"
"partitions, please see the fdisk manual page for additional\n"
"information.\n"));
if (leave) {
if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
fprintf(stderr, _("\nError closing file\n"));
@ -1780,7 +1725,7 @@ static void command_prompt(struct fdisk_context *cxt)
fdisk_create_disklabel(cxt, "sun");
break;
case 't':
change_sysid(cxt);
change_partition_type(cxt);
break;
case 'u':
change_units(cxt);

View File

@ -176,7 +176,8 @@ struct fdisk_label {
void (*part_delete)(struct fdisk_context *cxt, int partnum);
/* get partition type */
struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt, int partnum);
/* set partition type */
int (*part_set_type)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t);
};
/*
@ -205,6 +206,8 @@ extern int fdisk_write_disklabel(struct fdisk_context *cxt);
extern int fdisk_verify_disklabel(struct fdisk_context *cxt);
extern int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name);
extern struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum);
extern int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
struct fdisk_parttype *t);
extern size_t fdisk_get_nparttypes(struct fdisk_context *cxt);
extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt,

View File

@ -558,6 +558,7 @@ xbsd_write_bootstrap (struct fdisk_context *cxt)
sync_disks ();
}
/* TODO: remove this, use regular change_partition_type() in fdisk.c */
static void
xbsd_change_fstype (struct fdisk_context *cxt)
{
@ -856,6 +857,22 @@ static struct fdisk_parttype *xbsd_get_parttype(struct fdisk_context *cxt, int n
return t;
}
static int xbsd_set_parttype(struct fdisk_context *cxt, int partnum,
struct fdisk_parttype *t)
{
struct xbsd_partition *p;
if (partnum >= xbsd_dlabel.d_npartitions || !t || t->type > UINT8_MAX)
return -EINVAL;
p = &xbsd_dlabel.d_partitions[partnum];
if (t->type == p->p_fstype)
return 0;
p->p_fstype = t->type;
return 0;
}
const struct fdisk_label bsd_label =
{
.name = "bsd",
@ -869,4 +886,5 @@ const struct fdisk_label bsd_label =
.part_add = xbsd_add_part,
.part_delete = xbsd_delete_part,
.part_get_type = xbsd_get_parttype,
.part_set_type = xbsd_set_parttype,
};

View File

@ -414,7 +414,7 @@ static int dos_probe_label(struct fdisk_context *cxt)
* We might also do the opposite and warn in all cases except
* for "is probably nondos partition".
*/
int is_dos_partition(int t)
static int is_dos_partition(int t)
{
return (t == 1 || t == 4 || t == 6 ||
t == 0x0b || t == 0x0c || t == 0x0e ||
@ -840,6 +840,34 @@ static struct fdisk_parttype *dos_get_parttype(struct fdisk_context *cxt, int pa
return t;
}
static int dos_set_parttype(struct fdisk_context *cxt, int partnum,
struct fdisk_parttype *t)
{
struct partition *p;
if (partnum >= partitions || !t || t->type > UINT8_MAX)
return -EINVAL;
p = ptes[partnum].part_table;
if (t->type == p->sys_ind)
return 0;
if (IS_EXTENDED(p->sys_ind) || IS_EXTENDED(t->type)) {
printf(_("\nYou cannot change a partition into an extended one "
"or vice versa.\nDelete it first.\n\n"));
return -EINVAL;
}
if (is_dos_partition(t->type) || is_dos_partition(p->sys_ind))
printf(
_("\nWARNING: If you have created or modified any DOS 6.x"
"partitions, please see the fdisk manual page for additional"
"information.\n\n"));
p->sys_ind = t->type;
return 0;
}
const struct fdisk_label dos_label =
{
.name = "dos",
@ -853,4 +881,5 @@ const struct fdisk_label dos_label =
.part_add = dos_add_partition,
.part_delete = dos_delete_partition,
.part_get_type = dos_get_parttype,
.part_set_type = dos_set_parttype,
};

View File

@ -39,7 +39,6 @@ static inline sector_t get_partition_start(struct pte *pe)
extern void dos_print_mbr_id(struct fdisk_context *cxt);
extern void dos_set_mbr_id(struct fdisk_context *cxt);
extern int is_dos_partition(int t);
extern void dos_init(struct fdisk_context *cxt);
extern int mbr_is_valid_magic(unsigned char *b);

View File

@ -575,27 +575,6 @@ sgi_gaps(struct fdisk_context *cxt) {
return sgi_verify_disklabel(cxt);
}
int
sgi_change_sysid(struct fdisk_context *cxt, int i, int sys)
{
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 0;
}
if (((sys != ENTIRE_DISK) && (sys != 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 0;
}
sgilabel->partitions[i].id = SSWAP32(sys);
return 1;
}
/* returns partition index of first entry marked as entire disk */
static int
@ -910,6 +889,37 @@ static struct fdisk_parttype *sgi_get_parttype(struct fdisk_context *cxt, int n)
return t;
}
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;
}
const struct fdisk_label sgi_label =
{
.name = "sgi",
@ -923,4 +933,5 @@ const struct fdisk_label sgi_label =
.part_add = sgi_add_partition,
.part_delete = sgi_delete_partition,
.part_get_type = sgi_get_parttype,
.part_set_type = sgi_set_parttype,
};

View File

@ -504,36 +504,6 @@ static void sun_delete_partition(struct fdisk_context *cxt, int partnum)
part->num_sectors = 0;
}
int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys)
{
struct sun_partition *part = &sunlabel->partitions[i];
struct sun_tag_flag *tag = &sunlabel->part_tags[i];
if (sys == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
read_chars(
_("It is highly recommended that the partition at offset 0\n"
"is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
"there may destroy your partition table and bootblock.\n"
"Type YES if you're very sure you would like that partition\n"
"tagged with 82 (Linux swap): "));
if (strcmp (line_ptr, _("YES\n")))
return 0;
}
switch (sys) {
case SUN_TAG_SWAP:
case SUN_TAG_LINUX_SWAP:
/* swaps are not mountable by default */
tag->flag |= SSWAP16(SUN_FLAG_UNMNT);
break;
default:
/* assume other types are mountable;
user can change it anyway */
tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT);
break;
}
tag->tag = SSWAP16(sys);
return 1;
}
void sun_list_table(struct fdisk_context *cxt, int xtra)
{
@ -659,6 +629,49 @@ static struct fdisk_parttype *sun_get_parttype(struct fdisk_context *cxt, int n)
return t;
}
static int sun_set_parttype(struct fdisk_context *cxt, int i,
struct fdisk_parttype *t)
{
struct sun_partition *part;
struct sun_tag_flag *tag;
if (i >= partitions || !t || t->type > UINT16_MAX)
return -EINVAL;
if (i == 2 && t->type != SUN_TAG_BACKUP)
printf(_("Consider leaving partition 3 as Whole disk (5),\n"
"as SunOS/Solaris expects it and even Linux likes it.\n\n"));
part = &sunlabel->partitions[i];
tag = &sunlabel->part_tags[i];
if (t->type == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
read_chars(
_("It is highly recommended that the partition at offset 0\n"
"is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
"there may destroy your partition table and bootblock.\n"
"Type YES if you're very sure you would like that partition\n"
"tagged with 82 (Linux swap): "));
if (strcmp (line_ptr, _("YES\n")))
return 1;
}
switch (t->type) {
case SUN_TAG_SWAP:
case SUN_TAG_LINUX_SWAP:
/* swaps are not mountable by default */
tag->flag |= SSWAP16(SUN_FLAG_UNMNT);
break;
default:
/* assume other types are mountable;
user can change it anyway */
tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT);
break;
}
tag->tag = SSWAP16(t->type);
return 0;
}
const struct fdisk_label sun_label =
{
.name = "sun",
@ -672,4 +685,6 @@ const struct fdisk_label sun_label =
.part_add = sun_add_partition,
.part_delete = sun_delete_partition,
.part_get_type = sun_get_parttype,
.part_set_type = sun_set_parttype,
};

View File

@ -668,3 +668,20 @@ struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int p
return cxt->label->part_get_type(cxt, partnum);
}
/**
* fdisk_set_partition_type:
* @cxt: fdisk context
* @partnum: partition number
* @t: new type
*
* Returns partition type
*/
int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum,
struct fdisk_parttype *t)
{
if (!cxt || !cxt->label || !cxt->label->part_set_type)
return -EINVAL;
return cxt->label->part_set_type(cxt, partnum, t);
}