On Linux, does /dev/random unblocking imply that /dev/urandom is seeded?
I finally untangled what this code is doing.

YES.

The quick version of why this is true is that the first 128 bits of entropy which the system collects get mixed directly into the nonblocking pool, bypassing the input pool. The logic which implements this is part of each of the add_foo_randomness() functions:

 r = nonblocking_pool.initialized ? &amp;input_pool : &amp;nonblocking_pool;


http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L804
http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L924

And per http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L677, nonblocking_pool.initialized is set when its entropy_total exceeds 128 bits. So by the time anything is available from /dev/random, /dev/urandom has been seeded.

For completeness, here's the rest of the story on how the entropy pools are managed:


All pools, even the nonblocking pool, have entropy estimates that are credited when new entropy is mixed in and debited when entropy is extracted.
As detailed above, the first 128 bits of entropy collected get written and credited to the nonblocking pool; everything thereafter gets written and credited to the input pool.
If the input pool is overflowing (i.e. its entropy estimate is approaching its total size), then this triggers a transfer from the input pool to either the blocking or the nonblocking pool, on an alternating basis. Pools skip their turn if they're already at least 75% full. (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L692)
Reading from /dev/random always triggers a transfer from the input pool to the blocking pool (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L1177). Reading from /dev/urandom triggers a transfer from the input pool to the nonblocking pool only if there has been no such transfer in the past 60 seconds (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L983).
The amount transferred is (http://lxr.free-electrons.com/source/drivers/char/random.c?v=4.5#L995):


Typically equal to the amount being read from /dev/{u}random
But at least 64 bits
But not more than the current entropy estimate for the input pool
And not more than that estimate minus 128 bits if the transfer is to the nonblocking pool. (EDIT: I think this is a bug. See http://marc.info/?l=linux-kernel&amp;m=145945873501946&amp;w=2)