[Libguestfs] [nbdkit PATCH 0/7] Initial implementation of FUA flag passthrough

Richard W.M. Jones rjones at redhat.com
Tue Jan 16 08:25:16 UTC 2018


I had an idea about how we might do this and still keep a single
.pwrite method for plugins.  Maybe it's too complicated but here goes:


(1) Rename the pwrite method as pwrite_old1, and add new pwrite method
with either the FUA flag or general flags:

   int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset);
-  int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset);
+  int (*pwrite_old1) (void *handle, const void *buf, uint32_t count, uint64_t offset);
   int (*flush) (void *handle);
   int (*trim) (void *handle, uint32_t count, uint64_t offset);
   int (*zero) (void *handle, uint32_t count, uint64_t offset, int may_trim);
 
   int errno_is_preserved;
 
   void (*dump_plugin) (void);
 
+  int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags);


This is binary-compatible with old plugins, but not source compatible, so:


(2) Plugsin may optionally define NBDKIT_PLUGIN_LEVEL before including
<nbdkit-plugin.h>.  Code wishing to use the flags variant of pwrite
can do:

#define NBDKIT_PLUGIN_LEVEL 2
#include <nbdkit-plugin.h>

which would modify the definition of the struct (again), something
like:

#ifndef NBDKIT_PLUGIN_LEVEL
#define NBDKIT_PLUGIN_LEVEL 1
#endif

 ...
 
  int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset);
#if NBDKIT_PLUGIN_LEVEL <= 1
  int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset);
#else
  int (*pwrite_old1) (void *handle, const void *buf, uint32_t count, uint64_t offset);
#endif
  int (*flush) (void *handle);
  int (*trim) (void *handle, uint32_t count, uint64_t offset);
  int (*zero) (void *handle, uint32_t count, uint64_t offset, int may_trim);

  int errno_is_preserved;

  void (*dump_plugin) (void);

#if NBDKIT_PLUGIN_LEVEL <= 1
  int (*never_used1) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags);
#else
  int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags);
#endif


(3) Core nbdkit code always defines NBDKIT_PLUGIN_LEVEL == 2 so that
it always sees the new function, but it may need to call the old
function:

int
plugin_pwrite (...)
{
  if (plugin.pwrite != NULL)
    plugin.pwrite (handle, buf, count, offset, flags);
  else if (plugin.pwrite_old1 != NULL)
    plugin.pwrite_old1 (handle, buf, count, offset);
}


(4) Internal plugins which don't need the FUA flag can continue to use
the level 1 API, which means that we keep checking that the old API
still works.


What do you think?

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