summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2017-07-19 11:30:57 +0200
committerKarel Zak2017-07-19 11:30:57 +0200
commit992f7cbae420ab1b71fd9f2c2ae10c9804c1d213 (patch)
tree0ddb41ced462bf3fc0feebc1b5a14df76b4966aa
parentlibfdisk: (dos) return EINVAL when delete unused partition (diff)
downloadkernel-qcow2-util-linux-992f7cbae420ab1b71fd9f2c2ae10c9804c1d213.tar.gz
kernel-qcow2-util-linux-992f7cbae420ab1b71fd9f2c2ae10c9804c1d213.tar.xz
kernel-qcow2-util-linux-992f7cbae420ab1b71fd9f2c2ae10c9804c1d213.zip
libfdisk: add fdisk_disable_dialogs()
The default (for historical reasons) is to use dialog driven partitioning. It's possible to avoid dialogs by fdisk_partition template for fdisk_add_partition(). Unfortunately in some case (mostly DOS driver) it's not enough, because we need to distinguish between logical and primary partitions. If we know that dialogs are unwanted then we can default to primary partition, etc. This function simplify semantic of the library for non-interactive programs. Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--libfdisk/docs/libfdisk-sections.txt2
-rw-r--r--libfdisk/src/ask.c8
-rw-r--r--libfdisk/src/context.c34
-rw-r--r--libfdisk/src/dos.c6
-rw-r--r--libfdisk/src/fdiskP.h1
-rw-r--r--libfdisk/src/libfdisk.h.in3
-rw-r--r--libfdisk/src/libfdisk.sym2
-rw-r--r--libfdisk/src/partition.c10
8 files changed, 60 insertions, 6 deletions
diff --git a/libfdisk/docs/libfdisk-sections.txt b/libfdisk/docs/libfdisk-sections.txt
index 2674ed87b..68ca0927f 100644
--- a/libfdisk/docs/libfdisk-sections.txt
+++ b/libfdisk/docs/libfdisk-sections.txt
@@ -292,6 +292,7 @@ fdisk_enable_bootbits_protection
fdisk_enable_details
fdisk_enable_listonly
fdisk_enable_wipe
+fdisk_disable_dialogs
fdisk_get_alignment_offset
fdisk_get_collision
fdisk_get_devfd
@@ -312,6 +313,7 @@ fdisk_get_sector_size
fdisk_get_size_unit
fdisk_get_unit
fdisk_get_units_per_sector
+fdisk_has_dialogs
fdisk_has_label
fdisk_has_protected_bootbits
fdisk_has_wipe
diff --git a/libfdisk/src/ask.c b/libfdisk/src/ask.c
index 5a0952271..babe040ad 100644
--- a/libfdisk/src/ask.c
+++ b/libfdisk/src/ask.c
@@ -142,6 +142,14 @@ int fdisk_do_ask(struct fdisk_context *cxt, struct fdisk_ask *ask)
ask->type == FDISK_ASKTYPE_WARN ? "warn" :
"?nothing?"));
+ if (!fdisk_has_dialogs(cxt) &&
+ !(ask->type == FDISK_ASKTYPE_INFO ||
+ ask->type == FDISK_ASKTYPE_WARNX ||
+ ask->type == FDISK_ASKTYPE_WARN)) {
+ DBG(ASK, ul_debugobj(ask, "dialogs disabled"));
+ return -EINVAL;
+ }
+
if (!cxt->ask_cb) {
DBG(ASK, ul_debugobj(ask, "no ask callback specified!"));
return -EINVAL;
diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c
index c7e8a4276..fb7ad4b44 100644
--- a/libfdisk/src/context.c
+++ b/libfdisk/src/context.c
@@ -344,6 +344,40 @@ int fdisk_enable_bootbits_protection(struct fdisk_context *cxt, int enable)
cxt->protect_bootbits = enable ? 1 : 0;
return 0;
}
+/**
+ * fdisk_disable_dialogs
+ * @cxt: fdisk context
+ * @enable: 1 or 0
+ *
+ * The library uses dialog driven partitioning by default.
+ *
+ * Returns: 0 on success, < 0 on error.
+ *
+ * Since: 2.31
+ */
+int fdisk_disable_dialogs(struct fdisk_context *cxt, int disable)
+{
+ if (!cxt)
+ return -EINVAL;
+
+ cxt->no_disalogs = disable;
+ return 0;
+}
+
+/**
+ * fdisk_has_dialogs
+ * @cxt: fdisk context
+ *
+ * See fdisk_disable_dialogs()
+ *
+ * Returns: 1 if dialog driven partitioning enabled (default), or 0.
+ *
+ * Since: 2.31
+ */
+int fdisk_has_dialogs(struct fdisk_context *cxt)
+{
+ return cxt->no_disalogs == 0;
+}
/**
* fdisk_enable_wipe
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c
index 12d014449..6fa9108ed 100644
--- a/libfdisk/src/dos.c
+++ b/libfdisk/src/dos.c
@@ -1597,7 +1597,7 @@ static int dos_add_partition(struct fdisk_context *cxt,
DBG(LABEL, ul_debug("DOS: pa template specifies partno>=4 for primary partition"));
return -EINVAL;
}
- if (pa->type && IS_EXTENDED(pa->type->code)) {
+ if (ext_pe && pa->type && IS_EXTENDED(pa->type->code)) {
fdisk_warnx(cxt, _("Extended partition already exists."));
return -EINVAL;
}
@@ -1674,6 +1674,8 @@ static int dos_add_partition(struct fdisk_context *cxt,
DBG(LABEL, ul_debug("DOS: primary impossible, add logical"));
if (l->ext_offset) {
if (!pa || fdisk_partition_has_start(pa)) {
+ /* See above case A); here we have start, but
+ * out of extended partition */
const char *msg;
if (!free_primary)
msg = _("All primary partitions are in use.");
@@ -1708,7 +1710,7 @@ static int dos_add_partition(struct fdisk_context *cxt,
int c;
/* the default layout for scripts is to create primary partitions */
- if (cxt->script) {
+ if (cxt->script || !fdisk_has_dialogs(cxt)) {
rc = get_partition_unused_primary(cxt, pa, &res);
if (rc == 0)
rc = add_partition(cxt, res, pa);
diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h
index 434490edd..77ad7610d 100644
--- a/libfdisk/src/fdiskP.h
+++ b/libfdisk/src/fdiskP.h
@@ -378,6 +378,7 @@ struct fdisk_context {
display_details : 1, /* expert display mode */
protect_bootbits : 1, /* don't zeroize first sector */
pt_collision : 1, /* another PT detected by libblkid */
+ no_disalogs : 1, /* disable dialog-driven partititoning */
listonly : 1; /* list partition, nothing else */
char *collision; /* name of already existing FS/PT */
diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in
index eea02dba8..1c16fe4b3 100644
--- a/libfdisk/src/libfdisk.h.in
+++ b/libfdisk/src/libfdisk.h.in
@@ -187,6 +187,9 @@ int fdisk_is_readonly(struct fdisk_context *cxt);
int fdisk_is_regfile(struct fdisk_context *cxt);
int fdisk_device_is_used(struct fdisk_context *cxt);
+int fdisk_disable_dialogs(struct fdisk_context *cxt, int disable);
+int fdisk_has_dialogs(struct fdisk_context *cxt);
+
int fdisk_enable_details(struct fdisk_context *cxt, int enable);
int fdisk_is_details(struct fdisk_context *cxt);
diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym
index 7944538cf..0d274847a 100644
--- a/libfdisk/src/libfdisk.sym
+++ b/libfdisk/src/libfdisk.sym
@@ -287,4 +287,6 @@ FDISK_2.31 {
fdisk_reassign_device;
fdisk_device_is_used;
fdisk_reread_changes;
+ fdisk_disable_dialogs;
+ fdisk_has_dialogs;
} FDISK_2.30;
diff --git a/libfdisk/src/partition.c b/libfdisk/src/partition.c
index daa73a4ed..bc52ea573 100644
--- a/libfdisk/src/partition.c
+++ b/libfdisk/src/partition.c
@@ -705,9 +705,9 @@ int fdisk_partition_is_wholedisk(struct fdisk_partition *pa)
* If @pa specified and partno-follow-default (see fdisk_partition_partno_follow_default())
* enabled then returns next expected partno or -ERANGE on error.
*
- * If @pa is NULL, or @pa does not specify any sepamntic for the next partno
+ * If @pa is NULL, or @pa does not specify any semantic for the next partno
* then use Ask API to ask user for the next partno. In this case returns 1 if
- * no free partition avaialble.
+ * no free partition avaialble. If fdisk dialogs are disabled then returns -EINVAL.
*
* Returns: 0 on success, <0 on error, or 1 for non-free partno by Ask API.
*/
@@ -740,10 +740,12 @@ int fdisk_partition_next_partno(
fdisk_is_partition_used(cxt, pa->partno))
return -ERANGE;
*n = pa->partno;
- } else
+ return 0;
+
+ } else if (fdisk_has_dialogs(cxt))
return fdisk_ask_partnum(cxt, n, 1);
- return 0;
+ return -EINVAL;
}
static int probe_partition_content(struct fdisk_context *cxt, struct fdisk_partition *pa)