Use pseudo-random instead of random streams to intialize seeds
authorErik Lindahl <erik@kth.se>
Sat, 1 Feb 2014 12:46:30 +0000 (13:46 +0100)
committerErik Lindahl <erik@kth.se>
Sat, 1 Feb 2014 12:47:43 +0000 (13:47 +0100)
The /dev/random stream will block if enough entropy is not
present in the system. This has not historically been a problem,
but with the unit tests initializing dozens of new random number
generators the entropy pool becomes exhausted, and the tests
block 10-20 seconds before each cool quote call for recent gcc
versions on our Ubuntu versions. This is also a seriously bad
abuse of the system random stream on shared systems.
Since /dev/urandom (which does not block) should be sufficiently
random for everything apart from long-term cryptographic keys,
we should use this one instead and leave /dev/random alone.

This patch solves an issue problems where recent gcc versions
took several minutes to complete unit tests.

Change-Id: I4a8fcf7e302d94f5ec3c9715593fbfd257decdd9

src/gromacs/random/random.c

index 19007cf4d52b69d323d2f64a047c2e8a78e7025a..ab103a9d7aa4aca1ea8f0816fc0915b398ec533e 100644 (file)
@@ -209,7 +209,20 @@ gmx_rng_make_seed(void)
     long         my_pid;
 
 #ifdef HAVE_UNISTD_H
-    fp = fopen("/dev/random", "rb"); /* will return NULL if it is not present */
+    /* We never want Gromacs execution to halt 10-20 seconds while
+     * waiting for enough entropy in the random number generator.
+     * For this reason we should NOT use /dev/random, which will
+     * block in cases like that. That will cause all sorts of
+     * Gromacs programs to block ~20 seconds while waiting for a
+     * super-random-number to generate cool quotes. Apart from the
+     * minor irritation, it is really bad behavior of a program
+     * to abuse the system random numbers like that - other programs
+     * need them too.
+     * For this reason, we ONLY try to get random numbers from
+     * the pseudo-random stream /dev/urandom, and use other means
+     * if it is not present (in this case fopen() returns NULL).
+     */
+    fp = fopen("/dev/urandom", "rb");
 #else
     fp = NULL;
 #endif