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 <[email protected]> Thanks! Laszlo > + fetch_offset := Int64.add !fetch_offset len > + done; > + ); > + 0 > + ) (* NBD.block_status *) > + done > _______________________________________________ Libguestfs mailing list [email protected] https://listman.redhat.com/mailman/listinfo/libguestfs
