On 11/22/19 3:30 PM, Eric Blake wrote:
>>> + switch (py_api_version) {
>>> + case 1:
>>> + r = PyObject_CallFunction (fn, "ONL", obj,
>>> + PyByteArray_FromStringAndSize
>>> (buf, count),
>>> + offset, NULL);
>>
>> Here, we could assert (flags == 0) (the FUA flag should not be set
>> if the plugin uses v1 API).
>
> Is that true? The plugin asserts that it wants the v1 API, but we are
> still using the v2 C API, whatever the plugin asks for?
Hmm. If the user implements a 'can_fua' callback that returns 1 even
though they forgot to declare 'api_version', then the flag can indeed be
set. Perhaps that means our 'can_fua' C wrapper should have a version
1/2 difference in behavior (in v1, raise an error reminding the user to
fix their plugin to declare 'api_version', in v2 pass back the result),
so that we could indeed then use the assert with a guarantee that it
will not trigger on an arbitrary plugin.
In fact, that would be similar to other things we've had to open-code in
python.c to mirror what plugins.c does automatically: basically,
plugins.c has:
/* The plugin must use API version 2 and have .can_fua return
NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
if (p->plugin.can_fua) {
r = p->plugin.can_fua (handle);
if (r > NBDKIT_FUA_EMULATE && p->plugin._api_version == 1)
r = NBDKIT_FUA_EMULATE;
return r;
and so python.c has to have the same logic when dealing with a v1 plugin
but exposing the v2 interface back to nbdkit. Compare to things like
py_can_write(), which has:
/* No Python can_write callback, but there's a Python pwrite callback
* defined, so return 1. (In C modules, nbdkit would do this).
*/
else if (callback_defined ("pwrite", NULL))
return 1;
for a similar duplication in logic to what plugins.c can do. I suspect
I'll run into this later in the series.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org