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

Richard W.M. Jones rjones at redhat.com
Fri Jan 19 22:36:22 UTC 2018


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

diff --git a/src/connections.c b/src/connections.c
index e225b5c..e2de180 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);
@@ -246,6 +248,10 @@ _handle_single_connection (int sockin, int sockout)
 
   threadlocal_set_name (backend->plugin_name (backend));
 
+  /* Prepare (for filters), called just after open. */
+  if (prepare (conn) == -1)
+    goto done;
+
   /* Handshake. */
   if (negotiate_handshake (conn) == -1)
     goto done;
@@ -300,6 +306,10 @@ _handle_single_connection (int sockin, int sockout)
     free (workers);
   }
 
+  /* Finalize (for filters), called just before close. */
+  if (finalize (conn) == -1)
+    goto done;
+
   r = get_status (conn);
  done:
   debug ("connection cleanup with final status %d", r);
@@ -371,6 +381,36 @@ free_connection (struct connection *conn)
   free (conn);
 }
 
+static int
+prepare (struct connection *conn)
+{
+  int r;
+
+  lock_request (conn);
+  if (backend)
+    r = backend->prepare (backend, conn);
+  else
+    r = 0;
+  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 int
 compute_eflags (struct connection *conn, uint16_t *flags)
 {
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