[libvirt] PATCH: 21/25: Use random_r for random numbers

Daniel P. Berrange berrange at redhat.com
Tue Jan 13 17:47:27 UTC 2009


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




More information about the libvir-list mailing list