[Libguestfs] [PATCH nbdkit filters-v2 1/5] backend: Add prepare and finalize methods.

Richard W.M. Jones rjones at redhat.com
Fri Jan 19 15:23:32 UTC 2018


These methods are called just before and just after the data serving
phase respectively.  They are unused in this commit, but make more
sense when used from filters.
---
 src/connections.c | 37 +++++++++++++++++++++++++++++++++++++
 src/internal.h    |  2 ++
 src/plugins.c     | 18 ++++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/src/connections.c b/src/connections.c
index e225b5c..be19996 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -93,6 +93,8 @@ static struct connection *new_connection (int sockin, int sockout,
 static void free_connection (struct connection *conn);
 static int negotiate_handshake (struct connection *conn);
 static int recv_request_send_reply (struct connection *conn);
+static int prepare (struct connection *conn);
+static int finalize (struct connection *conn);
 
 /* Don't call these raw socket functions directly.  Use conn->recv etc. */
 static int raw_recv (struct connection *, void *buf, size_t len);
@@ -250,6 +252,10 @@ _handle_single_connection (int sockin, int sockout)
   if (negotiate_handshake (conn) == -1)
     goto done;
 
+  /* Prepare for data serving phase. */
+  if (prepare (conn) == -1)
+    goto done;
+
   if (!nworkers) {
     /* No need for a separate thread. */
     debug ("handshake complete, processing requests serially");
@@ -300,6 +306,10 @@ _handle_single_connection (int sockin, int sockout)
     free (workers);
   }
 
+  /* Finalize connection after data serving phase. */
+  if (finalize (conn) == -1)
+    goto done;
+
   r = get_status (conn);
  done:
   debug ("connection cleanup with final status %d", r);
@@ -775,6 +785,33 @@ negotiate_handshake (struct connection *conn)
   return r;
 }
 
+static int
+prepare (struct connection *conn)
+{
+  int r;
+
+  lock_request (conn);
+  r = backend->prepare (backend, conn);
+  unlock_request (conn);
+
+  return r;
+}
+
+static int
+finalize (struct connection *conn)
+{
+  int r;
+
+  lock_request (conn);
+  if (backend)
+    r = backend->finalize (backend, conn);
+  else
+    r = 0;
+  unlock_request (conn);
+
+  return r;
+}
+
 static bool
 valid_range (struct connection *conn, uint64_t offset, uint32_t count)
 {
diff --git a/src/internal.h b/src/internal.h
index 8047b3b..dbcd89c 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -165,6 +165,8 @@ struct backend {
   void (*config_complete) (struct backend *);
   int (*errno_is_preserved) (struct backend *);
   int (*open) (struct backend *, struct connection *conn, int readonly);
+  int (*prepare) (struct backend *, struct connection *conn);
+  int (*finalize) (struct backend *, struct connection *conn);
   void (*close) (struct backend *, struct connection *conn);
   int64_t (*get_size) (struct backend *, struct connection *conn);
   int (*can_write) (struct backend *, struct connection *conn);
diff --git a/src/plugins.c b/src/plugins.c
index 137bae3..da11c2c 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -251,6 +251,22 @@ plugin_open (struct backend *b, struct connection *conn, int readonly)
   return 0;
 }
 
+/* We don't expose .prepare and .finalize to plugins since they aren't
+ * necessary.  Plugins can easily do the same work in .open and
+ * .close.
+ */
+static int
+plugin_prepare (struct backend *b, struct connection *conn)
+{
+  return 0;
+}
+
+static int
+plugin_finalize (struct backend *b, struct connection *conn)
+{
+  return 0;
+}
+
 static void
 plugin_close (struct backend *b, struct connection *conn)
 {
@@ -503,6 +519,8 @@ static struct backend plugin_functions = {
   .config_complete = plugin_config_complete,
   .errno_is_preserved = plugin_errno_is_preserved,
   .open = plugin_open,
+  .prepare = plugin_prepare,
+  .finalize = plugin_finalize,
   .close = plugin_close,
   .get_size = plugin_get_size,
   .can_write = plugin_can_write,
-- 
2.15.1




More information about the Libguestfs mailing list