[Libguestfs] [PATCH nbdkit v2 03/10] python: Implement nbdkit API version 2.

Richard W.M. Jones rjones at redhat.com
Fri Nov 22 21:14:26 UTC 2019


On Fri, Nov 22, 2019 at 02:55:31PM -0600, Eric Blake wrote:
> On 11/22/19 1:53 PM, Richard W.M. Jones wrote:
> >To avoid breaking existing plugins, Python plugins wishing to use
> >version 2 of the API must opt in by declaring:
> >
> >   def api_version():
> >     return 2
> >
> >(Plugins which do not do this are assumed to want API version 1).
> 
> Could we also permit the python code to declare a global variable
> instead of a function?  But a function is just fine (and easier to
> integrate the way we do all our other callbacks).

I couldn't work out how to do this, plus we have the callback_defined
function which makes this easy, so yes, I did the easy thing :-)

> >@@ -54,20 +61,20 @@ def get_size(h):
> >      return len(disk)
> >-def pread(h, count, offset):
> >+def pread(h, count, offset, flags):
> >      global disk
> >      return disk[offset:offset+count]
> 
> Do we really want to be passing 'flags' as an integer that the
> python script must decode?

While I'm no Python programmer, it does look as if existing Python
core APIs are happy to use bitmasks, eg:

  https://docs.python.org/3/library/os.html#os.open

and this is also easy to implement and keeps it similar to the C API.

> >- def pwrite(h, buf, offset):
> >+ def pwrite(h, buf, offset, flags):
> >     length = len (buf)
> >     # no return value
> >  The body of your C<pwrite> function should write the C<buf> string to
> >  the disk.  You should write C<count> bytes to the disk starting at
> >-C<offset>.
> >+C<offset>.  C<flags> may contain C<nbdkit.FLAG_FUA>.
> 
> Should we mention that FLAG_FUA is only set if the python callback
> can_fua returned 1?  Or is that somewhat redundant with the fact
> that we already document that someone writing a python plugin should
> be familiar with the docs for C plugins, and that guarantee is
> already in the C plugin docs?

I think it would be better if we simply referred back to the C
documentation to avoid duplication.  Also an advantage of using
bitmasks.  That does require a rather larger change to the
documentation though.

> >  static int
> >-py_pwrite (void *handle, const void *buf,
> >-           uint32_t count, uint64_t offset)
> >+py_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
> >+           uint32_t flags)
> >  {
> >    PyObject *obj = handle;
> >    PyObject *fn;
> >@@ -515,9 +546,19 @@ py_pwrite (void *handle, const void *buf,
> >    if (callback_defined ("pwrite", &fn)) {
> >      PyErr_Clear ();
> >-    r = PyObject_CallFunction (fn, "ONL", obj,
> >-                               PyByteArray_FromStringAndSize (buf, count),
> >-                               offset, NULL);
> >+    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?

I'm cautious about adding asserts unless they can never happen now or
in the future, because we don't really want an assert() happening on a
customer site running virt-v2v with the rhv-upload Python plugin.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/




More information about the Libguestfs mailing list