[Libguestfs] [PATCH nbdkit 1/4] Add truncate filter for truncating or extending the size of plugins.

Eric Blake eblake at redhat.com
Tue Jul 31 21:48:25 UTC 2018


On 07/31/2018 02:55 PM, Richard W.M. Jones wrote:
> This can truncate, extend, or round up/down to a multiple.
> ---
>   common-rules.mk                               |   3 +-
>   configure.ac                                  |   1 +
>   filters/offset/nbdkit-offset-filter.pod       |   7 +-
>   filters/partition/nbdkit-partition-filter.pod |   1 +
>   filters/truncate/Makefile.am                  |  60 ++++
>   filters/truncate/nbdkit-truncate-filter.pod   |  87 ++++++
>   filters/truncate/truncate.c                   | 261 ++++++++++++++++++
>   7 files changed, 417 insertions(+), 3 deletions(-)
> 

> +/* Get the size.  As a side effect, calculate the size to serve. */
> +static int64_t
> +truncate_get_size (struct nbdkit_next_ops *next_ops, void *nxdata,
> +                   void *handle)
> +{
> +  real_size = size = next_ops->get_size (nxdata);
> +
> +  /* The truncate, round-up and round-down parameters are treated as
> +   * separate operations.  It's possible to specify more than one,
> +   * although perhaps not very useful.
> +   */
> +  if (truncate >= 0)
> +    size = truncate;
> +  if (round_up > 0)
> +    size = (size + round_up - 1) & ~(round_up-1);
> +  if (round_down > 0)
> +    size &= ~(round_down-1);

These last two operations presuppose that the user passed in a power of 
2, but nothing actually enforces that the user did that.  Something like 
'round-up=5 round-down=3' thus produces strange results; I'd require 
powers of 2 to not have to worry about it elsewhere.

> +/* Return true iff the buffer is all zero bytes.
> + *
> + * The clever approach here was suggested by Eric Blake.  See:
> + * https://www.redhat.com/archives/libguestfs/2017-April/msg00171.html
> + */
> +static inline int

Worth using bool (via <stdbool.h>) here...

> +is_zero (const char *buffer, size_t size)
> +{
> +  size_t i;
> +  const size_t limit = size < 16 ? size : 16;
> +
> +  for (i = 0; i < limit; ++i)
> +    if (buffer[i])
> +      return 0;

...and actually returning false/true, to match the documentation?

Otherwise looks good to me.  The offset filter duplicates behavior when 
real_size > truncated size, but the real win with this filter is when 
real_size < truncated size for quickly padding a plugin's actual length 
into a more practical length (qemu already does just that on every 
single image, rounding out to sector boundaries, although when it comes 
to writing in the last partial sector, qemu actually tries to resize the 
underlying file, for slightly less predictable outcomes than your nice 
trick of EIO unless the action doesn't change the all-zero read nature 
of the tail).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




More information about the Libguestfs mailing list