diff options
author | Karel Zak | 2011-11-11 12:41:35 +0100 |
---|---|---|
committer | Karel Zak | 2011-11-11 12:41:35 +0100 |
commit | 2b89be6c802bdbdf6830dbd060c96e33f179b135 (patch) | |
tree | 1f9d9530f2ca7bb4f23a02c98eed40926dba58ea /libblkid/src/probe.c | |
parent | libblkid: don't call CDROM_GET_CAPABILITY for partitions (diff) | |
download | kernel-qcow2-util-linux-2b89be6c802bdbdf6830dbd060c96e33f179b135.tar.gz kernel-qcow2-util-linux-2b89be6c802bdbdf6830dbd060c96e33f179b135.tar.xz kernel-qcow2-util-linux-2b89be6c802bdbdf6830dbd060c96e33f179b135.zip |
libblkid: add blkid_do_wipe()
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libblkid/src/probe.c')
-rw-r--r-- | libblkid/src/probe.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index e801c7afd..af1111943 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -109,6 +109,7 @@ #endif #include "blkidP.h" +#include "writeall.h" /* chains */ extern const struct blkid_chaindrv superblocks_drv; @@ -917,6 +918,91 @@ int blkid_do_probe(blkid_probe pr) } /** + * 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 * |