summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--disk-utils/cfdisk.c2
-rw-r--r--disk-utils/fdisk-menu.c2
-rw-r--r--disk-utils/sfdisk.c39
-rw-r--r--libfdisk/src/bsd.c5
-rw-r--r--libfdisk/src/dos.c108
-rw-r--r--libfdisk/src/fdiskP.h2
-rw-r--r--libfdisk/src/gpt.c5
-rw-r--r--libfdisk/src/libfdisk.h2
-rw-r--r--libfdisk/src/partition.c34
-rw-r--r--libfdisk/src/script.c11
-rw-r--r--libfdisk/src/sgi.c6
-rw-r--r--libfdisk/src/sun.c5
-rw-r--r--libfdisk/src/table.c2
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;
}