[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MirageOS-devel] mirage-entropy



> for our upcoming release of ocaml-tls, we need to seed our random
> number generator (which is fortuna, implemented here
> https://github.com/mirleft/ocaml-nocrypto/blob/master/src/rng.ml ).
> 
> To achieve that, I implemented an ENTROPY device in mirage and
> mirage-types (https://github.com/mirage/mirage/pull/256) - which API
> is only a single function:
>   val entropy : t -> int -> [ `Ok of buffer | `Error of error ] io
>   (** [entropy t count] returns a [buffer] of [count] bytes from the
> entropy pool [t]. *)
> 
> The buffer is a Cstruct.t in the V1_LWT interface.
> 
> The purpose is to get (in a non-blocking manner) some entropy bytes.
> If no entropy device is available, an error is thrown (type error = [
> | `No_entropy_device of string ]).
> 
> Furthermore, I implemented a unix version
> (https://github.com/mirage/mirage-entropy) which reads the bytes from
> /dev/random (any ideas whether there is a POSIX way to get entropy,
> not random?). On XEN the stub implementation currently errors out -
> the idea is that the host system provides an entropy device for the
> virtual machine guests (this code needs to be written, any volunteers?).

As I've seen a discussion on the bug tracker about having to release two 
separate packages (one for xen, one for unix) or only one, and as I had a 
similar discussion with Daniel on this about the design of his useri[1] 
library, I'll try to explain a bit more the rational we try to follow in 
general for mirage libraries in such cases.

Long time ago, when we started the development of mirage, we had no functors. 
The xen and unix backends where both implementing modules with the same name -- 
the libraries using these modules were just including/opening the given module 
signature and the magic of which implementation were actually picked was 
configured at link time (this is not totally correct, but that's the general 
idea). We called that the "linking trick": if you give to the compiler the 
right include paths when needed, you don't need functors, but you need a pretty 
clever build system (so that you can choose against which backend you want to 
link) -- and we wrote a pretty sophisticated myocamlbuild.ml to handle this[2].

All was fine and we were pretty happy: the added complexity of the build system 
let users develop simple code without the need to use functors at all. However, 
as we started working on the network stack, it appeared quickly that we wanted 
to have, in the same program, two different implementations of the same 
signature (killer example: having two full TCP/IP stacks, one fully in OCaml 
the other using the usual kernel stack for unit testing purposes). As OCaml 
does not allow to link two modules with the same name together, it means that 
all the network stack implementations needed to have different names. So the 
linking trick couldn't work anymore. Same issue with the storage backends. So 
we ended up simplifying the build system (no needs for complex build rules 
anymore) but putting back the complexity in the functor language. And functors 
slowly started to contaminate our code base 'cause now, every library using a 
functor should also expose a functor.

To tackle the difficulty of using functors, we had two strategies. The first 
one was to develop, during last december, an EDSL to describe the composition 
of functors[3], which was what we finally released in mirage 1.0. The second 
one was to be a bit more structured about how we design new libraries. We 
continue to use the linking trick for modules where there is clearly no way to 
have two concurrent implementation running at the same time in the same module. 
In the same time, we try to provide to the user, when possible, default functor 
instantiation in separate ocamlfind package to make easier to use the 
libraries. So most of the mirage libraries[4,5,...] are structured as follows:
- a core ocamlfind package, which consumes and provides a functor, which is 
independent of the backend
- a .lwt (should be called .unix really) ocamlfind subpackage, which applies 
the functors to work with Lwt_unix functions
- a .xen ocamlfind subpackage, which applies the functors to work with 
mirage/xen
And we use OPAM %{xxx:enable}% variables to enable or disable the compilation 
of sub-packages.

Hope it helps clarifying things a little bit,
Thomas

[1] https://github.com/dbuenzli/useri/blob/master/src/useri.ml#L7
[2] https://github.com/mirage/mirage/blob/old-master/lib/myocamlbuild.ml
[3] https://github.com/mirage/mirage/blob/master/lib/mirage.mli
[4] https://github.com/mirage/shared-memory-ring/blob/master/lib/META
[5] https://github.com/mirage/ocaml-git/blob/master/lib/META

> 
> 
> Hannes
> 
> 
> _______________________________________________
> MirageOS-devel mailing list
> MirageOS-devel@xxxxxxxxxxxxxxxxxxxx
> http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel


_______________________________________________
MirageOS-devel mailing list
MirageOS-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.