From fd853e34e2dbfe51b00c9f69335b103f1c1fdab2 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 19 Sep 2024 20:31:16 +0200 Subject: misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- deadshred.c | 70 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 24 deletions(-) (limited to 'deadshred.c') diff --git a/deadshred.c b/deadshred.c index 28a64fe..b1f21f2 100644 --- a/deadshred.c +++ b/deadshred.c @@ -3,8 +3,8 @@ #include -USAGE("[-o offset] [-l length | -e postend] device [< random-source]"); -/* TODO add option (-b) to switch start direction */ +USAGE("[-b blocksize] [-o offset] [-l length | -e postend] [-r] device [< random-source]"); +/* TODO document (also in README and man pages) options -b and -r */ struct status status = STATUS_INIT; @@ -129,18 +129,14 @@ print_status(int done, struct status *s) static void * -status_print_loop(void *user) +status_print_loop(void *initial_status) { struct pollfd pfd = {.fd = status_print_pipe[0], .events = POLLIN}; ssize_t r; int terminate = 0; - struct status s = STATUS_INIT; + struct status s = *(struct status *)initial_status; size_t status_off; - (void) user; - - s.last_success = start_time; - unblock_sigs(); do { @@ -195,6 +191,7 @@ shredspan(int fd, struct span *span, const char *fname) struct timespec when = {0, 0}; int bad = span->bad > 0; int first_fail = 1; + int was_successful = 0; const char *random_data; off = (status.direction == FORWARDS ? span->start : span->end); @@ -212,6 +209,10 @@ shredspan(int fd, struct span *span, const char *fname) if (clock_gettime(clck, &status.now)) eprintf("clock_gettime %s:", clkcstr); + if (was_successful) { + was_successful = 0; + status.last_success = status.now; + } if (libsimple_cmptimespec(&status.now, &when) >= 0) { libsimple_sumtimespec(&when, &status.now, &status_print_interval); status_off = 0; @@ -234,7 +235,7 @@ shredspan(int fd, struct span *span, const char *fname) n = MIN((off_t)span->blocksize, span->end - off); } else { n = off--; - off &= ~(off_t)(span->blocksize - 1U); + off -= off % (off_t)span->blocksize; if (off < span->start) off = span->start; n -= off; @@ -288,7 +289,7 @@ shredspan(int fd, struct span *span, const char *fname) status.shredded += (off_t)r; used_random(r); wravg_update_write(r, &status); - status.last_success = status.now; + was_successful = 1; if (span->bad) { status.bad_bytes -= (off_t)r; span->bad -= (off_t)r; @@ -332,26 +333,35 @@ fail: int main(int argc, char *argv[]) { - off_t off = -1, len = -1, end = -1; + off_t off = -1, len = -1, end = -1, blk = -1; size_t i, j; - int fd; + int fd, reverse_direction = 0; pthread_t status_print_thread; + struct status initial_status; ARGBEGIN { - case 'o': - if (off >= 0) + case 'b': + if (blk >= 0) usage(); - off = unhumansize(ARG(), FLAG()); + blk = unhumansize(ARG(), FLAG()); + break; + case 'e': + if (len >= 0 || end >= 0) + usage(); + end = unhumansize(ARG(), FLAG()); break; case 'l': if (len >= 0 || end >= 0) usage(); len = unhumansize(ARG(), FLAG()); break; - case 'e': - if (len >= 0 || end >= 0) + case 'o': + if (off >= 0) usage(); - end = unhumansize(ARG(), FLAG()); + off = unhumansize(ARG(), FLAG()); + break; + case 'r': + reverse_direction = 1; break; default: usage(); @@ -360,11 +370,20 @@ main(int argc, char *argv[]) if (argc != 1) usage(); + /* TODO If in foreground, and /dev/tty can be opened, + * use /dev/tty — however if stdin is a tty, use + * stdin instead — to request configuration unless + * bypassed with new option (-Y). The prompt shall + * be identify the device and display it's size, + * also the section the wipe shall be displayed + * if -elo was used. The use shall be required + * to enter 'yes' in upper case. */ + fd = open(argv[0], O_WRONLY | O_DSYNC); if (fd < 0) eprintf("open %s O_WRONLY|O_DSYNC:", argv[0]); - init_random(STDIN_FILENO, ""); + init_random(STDIN_FILENO, "", blk); spans = emalloc(sizeof(*spans)); spans[0].start = 0; @@ -408,10 +427,8 @@ main(int argc, char *argv[]) setup_sighandler(); block_sigs(); - errno = pthread_create(&status_print_thread, NULL, &status_print_loop, NULL); - if (errno) - eprintf("pthread_create NULL:"); - + if (reverse_direction) + status.direction ^= 1; if (clock_gettime(clck, &start_time)) { clck = CLOCK_MONOTONIC; clkcstr = "CLOCK_MONOTONIC"; @@ -421,6 +438,11 @@ main(int argc, char *argv[]) wravg_init(&start_time, &status); status.last_success = start_time; + initial_status = status; + errno = pthread_create(&status_print_thread, NULL, &status_print_loop, &initial_status); + if (errno) + eprintf("pthread_create NULL:"); + while (nspans) { size_t old_nspans = nspans; for (i = 0; i < old_nspans && !exiting; i++) @@ -429,7 +451,6 @@ main(int argc, char *argv[]) memmove(&spans[0], &spans[i], (nspans -= i) * sizeof(*spans)); break; } - /* TODO bug: this is sometimes reached immediately on write failure */ for (i = 0, j = nspans, nspans -= old_nspans; i < nspans;) spans[i++] = spans[--j]; status.direction ^= 1; @@ -439,6 +460,7 @@ main(int argc, char *argv[]) close(fd); if (status_print_pipe[1] >= 0) close(status_print_pipe[1]); + destroy_random(); errno = pthread_join(status_print_thread, NULL); if (errno) -- cgit v1.2.3-70-g09d2