aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2016-11-30 12:43:10 +0100
committerKarel Zak <kzak@redhat.com>2016-11-30 13:01:33 +0100
commit35ca51182782193f555fbdcb06bb10766550d017 (patch)
treee790c87db174462db010ed6c8ea32e7a7506df0f
parentc49b765a6e9031642e2bb846e93dddc6827e4b28 (diff)
downloadutil-linux-35ca51182782193f555fbdcb06bb10766550d017.tar.gz
sfdisk: support empty label use-case
By default sfdisk creates partition table when a first partition is specified, otherwise the device is not modified. This force users to create at least one partition. This commit allows to create empty label without partitions if "label: <name>" header line is specified by script. The commit also modifies "New situation:" output to list label name and label identifier. Addresses: https://github.com/karelzak/util-linux/issues/374 Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--disk-utils/fdisk-list.c23
-rw-r--r--disk-utils/fdisk-list.h1
-rw-r--r--disk-utils/sfdisk.818
-rw-r--r--disk-utils/sfdisk.c17
-rw-r--r--libfdisk/src/libfdisk.h.in1
-rw-r--r--libfdisk/src/libfdisk.sym5
-rw-r--r--libfdisk/src/script.c20
7 files changed, 75 insertions, 10 deletions
diff --git a/disk-utils/fdisk-list.c b/disk-utils/fdisk-list.c
index e6b2033e77..c9560f42bf 100644
--- a/disk-utils/fdisk-list.c
+++ b/disk-utils/fdisk-list.c
@@ -34,10 +34,23 @@ static int is_ide_cdrom_or_tape(char *device)
return ret;
}
+void list_disk_identifier(struct fdisk_context *cxt)
+{
+ struct fdisk_label *lb = fdisk_get_label(cxt, NULL);
+ char *id = NULL;
+
+ if (fdisk_has_label(cxt))
+ fdisk_info(cxt, _("Disklabel type: %s"),
+ fdisk_label_get_name(lb));
+
+ if (!fdisk_is_details(cxt) && fdisk_get_disklabel_id(cxt, &id) == 0 && id) {
+ fdisk_info(cxt, _("Disk identifier: %s"), id);
+ free(id);
+ }
+}
void list_disk_geometry(struct fdisk_context *cxt)
{
- char *id = NULL;
struct fdisk_label *lb = fdisk_get_label(cxt, NULL);
uint64_t bytes = fdisk_get_nsectors(cxt) * fdisk_get_sector_size(cxt);
char *strsz = size_to_human_string(SIZE_SUFFIX_SPACE
@@ -71,14 +84,8 @@ void list_disk_geometry(struct fdisk_context *cxt)
if (fdisk_get_alignment_offset(cxt))
fdisk_info(cxt, _("Alignment offset: %lu bytes"),
fdisk_get_alignment_offset(cxt));
- if (fdisk_has_label(cxt))
- fdisk_info(cxt, _("Disklabel type: %s"),
- fdisk_label_get_name(lb));
- if (!fdisk_is_details(cxt) && fdisk_get_disklabel_id(cxt, &id) == 0 && id) {
- fdisk_info(cxt, _("Disk identifier: %s"), id);
- free(id);
- }
+ list_disk_identifier(cxt);
}
void list_disklabel(struct fdisk_context *cxt)
diff --git a/disk-utils/fdisk-list.h b/disk-utils/fdisk-list.h
index eddab92ec3..4ed5c256bc 100644
--- a/disk-utils/fdisk-list.h
+++ b/disk-utils/fdisk-list.h
@@ -2,6 +2,7 @@
#define UTIL_LINUX_FDISK_LIST_H
extern void list_disklabel(struct fdisk_context *cxt);
+extern void list_disk_identifier(struct fdisk_context *cxt);
extern void list_disk_geometry(struct fdisk_context *cxt);
extern void list_freespace(struct fdisk_context *cxt);
diff --git a/disk-utils/sfdisk.8 b/disk-utils/sfdisk.8
index fcde8726b2..efe4a86bf7 100644
--- a/disk-utils/sfdisk.8
+++ b/disk-utils/sfdisk.8
@@ -212,7 +212,10 @@ Deprecated option. Only the sector unit is supported.
.BR \-X , " \-\-label " \fItype
Specify the disk label type (e.g. \fBdos\fR, \fBgpt\fR, ...). If this option
is not given, then \fBsfdisk\fR defaults to the existing label, but if there
-is no label on the device yet, then the type defaults to \fBdos\fR.
+is no label on the device yet, then the type defaults to \fBdos\fR. The default
+or the current label may be overwritten by the "label: <name>" script header
+line. The option \fB\-\-label\fR does not force \fBsfdisk\fR to create empty
+disk label (see the \fBEMPTY DISK LABEL\fR section below).
.TP
.BR \-Y , " \-\-label\-nested " \fItype
Force editing of a nested disk label. The primary disk label has to exist already.
@@ -404,6 +407,19 @@ For backward compatibility the \fBId=\fR field has the same meaning.
.RE
.RE
+.SH "EMPTY DISK LABEL"
+.B sfdisk
+does not create partition table without partitions by default. The lines with
+partitions are expected in the script by default. The empty partition table has
+to be explicitly requested by "label: <name>" script header line without any
+partitions lines. For example:
+.RS
+.sp
+.B "echo 'label: gpt' | sfdisk /dev/sdb"
+.sp
+.RE
+creates empty GPT partition table. Note that the \fB\-\-append\fR disables this feature.
+
.SH "BACKING UP THE PARTITION TABLE"
It is recommended to save the layout of your devices.
.B sfdisk
diff --git a/disk-utils/sfdisk.c b/disk-utils/sfdisk.c
index 10307ad14f..2d6597434f 100644
--- a/disk-utils/sfdisk.c
+++ b/disk-utils/sfdisk.c
@@ -1766,8 +1766,25 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
}
} while (1);
+ /* create empty disk label if label, but no partition specified */
+ if (rc == SFDISK_DONE_EOF && created == 0
+ && fdisk_script_has_force_label(dp) == 1
+ && fdisk_table_get_nents(tb) == 0
+ && fdisk_script_get_header(dp, "label")) {
+
+ int xrc = fdisk_apply_script_headers(sf->cxt, dp);
+ created = !xrc;
+ if (xrc) {
+ fdisk_warnx(sf->cxt, _(
+ "Failed to apply script headers, "
+ "disk label not created."));
+ rc = SFDISK_DONE_ABORT;
+ }
+ }
+
if (!sf->quiet && rc != SFDISK_DONE_ABORT) {
fdisk_info(sf->cxt, _("\nNew situation:"));
+ list_disk_identifier(sf->cxt);
list_disklabel(sf->cxt);
}
diff --git a/libfdisk/src/libfdisk.h.in b/libfdisk/src/libfdisk.h.in
index 9154f5bebe..59cce190d7 100644
--- a/libfdisk/src/libfdisk.h.in
+++ b/libfdisk/src/libfdisk.h.in
@@ -642,6 +642,7 @@ const char *fdisk_script_get_header(struct fdisk_script *dp, const char *name);
int fdisk_script_set_header(struct fdisk_script *dp, const char *name, const char *data);
struct fdisk_table *fdisk_script_get_table(struct fdisk_script *dp);
int fdisk_script_get_nlines(struct fdisk_script *dp);
+int fdisk_script_has_force_label(struct fdisk_script *dp);
int fdisk_script_set_userdata(struct fdisk_script *dp, void *data);
void *fdisk_script_get_userdata(struct fdisk_script *dp);
diff --git a/libfdisk/src/libfdisk.sym b/libfdisk/src/libfdisk.sym
index 02cd7a80f9..d6d4ac5577 100644
--- a/libfdisk/src/libfdisk.sym
+++ b/libfdisk/src/libfdisk.sym
@@ -274,3 +274,8 @@ FDISK_2.29 {
fdisk_labelitem_is_number;
fdisk_gpt_set_npartitions;
} FDISK_2.28;
+
+
+FDISK_2.30 {
+ fdisk_script_has_force_label;
+} FDISK_2.29;
diff --git a/libfdisk/src/script.c b/libfdisk/src/script.c
index ae7e99a143..0d1f260ea1 100644
--- a/libfdisk/src/script.c
+++ b/libfdisk/src/script.c
@@ -36,7 +36,8 @@ struct fdisk_script {
size_t nlines;
struct fdisk_label *label;
- unsigned int json : 1; /* JSON output */
+ unsigned int json : 1, /* JSON output */
+ force_label : 1; /* label: <name> specified */
};
@@ -354,6 +355,22 @@ int fdisk_script_get_nlines(struct fdisk_script *dp)
}
/**
+ * fdisk_script_has_force_label:
+ * @dp: script
+ *
+ * Note that fdisk_script_set_header(dp, "label", name) does not modify
+ * force_label status. The label has to be specified by script.
+ *
+ * Returns: true if "label: <name>" has been parsed.
+ */
+int fdisk_script_has_force_label(struct fdisk_script *dp)
+{
+ assert(dp);
+ return dp->force_label;
+}
+
+
+/**
* fdisk_script_read_context:
* @dp: script
* @cxt: context
@@ -706,6 +723,7 @@ static int parse_line_header(struct fdisk_script *dp, char *s)
if (strcmp(name, "label") == 0) {
if (dp->cxt && !fdisk_get_label(dp->cxt, value))
goto done; /* unknown label name */
+ dp->force_label = 1;
} else if (strcmp(name, "unit") == 0) {
if (strcmp(value, "sectors") != 0)
goto done; /* only "sectors" supported */