[Libguestfs] [nbdkit] Proposed (new) filter API

Richard W.M. Jones rjones at redhat.com
Tue Jan 16 14:40:15 UTC 2018


Here's my second attempt at a filter API.

As before, .config and .config_complete can only call the
next->.config or next->.config_complete methods in the chain
respectively.

The change is with the connected functions (get_size, pread, pwrite,
etc.).  Here we pass a struct of next functions allowing the filter to
call any functions on the plugin, so for example a write can turn into
read + write (and vice versa although that might not be a good idea).

Also .open and .close cannot be intercepted by the filter.  They're
just used to allow the filter to allocate a handle.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
-------------- next part --------------
/* nbdkit
 * Copyright (C) 2013-2017 Red Hat Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of Red Hat nor the names of its contributors may be
 * used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* See nbdkit-filter(3) for documentation and how to write a filter. */

#ifndef NBDKIT_FILTER_H
#define NBDKIT_FILTER_H

/* This header also defines some useful functions like nbdkit_debug
 * and nbdkit_parse_size which are appropriate for filters to use.
 */
#include <nbdkit-plugin.h>

#ifdef __cplusplus
extern "C" {
#endif

#define NBDKIT_FILTER_API_VERSION 1

typedef int (*nbdkit_next_config) (void *nxdata,
                                   const char *key, const char *value);
typedef int (*nbdkit_next_config_complete) (void *nxdata);

struct nbdkit_next {
  int64_t (*get_size) (void *nxdata);

  int (*can_write) (void *nxdata);
  int (*can_flush) (void *nxdata);
  int (*is_rotational) (void *nxdata);
  int (*can_trim) (void *nxdata);

  int (*pread) (void *nxdata, void *buf, uint32_t count, uint64_t offset);
  int (*pwrite) (void *nxdata,
                 const void *buf, uint32_t count, uint64_t offset);
  int (*flush) (void *nxdata);
  int (*trim) (void *nxdata, uint32_t count, uint64_t offset);
  int (*zero) (void *nxdata, uint32_t count, uint64_t offset, int may_trim);
};

struct nbdkit_filter {
  /* Do not set these fields directly; use NBDKIT_REGISTER_FILTER.
   * They exist so that we can support filters compiled against
   * one version of the header with a runtime compiled against a
   * different version with more (or fewer) fields.
   */
  uint64_t _struct_size;
  int _api_version;

  /* New fields will only be added at the end of the struct. */
  const char *name;
  const char *longname;
  const char *version;
  const char *description;

  void (*load) (void);
  void (*unload) (void);

  int (*config) (nbdkit_next_config *next, void *nxdata,
                 const char *key, const char *value);
  int (*config_complete) (nbdkit_next_config_complete *next, void *nxdata);
  const char *config_help;

  void * (*open) (int readonly);
  void (*close) (void *handle);

  int64_t (*get_size) (struct nbdkit_next *next, void *nxdata,
                       void *handle);

  int (*can_write) (struct nbdkit_next *next, void *nxdata,
                    void *handle);
  int (*can_flush) (struct nbdkit_next *next, void *nxdata,
                    void *handle);
  int (*is_rotational) (struct nbdkit_next *next,
                        void *nxdata,
                        void *handle);
  int (*can_trim) (struct nbdkit_next *next, void *nxdata,
                   void *handle);

  int (*pread) (struct nbdkit_next *next, void *nxdata,
                void *handle, void *buf, uint32_t count, uint64_t offset);
  int (*pwrite) (struct nbdkit_next *next, void *nxdata,
                 void *handle,
                 const void *buf, uint32_t count, uint64_t offset);
  int (*flush) (struct nbdkit_next *next, void *nxdata,
                void *handle);
  int (*trim) (struct nbdkit_next *next, void *nxdata,
               void *handle, uint32_t count, uint64_t offset);
  int (*zero) (struct nbdkit_next *next, void *nxdata,
               void *handle, uint32_t count, uint64_t offset, int may_trim);
};

#ifndef NBDKIT_CXX_LANG_C
#ifdef __cplusplus
#define NBDKIT_CXX_LANG_C extern "C"
#else
#define NBDKIT_CXX_LANG_C /* nothing */
#endif
#endif

#define NBDKIT_REGISTER_FILTER(filter)                                  \
  NBDKIT_CXX_LANG_C                                                     \
  struct nbdkit_filter *                                                \
  filter_init (void)                                                    \
  {                                                                     \
    (filter)._struct_size = sizeof (filter);                            \
    (filter)._api_version = NBDKIT_API_VERSION;                         \
    return &(filter);                                                   \
  }

#ifdef __cplusplus
}
#endif

#endif /* NBDKIT_FILTER_H */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nbdkit-filter.pod
Type: text/x-pod
Size: 14797 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20180116/88ab47f0/attachment.pod>


More information about the Libguestfs mailing list