From 347a7f775649f4431800023b36484e882962c06d Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 23 Sep 2014 12:28:01 +0200 Subject: [PATCH] sfdisk: add --append Signed-off-by: Karel Zak --- disk-utils/sfdisk.c | 46 +++++++++++++++++++++++++++++++++++------- libfdisk/src/context.c | 2 ++ libfdisk/src/script.c | 4 +++- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index d7d718d8d..ef38b2fa9 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -86,6 +86,7 @@ struct sfdisk { force : 1, /* do also stupid things */ backup : 1, /* backup sectors before write PT */ container : 1, /* PT contains container (MBR extended) partitions */ + append : 1, /* don't create new PT, append partitions only */ noact : 1; /* do not write to device */ }; @@ -801,7 +802,6 @@ static int has_container(struct sfdisk *sf) 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; @@ -815,6 +815,28 @@ static int has_container(struct sfdisk *sf) return sf->container; } +static size_t last_pt_partno(struct sfdisk *sf) +{ + size_t i, nparts, partno = 0; + struct fdisk_partition *pa = NULL; + + + nparts = fdisk_get_npartitions(sf->cxt); + for (i = 0; i < nparts; i++) { + size_t x; + + if (fdisk_get_partition(sf->cxt, i, &pa) != 0 || + !fdisk_partition_is_used(pa)) + continue; + x = fdisk_partition_get_partno(pa); + if (x > partno) + partno = x; + } + + fdisk_unref_partition(pa); + return partno; +} + static int is_device_used(struct sfdisk *sf) { #ifdef BLKRRPART @@ -856,14 +878,14 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) if (!devname) errx(EXIT_FAILURE, _("no disk device specified")); + rc = fdisk_assign_device(sf->cxt, devname, 0); + if (rc) + err(EXIT_FAILURE, _("cannot open %s"), devname); dp = fdisk_new_script(sf->cxt); if (!dp) err(EXIT_FAILURE, _("failed to allocate script handler")); - - rc = fdisk_assign_device(sf->cxt, devname, 0); - if (rc) - err(EXIT_FAILURE, _("cannot open %s"), devname); + fdisk_set_script(sf->cxt, dp); /* * Don't create a new disklabel when [-N] specified. In this @@ -886,6 +908,11 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) next_partno = partno; } + if (sf->append) { + created = 1; + next_partno = last_pt_partno(sf) + 1; + } + if (!sf->quiet && isatty(STDIN_FILENO)) { color_scheme_enable("welcome", UL_COLOR_GREEN); fdisk_info(sf->cxt, _("\nWelcome to sfdisk (%s)."), PACKAGE_STRING); @@ -953,7 +980,7 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) if (created && partno < 0 - && fdisk_table_get_nents(tb) == fdisk_get_npartitions(sf->cxt) + && next_partno == fdisk_get_npartitions(sf->cxt) && !has_container(sf)) { fdisk_info(sf->cxt, _("All partitions used.")); rc = SFDISK_DONE_ASK; @@ -1087,6 +1114,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) fputs(_(" partition type, GUID for GPT, hex for MBR\n"), out); fputs(USAGE_OPTIONS, out); + fputs(_(" -A, --append append partitions to existing partition table\n"), out); fputs(_(" -b, --backup backup partition table sectors (see -O)\n"), out); fputs(_(" -f, --force disable all consistency checking\n"), out); fputs(_(" -O, --backup-file override default backout file name\n"), out); @@ -1124,6 +1152,7 @@ int main(int argc, char *argv[]) static const struct option longopts[] = { { "activate",no_argument, NULL, 'a' }, + { "append", no_argument, NULL, 'A' }, { "backup", no_argument, NULL, 'b' }, { "backup-file", required_argument, NULL, 'O' }, { "dump", no_argument, NULL, 'd' }, @@ -1157,12 +1186,15 @@ int main(int argc, char *argv[]) textdomain(PACKAGE); atexit(close_stdout); - while ((c = getopt_long(argc, argv, "adfhglLO:nN:qsTu:vVX:", + while ((c = getopt_long(argc, argv, "aAdfhglLO:nN:qsTu:vVX:", longopts, &longidx)) != -1) { switch(c) { case 'a': sf->act = ACT_ACTIVATE; break; + case 'A': + sf->append = 1; + break; case 'b': sf->backup = 1; break; diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 4c353ac32..3926c37c5 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -394,6 +394,8 @@ static int warn_wipe(struct fdisk_context *cxt) * Open the device, discovery topology, geometry, detect disklabel and * switch the current label driver to reflect the probing result. * + * Note that this function resets all generic setting in context. + * * Returns: 0 on success, < 0 on error. */ int fdisk_assign_device(struct fdisk_context *cxt, diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index 6d3fe5e2e..2af081079 100644 --- a/libfdisk/src/script.c +++ b/libfdisk/src/script.c @@ -962,7 +962,9 @@ int fdisk_script_read_file(struct fdisk_script *dp, FILE *f) * @dp: script (or NULL to remove previous reference) * * Sets reference to the @dp script. The script headers might be used by label - * drivers to overwrite built-in defaults (for example disk label Id). + * drivers to overwrite built-in defaults (for example disk label Id) and label + * driver might optimize the default semantic to be more usable for scripts + * (for example to not ask for primary/logical/extended partition type). * * Note that script also contains reference to the fdisk context (see * fdisk_new_script()). This context may be completely independent on