[Libguestfs] [nbdkit PATCH 3/3] filters: Use only .thread_model, not THREAD_MODEL

Eric Blake eblake at redhat.com
Fri May 17 20:20:46 UTC 2019


No need for filters to specify their model in two different ways; the
callback alone is sufficient. Since all filters are in-tree, we can
deal with the API/ABI change made here.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 docs/nbdkit-filter.pod          | 48 +++++++++++++++------------------
 include/nbdkit-filter.h         |  6 ++---
 filters/cow/cow.c               |  2 --
 filters/delay/delay.c           |  2 --
 filters/error/error.c           |  2 --
 filters/fua/fua.c               |  2 --
 filters/log/log.c               |  2 --
 filters/nocache/nocache.c       |  2 --
 filters/noextents/noextents.c   |  2 --
 filters/noparallel/noparallel.c |  2 --
 filters/nozero/nozero.c         |  2 --
 filters/offset/offset.c         |  2 --
 filters/partition/partition.c   |  2 --
 filters/rate/rate.c             |  2 --
 filters/readahead/readahead.c   |  2 --
 filters/stats/stats.c           |  2 --
 filters/truncate/truncate.c     |  2 --
 filters/xz/xz.c                 |  6 ++++-
 server/filters.c                | 10 +++----
 19 files changed, 32 insertions(+), 68 deletions(-)

diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod
index 4033789..86894f1 100644
--- a/docs/nbdkit-filter.pod
+++ b/docs/nbdkit-filter.pod
@@ -6,8 +6,6 @@ nbdkit-filter - how to write nbdkit filters

  #include <nbdkit-filter.h>
  
- #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
- 
  static int
  myfilter_config (nbdkit_next_config *next, void *nxdata,
                   const char *key, const char *value)
@@ -107,24 +105,6 @@ should not expect to distribute filters separately from nbdkit.

 All filters should start by including this header file.

-=head1 C<#define THREAD_MODEL>
-
-All filters must define a default thread model by defining
-C<THREAD_MODEL>.  See L<nbdkit-plugin(3)/THREADS> for a discussion of
-thread models.
-
-The final thread model is the smallest (ie. most serialized) out of
-all the filters and the plugin.  Filters cannot alter the thread model
-to make it larger (more parallel).  However, they can dynamically
-request a smaller (more serialized) model from decisions made during
-C<.config> and C<.config_complete>, by implementing a <.thread_model>
-function callback.
-
-If possible filters should be be written to handle fully parallel
-requests (C<NBDKIT_THREAD_MODEL_PARALLEL>, even multiple requests
-issued in parallel on the same connection).  This ensures that they
-don't slow down other filters or plugins.
-
 =head1 C<struct nbdkit_filter>

 All filters must define and register one C<struct nbdkit_filter>,
@@ -275,13 +255,27 @@ omit this.

  int (*thread_model) (void);

-This optional function is called after C<.config_complete> to provide
-the filter an opportunity to reduce the resulting thread model below
-the value used at compilation via C<THREAD_MODEL>. The resulting
-thread model for all connections is determined by selecting the most
-restrictive model from the C<THREAD_MODEL> of the plugin and all
-filters, and from the results of any C<.thread_model> across all
-filters.
+=head1 C<#define THREAD_MODEL>
+
+Filters may tighten (but not relax) the thread model of the plugin, by
+defining this callback.  Note that while plugins use a compile-time
+definition of C<THREAD_MODEL>, filters do not need to declare a model
+at compile time; instead, this callback is called after
+C<.config_complete> and before any connections are created.  See
+L<nbdkit-plugin(3)/THREADS> for a discussion of thread models.
+
+The final thread model used by nbdkit is the smallest (ie. most
+serialized) out of all the filters and the plugin, and applies for all
+connections.  Requests for a model larger than permitted by the plugin
+are silently ignored. It is acceptable for decisions made during
+C<.config> and C<.config_complete> to determine which model to
+request.
+
+This callback is optional; if it is not present, the filter must be
+written to handle fully parallel requests, even if it is multiple
+requests issued in parallel on the same connection, similar to a
+plugin requesting C<NBDKIT_THREAD_MODEL_PARALLEL>.  This ensures the
+filter doesn't slow down other filters or plugins.

 If there is an error, C<.thread_model> should call C<nbdkit_error>
 with an error message and return C<-1>.
diff --git a/include/nbdkit-filter.h b/include/nbdkit-filter.h
index 70d32ce..94f1778 100644
--- a/include/nbdkit-filter.h
+++ b/include/nbdkit-filter.h
@@ -93,13 +93,12 @@ struct nbdkit_next_ops {
 };

 struct nbdkit_filter {
-  /* Do not set these fields directly; use NBDKIT_REGISTER_FILTER.
-   * They exist so that we can diagnose filters compiled against
+  /* Do not set this field directly; use NBDKIT_REGISTER_FILTER.
+   * It exists so that we can diagnose filters compiled against
    * one version of the header with a runtime compiled against a
    * different version.
    */
   int _api_version;
-  int _thread_model;

   /* Because there is no ABI guarantee, new fields may be added
    * where logically appropriate.  */
@@ -178,7 +177,6 @@ struct nbdkit_filter {
   filter_init (void)                                                    \
   {                                                                     \
     (filter)._api_version = NBDKIT_FILTER_API_VERSION;                  \
-    (filter)._thread_model = THREAD_MODEL;                              \
     return &(filter);                                                   \
   }

diff --git a/filters/cow/cow.c b/filters/cow/cow.c
index 006007e..ae4a3af 100644
--- a/filters/cow/cow.c
+++ b/filters/cow/cow.c
@@ -51,8 +51,6 @@
 #include "minmax.h"
 #include "rounding.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 /* In order to handle parallel requests safely, this lock must be held
  * when calling any blk_* functions.
  */
diff --git a/filters/delay/delay.c b/filters/delay/delay.c
index 486a24e..11681c8 100644
--- a/filters/delay/delay.c
+++ b/filters/delay/delay.c
@@ -40,8 +40,6 @@

 #include <nbdkit-filter.h>

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static int delay_read_ms = 0;   /* read delay (milliseconds) */
 static int delay_write_ms = 0;  /* write delay (milliseconds) */
 static int delay_zero_ms = 0;   /* zero delay (milliseconds) */
diff --git a/filters/error/error.c b/filters/error/error.c
index aba6213..968f283 100644
--- a/filters/error/error.c
+++ b/filters/error/error.c
@@ -48,8 +48,6 @@
 #include "cleanup.h"
 #include "random.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 struct error_settings {
   int error;                   /* errno, eg. EIO */
   double rate;                 /* rate, 0.0 = never, 1.0 = always */
diff --git a/filters/fua/fua.c b/filters/fua/fua.c
index 120ff0a..9d0e561 100644
--- a/filters/fua/fua.c
+++ b/filters/fua/fua.c
@@ -41,8 +41,6 @@

 #include <nbdkit-filter.h>

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static enum FuaMode {
   NONE,
   EMULATE,
diff --git a/filters/log/log.c b/filters/log/log.c
index 133e352..9c0f35c 100644
--- a/filters/log/log.c
+++ b/filters/log/log.c
@@ -47,8 +47,6 @@

 #include "cleanup.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static uint64_t connections;
 static char *logfilename;
 static FILE *logfile;
diff --git a/filters/nocache/nocache.c b/filters/nocache/nocache.c
index abb042e..a3f1198 100644
--- a/filters/nocache/nocache.c
+++ b/filters/nocache/nocache.c
@@ -43,8 +43,6 @@

 #include "minmax.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static enum CacheMode {
   NONE,
   EMULATE,
diff --git a/filters/noextents/noextents.c b/filters/noextents/noextents.c
index 59f4c37..e39723c 100644
--- a/filters/noextents/noextents.c
+++ b/filters/noextents/noextents.c
@@ -34,8 +34,6 @@

 #include <nbdkit-filter.h>

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static int
 noextents_can_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
                        void *handle)
diff --git a/filters/noparallel/noparallel.c b/filters/noparallel/noparallel.c
index 7034b01..057485f 100644
--- a/filters/noparallel/noparallel.c
+++ b/filters/noparallel/noparallel.c
@@ -41,8 +41,6 @@

 #include <nbdkit-filter.h>

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static int thread_model = NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS;

 static int
diff --git a/filters/nozero/nozero.c b/filters/nozero/nozero.c
index 6e0ffa9..16ec710 100644
--- a/filters/nozero/nozero.c
+++ b/filters/nozero/nozero.c
@@ -43,8 +43,6 @@

 #include "minmax.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 #define MAX_WRITE (64 * 1024 * 1024)

 static const char buffer[MAX_WRITE];
diff --git a/filters/offset/offset.c b/filters/offset/offset.c
index fe07d28..efe5c6d 100644
--- a/filters/offset/offset.c
+++ b/filters/offset/offset.c
@@ -41,8 +41,6 @@

 #include "cleanup.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static int64_t offset = 0, range = -1;

 /* Called for each key=value passed on the command line. */
diff --git a/filters/partition/partition.c b/filters/partition/partition.c
index ee2cc77..56ad05e 100644
--- a/filters/partition/partition.c
+++ b/filters/partition/partition.c
@@ -45,8 +45,6 @@

 #include "partition.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 int partnum = -1;

 /* Called for each key=value passed on the command line. */
diff --git a/filters/rate/rate.c b/filters/rate/rate.c
index cf03541..30e093e 100644
--- a/filters/rate/rate.c
+++ b/filters/rate/rate.c
@@ -50,8 +50,6 @@

 #include "bucket.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 /* Per-connection and global limit, both in bits per second, with zero
  * meaning not set / not enforced.  These are only used when reading
  * the command line and initializing the buckets for the first time.
diff --git a/filters/readahead/readahead.c b/filters/readahead/readahead.c
index 95bda0e..b6c1809 100644
--- a/filters/readahead/readahead.c
+++ b/filters/readahead/readahead.c
@@ -45,8 +45,6 @@
 #include "cleanup.h"
 #include "minmax.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 /* Copied from server/plugins.c. */
 #define MAX_REQUEST_SIZE (64 * 1024 * 1024)

diff --git a/filters/stats/stats.c b/filters/stats/stats.c
index 037fc61..4f94f73 100644
--- a/filters/stats/stats.c
+++ b/filters/stats/stats.c
@@ -47,8 +47,6 @@
 #include "cleanup.h"
 #include "tvdiff.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 static char *filename;
 static bool append;
 static FILE *fp;
diff --git a/filters/truncate/truncate.c b/filters/truncate/truncate.c
index 38b1cd9..64be839 100644
--- a/filters/truncate/truncate.c
+++ b/filters/truncate/truncate.c
@@ -46,8 +46,6 @@
 #include "iszero.h"
 #include "rounding.h"

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-
 /* These are the parameters. */
 static int64_t truncate_size = -1;
 static unsigned round_up = 0, round_down = 0;
diff --git a/filters/xz/xz.c b/filters/xz/xz.c
index 8ada294..51ac919 100644
--- a/filters/xz/xz.c
+++ b/filters/xz/xz.c
@@ -246,7 +246,10 @@ xz_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
   return 0;
 }

-#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS
+static int xz_thread_model (void)
+{
+  return NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS;
+}

 static struct nbdkit_filter filter = {
   .name              = "xz",
@@ -254,6 +257,7 @@ static struct nbdkit_filter filter = {
   .version           = PACKAGE_VERSION,
   .config            = xz_config,
   .config_help       = xz_config_help,
+  .thread_model      = xz_thread_model,
   .open              = xz_open,
   .close             = xz_close,
   .prepare           = xz_prepare,
diff --git a/server/filters.c b/server/filters.c
index 87a9c0e..3d9e1ef 100644
--- a/server/filters.c
+++ b/server/filters.c
@@ -93,20 +93,18 @@ static int
 filter_thread_model (struct backend *b)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
-  int filter_thread_model = f->filter._thread_model;
+  int filter_thread_model = NBDKIT_THREAD_MODEL_PARALLEL;
   int thread_model = f->backend.next->thread_model (f->backend.next);

-  if (filter_thread_model < thread_model) /* more serialized */
-    thread_model = filter_thread_model;
-
   if (f->filter.thread_model) {
     filter_thread_model = f->filter.thread_model ();
     if (filter_thread_model == -1)
       exit (EXIT_FAILURE);
-    if (filter_thread_model < thread_model)
-      thread_model = filter_thread_model;
   }

+  if (filter_thread_model < thread_model) /* more serialized */
+    thread_model = filter_thread_model;
+
   return thread_model;
 }

-- 
2.20.1




More information about the Libguestfs mailing list