From: Mike Frysinger Date: Wed, 26 Dec 2012 19:09:37 +0000 (-0500) Subject: faster dd helper for erasing drivers X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=d777d1fb803a4adf084869a526eda1e6f282abc0;p=home.git faster dd helper for erasing drivers --- diff --git a/ddnuke.c b/ddnuke.c new file mode 100644 index 0000000..3d01d36 --- /dev/null +++ b/ddnuke.c @@ -0,0 +1,91 @@ +/* + * released into the public domain + * written by Mike Frysinger + */ + +#define _FILE_OFFSET_BITS 64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char zero[1024 * 1024]; + +#define errp(msg, args...) \ + do { \ + printf("%s: " msg ": %m\n", argv[0], ## args); \ + return 1; \ + } while (0) + +static unsigned long long mbps(struct timespec *stime, struct timespec *etime, off_t len) +{ + uint64_t dtime; + clock_gettime(CLOCK_MONOTONIC, etime); + dtime = ((etime->tv_sec - stime->tv_sec) * 1000 * 1000 * 1000) + + (etime->tv_nsec - stime->tv_nsec); + *stime = *etime; + return 1000 * len / dtime; +} + +int main(int argc, char *argv[]) +{ + off_t offset = 0; + const char *file; + + setlocale(LC_NUMERIC, "en_US"); + + switch (argc) { + case 3: + offset = atoll(argv[2]); + case 2: + file = argv[1]; + break; + default: + puts("Usage: ddnuke [offset in bytes]"); + return 1; + } + + int fd = open(file, O_WRONLY); + if (fd == -1) + errp("open(%s) failed", file); + + if (lseek(fd, offset, SEEK_SET) != offset) + errp("lseek(%"PRIu64"u) failed", offset); + + unsigned long long speed = 0; + struct timespec stime, etime, itime; + clock_gettime(CLOCK_MONOTONIC, &stime); + itime = stime; + + off_t pos = 0, last_pos = 0; + ssize_t ret; + int fsync_pos = 0; + while (1) { + ret = write(fd, zero, sizeof(zero)); + pos += ret; + if (ret != sizeof(zero)) { + printf("\ngot back %zi (wanted %zu)\n%'llu MB/s over entire run\n", + ret, sizeof(zero), mbps(&itime, &etime, pos)); + return 0; + } + + printf("%'llu bytes (%'llu MB/s)%20s\r", (unsigned long long)pos, speed, ""); + + if ((++fsync_pos % 16) == 0) { + speed = mbps(&stime, &etime, pos - last_pos); + last_pos = pos; + fflush(stdout); + fsync(fd); + } + } + + return 0; +}