]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
sfdisk: support empty label use-case
authorKarel Zak <kzak@redhat.com>
Wed, 30 Nov 2016 11:43:10 +0000 (12:43 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 30 Nov 2016 12:01:33 +0000 (13:01 +0100)
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>
disk-utils/fdisk-list.c
disk-utils/fdisk-list.h
disk-utils/sfdisk.8
disk-utils/sfdisk.c
libfdisk/src/libfdisk.h.in
libfdisk/src/libfdisk.sym
libfdisk/src/script.c

index e6b2033e77a7219abbb2b0318347de388494b030..c9560f42bf09585cf0773c24ee799f6a28101058 100644 (file)
@@ -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)
index eddab92ec33faa6922ba19617fa8bbfcc88cc8fd..4ed5c256bcb156c4e077116cf895c6eeec208535 100644 (file)
@@ -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);
 
index fcde8726b2bcae37403969250fc99224841740ad..efe4a86bf707980c9a2020e572fcbf969e2fcb94 100644 (file)
@@ -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
index 10307ad14f200b94ca78b1c9e66b49d2ecb9c164..2d6597434ff9184b3084fbba3336c1892dc54953 100644 (file)
@@ -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);
        }
 
index 9154f5bebe0f1bdfaf0a2f00924610cdcb3d42a2..59cce190d7805897f73565b71421cfe88daaef63 100644 (file)
@@ -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);
index 02cd7a80f9e57af1eba34f628a1b06c0024cdf97..d6d4ac55778f0712a46e732be096b8a263e2365f 100644 (file)
@@ -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;
index ae7e99a1437c61aecb0f48abc50286449209ae14..0d1f260ea11c59a3f8fc8d3594bbbfe48b86a5ea 100644 (file)
@@ -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 */
 };
 
 
@@ -353,6 +354,22 @@ int fdisk_script_get_nlines(struct fdisk_script *dp)
        return dp->nlines;
 }
 
+/**
+ * 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
@@ -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 */