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 :|