]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: add fdisk_set_partition_type()
authorKarel Zak <kzak@redhat.com>
Wed, 26 Sep 2012 11:30:44 +0000 (13:30 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 27 Sep 2012 11:38:13 +0000 (13:38 +0200)
 - 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>
fdisks/fdisk.c
fdisks/fdisk.h
fdisks/fdiskbsdlabel.c
fdisks/fdiskdoslabel.c
fdisks/fdiskdoslabel.h
fdisks/fdisksgilabel.c
fdisks/fdisksunlabel.c
fdisks/utils.c

index 151790262b50791be683f0159ea615b47fb600f6..814183108c8e906c331f02ce135afad528c58bc9 100644 (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);
index 879f3d640df6ce691835fb9725d5e3291748eb17..5af172fcf22e9dd986b39d1ca04bdc9965ecae89 100644 (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,
index 3a23c02f099cd6efa688a777959744af0684a892..b11bcf1cb76e994ad6c085340c5fb6a80aff2e9a 100644 (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,
 };
index 3b2f9d5bfdf0860ecf441dd1350c1391a373625a..d391126eccccde666332c2655020083fb3f618cb 100644 (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,
 };
index 0754b1714138a1d3c8f36c17a3111eade48df3b2..3b6d64478db0770317e4ca18114e5e781e932b96 100644 (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);
index a181a77091f4e89964a18331f61fedba9b282338..6cef145e4d4564877d16f2264801cd105ae05988 100644 (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,
 };
index 521c43a174d2da1abf8cf3b4eac82b35419259ef..43d3cdfd94ac4348fe8c8d7525d9e864e18372b0 100644 (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,
+
 };
index fd69fb72ca2566cf2672eeb188119b926de3e2a1..e9bc0182c2ab92955bb75f61fbd63ac818f9c34e 100644 (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);
+}