From: Karel Zak Date: Tue, 23 Sep 2014 09:39:02 +0000 (+0200) Subject: sfdisk: be sensitive to PT limits X-Git-Tag: v2.26-rc1~361 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e54b1c6fcb42cee06d2b72f110844ff9ed98415d;p=thirdparty%2Futil-linux.git sfdisk: be sensitive to PT limits Signed-off-by: Karel Zak --- diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index 1a6db98772..d7d718d8d2 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -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(_(" \n"), stdout); + fputs(_(" , , , \n"), stdout); fputc('\n', stdout); fputs(_(" 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) { diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index 2404d6758a..ad19c41c67 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -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); diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c index efa55cd101..fb8f52c7eb 100644 --- a/libfdisk/src/table.c +++ b/libfdisk/src/table.c @@ -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; }