]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: add API to control signatures wiping
authorKarel Zak <kzak@redhat.com>
Thu, 18 Feb 2016 11:42:06 +0000 (12:42 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 18 Feb 2016 11:58:12 +0000 (12:58 +0100)
Now libfdisk warns if another filesystem/RAID/PT signature is detected
on the device. It seems better and user-friendly to make it possible to
wipe the signatures when we write a new disk label to the device.

This patch adds to the library API

fdisk_enable_wipe()
fdisk_has_wipe()
fdisk_get_collision()

to control this new feature. The device modification is done by
libblkid (the same we use in some mkfs-like utils).

Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/docs/libfdisk-sections.txt
libfdisk/src/context.c
libfdisk/src/fdiskP.h
libfdisk/src/label.c
libfdisk/src/libfdisk.h.in
libfdisk/src/libfdisk.sym

index f69c6671c894540b9d12657c206daeef25b49c51..dd8df21efa1bc8963c8e7ce2da3e56cbd1ebda81 100644 (file)
@@ -293,7 +293,9 @@ fdisk_deassign_device
 fdisk_enable_bootbits_protection
 fdisk_enable_details
 fdisk_enable_listonly
+fdisk_enable_wipe
 fdisk_get_alignment_offset
+fdisk_get_collision
 fdisk_get_devfd
 fdisk_get_devname
 fdisk_get_first_lba
@@ -313,6 +315,7 @@ fdisk_get_unit
 fdisk_get_units_per_sector
 fdisk_has_label
 fdisk_has_protected_bootbits
+fdisk_has_wipe
 fdisk_is_details
 fdisk_is_labeltype
 fdisk_is_listonly
index 1f6118cd04dffbf435780845b54f2ca002f74363..73d72ecb825ca448a8af6c4657367d3b96a3f933 100644 (file)
@@ -334,6 +334,50 @@ int fdisk_enable_bootbits_protection(struct fdisk_context *cxt, int enable)
        return 0;
 }
 
+/**
+ * fdisk_enable_wipe
+ * @cxt: fdisk context
+ * @enable: 1 or 0
+ *
+ * The library removes all filesystem/RAID signatures before write PT. This is
+ * no-op if any collision has not been detected by fdisk_assign_device(). See
+ * fdisk_has_collision(). The default is not wipe a device.
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_enable_wipe(struct fdisk_context *cxt, int enable)
+{
+       if (!cxt)
+               return -EINVAL;
+       cxt->wipe_device = enable ? 1 : 0;
+       return 0;
+}
+
+/**
+ * fdisk_has_wipe
+ * @cxt: fdisk context
+ *
+ * Returns the current wipe setting. See fdisk_enable_wipe().
+ *
+ * Returns: 0 on success, < 0 on error.
+ */
+int fdisk_has_wipe(struct fdisk_context *cxt)
+{
+       return cxt && cxt->wipe_device;
+}
+
+
+/**
+ * fdisk_get_collision
+ * @cxt: fdisk context
+ *
+ * Returns: name of the filesystem or RAID detected on the device or NULL.
+ */
+const char *fdisk_get_collision(struct fdisk_context *cxt)
+{
+       return cxt->collision;
+}
+
 /**
  * fdisk_get_npartitions:
  * @cxt: context
@@ -427,6 +471,9 @@ static void reset_context(struct fdisk_context *cxt)
        free(cxt->dev_path);
        cxt->dev_path = NULL;
 
+       free(cxt->collision);
+       cxt->collision = NULL;
+
        cxt->dev_fd = -1;
        cxt->firstsector = NULL;
        cxt->firstsector_bufsz = 0;
@@ -445,18 +492,15 @@ static void reset_context(struct fdisk_context *cxt)
  *
  * Returns: 0 if nothing found, < 0 on error, 1 if found a signature
  */
-static int warn_wipe(struct fdisk_context *cxt)
+static int check_collisions(struct fdisk_context *cxt)
 {
 #ifdef HAVE_LIBBLKID
-       blkid_probe pr;
-#endif
        int rc = 0;
+       blkid_probe pr;
 
        assert(cxt);
+       assert(cxt->dev_fd >= 0);
 
-       if (fdisk_has_label(cxt) || cxt->dev_fd < 0)
-               return -EINVAL;
-#ifdef HAVE_LIBBLKID
        DBG(CXT, ul_debugobj(cxt, "wipe check: initialize libblkid prober"));
 
        pr = blkid_new_probe();
@@ -478,18 +522,48 @@ static int warn_wipe(struct fdisk_context *cxt)
 
                if (blkid_probe_lookup_value(pr, "TYPE", &name, 0) == 0 ||
                    blkid_probe_lookup_value(pr, "PTTYPE", &name, 0) == 0) {
-                       fdisk_warnx(cxt, _(
-                               "%s: device contains a valid '%s' signature; it is "
-                               "strongly recommended to wipe the device with "
-                               "wipefs(8) if this is unexpected, in order to "
-                               "avoid possible collisions"), cxt->dev_path, name);
-                       rc = 1;
+                       cxt->collision = strdup(name);
+                       if (!cxt->collision)
+                               rc = -ENOMEM;
                }
        }
 
        blkid_free_probe(pr);
-#endif
        return rc;
+#elif
+       return 0;
+#endif
+}
+
+int fdisk_wipe_collisions(struct fdisk_context *cxt)
+{
+#ifdef HAVE_LIBBLKID
+       blkid_probe pr;
+       int rc;
+
+       assert(cxt);
+       assert(cxt->dev_fd >= 0);
+
+       DBG(CXT, ul_debugobj(cxt, "wipe: initialize libblkid prober"));
+
+       pr = blkid_new_probe();
+       if (!pr)
+               return -ENOMEM;
+       rc = blkid_probe_set_device(pr, cxt->dev_fd, 0, 0);
+       if (rc)
+               return rc;
+
+       blkid_probe_enable_superblocks(pr, 1);
+       blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
+       blkid_probe_enable_partitions(pr, 1);
+       blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC);
+
+       while (blkid_do_probe(pr) == 0)
+               blkid_do_wipe(pr, FALSE);
+
+       blkid_free_probe(pr);
+#endif
+       return 0;
 }
 
 /**
@@ -564,8 +638,8 @@ int fdisk_assign_device(struct fdisk_context *cxt,
 
        /* warn about obsolete stuff on the device if we aren't in
         * list-only mode and there is not PT yet */
-       if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt))
-               warn_wipe(cxt);
+       if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt) && check_collisions(cxt) < 0)
+               goto fail;
 
        DBG(CXT, ul_debugobj(cxt, "initialized for %s [%s]",
                              fname, readonly ? "READ-ONLY" : "READ-WRITE"));
index 2961095c984d3e60de877348de9baf1625d8f616..494eda9893ddd3bda7324f1f03d358ac2e690bfa 100644 (file)
@@ -355,8 +355,11 @@ struct fdisk_context {
                     display_in_cyl_units : 1,  /* for obscure labels */
                     display_details : 1,       /* expert display mode */
                     protect_bootbits : 1,      /* don't zeroize fll irst sector */
+                    wipe_device : 1,           /* wipe device before write */
                     listonly : 1;              /* list partition, nothing else */
 
+       char *collision;                        /* name of already existing FS/PT */
+
        int sizeunit;                           /* SIZE fields, FDISK_SIZEUNIT_* */
 
        /* alignment */
@@ -386,6 +389,8 @@ struct fdisk_context {
        struct fdisk_script     *script;        /* what we want to follow */
 };
 
+int fdisk_wipe_collisions(struct fdisk_context *cxt);
+
 /* partition.c */
 int fdisk_partition_next_partno(struct fdisk_partition *pa,
                                       struct fdisk_context *cxt,
index bcb02ba3abb1664df753fcc33c79b989aed387d0..f2580cf030c2f7ea24ae03e07f79f9c2ac006796 100644 (file)
@@ -303,6 +303,12 @@ int fdisk_write_disklabel(struct fdisk_context *cxt)
                return -EINVAL;
        if (!cxt->label->op->write)
                return -ENOSYS;
+
+       if (cxt->collision && cxt->wipe_device) {
+               int rc = fdisk_wipe_collisions(cxt);
+               if (rc)
+                       return rc;
+       }
        return cxt->label->op->write(cxt);
 }
 
index f99dee8cdf70b55e3160b0ecc461c423096ddd75..7bcacd6da8b457fa094db31644ad82f26681c523 100644 (file)
@@ -190,6 +190,10 @@ int fdisk_is_details(struct fdisk_context *cxt);
 int fdisk_enable_listonly(struct fdisk_context *cxt, int enable);
 int fdisk_is_listonly(struct fdisk_context *cxt);
 
+int fdisk_enable_wipe(struct fdisk_context *cxt, int enable);
+int fdisk_has_wipe(struct fdisk_context *cxt);
+const char *fdisk_get_collision(struct fdisk_context *cxt);
+
 int fdisk_set_unit(struct fdisk_context *cxt, const char *str);
 const char *fdisk_get_unit(struct fdisk_context *cxt, int n);
 int fdisk_use_cylinders(struct fdisk_context *cxt);
index c4d0a2526b6b7c7e503cd4236608f6e069c5f77f..6a412bc20d94ab43a808275c17b39b2369030a91 100644 (file)
@@ -253,3 +253,9 @@ FDISK_2.27 {
        fdisk_get_disklabel_item;
        fdisk_script_enable_json;
 } FDISK_2.26;
+
+FDISK_2.28 {
+       fdisk_enable_wipe;
+       fdisk_get_collision;
+       fdisk_has_wipe;
+} FDISK_2.27;