[Libguestfs] [PATCH nbdkit v2 7/7] New filter: nbdkit-block-size-constraint-filter
Richard W.M. Jones
rjones at redhat.com
Thu Feb 17 20:55:43 UTC 2022
> > Subject: Re: [PATCH nbdkit v2 7/7] New filter: nbdkit-block-size-constraint-filter
Now also notice that I didn't change the commit message! Fixed in my
local copy.
On Thu, Feb 17, 2022 at 12:40:23PM -0600, Eric Blake wrote:
> On Thu, Feb 17, 2022 at 02:36:48PM +0000, Richard W.M. Jones wrote:
...
> > + nbdkit --filter=blocksize-policy \
> > + --filter=blocksize \
> > + PLUGIN ... \
> > + blocksize-error-policy=allow \
> > + blocksize-minimum=64K minblock=64K
> > +
> > +This says to advertise a minimum block size of 64K. Well-behaved
> > +clients will obey this. Badly behaved clients will send requests
> > +S<E<lt> 64K> which will be converted to slow 64K read-modify-write
> > +cycles to the underlying plugin. In either case the plugin will only
> > +see requests on 64K (or multiples of 64K) boundaries.
>
> Should the blocksize filter implement .block_size? But that's a
> separate patch compared to this one adding a new filter. The example
> looks good.
I think there's an argument for the blocksize filter returning minimum
the same as minblock (if set) and maximum the same as
MAX (maxlen, maxdata), but I think it is a separate patch.
...
> > + if (config_maximum)
> > + *maximum = config_maximum;
> > + else
> > + *maximum = 0xffffffff;
>
> I'd be inclined to advertise 64*1024*1024 here instead of 0xffffffff,
> to match the actual buffer size that we know nbdkit is constrained by.
>
> Then again, doing that may cause clients to self-limit calls to .zero
> with at most 64M in a chunk, instead of calling it with 4G in a chunk.
> It's a toss-up. (The NBD protocol really does need a fourth value, to
> distinguish between maximum buffer and maximum length)
Agreed. Clients shouldn't set > 32M pread/pwrite requests regardless
of the limit, if I'm reading the spec correctly.
...
> > +/* This function checks the error policy for all request functions below. */
> > +static int
> > +check_policy (nbdkit_next *next, const char *type,
> > + uint32_t count, uint64_t offset, int *err)
>
> Ah, new code compared to the last draft ;)
>
> > +{
> > + uint32_t minimum, preferred, maximum;
> > +
> > + if (error_policy == ALLOW)
> > + return 0;
> > +
> > + /* Get the current block size constraints. Note these are cached in
> > + * the backend so if they've already been computed then this simply
> > + * returns the cached values. The plugin is only asked once per
> > + * connection.
> > + */
> > + errno = 0;
> > + if (next->block_size (next, &minimum, &preferred, &maximum) == -1) {
> > + *err = errno ? : EIO;
> > + return -1;
> > + }
>
> Correct.
>
> > +
> > + /* If there are no constraints, allow. */
> > + if (minimum == 0)
> > + return 0;
> > +
> > + /* Check constraints. */
> > + if (count < minimum) {
> > + *err = EIO;
> > + nbdkit_error ("client %s request rejected: "
> > + "count %" PRIu32 " is smaller than minimum size %" PRIu32,
> > + type, count, minimum);
> > + return -1;
> > + }
> > + if (count > maximum) {
> > + *err = EIO;
> > + nbdkit_error ("client %s request rejected: "
> > + "count %" PRIu32 " is larger than maximum size %" PRIu32,
> > + type, count, maximum);
> > + return -1;
> > + }
>
> This is where I worry about size constraints on data (pread/pwrite)
> vs. length (zero/trim/cache). Again, I'm happy to propose a patch on
> top of this, so we can use this as our starting point.
Hmm, this is a good point that I didn't think about.
Maybe make the maximum check here conditional on it not being
a non-data request?
> > + if ((count % minimum) != 0) {
> > + *err = EIO;
> > + nbdkit_error ("client %s request rejected: "
> > + "count %" PRIu32 " is not a multiple "
> > + "of minimum size %" PRIu32,
> > + type, count, minimum);
> > + return -1;
> > + }
> > + if ((offset % minimum) != 0) {
> > + *err = EIO;
> > + nbdkit_error ("client %s request rejected: "
> > + "offset %" PRIu64 " is not aligned to a multiple "
> > + "of minimum size %" PRIu32,
> > + type, offset, minimum);
> > + return -1;
> > + }
>
> Do we also want to override .get_size, to flag (or round down) the
> case where the size reported by the plugin is not a multiple of the
> plugin's minsize, at which point those trailing bytes are inaccessbile
> to the client? Could be done on top.
>
> Overall the series looks good, I'll leave it up to you if you think it
> is ready to push now or if you want to adjust for one more round of
> reviews, and meanwhile I can start working on my proposed tweaks to
> compare on top to see how they look.
I've got a bit of thinking to do on it.
BTW I extended nbdkit-nbd-plugin proxy, OCaml and Python already, will
send those patches separately.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
More information about the Libguestfs
mailing list