]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fdisk: add --wipe
authorKarel Zak <kzak@redhat.com>
Thu, 18 Feb 2016 11:50:11 +0000 (12:50 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 18 Feb 2016 11:58:12 +0000 (12:58 +0100)
This patch changes fdisk behavior and it wipes foreign signatures
from the device to avoid collisions. The wipe functionality is
automatically enabled in the interactive mode only (user is always
warned about it), otherwise it's possible to control all by --wipe
<auto|never|always>.

The program does not change behavior when executed in scripts (echo
<something> | fdisk), the option "--wipe=always" is required to enable
in this case.

Signed-off-by: Karel Zak <kzak@redhat.com>
disk-utils/fdisk-list.h
disk-utils/fdisk.8
disk-utils/fdisk.c

index c24c4ddcc0b9468f65623980a6fd3169efefdbe0..eddab92ec33faa6922ba19617fa8bbfcc88cc8fd 100644 (file)
@@ -15,4 +15,32 @@ extern void print_all_devices_freespace(struct fdisk_context *cxt);
 extern void list_available_columns(FILE *out);
 extern int *init_fields(struct fdisk_context *cxt, const char *str, size_t *n);
 
+
+/* used by fdisk and sfdisk */
+enum {
+       WIPEMODE_AUTO = 0,
+       WIPEMODE_NEVER = 1,
+       WIPEMODE_ALWAYS = 2
+};
+
+static inline int wipemode_from_string(const char *str)
+{
+       size_t i;
+       static const char *modes[] = {
+               [WIPEMODE_AUTO]   = "auto",
+               [WIPEMODE_NEVER]  = "never",
+               [WIPEMODE_ALWAYS] = "always"
+       };
+
+       if (!str || !*str)
+               return -EINVAL;
+
+       for (i = 0; i < ARRAY_SIZE(modes); i++) {
+               if (strcasecmp(str, modes[i]) == 0)
+                       return i;
+       }
+
+       return -EINVAL;
+}
+
 #endif /* UTIL_LINUX_FDISK_LIST_H */
index fb298220eda49c560dbffe6cf6b19f0e95d73877..f0c6def45de930fa54248106e34173cf9e55851c 100644 (file)
@@ -118,6 +118,16 @@ Specify the number of sectors per track of the disk.
 (Not the physical number, of course, but the number used for
 partition tables.) A reasonable value is 63.
 
+.TP
+\fB\-w\fR, \fB\-\-wipe\fR \fImode\fR
+Wipe filesystems, RAIDs and partition tables signatures from the device, in
+order to avoid possible collisions.  The \fImode\fR can be \fBauto\fR,
+\fBnever\fR or \fBalways\fR.  The default is \fBauto\fR, in this case signatures
+are wiped in the interactive mode only, in all cases detected signatures are
+reported by warning message before a new partition table is created. See also
+.BR wipefs (8)
+command.
+
 .TP
 \fB\-V\fR, \fB\-\-version\fR
 Display version information and exit.
index c924d26b6a91ffbb5d3176abc75b639990237221..0b229839ede8a299ba128c4029b2900fbde8cb0d 100644 (file)
@@ -734,6 +734,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
        fputs(_(" -u, --units[=<unit>]          display units: 'cylinders' or 'sectors' (default)\n"), out);
        fputs(_(" -s, --getsz                   display device size in 512-byte sectors [DEPRECATED]\n"), out);
        fputs(_("     --bytes                   print SIZE in bytes rather than in human readable format\n"), out);
+       fputs(_(" -w, --wipe <mode>             wipe signatures (auto, always or never)\n"), out);
 
        fputs(USAGE_SEPARATOR, out);
        fputs(_(" -C, --cylinders <number>      specify the number of cylinders\n"), out);
@@ -761,6 +762,7 @@ int main(int argc, char **argv)
 {
        int rc, i, c, act = ACT_FDISK;
        int colormode = UL_COLORMODE_UNDEF;
+       int wipemode = WIPEMODE_AUTO;
        struct fdisk_context *cxt;
        char *outarg = NULL;
        enum {
@@ -782,6 +784,7 @@ int main(int argc, char **argv)
                { "version",        no_argument,       NULL, 'V' },
                { "output",         no_argument,       NULL, 'o' },
                { "protect-boot",   no_argument,       NULL, 'B' },
+               { "wipe",           required_argument, NULL, 'w' },
                { NULL, 0, NULL, 0 }
        };
 
@@ -800,7 +803,7 @@ int main(int argc, char **argv)
 
        fdisk_set_ask(cxt, ask_callback, NULL);
 
-       while ((c = getopt_long(argc, argv, "b:Bc::C:hH:lL::o:sS:t:u::vV",
+       while ((c = getopt_long(argc, argv, "b:Bc::C:hH:lL::o:sS:t:u::vVw:",
                                longopts, NULL)) != -1) {
                switch (c) {
                case 'b':
@@ -891,6 +894,11 @@ int main(int argc, char **argv)
                case 'v': /* for backward compatibility only */
                        printf(UTIL_LINUX_VERSION);
                        return EXIT_SUCCESS;
+               case 'w':
+                       wipemode = wipemode_from_string(optarg);
+                       if (wipemode < 0)
+                               errx(EXIT_FAILURE, _("unsupported wipe mode"));
+                       break;
                case 'h':
                        usage(stdout);
                case OPT_BYTES:
@@ -957,6 +965,24 @@ int main(int argc, char **argv)
 
                fflush(stdout);
 
+               if (fdisk_get_collision(cxt)) {
+                       int dowipe = wipemode == WIPEMODE_ALWAYS ? 1 : 0;
+
+                       fdisk_warnx(cxt, _("%s: device already contains %s signature."),
+                               argv[optind], fdisk_get_collision(cxt));
+
+                       if (isatty(STDIN_FILENO) && wipemode == WIPEMODE_AUTO)
+                               dowipe = 1;     /* do it in interactive mode */
+
+                       fdisk_enable_wipe(cxt, dowipe);
+                       if (dowipe)
+                               fdisk_warnx(cxt, _(
+                                       "The signature will be removed by write command."));
+                       else
+                               fdisk_warnx(cxt, _(
+                                       "It is strongly recommended to wipe the device with "
+                                       "wipefs(8), in order to avoid possible collisions."));
+               }
                if (!fdisk_has_label(cxt)) {
                        fdisk_info(cxt, _("Device does not contain a recognized partition table."));
                        fdisk_create_disklabel(cxt, NULL);