]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
sfdisk: be sensitive to PT limits
authorKarel Zak <kzak@redhat.com>
Tue, 23 Sep 2014 09:39:02 +0000 (11:39 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 7 Oct 2014 12:55:32 +0000 (14:55 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/sfdisk.c
libfdisk/src/libfdisk.h
libfdisk/src/table.c

index 1a6db9877240381cde918f3fffa1762b424e2ced..d7d718d8d2b076791a2eb3e33955a3e79fa449bb 100644 (file)
@@ -85,6 +85,7 @@ struct sfdisk {
                     noreread : 1,      /* don't check device is in use */
                     force  : 1,        /* do also stupid things */
                     backup : 1,        /* backup sectors before write PT */
+                    container : 1,     /* PT contains container (MBR extended) partitions */
                     noact  : 1;        /* do not write to device */
 };
 
@@ -726,7 +727,7 @@ static void command_fdisk_help(void)
        color_scheme_enable("help-title", UL_COLOR_BOLD);
        fputs(_(" Input format:\n"), stdout);
        color_disable();
-       fputs(_("   <start> <size> <typy> <bootable>\n"), stdout);
+       fputs(_("   <start>, <size>, <typy>, <bootable>\n"), stdout);
 
        fputc('\n', stdout);
        fputs(_("   <start>  begin of the partition in sectors. The default is the first\n"
@@ -791,6 +792,29 @@ static int loop_control_commands(struct sfdisk *sf,
        return rc;
 }
 
+static int has_container(struct sfdisk *sf)
+{
+       size_t i, nparts;
+       struct fdisk_partition *pa = NULL;
+
+       if (sf->container)
+               return sf->container;
+
+       nparts = fdisk_get_npartitions(sf->cxt);
+
+       for (i = 0; i < nparts; i++) {
+               if (fdisk_get_partition(sf->cxt, i, &pa) != 0)
+                       continue;
+               if (fdisk_partition_is_container(pa)) {
+                       sf->container = 1;
+                       break;
+               }
+       }
+
+       fdisk_unref_partition(pa);
+       return sf->container;
+}
+
 static int is_device_used(struct sfdisk *sf)
 {
 #ifdef BLKRRPART
@@ -927,6 +951,15 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
                if (next_partno == (size_t) -1)
                        next_partno = fdisk_table_get_nents(tb);
 
+               if (created
+                   && partno < 0
+                   && fdisk_table_get_nents(tb) == fdisk_get_npartitions(sf->cxt)
+                   && !has_container(sf)) {
+                       fdisk_info(sf->cxt, _("All partitions used."));
+                       rc = SFDISK_DONE_ASK;
+                       break;
+               }
+
                if (created) {
                        char *partname = fdisk_partname(devname, next_partno + 1);
                        if (!partname)
@@ -976,10 +1009,16 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
                        if (!rc) {              /* success, print reult */
                                sfdisk_print_partition(sf, cur_partno);
                                next_partno = cur_partno + 1;
-                       } else if (pa)          /* error, drop partition from script */
+                       } else if (pa) {        /* error, drop partition from script */
                                fdisk_table_remove_partition(tb, pa);
+                               if (rc == -ENOSPC) {
+                                       rc = SFDISK_DONE_ASK;
+                                       break;
+                               }
+                       }
                } else
                        fdisk_info(sf->cxt, _("Script header accepted."));
+
        } while (1);
 
        if (!sf->quiet && rc != SFDISK_DONE_ABORT) {
index 2404d6758a1d1445b0980457fee2bdf3cd826f28..ad19c41c671e62ce06bf9dd7980d7b87366333a0 100644 (file)
@@ -284,7 +284,7 @@ extern struct fdisk_table *fdisk_new_table(void);
 extern int fdisk_reset_table(struct fdisk_table *tb);
 extern void fdisk_ref_table(struct fdisk_table *tb);
 extern void fdisk_unref_table(struct fdisk_table *tb);
-extern int fdisk_table_get_nents(struct fdisk_table *tb);
+extern size_t fdisk_table_get_nents(struct fdisk_table *tb);
 extern int fdisk_table_is_empty(struct fdisk_table *tb);
 extern int fdisk_table_add_partition(struct fdisk_table *tb, struct fdisk_partition *pa);
 extern int fdisk_table_remove_partition(struct fdisk_table *tb, struct fdisk_partition *pa);
index efa55cd10165375e163f032fb46a84ce32aae373..fb8f52c7ebf7b590e28f66d1490eaf2431ce162f 100644 (file)
@@ -101,7 +101,7 @@ int fdisk_table_is_empty(struct fdisk_table *tb)
  *
  * Returns: number of entries in table.
  */
-int fdisk_table_get_nents(struct fdisk_table *tb)
+size_t fdisk_table_get_nents(struct fdisk_table *tb)
 {
        return tb ? tb->nents : 0;
 }