xfs
[Top] [All Lists]

[PATCH] xfs_mkfs: wipe old signatures from the device

To: xfs@xxxxxxxxxxx
Subject: [PATCH] xfs_mkfs: wipe old signatures from the device
From: Lukas Czerner <lczerner@xxxxxxxxxx>
Date: Tue, 12 Feb 2013 12:06:55 +0100
Cc: sandeen@xxxxxxxxxx, kzak@xxxxxxxxxx, Lukas Czerner <lczerner@xxxxxxxxxx>
Delivered-to: xfs@xxxxxxxxxxx
We should wipe off all the signatures from the device prior the file
system creation. It is because because some file systems (btrfs) may
still have their signatures on the device which can be confusing for
userspace possibly resulting in the unmountable file system.

This patch adds a function which uses libblkid library to wipe all the
signatures from the device.

If user disables libblkid library or does not have it installed this new
feature will not be used. This case can be implemented separately.

Signed-off-by: Lukas Czerner <lczerner@xxxxxxxxxx>
---
 mkfs/xfs_mkfs.c |  134 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 97 insertions(+), 37 deletions(-)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index d636549..a889620 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -286,18 +286,73 @@ calc_stripe_factors(
 }
 
 #ifdef ENABLE_BLKID
+static int
+wipe_signatures(
+       char            *device,
+       int             dryrun)
+{
+       blkid_probe     pr = NULL;
+       int             ret = 0;
+       int             fd;
+
+       pr = blkid_new_probe_from_filename(device);
+       if (!pr)
+               goto out;
+
+       fd = open(device, O_RDWR|O_CLOEXEC);
+       if (fd < 0) {
+               ret = -1;
+               goto out;
+       }
+       ret = blkid_probe_set_device(pr, fd, 0, 0);
+       if (ret)
+               goto out;
+
+       /* No need to check return values we know that 'pr' is initialized */
+       blkid_probe_enable_partitions(pr, 1);
+       blkid_probe_enable_superblocks(pr, 1);
+       blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
+       blkid_probe_set_superblocks_flags(pr,
+                                       BLKID_SUBLKS_MAGIC | BLKID_SUBLKS_TYPE);
+
+       while (1) {
+               ret = blkid_do_probe(pr);
+               if (ret != 0)
+                       break;
+
+               /* Wipe off the signature */
+               ret = blkid_do_wipe(pr, dryrun);
+               if (ret)
+                       break;
+       }
+       close(fd);
+
+out:
+       if (pr)
+               blkid_free_probe(pr);
+       if (ret < 0)
+               fprintf(stderr,
+                       _("%s: Cannot wipe off existing signatures\n"), 
progname);
+       return (ret < 0 ? ret : 0);
+}
+
 /*
  * Check for existing filesystem or partition table on device.
  * Returns:
  *      1 for existing fs or partition
  *      0 for nothing found
  *     -1 for internal error
+ * If wipe is set, we'll attempt to wipe of all the signatures from
+ * the device. In this case we never return 1 (existing fs or partition).
  */
 static int
 check_overwrite(
-       char            *device)
+       char            *device,
+       int             wipe,
+       int             dryrun)
 {
        const char      *type;
+       const char      *name;
        blkid_probe     pr = NULL;
        int             ret;
        int             fd;
@@ -325,40 +380,43 @@ check_overwrite(
        if (!pr)
                goto out;
 
-       ret = blkid_probe_enable_partitions(pr, 1);
-       if (ret < 0)
-               goto out;
+       /* No need to check return values we know that 'pr' is initialized */
+       blkid_probe_enable_partitions(pr, 1);
+       blkid_probe_enable_superblocks(pr, 1);
+       blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
+       blkid_probe_set_superblocks_flags(pr,
+                                       BLKID_SUBLKS_MAGIC | BLKID_SUBLKS_TYPE);
 
-       ret = blkid_do_fullprobe(pr);
-       if (ret < 0)
-               goto out;
+       ret = 0;
+       while (1) {
+               int retval = 0;
 
-       /*
-        * Blkid returns 1 for nothing found and 0 when it finds a signature,
-        * but we want the exact opposite, so reverse the return value here.
-        *
-        * In addition print some useful diagnostics about what actually is
-        * on the device.
-        */
-       if (ret) {
-               ret = 0;
-               goto out;
-       }
+               retval = blkid_do_probe(pr);
+               if (retval != 0) {
+                       ret = retval;
+                       break;
+               }
 
-       if (!blkid_probe_lookup_value(pr, "TYPE", &type, NULL)) {
-               fprintf(stderr,
-                       _("%s: %s appears to contain an existing "
-                       "filesystem (%s).\n"), progname, device, type);
-       } else if (!blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL)) {
-               fprintf(stderr,
-                       _("%s: %s appears to contain a partition "
-                       "table (%s).\n"), progname, device, type);
-       } else {
-               fprintf(stderr,
-                       _("%s: %s appears to contain something weird "
-                       "according to blkid\n"), progname, device);
+               if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) == 0)
+                       name = "filesystem";
+
+               else if (blkid_probe_lookup_value(pr, "PTTYPE",
+                                                   &type, NULL) == 0)
+                       name = "partition table";
+               else
+                       continue;
+
+               if (wipe)
+                       fprintf(stderr, _("%s: Wiping off %s signature.\n"),
+                               progname, type);
+               else {
+                       fprintf(stderr,
+                               _("%s: %s appears to contain an existing "
+                               "%s (%s).\n"), progname, device, name, type);
+                       ret = 1;
+                       continue;
+               }
        }
-       ret = 1;
 
 out:
        if (pr)
@@ -367,6 +425,8 @@ out:
                fprintf(stderr,
                        _("%s: probe of %s failed, cannot detect "
                          "existing filesystem.\n"), progname, device);
+       if (ret == 1 && wipe)
+               ret = wipe_signatures(device, dryrun);
        return ret;
 }
 
@@ -464,7 +524,8 @@ static void get_topology(
 #else /* ENABLE_BLKID */
 static int
 check_overwrite(
-       char            *device)
+       char            *device,
+       int             wipe)
 {
        char            *type;
 
@@ -1939,16 +2000,15 @@ _("block size %d cannot be smaller than logical sector 
size %d\n"),
        xi.rtsize &= sector_mask;
        xi.logBBsize &= (__uint64_t)-1 << (MAX(lsectorlog, 10) - BBSHIFT);
 
-       if (!force_overwrite) {
-               if (check_overwrite(dfile) ||
-                   check_overwrite(logfile) ||
-                   check_overwrite(xi.rtname)) {
+       if (check_overwrite(dfile, force_overwrite, Nflag) ||
+           check_overwrite(logfile, force_overwrite, Nflag) ||
+           check_overwrite(xi.rtname, force_overwrite, Nflag))
+               if (force_overwrite) {
                        fprintf(stderr,
                        _("%s: Use the -f option to force overwrite.\n"),
                                progname);
                        exit(1);
                }
-       }
 
        if (discard) {
                discard_blocks(xi.ddev, xi.dsize);
-- 
1.7.7.6

<Prev in Thread] Current Thread [Next in Thread>