]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: add blkid_do_wipe()
authorKarel Zak <kzak@redhat.com>
Fri, 11 Nov 2011 11:41:35 +0000 (12:41 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 11 Nov 2011 11:41:35 +0000 (12:41 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/src/blkid.h.in
libblkid/src/blkid.sym
libblkid/src/probe.c

index a74c810e32f957b8da257afd4667a78b29410570..2d7d68959d42adf1f783893173bb86df4dbdf98a 100644 (file)
@@ -319,6 +319,8 @@ extern int blkid_probe_lookup_value(blkid_probe pr, const char *name,
                         const char **data, size_t *len);
 extern int blkid_probe_has_value(blkid_probe pr, const char *name);
 
+extern int blkid_do_wipe(blkid_probe pr, int dryrun);
+
 /*
  * Deprecated functions/macros
  */
index fda27ea2b3721ba24d3cf10776309cc9ca536555..697f690244a97058ebc18130d8bdf1a1c2afdfe3 100644 (file)
@@ -140,3 +140,11 @@ global:
        blkid_superblocks_get_name;
 } BLKID_2.18;
 
+/*
+ * symbols since util-linux 2.21
+ */
+BLKID_2.21 {
+global:
+       blkid_do_wipe;
+} BLKID_2.20;
+
index e801c7afdf4739950acabba18f420e1fbebcfd4c..af111194357132be46e0ad64e6d5ac68062bd9e3 100644 (file)
 #endif
 
 #include "blkidP.h"
+#include "writeall.h"
 
 /* chains */
 extern const struct blkid_chaindrv superblocks_drv;
@@ -916,6 +917,91 @@ int blkid_do_probe(blkid_probe pr)
        return rc;
 }
 
+/**
+ * blkid_do_wipe:
+ * @pr: prober
+ * @dryrun: if TRUE then don't touch the device.
+ *
+ * This function erases the current signature detected by @pr. The @pr has to
+ * be open in O_RDWR mode and BLKID_SUBLKS_MAGIC flag has to be enabled.
+ *
+ * After successful signature removing the @pr prober will be moved one step
+ * back and the next blkid_do_probe() call will again call previously called
+ * probing function.
+ *
+ *  <example>
+ *  <title>wipe all filesystems or raids from the device</title>
+ *   <programlisting>
+ *      fd = open(devname, O_RDWR);
+ *      blkid_probe_set_device(pr, fd, 0, 0);
+ *
+ *      blkid_probe_enable_superblocks(pr, 1);
+ *      blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC);
+ *
+ *     while (blkid_do_probe(pr) == 0)
+ *             blkid_do_wipe(pr, FALSE);
+ *  </programlisting>
+ * </example>
+ *
+ * Returns: 0 on success, 1 when probing is done and -1 in case of error.
+ */
+int blkid_do_wipe(blkid_probe pr, int dryrun)
+{
+       const char *off;
+       size_t len = 0;
+       loff_t offset, l;
+       char buf[BUFSIZ];
+       int fd;
+       struct blkid_chain *chn;
+
+       if (!pr)
+               return -1;
+
+       chn = pr->cur_chain;
+       if (!chn)
+               return -1;
+
+       if (blkid_probe_lookup_value(pr, "SBMAGIC_OFFSET", &off, NULL) ||
+           blkid_probe_lookup_value(pr, "SBMAGIC", NULL, &len) ||
+           len == 0 || off == NULL)
+               return 0;
+
+       offset = strtoll(off, NULL, 10);
+       fd = blkid_probe_get_fd(pr);
+       if (fd < 0)
+               return -1;
+
+       if (len > sizeof(buf))
+               len = sizeof(buf);
+
+       DBG(DEBUG_LOWPROBE, printf(
+           "wiping [offset=0x%jx, len=%zd, chain=%s, idx=%d, dryrun=%s]\n",
+           offset, len, chn->driver->name, chn->idx, dryrun ? "yes" : "not"));
+
+       l = lseek(fd, offset, SEEK_SET);
+       if (l == (off_t) -1)
+               return -1;
+
+       memset(buf, 0, len);
+
+       if (!dryrun && len) {
+               if (write_all(fd, buf, len))
+                       return -1;
+               fsync(fd);
+
+               blkid_probe_reset_buffer(pr);
+
+               if (chn->idx >= 0) {
+                       chn->idx--;
+                       DBG(DEBUG_LOWPROBE,
+                               printf("wipe: moving %s chain index to %d\n",
+                               chn->driver->name,
+                               chn->idx));
+               }
+       }
+       return 0;
+}
+
 /**
  * blkid_do_safeprobe:
  * @pr: prober