On a modern linux system, s6-rc-update ends up calling getrandom(2) via the random_sauniquename() library function. But on embedded systems, and especially during early initialization, that is likely to block, which means that the entire boot process hangs.
No, writing 160 bytes of crap to /dev/urandom as random_init does makes no difference; it does not in any way "speed up /dev/urandom initialization". And no, we cannot just make sure the kernel's random number generator is fully initialized before calling s6-rc-update, as s6-rc-update may very well be the one that starts the service(s) that eventually ensures this initialization (e.g., all the network-facing services). In general, none of the infrastructure utilities (skaware or otherwise) involved in the boot process can be allowed to make a possibly-blocking getrandom() call. We don't need a hard-to-predict name, we just need a name that doesn't already exist. So avoid getrandom() in s6-rc-update, and use mkdtemp() instead. Unfortunately, that doesn't accept a mode argument and uses 0700, so to emulate a mkdir(, 0755), do a little umask dance afterwards. It shouldn't be hard to reimplement mkdtemp and have that function take a mode argument, but for now this at least makes my board boot. Signed-off-by: Rasmus Villemoes <rasmus.villem...@prevas.dk> --- src/s6-rc/s6-rc-update.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c index a6e7cfe..5c933de 100644 --- a/src/s6-rc/s6-rc-update.c +++ b/src/s6-rc/s6-rc-update.c @@ -3,7 +3,10 @@ #include <string.h> #include <stdint.h> #include <sys/wait.h> +#include <sys/types.h> +#include <sys/stat.h> #include <unistd.h> +#include <stdlib.h> #include <errno.h> #include <stdio.h> #include <skalibs/types.h> @@ -19,7 +22,6 @@ #include <skalibs/skamisc.h> #include <skalibs/webipc.h> #include <skalibs/unix-transactional.h> -#include <skalibs/random.h> #include <execline/execline.h> #include <s6/config.h> #include <s6/s6-supervise.h> @@ -330,12 +332,14 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co size_t dirlen, llen, newlen, sdlen ; int e = 0 ; unsigned int i = 0 ; + mode_t mask; if (sareadlink(&satmp, live) < 0) strerr_diefu2sys(111, "readlink ", live) ; if (!s6rc_sanitize_dir(sa, live, &dirlen)) dienomem() ; llen = sa->len ; - if (!random_sauniquename(sa, 8) || !stralloc_0(sa)) dienomem() ; + if (!sauniquename(sa) || !stralloc_cats(sa, ":XXXXXX") || !stralloc_0(sa)) dienomem() ; newlen = --sa->len ; - if (mkdir(sa->s + sabase, 0755) < 0) strerr_diefu2sys(111, "mkdir ", sa->s + sabase) ; + if (!mkdtemp(sa->s + sabase)) strerr_diefu2sys(111, "mkdtemp ", sa->s + sabase) ; + mask = umask(0); chmod(sa->s + sabase, 0755 & ~mask); umask(mask); { size_t tmplen = satmp.len ; char fn[llen - sabase + 9] ; @@ -642,9 +646,6 @@ int main (int argc, char const *const *argv, char const *const *envp) strerr_dief2x(100, live, " is not an absolute path") ; livelen = strlen(live) ; - if (!random_init()) - strerr_diefu1sys(111, "init random generator") ; - { int livelock, oldlock, newlock ; int fdoldc, fdnewc ; -- 2.7.4