rng-random.c (84a5a8014801a83d1b8d15fa7f0fde03db081530) | rng-random.c (cde63615343fb241f4044e6471e6e25be78574c8) |
---|---|
1/* 2 * QEMU Random Number Generator Backend 3 * 4 * Copyright IBM, Corp. 2012 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13#include "qemu/osdep.h" 14#include "sysemu/rng-random.h" 15#include "sysemu/rng.h" 16#include "qapi/error.h" 17#include "qapi/qmp/qerror.h" 18#include "qemu/main-loop.h" 19 | 1/* 2 * QEMU Random Number Generator Backend 3 * 4 * Copyright IBM, Corp. 2012 5 * 6 * Authors: 7 * Anthony Liguori <aliguori@us.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13#include "qemu/osdep.h" 14#include "sysemu/rng-random.h" 15#include "sysemu/rng.h" 16#include "qapi/error.h" 17#include "qapi/qmp/qerror.h" 18#include "qemu/main-loop.h" 19 |
20struct RndRandom | 20struct RngRandom |
21{ 22 RngBackend parent; 23 24 int fd; 25 char *filename; 26}; 27 28/** 29 * A simple and incomplete backend to request entropy from /dev/random. 30 * 31 * This backend exposes an additional "filename" property that can be used to 32 * set the filename to use to open the backend. 33 */ 34 35static void entropy_available(void *opaque) 36{ | 21{ 22 RngBackend parent; 23 24 int fd; 25 char *filename; 26}; 27 28/** 29 * A simple and incomplete backend to request entropy from /dev/random. 30 * 31 * This backend exposes an additional "filename" property that can be used to 32 * set the filename to use to open the backend. 33 */ 34 35static void entropy_available(void *opaque) 36{ |
37 RndRandom *s = RNG_RANDOM(opaque); | 37 RngRandom *s = RNG_RANDOM(opaque); |
38 39 while (!QSIMPLEQ_EMPTY(&s->parent.requests)) { 40 RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); 41 ssize_t len; 42 43 len = read(s->fd, req->data, req->size); 44 if (len < 0 && errno == EAGAIN) { 45 return; --- 6 unchanged lines hidden (view full) --- 52 } 53 54 /* We've drained all requests, the fd handler can be reset. */ 55 qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 56} 57 58static void rng_random_request_entropy(RngBackend *b, RngRequest *req) 59{ | 38 39 while (!QSIMPLEQ_EMPTY(&s->parent.requests)) { 40 RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); 41 ssize_t len; 42 43 len = read(s->fd, req->data, req->size); 44 if (len < 0 && errno == EAGAIN) { 45 return; --- 6 unchanged lines hidden (view full) --- 52 } 53 54 /* We've drained all requests, the fd handler can be reset. */ 55 qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 56} 57 58static void rng_random_request_entropy(RngBackend *b, RngRequest *req) 59{ |
60 RndRandom *s = RNG_RANDOM(b); | 60 RngRandom *s = RNG_RANDOM(b); |
61 62 if (QSIMPLEQ_EMPTY(&s->parent.requests)) { 63 /* If there are no pending requests yet, we need to 64 * install our fd handler. */ 65 qemu_set_fd_handler(s->fd, entropy_available, NULL, s); 66 } 67} 68 69static void rng_random_opened(RngBackend *b, Error **errp) 70{ | 61 62 if (QSIMPLEQ_EMPTY(&s->parent.requests)) { 63 /* If there are no pending requests yet, we need to 64 * install our fd handler. */ 65 qemu_set_fd_handler(s->fd, entropy_available, NULL, s); 66 } 67} 68 69static void rng_random_opened(RngBackend *b, Error **errp) 70{ |
71 RndRandom *s = RNG_RANDOM(b); | 71 RngRandom *s = RNG_RANDOM(b); |
72 73 if (s->filename == NULL) { 74 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 75 "filename", "a valid filename"); 76 } else { 77 s->fd = qemu_open(s->filename, O_RDONLY | O_NONBLOCK); 78 if (s->fd == -1) { 79 error_setg_file_open(errp, errno, s->filename); 80 } 81 } 82} 83 84static char *rng_random_get_filename(Object *obj, Error **errp) 85{ | 72 73 if (s->filename == NULL) { 74 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, 75 "filename", "a valid filename"); 76 } else { 77 s->fd = qemu_open(s->filename, O_RDONLY | O_NONBLOCK); 78 if (s->fd == -1) { 79 error_setg_file_open(errp, errno, s->filename); 80 } 81 } 82} 83 84static char *rng_random_get_filename(Object *obj, Error **errp) 85{ |
86 RndRandom *s = RNG_RANDOM(obj); | 86 RngRandom *s = RNG_RANDOM(obj); |
87 88 return g_strdup(s->filename); 89} 90 91static void rng_random_set_filename(Object *obj, const char *filename, 92 Error **errp) 93{ 94 RngBackend *b = RNG_BACKEND(obj); | 87 88 return g_strdup(s->filename); 89} 90 91static void rng_random_set_filename(Object *obj, const char *filename, 92 Error **errp) 93{ 94 RngBackend *b = RNG_BACKEND(obj); |
95 RndRandom *s = RNG_RANDOM(obj); | 95 RngRandom *s = RNG_RANDOM(obj); |
96 97 if (b->opened) { 98 error_setg(errp, QERR_PERMISSION_DENIED); 99 return; 100 } 101 102 g_free(s->filename); 103 s->filename = g_strdup(filename); 104} 105 106static void rng_random_init(Object *obj) 107{ | 96 97 if (b->opened) { 98 error_setg(errp, QERR_PERMISSION_DENIED); 99 return; 100 } 101 102 g_free(s->filename); 103 s->filename = g_strdup(filename); 104} 105 106static void rng_random_init(Object *obj) 107{ |
108 RndRandom *s = RNG_RANDOM(obj); | 108 RngRandom *s = RNG_RANDOM(obj); |
109 110 object_property_add_str(obj, "filename", 111 rng_random_get_filename, 112 rng_random_set_filename, 113 NULL); 114 115 s->filename = g_strdup("/dev/random"); 116 s->fd = -1; 117} 118 119static void rng_random_finalize(Object *obj) 120{ | 109 110 object_property_add_str(obj, "filename", 111 rng_random_get_filename, 112 rng_random_set_filename, 113 NULL); 114 115 s->filename = g_strdup("/dev/random"); 116 s->fd = -1; 117} 118 119static void rng_random_finalize(Object *obj) 120{ |
121 RndRandom *s = RNG_RANDOM(obj); | 121 RngRandom *s = RNG_RANDOM(obj); |
122 123 if (s->fd != -1) { 124 qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 125 qemu_close(s->fd); 126 } 127 128 g_free(s->filename); 129} --- 4 unchanged lines hidden (view full) --- 134 135 rbc->request_entropy = rng_random_request_entropy; 136 rbc->opened = rng_random_opened; 137} 138 139static const TypeInfo rng_random_info = { 140 .name = TYPE_RNG_RANDOM, 141 .parent = TYPE_RNG_BACKEND, | 122 123 if (s->fd != -1) { 124 qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 125 qemu_close(s->fd); 126 } 127 128 g_free(s->filename); 129} --- 4 unchanged lines hidden (view full) --- 134 135 rbc->request_entropy = rng_random_request_entropy; 136 rbc->opened = rng_random_opened; 137} 138 139static const TypeInfo rng_random_info = { 140 .name = TYPE_RNG_RANDOM, 141 .parent = TYPE_RNG_BACKEND, |
142 .instance_size = sizeof(RndRandom), | 142 .instance_size = sizeof(RngRandom), |
143 .class_init = rng_random_class_init, 144 .instance_init = rng_random_init, 145 .instance_finalize = rng_random_finalize, 146}; 147 148static void register_types(void) 149{ 150 type_register_static(&rng_random_info); 151} 152 153type_init(register_types); | 143 .class_init = rng_random_class_init, 144 .instance_init = rng_random_init, 145 .instance_finalize = rng_random_finalize, 146}; 147 148static void register_types(void) 149{ 150 type_register_static(&rng_random_info); 151} 152 153type_init(register_types); |