]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
sfdisk: add --wipe-partitions=auto|never|default
authorKarel Zak <kzak@redhat.com>
Wed, 4 May 2016 10:43:35 +0000 (12:43 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 4 May 2016 10:47:17 +0000 (12:47 +0200)
The option allows to remove filesystes/RAIDs from newly created
partitions before the partition table is updated (and partition
device created).

The default is "auto" in this case wipe is enabled in interactive mode
only and user's confirmation (yes/no dialog) is required. Note that
keep filesystem signature on partition is pretty valid use-case, so we
don't erase anything by default.

Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/cfdisk.c
disk-utils/sfdisk.8
disk-utils/sfdisk.c

index 3908e313672dca36d9989cc528f94691e5763ab9..b7014e330eae974b2f75943b075c43c3ff6c2aea 100644 (file)
@@ -180,7 +180,7 @@ static struct cfdisk_menuitem main_menuitems[] = {
        { 'b', N_("Bootable"), N_("Toggle bootable flag of the current partition") },
        { 'd', N_("Delete"), N_("Delete the current partition") },
        { 'n', N_("New"), N_("Create new partition from free space") },
-       { 'q', N_("Quit"), N_("Quit program without writing partition table") },
+       { 'q', N_("Quit"), N_("Quit program without writing changes") },
        { 't', N_("Type"), N_("Change the partition type") },
        { 'h', N_("Help"), N_("Print help screen") },
        { 's', N_("Sort"), N_("Fix partitions order") },
@@ -1309,39 +1309,19 @@ static void extra_prepare_data(struct cfdisk *cf)
                free(data);
        }
 
-#ifdef HAVE_LIBBLKID
-       if (fdisk_partition_has_start(pa) && fdisk_partition_has_size(pa)) {
-               int fd;
-               uintmax_t start, size;
-               blkid_probe pr = blkid_new_probe();
-
-               if (!pr)
-                       goto done;
-
-               DBG(UI, ul_debug("blkid prober: %p", pr));
-
-               start = fdisk_partition_get_start(pa) * fdisk_get_sector_size(cf->cxt);
-               size = fdisk_partition_get_size(pa) * fdisk_get_sector_size(cf->cxt);
-               fd = fdisk_get_devfd(cf->cxt);
-
-               if (blkid_probe_set_device(pr, fd, start, size) == 0 &&
-                   blkid_do_fullprobe(pr) == 0) {
-                       const char *bdata = NULL;
+       if (!fdisk_partition_to_string(pa, cf->cxt, FDISK_FIELD_FSUUID, &data) && data) {
+               extra_insert_pair(l, _("Filesystem UUID:"), data);
+               free(data);
+       }
 
-                       if (!blkid_probe_lookup_value(pr, "TYPE", &bdata, NULL))
-                               extra_insert_pair(l, _("Filesystem:"), bdata);
-                       if (!blkid_probe_lookup_value(pr, "LABEL", &bdata, NULL)) {
-                               extra_insert_pair(l, _("Filesystem label:"), bdata);
-                               devlabel = xstrdup(bdata);
-                       }
-                       if (!blkid_probe_lookup_value(pr, "UUID", &bdata, NULL)) {
-                               extra_insert_pair(l, _("Filesystem UUID:"), bdata);
-                               devuuid = xstrdup(bdata);
-                       }
-               }
-               blkid_free_probe(pr);
+       if (!fdisk_partition_to_string(pa, cf->cxt, FDISK_FIELD_FSLABEL, &data) && data) {
+               extra_insert_pair(l, _("Filesystem LABEL:"), data);
+               free(data);
+       }
+       if (!fdisk_partition_to_string(pa, cf->cxt, FDISK_FIELD_FSTYPE, &data) && data) {
+               extra_insert_pair(l, _("Filesystem:"), data);
+               free(data);
        }
-#endif /* HAVE_LIBBLKID */
 
 #ifdef HAVE_LIBMOUNT
        if (devuuid || devlabel) {
@@ -1352,7 +1332,6 @@ static void extra_prepare_data(struct cfdisk *cf)
                }
        }
 #endif /* HAVE_LIBMOUNT */
-done:
        free(devlabel);
        free(devuuid);
 }
index 277b84373f99b835192f7c36171920c6148f372f..79424c5260b67b54dd6864ecb5ccc01541775c2d 100644 (file)
@@ -222,6 +222,18 @@ before a new partition table is created.  See also
 .BR wipefs (8)
 command.
 
+.TP
+.BR -W , " \-\-wipe-partitions "\fIwhen
+Wipe filesystem, RAID and partition-table signatures from a newly created
+partitions, in order to avoid possible collisions.  The argument \fIwhen\fR can
+be \fBauto\fR, \fBnever\fR or \fBalways\fR.  When this option is not given, the
+default is \fBauto\fR, in which case signatures are wiped only when in
+interactive mode and after confirmation by user.  In all cases detected
+signatures are reported by warning messages after a new partition is created.
+See also
+.BR wipefs (8)
+command.
+
 .TP
 .BR \-v , " \-\-version"
 Display version information and exit.
index 15fa99c47d699f69d77508a7d24ad63d5565ead1..009803e6c65bccb65f108eb904a1518dd22d743f 100644 (file)
@@ -89,7 +89,8 @@ enum {
 struct sfdisk {
        int             act;            /* ACT_* */
        int             partno;         /* -N <partno>, default -1 */
-       int             wipemode;       /* remove foreign signatures */
+       int             wipemode;       /* remove foreign signatures from disk */
+       int             pwipemode;      /* remove foreign signatures from partitions */
        const char      *label;         /* --label <label> */
        const char      *label_nested;  /* --label-nested <label> */
        const char      *backup_file;   /* -O <path> */
@@ -1437,7 +1438,39 @@ static int ignore_partition(struct fdisk_partition *pa)
        return 0;
 }
 
+static int wipe_partition(struct sfdisk *sf, size_t partno)
+{
+       int rc, yes = 0;
+       char *fstype = NULL;;
+       struct fdisk_partition *tmp = NULL;
+
+       DBG(MISC, ul_debug("checking for signature"));
+
+       rc = fdisk_get_partition(sf->cxt, partno, &tmp);
+       if (rc)
+               goto done;
+
+       rc = fdisk_partition_to_string(tmp, sf->cxt, FDISK_FIELD_FSTYPE, &fstype);
+       if (rc || fstype == NULL)
+               goto done;
 
+       fdisk_warnx(sf->cxt, _("Partition #%zu contains a %s signature."), partno + 1, fstype);
+
+       if (sf->pwipemode == WIPEMODE_AUTO && isatty(STDIN_FILENO))
+               fdisk_ask_yesno(sf->cxt, _("Do you want to remove the signature?"), &yes);
+       else if (sf->pwipemode == WIPEMODE_ALWAYS)
+               yes = 1;
+
+       if (yes) {
+               fdisk_info(sf->cxt, _("The signature will be removed by a write command."));
+               rc = fdisk_wipe_partition(sf->cxt, partno, TRUE);
+       }
+done:
+       fdisk_unref_partition(tmp);
+       free(fstype);
+       DBG(MISC, ul_debug("partition wipe check end [rc=%d]", rc));
+       return rc;
+}
 
 /*
  * sfdisk <device> [[-N] <partno>]
@@ -1446,7 +1479,7 @@ static int ignore_partition(struct fdisk_partition *pa)
  */
 static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
 {
-       int rc = 0, partno = sf->partno, created = 0;
+       int rc = 0, partno = sf->partno, created = 0, unused = 0;
        struct fdisk_script *dp;
        struct fdisk_table *tb = NULL;
        const char *devname = NULL, *label;
@@ -1493,9 +1526,11 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
                                             "partitions"),
                                        devname, partno + 1, n);
 
-               if (!fdisk_is_partition_used(sf->cxt, partno))
+               if (!fdisk_is_partition_used(sf->cxt, partno)) {
                        fdisk_warnx(sf->cxt, _("warning: %s: partition %d is not defined yet"),
                                        devname, partno + 1);
+                       unused = 1;
+               }
                created = 1;
                next_partno = partno;
 
@@ -1669,10 +1704,23 @@ static int command_fdisk(struct sfdisk *sf, int argc, char **argv)
                                if (rc) {
                                        errno = -rc;
                                        fdisk_warn(sf->cxt, _("Failed to add partition"));
+
                                }
                        }
 
-                       if (!rc) {              /* success, print reult */
+                       /* wipe partition on success
+                        *
+                        * Note that unused=1 means -N <partno> for unused,
+                        * otherwise we wipe only newly created partitions.
+                        */
+                       if (rc == 0 && (unused || partno < 0)) {
+                               rc = wipe_partition(sf, unused ? (size_t) partno : cur_partno);
+                               if (rc)
+                                       errno = -rc;
+                       }
+
+                       if (!rc) {
+                               /* success print result */
                                if (sf->interactive)
                                        sfdisk_print_partition(sf, cur_partno);
                                next_partno = cur_partno + 1;
@@ -1768,6 +1816,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
        fputs(_(" -o, --output <list>       output columns\n"), out);
        fputs(_(" -q, --quiet               suppress extra info messages\n"), out);
        fputs(_(" -w, --wipe <mode>         wipe signatures (auto, always or never)\n"), out);
+       fputs(_(" -W, --wipe-partitons <mode>  wipe signatures from new partitions (auto, always or never)\n"), out);
        fputs(_(" -X, --label <name>        specify label type (dos, gpt, ...)\n"), out);
        fputs(_(" -Y, --label-nested <name> specify nested label type (dos, bsd)\n"), out);
        fputs(USAGE_SEPARATOR, out);
@@ -1793,6 +1842,7 @@ int main(int argc, char *argv[])
        struct sfdisk _sf = {
                .partno = -1,
                .wipemode = WIPEMODE_AUTO,
+               .pwipemode = WIPEMODE_AUTO,
                .interactive = isatty(STDIN_FILENO) ? 1 : 0,
        }, *sf = &_sf;
 
@@ -1840,6 +1890,7 @@ int main(int argc, char *argv[])
                { "verify",  no_argument,       NULL, 'V' },
                { "version", no_argument,       NULL, 'v' },
                { "wipe",    required_argument, NULL, 'w' },
+               { "wipe-partitions",    required_argument, NULL, 'W' },
 
                { "part-uuid",  no_argument,    NULL, OPT_PARTUUID },
                { "part-label", no_argument,    NULL, OPT_PARTLABEL },
@@ -1861,7 +1912,7 @@ int main(int argc, char *argv[])
        textdomain(PACKAGE);
        atexit(close_stdout);
 
-       while ((c = getopt_long(argc, argv, "aAbcdfFghJlLo:O:nN:qrsTu:vVX:Y:w:",
+       while ((c = getopt_long(argc, argv, "aAbcdfFghJlLo:O:nN:qrsTu:vVX:Y:w:W:",
                                        longopts, &longidx)) != -1) {
                switch(c) {
                case 'A':
@@ -1949,6 +2000,11 @@ int main(int argc, char *argv[])
                        if (sf->wipemode < 0)
                                errx(EXIT_FAILURE, _("unsupported wipe mode"));
                        break;
+               case 'W':
+                       sf->pwipemode = wipemode_from_string(optarg);
+                       if (sf->pwipemode < 0)
+                               errx(EXIT_FAILURE, _("unsupported wipe mode"));
+                       break;
                case 'X':
                        sf->label = optarg;
                        break;