All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: linux-btrfs@vger.kernel.org
Cc: dsterba@suse.cz
Subject: [PATCH 1/2] btrfs-progs: utils: Introduce new pseudo random API
Date: Wed, 25 May 2016 12:14:04 +0800	[thread overview]
Message-ID: <1464149645-4308-1-git-send-email-quwenruo@cn.fujitsu.com> (raw)

David has reported some quite chaos usage of pseudo random numbers.
Like using static srand seed, or even calling rand() without setting
seed correctly.

The new pseudo random API will initialize the random seed on its first
calling and use uniformly distributed pseudo random number generator as
backend.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 utils.c | 36 ++++++++++++++++++++++++++++++++++++
 utils.h | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/utils.c b/utils.c
index 7761165..c0e860a 100644
--- a/utils.c
+++ b/utils.c
@@ -54,9 +54,11 @@
 #define BLKDISCARD	_IO(0x12,119)
 #endif
 
+static int seed_initlized = 0;
 static int btrfs_scan_done = 0;
 
 static char argv0_buf[ARGV0_BUF_SIZE] = "btrfs";
+static unsigned short seeds[3];
 
 const char *get_argv0_buf(void)
 {
@@ -4051,3 +4053,37 @@ out:
 
 	return ret;
 }
+
+void rand_seed(u64 seed)
+{
+	int i;
+	/* only use the last 48 bits */
+	for (i = 0; i < 3; i++) {
+		seeds[i] = (unsigned short)(seed ^ (unsigned short)(-1));
+		seed >>= 16;
+	}
+	seed_initlized = 1;
+}
+
+u32 rand_u32(void)
+{
+	struct timeval tv;
+
+	if (seed_initlized)
+		return nrand48(seeds);
+
+	/*
+	 * It's possible to use /dev/random, but we don't need that true
+	 * random number nor want to wait for entropy,
+	 * since we're only using random API to do corruption to test.
+	 * Time and pid/ppid based seed would be good enough, and won't
+	 * cause sleep for entropy pool.
+	 */
+	gettimeofday(&tv, 0);
+	seeds[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
+	seeds[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
+	seeds[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
+	seed_initlized = 1;
+
+	return (u32)nrand48(seeds);
+}
diff --git a/utils.h b/utils.h
index ebe6d61..0977262 100644
--- a/utils.h
+++ b/utils.h
@@ -362,4 +362,40 @@ static inline int error_on(int condition, const char *fmt, ...)
 	return 1;
 }
 
+/* pseudo random number generator wrappers */
+u32 rand_u32(void);
+
+static inline int rand_int(void)
+{
+	return (int)(rand_u32());
+}
+
+static inline u64 rand_u64(void)
+{
+	u64 ret = 0;
+
+	ret += rand_u32();
+	ret <<= 32;
+	ret += rand_u32();
+	return ret;
+}
+
+static inline u16 rand_u16(void)
+{
+	return (u16)(rand_u32());
+}
+
+static inline u8 rand_u8(void)
+{
+	return (u8)(rand_u32());
+}
+
+/* Return random number in range [0, limit) */
+static inline unsigned int rand_range(unsigned int up)
+{
+	return (unsigned int)(rand_u32() % up);
+}
+
+/* Also allow setting seeds manually */
+void rand_seed(u64 seed);
 #endif
-- 
2.8.2




             reply	other threads:[~2016-05-25  4:14 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-25  4:14 Qu Wenruo [this message]
2016-05-25  4:14 ` [PATCH 2/2] btrfs-progs: Use new random number API Qu Wenruo
2016-05-25 16:15 ` [PATCH 1/2] btrfs-progs: utils: Introduce new pseudo random API Noah Massey
2016-05-26  0:29   ` Qu Wenruo
2016-05-25 19:06 ` Goffredo Baroncelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464149645-4308-1-git-send-email-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=dsterba@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.