diff options
author | Karel Zak | 2014-09-09 13:04:57 +0200 |
---|---|---|
committer | Karel Zak | 2014-10-07 14:55:31 +0200 |
commit | c3bc74835259bb1d6443ea52f875ce3c179dff20 (patch) | |
tree | 2f8be35f22336210b7b09adc1272fd360fa03a07 | |
parent | sfdisk: implement command_fdisk() (diff) | |
download | kernel-qcow2-util-linux-c3bc74835259bb1d6443ea52f875ce3c179dff20.tar.gz kernel-qcow2-util-linux-c3bc74835259bb1d6443ea52f875ce3c179dff20.tar.xz kernel-qcow2-util-linux-c3bc74835259bb1d6443ea52f875ce3c179dff20.zip |
libfdisk: return partno when add new partition
* improve the way how sfdisk report results
* the API change simplify applications
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | disk-utils/cfdisk.c | 2 | ||||
-rw-r--r-- | disk-utils/fdisk-menu.c | 2 | ||||
-rw-r--r-- | disk-utils/sfdisk.c | 39 | ||||
-rw-r--r-- | libfdisk/src/bsd.c | 5 | ||||
-rw-r--r-- | libfdisk/src/dos.c | 108 | ||||
-rw-r--r-- | libfdisk/src/fdiskP.h | 2 | ||||
-rw-r--r-- | libfdisk/src/gpt.c | 5 | ||||
-rw-r--r-- | libfdisk/src/libfdisk.h | 2 | ||||
-rw-r--r-- | libfdisk/src/partition.c | 34 | ||||
-rw-r--r-- | libfdisk/src/script.c | 11 | ||||
-rw-r--r-- | libfdisk/src/sgi.c | 6 | ||||
-rw-r--r-- | libfdisk/src/sun.c | 5 | ||||
-rw-r--r-- | libfdisk/src/table.c | 2 |
13 files changed, 142 insertions, 81 deletions
diff --git a/disk-utils/cfdisk.c b/disk-utils/cfdisk.c index 13e98b4b2..4101827f1 100644 --- a/disk-utils/cfdisk.c +++ b/disk-utils/cfdisk.c @@ -1829,7 +1829,7 @@ static int main_menu_action(struct cfdisk *cf, int key) fdisk_partition_set_start(npa, start); fdisk_partition_partno_follow_default(npa, 1); /* add to disk label -- libfdisk will ask for missing details */ - rc = fdisk_add_partition(cf->cxt, npa); + rc = fdisk_add_partition(cf->cxt, npa, NULL); fdisk_unref_partition(npa); if (rc == 0) ref = 1; diff --git a/disk-utils/fdisk-menu.c b/disk-utils/fdisk-menu.c index efd8dc1c6..e9bdc4554 100644 --- a/disk-utils/fdisk-menu.c +++ b/disk-utils/fdisk-menu.c @@ -520,7 +520,7 @@ static int generic_menu_cb(struct fdisk_context **cxt0, list_partition_types(cxt); break; case 'n': - rc = fdisk_add_partition(cxt, NULL); + rc = fdisk_add_partition(cxt, NULL, NULL); break; case 't': change_partition_type(cxt); diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c index 8dc102506..5381d43dc 100644 --- a/disk-utils/sfdisk.c +++ b/disk-utils/sfdisk.c @@ -317,7 +317,7 @@ static int command_dump(struct sfdisk *sf, int argc, char **argv) static void sfdisk_print_partition(struct sfdisk *sf, int n) { - struct fdisk_partition *pa; + struct fdisk_partition *pa = NULL; char *data; assert(sf); @@ -355,6 +355,7 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) struct fdisk_table *tb = NULL; const char *devname = NULL, *label; char buf[BUFSIZ]; + size_t next_partno = (size_t) -1; if (argc) devname = argv[0]; @@ -387,27 +388,38 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) printf(_("\nInput in the following format; absent fields get a default value.\n" "<start> <size> <type [uuid, hex or E,S,L,X]> <bootable [-,*]>\n" - "Usually you only need to specify <start> and <size>\n")); + "Usually you only need to specify <start> and <size>\n\n")); if (!fdisk_has_label(sf->cxt)) - printf(_("\nsfdisk is going to create a new '%s' disk label.\n" + printf(_("sfdisk is going to create a new '%s' disk label.\n" "Use 'label: <name>' before you define a first partition\n" - "to override the default.\n"), label); + "to override the default.\n\n"), label); tb = fdisk_script_get_table(dp); + assert(tb); do { - size_t nparts = fdisk_table_get_nents(tb); + size_t nparts; char *partname; - partname = fdisk_partname(devname, nparts + 1); + DBG(PARSE, ul_debug("<---next-line--->")); + if (next_partno == (size_t) -1) + next_partno = fdisk_table_get_nents(tb); + + partname = fdisk_partname(devname, next_partno + 1); if (!partname) err(EXIT_FAILURE, _("failed to allocate partition name")); + fflush(stdout); printf("%s: ", partname); free(partname); rc = fdisk_script_read_line(dp, stdin, buf, sizeof(buf)); - if (rc) { + + if (rc == 1) { /* end of file */ + rc = 0; + break; + } else if (rc < 0) { + DBG(PARSE, ul_debug("script parsing failed, trying sfdisk specific commands")); buf[sizeof(buf) - 1] = '\0'; if (strcmp(buf, "print") == 0) @@ -424,18 +436,23 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv) nparts = fdisk_table_get_nents(tb); if (nparts) { + size_t cur_partno; struct fdisk_partition *pa = fdisk_table_get_partition(tb, nparts - 1); + fputc('\n', stdout); + + assert(pa); if (!created) { /* create a disklabel */ rc = fdisk_apply_script_headers(sf->cxt, dp); created = !rc; } if (!rc) /* cretate partition */ - rc = fdisk_add_partition(sf->cxt, pa); + rc = fdisk_add_partition(sf->cxt, pa, &cur_partno); - if (!rc) /* sucess, print reult */ - sfdisk_print_partition(sf, nparts - 1); - else if (pa) /* error, drop partition from script */ + if (!rc) { /* success, print reult */ + sfdisk_print_partition(sf, cur_partno); + next_partno = cur_partno + 1; + } else if (pa) /* error, drop partition from script */ fdisk_table_remove_partition(tb, pa); } else printf(_("OK\n")); /* probably added script header */ diff --git a/libfdisk/src/bsd.c b/libfdisk/src/bsd.c index 6dddd3d71..093925ef2 100644 --- a/libfdisk/src/bsd.c +++ b/libfdisk/src/bsd.c @@ -194,7 +194,8 @@ static int bsd_probe_label(struct fdisk_context *cxt) } static int bsd_add_partition(struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { struct fdisk_bsd_label *l = self_label(cxt); struct bsd_disklabel *d = self_disklabel(cxt); @@ -297,6 +298,8 @@ static int bsd_add_partition(struct fdisk_context *cxt, bsd_set_parttype(cxt, i, pa->type); fdisk_label_set_changed(cxt->label, 1); + if (partno) + *partno = i; return 0; } diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index 76080c207..b90a01f5b 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -946,6 +946,7 @@ static int get_start_from_user( struct fdisk_context *cxt, } } + DBG(LABEL, ul_debug("DOS: start is %ju", (uintmax_t) *start)); return 0; } @@ -1151,11 +1152,14 @@ static int add_partition(struct fdisk_context *cxt, size_t n, return 0; } -static int add_logical(struct fdisk_context *cxt, struct fdisk_partition *pa) +static int add_logical(struct fdisk_context *cxt, + struct fdisk_partition *pa, + size_t *partno) { struct pte *pe; assert(cxt); + assert(partno); assert(cxt->label); assert(self_label(cxt)->ext_offset); @@ -1179,7 +1183,8 @@ static int add_logical(struct fdisk_context *cxt, struct fdisk_partition *pa) fdisk_info(cxt, _("Adding logical partition %zu"), cxt->label->nparts_max); - return add_partition(cxt, cxt->label->nparts_max - 1, pa); + *partno = cxt->label->nparts_max - 1; + return add_partition(cxt, *partno, pa); } static void check(struct fdisk_context *cxt, size_t n, @@ -1377,53 +1382,65 @@ static int dos_verify_disklabel(struct fdisk_context *cxt) * API callback. */ static int dos_add_partition(struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { size_t i, free_primary = 0, free_sectors = 0; sector_t last = 0, grain; int rc = 0; struct fdisk_dos_label *l; struct pte *ext_pe; + size_t res; /* partno */ assert(cxt); assert(cxt->label); assert(fdisk_is_label(cxt, DOS)); + DBG(LABEL, ul_debug("DOS: new partition wanted")); + l = self_label(cxt); ext_pe = l->ext_offset ? self_pte(cxt, l->ext_index) : NULL; + /* + * partition template (@pa) based partitioning + */ + /* pa specifies start within extended partition, add logical */ if (pa && pa->start && ext_pe && pa->start >= l->ext_offset && pa->start <= get_abs_partition_end(ext_pe)) { - rc = add_logical(cxt, pa); + DBG(LABEL, ul_debug("DOS: pa template %p: add logical", pa)); + rc = add_logical(cxt, pa, &res); goto done; - /* pa specifies start, but outside extended partition */ - } else if (pa && pa->start && l->ext_offset) { - int j; - - j = get_partition_unused_primary(cxt, pa); - if (j >= 0) { - rc = add_partition(cxt, j, pa); - goto done; - } - /* pa specifies that extended partition is wanted */ } else if (pa && pa->type && pa->type->code == MBR_DOS_EXTENDED_PARTITION) { - int j; - + DBG(LABEL, ul_debug("DOS: pa template %p: add extened", pa)); if (l->ext_offset) { fdisk_warnx(cxt, _("Extended partition already exists.")); return -EINVAL; } - j = get_partition_unused_primary(cxt, pa); - if (j >= 0) { - rc = add_partition(cxt, j, pa); + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) { + rc = add_partition(cxt, res, pa); + goto done; + } + + /* pa specifies start, but outside extended partition */ + } else if (pa && pa->start && l->ext_offset) { + DBG(LABEL, ul_debug("DOS: pa template %p: add primary", pa)); + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) { + rc = add_partition(cxt, res, pa); goto done; } } + /* + * dialog driven partitioning (it does not mean that @pa template is + * completely ignored!) + */ + /* check if there is space for primary partition */ grain = cxt->grain > cxt->sector_size ? cxt->grain / cxt->sector_size : 1; last = cxt->first_lba; @@ -1450,27 +1467,29 @@ static int dos_add_partition(struct fdisk_context *cxt, rc = 1; if (!free_primary || !free_sectors) { + DBG(LABEL, ul_debug("DOS: primary impossible, add logical")); if (l->ext_offset) { - if (!free_primary) - fdisk_info(cxt, _("All primary partitions are in use.")); - else if (!free_sectors) - fdisk_info(cxt, _("All space for primary partitions are in use.")); - rc = add_logical(cxt, pa); + if (!pa || pa->start) { + if (!free_primary) + fdisk_info(cxt, _("All primary partitions are in use.")); + else if (!free_sectors) + fdisk_info(cxt, _("All space for primary partitions is in use.")); + } + rc = add_logical(cxt, pa, &res); } else { - fdisk_info(cxt, _("If you want to create more than " - "four partitions, you must replace a " - "primary partition with an extended " + fdisk_info(cxt, + _( "Impossible to create another primary partition. " + "If you want to create more partitions, you must " + "replace a primary partition with an extended " "partition first.")); return -EINVAL; } } else if (cxt->label->nparts_max >= MAXIMUM_PARTS) { - int j; - fdisk_info(cxt, _("All logical partitions are in use. " "Adding a primary partition.")); - j = get_partition_unused_primary(cxt, pa); - if (j >= 0) - rc = add_partition(cxt, j, pa); + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) + rc = add_partition(cxt, res, pa); } else { char hint[BUFSIZ]; struct fdisk_ask *ask; @@ -1478,9 +1497,9 @@ static int dos_add_partition(struct fdisk_context *cxt, /* the default layout for scripts is to create primary partitions */ if (cxt->script) { - int j = get_partition_unused_primary(cxt, pa); - if (j >= 0) - rc = add_partition(cxt, j, pa); + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) + rc = add_partition(cxt, res, pa); goto done; } @@ -1510,16 +1529,16 @@ static int dos_add_partition(struct fdisk_context *cxt, fdisk_free_ask(ask); if (c == 'p') { - int j = get_partition_unused_primary(cxt, pa); - if (j >= 0) - rc = add_partition(cxt, j, pa); + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) + rc = add_partition(cxt, res, pa); goto done; } else if (c == 'l' && l->ext_offset) { - rc = add_logical(cxt, pa); + rc = add_logical(cxt, pa, &res); goto done; } else if (c == 'e' && !l->ext_offset) { - int j = get_partition_unused_primary(cxt, pa); - if (j >= 0) { + res = get_partition_unused_primary(cxt, pa); + if (res >= 0) { struct fdisk_partition xpa = { .type = NULL }; struct fdisk_parttype *t; @@ -1528,15 +1547,18 @@ static int dos_add_partition(struct fdisk_context *cxt, if (!pa) pa = &xpa; fdisk_partition_set_type(pa, t); - rc = add_partition(cxt, j, pa); + rc = add_partition(cxt, res, pa); } goto done; } else fdisk_warnx(cxt, _("Invalid partition type `%c'."), c); } done: - if (rc == 0) + if (rc == 0) { cxt->label->nparts_cur++; + if (partno && res >= 0) + *partno = res; + } return rc; } diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 15f394cfe..05ce28293 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -192,7 +192,7 @@ struct fdisk_label_operations { int (*set_id)(struct fdisk_context *cxt); /* new partition */ - int (*add_part)(struct fdisk_context *cxt, struct fdisk_partition *pa); + int (*add_part)(struct fdisk_context *cxt, struct fdisk_partition *pa, size_t *partno); /* delete partition */ int (*part_delete)(struct fdisk_context *cxt, diff --git a/libfdisk/src/gpt.c b/libfdisk/src/gpt.c index 082dcadce..8a3c8c6bd 100644 --- a/libfdisk/src/gpt.c +++ b/libfdisk/src/gpt.c @@ -1755,7 +1755,8 @@ static int gpt_entry_set_uuid(struct gpt_entry *e, char *str) /* Performs logical checks to add a new partition entry */ static int gpt_add_partition( struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { uint64_t user_f, user_l; /* user input ranges for first and last sectors */ uint64_t disk_f, disk_l; /* first and last available sector ranges on device*/ @@ -1947,6 +1948,8 @@ static int gpt_add_partition( } rc = 0; + if (partno) + *partno = partnum; done: fdisk_free_ask(ask); return rc; diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index 6abae04b5..b806b349b 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -197,7 +197,7 @@ extern int fdisk_set_disklabel_id(struct fdisk_context *cxt); extern int fdisk_get_partition(struct fdisk_context *cxt, size_t partno, struct fdisk_partition **pa); -extern int fdisk_add_partition(struct fdisk_context *cxt, struct fdisk_partition *pa); +extern int fdisk_add_partition(struct fdisk_context *cxt, struct fdisk_partition *pa, size_t *partno); extern int fdisk_delete_partition(struct fdisk_context *cxt, size_t partnum); extern int fdisk_delete_all_partitions(struct fdisk_context *cxt); diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c index c60e064fb..717eea711 100644 --- a/libfdisk/src/partition.c +++ b/libfdisk/src/partition.c @@ -73,9 +73,9 @@ void fdisk_unref_partition(struct fdisk_partition *pa) pa->refcount--; if (pa->refcount <= 0) { - DBG(PART, ul_debugobj(pa, "free")); fdisk_reset_partition(pa); list_del(&pa->parts); + DBG(PART, ul_debugobj(pa, "free")); free(pa); } } @@ -548,7 +548,9 @@ int fdisk_partition_to_string(struct fdisk_partition *pa, * @partno: * @pa: pointer to partition struct * - * Fills in @pa with data about partition @n. + * Fills in @pa with data about partition @n. Note that partno may address + * unused partition and then this function does not fill anything to @pa. + * See fdisk_is_partition_used(). * * Returns: 0 on success, otherwise, a corresponding error. */ @@ -601,7 +603,8 @@ int fdisk_is_partition_used(struct fdisk_context *cxt, size_t n) /** * fdisk_add_partition: * @cxt: fdisk context - * @pa: template for the partition + * @pa: template for the partition (or NULL) + * @partno: returns new partition number (optional) * * If @pa is not specified or any @pa item is missiong the libfdisk will ask by * fdisk_ask_ API. @@ -611,7 +614,8 @@ int fdisk_is_partition_used(struct fdisk_context *cxt, size_t n) * Returns 0. */ int fdisk_add_partition(struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { int rc; @@ -625,16 +629,20 @@ int fdisk_add_partition(struct fdisk_context *cxt, if (fdisk_missing_geometry(cxt)) return -EINVAL; - DBG(CXT, ul_debugobj(cxt, "adding new partition (start=%ju, end=%ju, size=%ju, " + if (pa) + DBG(CXT, ul_debugobj(cxt, "adding new partition %p (start=%ju, end=%ju, size=%ju, " "defaults(start=%s, end=%s, partno=%s)", - pa ? pa->start : 0, - pa ? pa->end : 0, - pa ? pa->size : 0, - pa && pa->start_follow_default ? "yes" : "no", - pa && pa->end_follow_default ? "yes" : "no", - pa && pa->partno_follow_default ? "yes" : "no")); - - rc = cxt->label->op->add_part(cxt, pa); + pa, + pa->start, + pa->end, + pa->size, + pa->start_follow_default ? "yes" : "no", + pa->end_follow_default ? "yes" : "no", + pa->partno_follow_default ? "yes" : "no")); + else + DBG(CXT, ul_debugobj(cxt, "adding partition")); + + rc = cxt->label->op->add_part(cxt, pa, partno); DBG(CXT, ul_debugobj(cxt, "add partition done (rc=%d)", rc)); return rc; diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c index 7d6f5eec3..e0e2d5387 100644 --- a/libfdisk/src/script.c +++ b/libfdisk/src/script.c @@ -865,7 +865,7 @@ int fdisk_script_read_buffer(struct fdisk_script *dp, char *s) * * Reads next line into dump. * - * Returns: 0 on success, <0 on error. + * Returns: 0 on success, <0 on error, 1 when nothing to read. */ int fdisk_script_read_line(struct fdisk_script *dp, FILE *f, char *buf, size_t bufsz) { @@ -879,7 +879,7 @@ int fdisk_script_read_line(struct fdisk_script *dp, FILE *f, char *buf, size_t b /* read the next non-blank non-comment line */ do { if (fgets(buf, bufsz, f) == NULL) - return -errno; + return 1; dp->nlines++; s = strchr(buf, '\n'); if (!s) { @@ -993,6 +993,7 @@ int fdisk_apply_script_headers(struct fdisk_context *cxt, struct fdisk_script *d assert(cxt); assert(dp); + DBG(SCRIPT, ul_debugobj(dp, "applying script headers")); fdisk_set_script(cxt, dp); /* create empty label */ @@ -1098,10 +1099,12 @@ int test_stdin(struct fdisk_test *ts, int argc, char *argv[]) printf(" #%zu :\n", n + 1); rc = fdisk_script_read_line(dp, stdin); - pa = fdisk_table_get_partition(dp->table, n); - printf(" #%zu %12ju %12ju\n", n + 1, + if (rc == 0) { + pa = fdisk_table_get_partition(dp->table, n); + printf(" #%zu %12ju %12ju\n", n + 1, fdisk_partition_get_start(pa), fdisk_partition_get_size(pa)); + } } while (rc == 0); if (!rc) diff --git a/libfdisk/src/sgi.c b/libfdisk/src/sgi.c index 10e5b5672..c0c6e33cb 100644 --- a/libfdisk/src/sgi.c +++ b/libfdisk/src/sgi.c @@ -759,7 +759,8 @@ static int sgi_delete_partition(struct fdisk_context *cxt, size_t partnum) } static int sgi_add_partition(struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { struct fdisk_sgi_label *sgi; char mesg[256]; @@ -900,7 +901,8 @@ static int sgi_add_partition(struct fdisk_context *cxt, sgi_set_partition(cxt, n, first, last - first, sys); cxt->label->nparts_cur = count_used_partitions(cxt); - + if (partno) + *partno = n; return 0; } diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c index 7148e4f68..68ad11eec 100644 --- a/libfdisk/src/sun.c +++ b/libfdisk/src/sun.c @@ -474,7 +474,8 @@ static int is_free_sector(struct fdisk_context *cxt, static int sun_add_partition( struct fdisk_context *cxt, - struct fdisk_partition *pa) + struct fdisk_partition *pa, + size_t *partno) { struct sun_disklabel *sunlabel = self_disklabel(cxt); uint32_t starts[SUN_MAXPARTITIONS], lens[SUN_MAXPARTITIONS]; @@ -681,6 +682,8 @@ static int sun_add_partition( set_sun_partition(cxt, n, first, last, sys); cxt->label->nparts_cur = count_used_partitions(cxt); + if (partno) + *partno = n; return 0; } diff --git a/libfdisk/src/table.c b/libfdisk/src/table.c index c6c51c837..e5cc79aa3 100644 --- a/libfdisk/src/table.c +++ b/libfdisk/src/table.c @@ -554,7 +554,7 @@ int fdisk_apply_table(struct fdisk_context *cxt, struct fdisk_table *tb) fdisk_reset_iter(&itr, FDISK_ITER_FORWARD); while (tb && fdisk_table_next_partition(tb, &itr, &pa) == 0) { - rc = fdisk_add_partition(cxt, pa); + rc = fdisk_add_partition(cxt, pa, NULL); if (rc) break; } |