[Libguestfs] [PATCH libnbd 1/2] ocaml/examples: Fix extents example
Laszlo Ersek
lersek at redhat.com
Mon Dec 13 11:14:47 UTC 2021
On 12/11/21 14:41, Richard W.M. Jones wrote:
> Laszlo Ersek noted that the original example we had did not work
> properly if the size of the disk was larger than around 2G.
>
> The nbd_block_status API is really difficult to use correctly! In
> particular it is not guaranteed that the server will return extents
> covering the size requested. It's also not guaranteed that a bad
> server will return any base:allocation extents at all (although such a
> server would not be conforming - the protocol says that servers must
> always make forward progress).
>
> This commit attempts a fix, although it is not complete especially if
> the server is badly behaved. It also makes the output look a bit
> better by aligning the columns. Also we use nbdkit-sparse-random-
> plugin with a larger size to test the > 2G case.
> ---
> ocaml/examples/extents.ml | 53 ++++++++++++++++++++-------------------
> 1 file changed, 27 insertions(+), 26 deletions(-)
>
> diff --git a/ocaml/examples/extents.ml b/ocaml/examples/extents.ml
> index 6fa70e087..e4422b270 100644
> --- a/ocaml/examples/extents.ml
> +++ b/ocaml/examples/extents.ml
> @@ -4,32 +4,33 @@ let () =
> let nbd = NBD.create () in
> NBD.add_meta_context nbd "base:allocation";
> NBD.connect_command nbd
> - ["nbdkit"; "-s"; "--exit-with-parent"; "memory"; "size=128K"];
> -
> - (* Write some sectors. *)
> - let data_sector = Bytes.make 512 'a' in
> - let zero_sector = Bytes.make 512 '\000' in
> - NBD.pwrite nbd data_sector 0_L;
> - NBD.pwrite nbd zero_sector 32768_L;
> - NBD.pwrite nbd data_sector 65536_L;
> + ["nbdkit"; "-s"; "--exit-with-parent"; "-r";
> + "sparse-random"; "8G"];
>
> (* Read the extents and print them. *)
> let size = NBD.get_size nbd in
> - NBD.block_status nbd size 0_L (
> - fun meta _ entries err ->
> - printf "err=%d\n" !err;
> - if meta = "base:allocation" then (
> - printf "index\tlength\tflags\n";
> - for i = 0 to Array.length entries / 2 - 1 do
> - let flags =
> - match entries.(i*2+1) with
> - | 0_l -> "data"
> - | 1_l -> "hole"
> - | 2_l -> "zero"
> - | 3_l -> "hole+zero"
> - | i -> sprintf "unknown (%ld)" i in
> - printf "%d:\t%ld\t%s\n" i entries.(i*2) flags
> - done
> - );
> - 0
> - )
> + let fetch_offset = ref 0_L in
> + while !fetch_offset < size do
> + let remaining = Int64.sub size !fetch_offset in
> + let fetch_size = min remaining 0x8000_0000_L in
> + NBD.block_status nbd fetch_size !fetch_offset (
> + fun meta _ entries err ->
> + printf "nbd_block_status callback: meta=%s err=%d\n" meta !err;
> + if meta = "base:allocation" then (
> + printf "index\t%-20s %-20s %s\n" "offset" "length" "flags";
> + for i = 0 to Array.length entries / 2 - 1 do
> + let len = Int64.of_int32 entries.(i*2)
> + and flags =
> + match entries.(i*2+1) with
> + | 0_l -> "data"
> + | 1_l -> "hole"
> + | 2_l -> "zero"
> + | 3_l -> "hole+zero"
> + | i -> sprintf "unknown (%ld)" i in
> + printf "%d:\t%-20Ld %-20Ld %s\n" i !fetch_offset len flags;
Should we use right-justification for the numbers?
Reviewed-by: Laszlo Ersek <lersek at redhat.com>
Thanks!
Laszlo
> + fetch_offset := Int64.add !fetch_offset len
> + done;
> + );
> + 0
> + ) (* NBD.block_status *)
> + done
>
More information about the Libguestfs
mailing list