bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [patch #6797] shred option to use internal RNG


From: Pádraig Brady
Subject: Re: [patch #6797] shred option to use internal RNG
Date: Mon, 6 Apr 2009 10:10:28 +0100
User-agent: Thunderbird 2.0.0.6 (X11/20071008)

Pádraig Brady wrote:
> So in summary I would do:
> 
> 1. by default always use internal PRNG seeded with getpid()
> 2. if --random-source specified read all random data from there
> 
> Note 2 will allow one to specify /dev/zero if desired.
> We could seed our PRNG with /dev/urandom if available, but
> that complication is not necessary I think for this problem.

Simple patch attached to do as above.
Note I've left `sort -R` and `shuf` reading /dev/urandom as before.

This shows the speedup on my system with default options:

$ shred -v -n3 t
shred: t: pass 1/3 (random)...
shred: t: pass 1/3 (random)...8.3MiB/1000MiB 0%
shred: t: pass 1/3 (random)...17MiB/1000MiB 1%
shred: t: pass 1/3 (random)...32MiB/1000MiB 3%
...

$ time ./shred -v t
./shred: t: pass 1/3 (random)...
./shred: t: pass 1/3 (random)...116MiB/1000MiB 11%
./shred: t: pass 1/3 (random)...216MiB/1000MiB 21%
./shred: t: pass 1/3 (random)...340MiB/1000MiB 34%
...

cheers,
Pádraig.
>From 005277ea7c645ae2bc1d0e88b1681b55c44348af Mon Sep 17 00:00:00 2001
From: =?utf-8?q?P=C3=A1draig=20Brady?= <address@hidden>
Date: Mon, 6 Apr 2009 08:42:15 +0100
Subject: [PATCH] shred: speed up random passes by not using /dev/urandom

Suggestion from Steven Schveighoffer at:
http://savannah.gnu.org/patch/?6797
* gl/lib/randread.c: Don't default to using /dev/urandom
* gl/lib/randread.h: Expose DEFAULT_RANDOM_FILE define
* src/shred.c: Use internal PRNG by default
* src/shuf.c: Explicitly choose DEFAULT_RANDOM_FILE
* src/sort.c: ditto
---
 NEWS              |    7 +++++++
 THANKS            |    1 +
 gl/lib/randread.c |   24 +++++++-----------------
 gl/lib/randread.h |    6 ++++++
 src/shred.c       |    2 +-
 src/shuf.c        |    2 +-
 src/sort.c        |    2 +-
 7 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/NEWS b/NEWS
index 7fdbd08..57b5361 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,13 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   ls now aligns output correctly in the presence of abbreviated month
   names from the locale database that have differing widths.
 
+** Changes in behavior
+
+  shred: now uses its internal random data generator by default, which
+  means the 3 random passes it does by default should proceed at the
+  speed of the disk.  Previously /dev/urandom was used if available,
+  which is relatively slow on GNU/Linux systems at least.
+
 * Noteworthy changes in release 7.2 (2009-03-31) [stable]
 
 ** New features
diff --git a/THANKS b/THANKS
index 11f43ac..6a918a4 100644
--- a/THANKS
+++ b/THANKS
@@ -525,6 +525,7 @@ Steve McIntyre                      address@hidden
 Steve Ward                          address@hidden
 Steven G. Johnson                   address@hidden
 Steven Mocking                      address@hidden
+Steven Schveighoffer                address@hidden
 Steven P Watson                     address@hidden
 Stuart Kemp                         address@hidden
 Stuart Shelton                      address@hidden
diff --git a/gl/lib/randread.c b/gl/lib/randread.c
index b81a451..798d4e0 100644
--- a/gl/lib/randread.c
+++ b/gl/lib/randread.c
@@ -50,10 +50,6 @@
 # define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)
 #endif
 
-#ifndef DEFAULT_RANDOM_FILE
-# define DEFAULT_RANDOM_FILE "/dev/urandom"
-#endif
-
 /* The maximum buffer size used for reads of random data.  Using the
    value 2 * ISAAC_BYTES makes this the largest power of two that
    would not otherwise cause struct randread_source to grow.  */
@@ -62,10 +58,8 @@
 /* A source of random data for generating random buffers.  */
 struct randread_source
 {
-  /* Stream to read random bytes from.  If null, the behavior is
-     undefined; the current implementation uses ISAAC in this case,
-     but this is for old-fashioned implementations that lack
-     /dev/urandom and callers should not rely on this.  */
+  /* Stream to read random bytes from.  If null, the current
+     implementation uses an internal PRNG (ISAAC).  */
   FILE *source;
 
   /* Function to call, and its argument, if there is an input error or
@@ -147,18 +141,14 @@ randread_new (char const *name, size_t bytes_bound)
     return simple_new (NULL, NULL);
   else
     {
-      char const *file_name = (name ? name : DEFAULT_RANDOM_FILE);
-      FILE *source = fopen_safer (file_name, "rb");
+      FILE *source = NULL;
       struct randread_source *s;
 
-      if (! source)
-       {
-         if (name)
-           return NULL;
-         file_name = NULL;
-       }
+      if (name)
+       if (! (source = fopen_safer (name, "rb")))
+         return NULL;
 
-      s = simple_new (source, file_name);
+      s = simple_new (source, name);
 
       if (source)
        setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
diff --git a/gl/lib/randread.h b/gl/lib/randread.h
index 5f044bd..902251e 100644
--- a/gl/lib/randread.h
+++ b/gl/lib/randread.h
@@ -22,6 +22,12 @@
 
 # include <stddef.h>
 
+#ifndef DEFAULT_RANDOM_FILE
+/* Note /dev/urandom is not designed as a bulk random data source as
+   it's quite slow and also it depletes the entropy of the system.  */
+# define DEFAULT_RANDOM_FILE "/dev/urandom"
+#endif
+
 struct randread_source;
 
 struct randread_source *randread_new (char const *, size_t);
diff --git a/src/shred.c b/src/shred.c
index 6ed4daa..69bc226 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -167,7 +167,7 @@ Mandatory arguments to long options are mandatory for short 
options too.\n\
       printf (_("\
   -f, --force    change permissions to allow writing if necessary\n\
   -n, --iterations=N  overwrite N times instead of the default (%d)\n\
-      --random-source=FILE  get random bytes from FILE (default 
/dev/urandom)\n\
+      --random-source=FILE  get random bytes from FILE\n\
   -s, --size=N   shred this many bytes (suffixes like K, M, G accepted)\n\
 "), DEFAULT_PASSES);
       fputs (_("\
diff --git a/src/shuf.c b/src/shuf.c
index 977eedc..cf9d27b 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -245,7 +245,7 @@ main (int argc, char **argv)
   size_t hi_input = 0;
   size_t head_lines = SIZE_MAX;
   char const *outfile = NULL;
-  char *random_source = NULL;
+  const char *random_source = DEFAULT_RANDOM_FILE;
   char eolbyte = '\n';
   char **input_lines = NULL;
 
diff --git a/src/sort.c b/src/sort.c
index 5b63a25..8ce3f00 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -3037,7 +3037,7 @@ main (int argc, char **argv)
   int c = 0;
   char checkonly = 0;
   bool mergeonly = false;
-  char *random_source = NULL;
+  const char *random_source = DEFAULT_RANDOM_FILE;
   bool need_random = false;
   size_t nfiles = 0;
   bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
-- 
1.5.3.6


reply via email to

[Prev in Thread] Current Thread [Next in Thread]