aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--deadshred.c73
2 files changed, 60 insertions, 17 deletions
diff --git a/TODO b/TODO
index ff4552a..9a3b805 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
Add `-n iterations`
+Add offset..length option
Add shred map for continuing later (print to stdout on SIGTERM)
Enhance progress printout with:
- bad sections (count, bytes)
- shredded bytes per seconds
+ shredded bytes per seconds (dont't forget machine and process suspension)
diff --git a/deadshred.c b/deadshred.c
index 84a5184..3321a4e 100644
--- a/deadshred.c
+++ b/deadshred.c
@@ -10,6 +10,7 @@ USAGE("device [< random-source]");
struct span {
off_t start;
off_t end;
+ off_t bad;
size_t blocksize;
};
@@ -28,6 +29,10 @@ static int use_stdin;
static char total_size_1000[256];
static char total_size_1024[256];
+static uintmax_t bad_writes = 0;
+static uintmax_t bad_sections = 0;
+static off_t bad_bytes = 0;
+
static off_t
filesize(int fd, const char *fname)
@@ -99,8 +104,11 @@ add_span(off_t off, off_t max_end, size_t blocksize)
spans[nspans].start = off;
spans[nspans].end = end;
+ spans[nspans].bad = end - off;
spans[nspans].blocksize = (size_t)blocksize;
nspans++;
+
+ return end - off;
}
@@ -136,12 +144,12 @@ humansize1024(off_t s, char *buf)
s /= 1024;
unit++;
}
- sprintf(buf, "%lu.%u %ciB", (unsigned long int)s / 1024U, (unsigned long int)((s * 10 % 10240) / 1024U), units[unit]);
+ sprintf(buf, "%lu.%lu %ciB", (unsigned long int)s / 1024UL, (unsigned long int)(s * 10 % 10240) / 1024UL, units[unit]);
return buf;
}
-static int
+static void
print_progress(int done)
{
static char buf1[1024] = {0};
@@ -150,16 +158,23 @@ print_progress(int done)
char subbuf1[256];
char subbuf2[256];
+ char subbuf3[256];
+ char subbuf4[256];
sprintf(i == 0 ? buf1 : buf2,
- "%ji bytes (%s, %s, %.2lf %%) of %s (%s) shredded\033[K\n%s",
+ "%ji bytes (%s, %s, %.2lf %%) of %s (%s) shredded\033[K\n"
+ "failed writes: %ju; bad sections: %ju (%s, %s)\033[K\n%s",
(intmax_t)shredded,
humansize1000(shredded, subbuf1),
humansize1024(shredded, subbuf2),
- 100. * (double)shredded / (double)total_size,
+ 100 * (double)shredded / (double)total_size,
total_size_1000,
total_size_1024,
- done ? "" : "\033[A");
+ bad_writes,
+ bad_sections,
+ humansize1000(bad_bytes, subbuf3),
+ humansize1024(bad_bytes, subbuf4),
+ done ? "" : "\033[A\033[A");
if (strcmp(buf1, buf2)) {
fprintf(stderr, "%s", i == 0 ? buf1 : buf2);
@@ -171,15 +186,28 @@ print_progress(int done)
static void
-shredspan(int fd, const struct span *span, const char *fname)
+shredspan(int fd, struct span *span, const char *fname)
{
- off_t off;
+ off_t off, n;
ssize_t r;
- int update_progress_delay = 0;
+ clockid_t clck = CLOCK_MONOTONIC_COARSE;
+ const char *clkcstr = "CLOCK_MONOTONIC_COARSE";
+ struct timespec now, when = {0, 0};
+ int bad = span->bad > 0;
+
+ if (clock_gettime(clck, &now)) {
+ clck = CLOCK_MONOTONIC;
+ clkcstr = "CLOCK_MONOTONIC";
+ }
for (off = span->start; off < span->end;) {
- if (!update_progress_delay--) {
- update_progress_delay = 1000; /* TOOD use half a second instead */
+ if (clock_gettime(clck, &now))
+ eprintf("clock_gettime %s:", clkcstr);
+ if (now.tv_sec > when.tv_sec || (now.tv_sec == when.tv_sec && now.tv_nsec >= when.tv_nsec)) {
+ when = now;
+ when.tv_nsec += 500000000L;
+ when.tv_sec += when.tv_nsec / 1000000000L;
+ when.tv_nsec = when.tv_nsec % 1000000000L;
print_progress(0);
}
if (lseek(fd, off, SEEK_SET) < 0)
@@ -187,23 +215,37 @@ shredspan(int fd, const struct span *span, const char *fname)
ensure_random(span->blocksize);
r = write(fd, &reservoir[reservoir_off], (size_t)MIN((off_t)span->blocksize, span->end - off));
if (r < 0) {
- if (errno != EINTR)
- off = add_span(off, span->end, span->blocksize == 1U ? 1U : span->blocksize);
- update_progress_delay = 0;
+ if (errno != EINTR) {
+ off += n = add_span(off, span->end, span->blocksize == 1U ? 1U : span->blocksize);
+ if (!span->bad)
+ bad_bytes += n;
+ if (bad)
+ bad = 0;
+ else
+ bad_sections += 1U;
+ }
+ when.tv_sec = 0;
+ when.tv_nsec = 0;
+ bad_writes += 1U;
continue;
}
off += (off_t)r;
shredded += (off_t)r;
reservoir_off += (size_t)r;
+ if (span->bad) {
+ bad_bytes -= (off_t)r;
+ span->bad -= (off_t)r;
+ }
}
+
+ if (bad && !span->bad)
+ bad_sections -= 1U;
}
int
main(int argc, char *argv[])
{
- char buf1[256];
- char buf2[256];
size_t i;
int fd;
@@ -227,6 +269,7 @@ main(int argc, char *argv[])
spans = emalloc(sizeof(*spans));
spans[0].start = 0;
spans[0].end = total_size = filesize(fd, argv[0]);
+ spans[0].bad = 0;
spans[0].blocksize = 8192U;
nspans = 1U;
spans_size = 1U;