Il 31/10/2012 00:02, Anthony Liguori ha scritto: > The filename can be overridden but it expects a non-blocking source of > entropy. > A typical invocation would be: > > qemu -object rng-random,id=rng0 -device virtio-rng-pci,rng=rng0 > > This can also be used with /dev/urandom by using the command line: > > qemu -object rng-random,filename=/dev/urandom,id=rng0 \ > -device virtio-rng-pci,rng=rng0 > > Signed-off-by: Anthony Liguori <aligu...@us.ibm.com> > --- > v1 -> v2 > - merged header split patch into this one > --- > backends/Makefile.objs | 2 +- > backends/rng-random.c | 161 > ++++++++++++++++++++++++++++++++++++++++++++++ > include/qemu/rng-random.h | 22 +++++++ > 3 files changed, 184 insertions(+), 1 deletion(-) > create mode 100644 backends/rng-random.c > create mode 100644 include/qemu/rng-random.h > > diff --git a/backends/Makefile.objs b/backends/Makefile.objs > index 06e08c7..23ca19b 100644 > --- a/backends/Makefile.objs > +++ b/backends/Makefile.objs > @@ -1 +1 @@ > -common-obj-y += rng.o > +common-obj-y += rng.o rng-random.o > diff --git a/backends/rng-random.c b/backends/rng-random.c > new file mode 100644 > index 0000000..8325686 > --- /dev/null > +++ b/backends/rng-random.c > @@ -0,0 +1,161 @@ > +/* > + * QEMU Random Number Generator Backend > + * > + * Copyright IBM, Corp. 2012 > + * > + * Authors: > + * Anthony Liguori <aligu...@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + */ > + > +#include "qemu/rng-random.h" > +#include "qemu/rng.h" > +#include "qerror.h" > +#include "main-loop.h" > + > +struct RndRandom > +{ > + RngBackend parent; > + > + int fd; > + char *filename; > + > + EntropyReceiveFunc *receive_func; > + void *opaque; > + size_t size; > +}; > + > +/** > + * A simple and incomplete backend to request entropy from /dev/random. > + * > + * This backend exposes an additional "filename" property that can be used to > + * set the filename to use to open the backend. > + */ > + > +static void entropy_available(void *opaque) > +{ > + RndRandom *s = RNG_RANDOM(opaque); > + uint8_t buffer[s->size]; > + ssize_t len; > + > + len = read(s->fd, buffer, s->size); > + g_assert(len != -1); > + > + s->receive_func(s->opaque, buffer, s->size);
Should be len here, not s->size. Otherwise looks good. Paolo > + s->receive_func = NULL; > + > + qemu_set_fd_handler(s->fd, NULL, NULL, NULL); > +} > + > +static void rng_random_request_entropy(RngBackend *b, size_t size, > + EntropyReceiveFunc *receive_entropy, > + void *opaque) > +{ > + RndRandom *s = RNG_RANDOM(b); > + > + if (s->receive_func) { > + s->receive_func(s->opaque, NULL, 0); > + } > + > + s->receive_func = receive_entropy; > + s->opaque = opaque; > + s->size = size; > + > + qemu_set_fd_handler(s->fd, entropy_available, NULL, s); > +} > + > +static void rng_random_opened(RngBackend *b, Error **errp) > +{ > + RndRandom *s = RNG_RANDOM(b); > + > + if (s->filename == NULL) { > + error_set(errp, QERR_INVALID_PARAMETER_VALUE, > + "filename", "a valid filename"); > + } else { > + s->fd = open(s->filename, O_RDONLY | O_NONBLOCK); > + > + if (s->fd == -1) { > + error_set(errp, QERR_OPEN_FILE_FAILED, s->filename); > + } > + } > +} > + > +static char *rng_random_get_filename(Object *obj, Error **errp) > +{ > + RndRandom *s = RNG_RANDOM(obj); > + > + if (s->filename) { > + return g_strdup(s->filename); > + } > + > + return NULL; > +} > + > +static void rng_random_set_filename(Object *obj, const char *filename, > + Error **errp) > +{ > + RngBackend *b = RNG_BACKEND(obj); > + RndRandom *s = RNG_RANDOM(obj); > + > + if (b->opened) { > + error_set(errp, QERR_PERMISSION_DENIED); > + return; > + } > + > + if (s->filename) { > + g_free(s->filename); > + } > + > + s->filename = g_strdup(filename); > +} > + > +static void rng_random_init(Object *obj) > +{ > + RndRandom *s = RNG_RANDOM(obj); > + > + object_property_add_str(obj, "filename", > + rng_random_get_filename, > + rng_random_set_filename, > + NULL); > + > + s->filename = g_strdup("/dev/random"); > +} > + > +static void rng_random_finalize(Object *obj) > +{ > + RndRandom *s = RNG_RANDOM(obj); > + > + qemu_set_fd_handler(s->fd, NULL, NULL, NULL); > + > + if (s->fd != -1) { > + close(s->fd); > + } > + > + g_free(s->filename); > +} > + > +static void rng_random_class_init(ObjectClass *klass, void *data) > +{ > + RngBackendClass *rbc = RNG_BACKEND_CLASS(klass); > + > + rbc->request_entropy = rng_random_request_entropy; > + rbc->opened = rng_random_opened; > +} > + > +static TypeInfo rng_random_info = { > + .name = TYPE_RNG_RANDOM, > + .parent = TYPE_RNG_BACKEND, > + .instance_size = sizeof(RndRandom), > + .class_init = rng_random_class_init, > + .instance_init = rng_random_init, > + .instance_finalize = rng_random_finalize, > +}; > + > +static void register_types(void) > +{ > + type_register_static(&rng_random_info); > +} > + > +type_init(register_types); > diff --git a/include/qemu/rng-random.h b/include/qemu/rng-random.h > new file mode 100644 > index 0000000..6249290 > --- /dev/null > +++ b/include/qemu/rng-random.h > @@ -0,0 +1,22 @@ > +/* > + * QEMU Random Number Generator Backend > + * > + * Copyright IBM, Corp. 2012 > + * > + * Authors: > + * Anthony Liguori <aligu...@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + */ > +#ifndef QEMU_RNG_RANDOM_H > +#define QEMU_RNG_RANDOM_H > + > +#include "qemu/object.h" > + > +#define TYPE_RNG_RANDOM "rng-random" > +#define RNG_RANDOM(obj) OBJECT_CHECK(RndRandom, (obj), TYPE_RNG_RANDOM) > + > +typedef struct RndRandom RndRandom; > + > +#endif > -- 1.8.0 >