aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2012-07-30 14:42:36 -0700
committerJeff Garzik <jgarzik@redhat.com>2012-07-31 15:32:58 -0400
commit870f0d5d2f06d778a49e35d3a5f55183e5c9b9c0 (patch)
treeef64fe562cb09af6f91b3478329645d6f707ac04
parent593a93021566a41546b433bbb5d4eb66302c5eb3 (diff)
downloadrng-tools-870f0d5d2f06d778a49e35d3a5f55183e5c9b9c0.tar.gz
rngd_linux: Modify write_wakeup_threshold to the fill threshold
The kernel.random.write_wakeup_threshold sysctl needs to be set to the point where we want poll() on the random device to wake up. This replaces the level check in ioctl() used during polling. Set it by default to 3/4 to the value of kernel.random.poolsize. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--rngd.c4
-rw-r--r--rngd_linux.c39
-rw-r--r--rngd_linux.h3
3 files changed, 45 insertions, 1 deletions
diff --git a/rngd.c b/rngd.c
index 9819ed5..f6ee8a3 100644
--- a/rngd.c
+++ b/rngd.c
@@ -112,7 +112,6 @@ static struct arguments default_arguments = {
.random_name = "/dev/random",
.pid_file = "/var/run/rngd.pid",
.random_step = 64,
- .fill_watermark = 2048,
.daemon = true,
.enable_drng = true,
.enable_tpm = true,
@@ -292,6 +291,9 @@ int main(int argc, char **argv)
openlog("rngd", 0, LOG_DAEMON);
+ /* Get the default watermark level for this platform */
+ arguments->fill_watermark = default_watermark();
+
/* Parsing of commandline parameters */
argp_parse(&argp, argc, argv, 0, 0, arguments);
diff --git a/rngd_linux.c b/rngd_linux.c
index 6400adf..3556fd0 100644
--- a/rngd_linux.c
+++ b/rngd_linux.c
@@ -53,6 +53,37 @@ extern struct rng *rng_list;
/* Kernel output device */
static int random_fd;
+/*
+ * Get the default watermark
+ */
+int default_watermark(void)
+{
+ char psbuf[64], *p;
+ unsigned long ps;
+ FILE *f;
+ size_t l;
+ unsigned int wm = 2048; /* Default guess */
+
+ f = fopen("/proc/sys/kernel/random/poolsize", "r");
+ if (!f)
+ goto err;
+ l = fread(psbuf, 1, sizeof psbuf, f);
+ if (ferror(f) || !feof(f) || l == 0)
+ goto err;
+ if (psbuf[l-1] != '\n')
+ goto err;
+ psbuf[l-1] = '\0';
+ ps = strtoul(psbuf, &p, 0);
+ if (*p)
+ goto err;
+
+ wm = ps*3/4;
+
+err:
+ if (f)
+ fclose(f);
+ return wm;
+}
/*
* Initialize the interface to the Linux Kernel
@@ -62,12 +93,20 @@ static int random_fd;
*/
void init_kernel_rng(const char* randomdev)
{
+ FILE *f;
+
random_fd = open(randomdev, O_RDWR);
if (random_fd == -1) {
message(LOG_DAEMON|LOG_ERR, "can't open %s: %s",
randomdev, strerror(errno));
exit(EXIT_USAGE);
}
+
+ f = fopen("/proc/sys/kernel/random/write_wakeup_threshold", "w");
+ if (f) {
+ fprintf(f, "%u\n", arguments->fill_watermark);
+ fclose(f);
+ }
}
void random_add_entropy(void *buf, size_t size)
diff --git a/rngd_linux.h b/rngd_linux.h
index 187e17c..029584b 100644
--- a/rngd_linux.h
+++ b/rngd_linux.h
@@ -26,6 +26,9 @@
#include <unistd.h>
#include <stdint.h>
+/* The default watermark level for this platform */
+extern int default_watermark(void);
+
/*
* Initialize the interface to the Linux Kernel
* entropy pool (through /dev/random)