]> git.wh0rd.org - home.git/commitdiff
faster dd helper for erasing drivers
authorMike Frysinger <vapier@gentoo.org>
Wed, 26 Dec 2012 19:09:37 +0000 (14:09 -0500)
committerMike Frysinger <vapier@gentoo.org>
Wed, 26 Dec 2012 19:10:28 +0000 (14:10 -0500)
ddnuke.c [new file with mode: 0644]

diff --git a/ddnuke.c b/ddnuke.c
new file mode 100644 (file)
index 0000000..3d01d36
--- /dev/null
+++ b/ddnuke.c
@@ -0,0 +1,91 @@
+/*
+ * released into the public domain
+ * written by Mike Frysinger <vapier>
+ */
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+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 <dev> [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;
+}