Now that gnulib's rand module is imported, we have a decent quality random number generator that's portable. We don't want to mess with the apps state, so in virInitialize() we explicitly initialize our own private random nubmer generator state with virRandomInitialize(). The util.h file gains a convenience macro, since random_r() is horrible to call and we need to protect our global state int virRandom(int max) Makefile.maint | 2 +- src/libvirt.c | 3 ++- src/util.c | 38 +++++++++++++++++++++++++++++++++++--- src/util.h | 3 +++ src/uuid.c | 4 ++-- 5 files changed, 43 insertions(+), 7 deletions(-) Daniel diff --git a/Makefile.maint b/Makefile.maint --- a/Makefile.maint +++ b/Makefile.maint @@ -117,7 +117,7 @@ sc_prohibit_nonreentrant: @fail=0 ; \ for i in $(NON_REENTRANT) ; \ do \ - grep -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \ + grep --before 2 --after 1 -nE "\<$$i\>[:space:]*\(" $$($(VC_LIST_EXCEPT)) && \ fail=1 && echo "$(ME): use $${i}_r, not $${i}" || : ; \ done ; \ exit $$fail diff --git a/src/libvirt.c b/src/libvirt.c --- a/src/libvirt.c +++ b/src/libvirt.c @@ -257,7 +257,8 @@ virInitialize(void) initialized = 1; if (virThreadInitialize() < 0 || - virErrorInitialize() < 0) + virErrorInitialize() < 0 || + virRandomInitialize()) return -1; #ifdef ENABLE_DEBUG diff --git a/src/util.c b/src/util.c --- a/src/util.c +++ b/src/util.c @@ -32,6 +32,7 @@ #include <fcntl.h> #include <errno.h> #include <poll.h> +#include <time.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> @@ -56,6 +57,7 @@ #include "buf.h" #include "util.h" #include "memory.h" +#include "threads.h" #ifndef NSIG # define NSIG 32 @@ -1282,9 +1284,9 @@ void virGenerateMacAddr(const unsigned c addr[0] = prefix[0]; addr[1] = prefix[1]; addr[2] = prefix[2]; - addr[3] = (int)(256*(rand()/(RAND_MAX+1.0))); - addr[4] = (int)(256*(rand()/(RAND_MAX+1.0))); - addr[5] = (int)(256*(rand()/(RAND_MAX+1.0))); + addr[3] = virRandom(256); + addr[4] = virRandom(256); + addr[5] = virRandom(256); } @@ -1431,3 +1433,33 @@ int virKillProcess(pid_t pid, int sig) return kill(pid, sig); #endif } + + +static char randomState[128]; +static struct random_data randomData; +static virMutex randomLock; + +int virRandomInitialize(void) +{ + if (virMutexInit(&randomLock) < 0) + return -1; + + if (initstate_r(time(NULL), + randomState, + sizeof(randomState), + &randomData) < 0) + return -1; + + return 0; +} + +int virRandom(int max) +{ + int32_t ret; + + virMutexLock(&randomLock); + random_r(&randomData, &ret); + virMutexUnlock(&randomLock); + + return (int) ((double)max * ((double)ret / (double)RAND_MAX)); +} diff --git a/src/util.h b/src/util.h --- a/src/util.h +++ b/src/util.h @@ -172,4 +172,7 @@ char *virGetHostname(void); int virKillProcess(pid_t pid, int sig); +int virRandomInitialize(void); +int virRandom(int max); + #endif /* __VIR_UTIL_H__ */ diff --git a/src/uuid.c b/src/uuid.c --- a/src/uuid.c +++ b/src/uuid.c @@ -35,6 +35,7 @@ #include "c-ctype.h" #include "internal.h" +#include "util.h" #define qemudLog(level, msg...) fprintf(stderr, msg) @@ -74,9 +75,8 @@ virUUIDGeneratePseudoRandomBytes(unsigne virUUIDGeneratePseudoRandomBytes(unsigned char *buf, int buflen) { - srand(time(NULL)); while (buflen > 0) { - *buf = (int) (255.0 * (rand() / (double) RAND_MAX)); + *buf = virRandom(256); buflen--; } -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list