[Libguestfs] [libnbd PATCH 0/3] Improve type-safety of ocaml/golang getters
Richard W.M. Jones
rjones at redhat.com
Mon Sep 7 07:37:02 UTC 2020
On Sat, Sep 05, 2020 at 08:40:57PM -0500, Eric Blake wrote:
> Natural fallout after my recent testsuite additions that fixed a
> couple of ocaml bugs in the setters. However, on at least the OCaml
> code, I'm not sure what we should do if a newer libnbd ever returns a
> bit that an older NBD.mli was not expecting at the time the OCaml
> compiler ran (see below). I'm also not sure if there is a more
> efficient way to avoid outputting Val_FOO() converters for types not
> referenced in REnum/RFlags than my hack of __attribute__((unused)).
> Hence I'll wait for a review on these.
>
> Now, for the future compatibility lesson, promised above.
> nbd_get_handshake_flags is documented as potentially returning
> additional bits from a newer libnbd than what the current client code
> was compiled against. How? Let's say a future NBD protocol addition
> adds LIBNBD_HANDSHAKE_FLAG_64BIT (as that one might actually be a way
> that we implement 64-bit requests...). Presumably, once the NBD
> protocol defines it and future libnbd implements it, then future
> libnbd will default to setting that bit during nbd_create(). An older
> C client that did:
>
> flags = nbd_get_handshake_flags (nbd) & ~LIBNBD_HANDSHAKE_FLAG_NO_ZEROES;
> nbd_set_handshake_flags (nbd, flags);
>
> will still run (even though flags contains a bit that was not known at
> the time the C app was compiled, the libnbd call that checks that all
> input bits are known is from the newer libnbd that recognizes
> LIBNBD_HANDSHAKE_FLAG_64BIT as valid). But an OCaml client compiled
> against the older interface has no OCaml value to represent the new
> bit from the getter, nor any way to specify that new bit to the setter
> that is expecting a list of only the old variant type. Maybe we want
> the generator to produce a full list of 31 variants per 'flags' type,
> using placeholders for all bits not currently in use, to make it
> easier to receive an unknown bit from the getter and turn around to
> re-supply it to the setter? In such a setup, libnbd would still be
> rejecting input of out-of-range bits in relation to what libnbd knew
> at its compilation time.
While placeholders could be used, a more natural way is to extend the
flags type (in OCaml) to:
type t =
| FIXED_NEWSTYLE
| NO_ZEROES
| UNKNOWN_FLAG of int
where the unknown (at the time of compilation) flags would be
encoded as UNKNOWN_FLAG + the bit index of the unknown flag. eg:
[ FIXED_NEWSTYLE; UNKNOWN_FLAG 2 ] => 1 | (1<<2)
(1<<3) | 2 => [ UNKNOWN_FLAG 3; NO_ZEROES ]
Even though we distribute the OCaml bindings with libnbd it's
conceivable this could be useful because OCaml bindings are generally
statically linked into the final binary so you could get a newer
libnbd.so.0 / old binary with old OCaml bindings scenario.
Rich.
> Eric Blake (3):
> generator: Introduce REnum/RFlags return types
> golang: Typesafe returns for REnum/RFlags
> ocaml: Typesafe returns for REnum/RFlags
>
> generator/API.ml | 16 ++++--
> generator/API.mli | 2 +
> generator/C.ml | 20 ++++---
> generator/GoLang.ml | 13 ++++-
> generator/OCaml.ml | 55 +++++++++++++++++++
> generator/Python.ml | 2 +
> ocaml/tests/test_110_defaults.ml | 5 +-
> ocaml/tests/test_120_set_non_defaults.ml | 4 +-
> .../libnbd/libnbd_110_defaults_test.go | 6 +-
> .../libnbd_120_set_non_defaults_test.go | 2 +-
> 10 files changed, 102 insertions(+), 23 deletions(-)
>
> --
> 2.28.0
>
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
More information about the Libguestfs
mailing list