The NBD protocol is adding an extension to let servers advertise initialization state to the client: whether the image contains holes, and whether it is known to read as all zeroes. For Ocaml, the changes are just copy-and-paste, but I wasn't sure how to test them beyond a successful build.
Signed-off-by: Eric Blake <[email protected]> --- plugins/ocaml/NBDKit.ml | 14 +++++++++++- plugins/ocaml/NBDKit.mli | 5 ++++- plugins/ocaml/ocaml.c | 47 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/plugins/ocaml/NBDKit.ml b/plugins/ocaml/NBDKit.ml index 85c30a1..2db011f 100644 --- a/plugins/ocaml/NBDKit.ml +++ b/plugins/ocaml/NBDKit.ml @@ -100,6 +100,9 @@ type 'a plugin = { can_fast_zero : ('a -> bool) option; preconnect : (bool -> unit) option; + + init_sparse : ('a -> bool) option; + init_zero : ('a -> bool) option; } let default_callbacks = { @@ -149,6 +152,9 @@ let default_callbacks = { can_fast_zero = None; preconnect = None; + + init_sparse = None; + init_zero = None; } external set_name : string -> unit = "ocaml_nbdkit_set_name" "noalloc" @@ -198,6 +204,9 @@ external set_can_fast_zero : ('a -> bool) -> unit = "ocaml_nbdkit_set_can_fast_z external set_preconnect : (bool -> unit) -> unit = "ocaml_nbdkit_set_preconnect" +external set_init_sparse : ('a -> bool) -> unit = "ocaml_nbdkit_set_init_sparse" +external set_init_zero : ('a -> bool) -> unit = "ocaml_nbdkit_set_init_zero" + let may f = function None -> () | Some a -> f a let register_plugin plugin = @@ -265,7 +274,10 @@ let register_plugin plugin = may set_can_fast_zero plugin.can_fast_zero; - may set_preconnect plugin.preconnect + may set_preconnect plugin.preconnect; + + may set_init_sparse plugin.init_sparse; + may set_init_zero plugin.init_zero; external _set_error : int -> unit = "ocaml_nbdkit_set_error" "noalloc" diff --git a/plugins/ocaml/NBDKit.mli b/plugins/ocaml/NBDKit.mli index 4cdf911..966b1bb 100644 --- a/plugins/ocaml/NBDKit.mli +++ b/plugins/ocaml/NBDKit.mli @@ -105,12 +105,15 @@ type 'a plugin = { can_fast_zero : ('a -> bool) option; preconnect : (bool -> unit) option; + + init_sparse : ('a -> bool) option; + init_zero : ('a -> bool) option; } (** The plugin fields and callbacks. ['a] is the handle type. *) val default_callbacks : 'a plugin (** The plugin with all fields set to [None], so you can write - [{ defaults_callbacks with field1 = Some foo1; field2 = Some foo2 }] *) + [{ default_callbacks with field1 = Some foo1; field2 = Some foo2 }] *) val register_plugin : 'a plugin -> unit (** Register the plugin with nbdkit. *) diff --git a/plugins/ocaml/ocaml.c b/plugins/ocaml/ocaml.c index a7d188f..db88f68 100644 --- a/plugins/ocaml/ocaml.c +++ b/plugins/ocaml/ocaml.c @@ -138,6 +138,9 @@ static value can_fast_zero_fn; static value preconnect_fn; +static value init_sparse_fn; +static value init_zero_fn; + /*----------------------------------------------------------------------*/ /* Wrapper functions that translate calls from C (ie. nbdkit) to OCaml. */ @@ -747,6 +750,44 @@ preconnect_wrapper (int readonly) CAMLreturnT (int, 1); } +static int +init_sparse_wrapper (void *h) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + caml_leave_blocking_section (); + + rv = caml_callback_exn (init_sparse_fn, *(value *) h); + if (Is_exception_result (rv)) { + nbdkit_error ("%s", caml_format_exception (Extract_exception (rv))); + caml_enter_blocking_section (); + CAMLreturnT (int, -1); + } + + caml_enter_blocking_section (); + CAMLreturnT (int, Bool_val (rv)); +} + +static int +init_zero_wrapper (void *h) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + caml_leave_blocking_section (); + + rv = caml_callback_exn (init_zero_fn, *(value *) h); + if (Is_exception_result (rv)) { + nbdkit_error ("%s", caml_format_exception (Extract_exception (rv))); + caml_enter_blocking_section (); + CAMLreturnT (int, -1); + } + + caml_enter_blocking_section (); + CAMLreturnT (int, Bool_val (rv)); +} + /*----------------------------------------------------------------------*/ /* set_* functions called from OCaml code at load time to initialize * fields in the plugin struct. @@ -838,6 +879,9 @@ SET(can_fast_zero) SET(preconnect) +SET(init_sparse) +SET(init_zero) + #undef SET static void @@ -886,6 +930,9 @@ remove_roots (void) REMOVE (preconnect); + REMOVE (init_sparse); + REMOVE (init_zero); + #undef REMOVE } -- 2.24.1 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
