[Libguestfs] [PATCH nbdkit BROKEN 1/2] BROKEN vddk: Support multi-conn, but only open one VDDK connection

Richard W.M. Jones rjones at redhat.com
Thu Dec 16 10:31:54 UTC 2021


***
BROKEN: Increases the time taken to do an nbdcopy by about 66%.  All
of the extra time is taken in QueryAllocatedBlocks even though we make
the same number of calls before and after.  It seems as if
QueryAllocatedBlocks really cannot be overlapped with other operations
even on the same connection.
***

On the NBD side, support multi-conn.  However actually opening
multiple VDDK connections causes severe slowdowns:

https://github.com/libguestfs/virt-v2v/commit/bb0e698360470cb4ff5992e8e01a3165f56fe41e

So instead only ever hold a single VDDK handle open.  It is opened
when the first NBD connection is made and closed when the last NBD
connection is closed.  There is only a single VDDK worker thread for
the same reason.

The change is mostly mechanical - we get rid of the per-connection
handle, store everything as globals, and make sure we only connect
once to VDDK on first connection and disconnect once on final
disconnection.

We can then advertise multi-conn.
---
 plugins/vddk/vddk.h   |  30 +++----
 plugins/vddk/vddk.c   | 196 ++++++++++++++++++++++++------------------
 plugins/vddk/worker.c |  69 ++++++++-------
 3 files changed, 157 insertions(+), 138 deletions(-)

diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h
index d99b6f4b..162e05c6 100644
--- a/plugins/vddk/vddk.h
+++ b/plugins/vddk/vddk.h
@@ -75,6 +75,10 @@ extern int vddk_debug_extents;
 extern int vddk_debug_datapath;
 extern int vddk_debug_stats;
 
+extern VixDiskLibHandle handle;
+
+extern pthread_t worker_thread;
+
 #define STUB(fn,ret,args) extern ret (*fn) args
 #define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args)
 #include "vddk-stubs.h"
@@ -143,24 +147,10 @@ struct command {
 
 DEFINE_VECTOR_TYPE(command_queue, struct command *)
 
-/* The per-connection handle. */
-struct vddk_handle {
-  VixDiskLibConnectParams *params; /* connection parameters */
-  VixDiskLibConnection connection; /* connection */
-  VixDiskLibHandle handle;         /* disk handle */
-
-  pthread_t thread;                /* background thread for asynch work */
-
-  /* Command queue of commands sent to the background thread.  Use
-   * send_command_and_wait to add a command.  Only the background
-   * thread must make VDDK API calls (apart from opening and closing).
-   * The lock protects all of these fields.
-   */
-  pthread_mutex_t commands_lock;   /* lock */
-  command_queue commands;          /* command queue */
-  pthread_cond_t commands_cond;    /* condition (queue size 0 -> 1) */
-  uint64_t id;                     /* next command ID */
-};
+extern pthread_mutex_t commands_lock;
+extern command_queue commands;
+extern pthread_cond_t commands_cond;
+extern uint64_t next_command_id;
 
 /* reexec.c */
 extern bool noreexec;
@@ -188,7 +178,7 @@ extern void trim (char *str);
 
 /* worker.c */
 extern const char *command_type_string (enum command_type type);
-extern int send_command_and_wait (struct vddk_handle *h, struct command *cmd);
-extern void *vddk_worker_thread (void *handle);
+extern int send_command_and_wait (struct command *cmd);
+extern void *vddk_worker_thread (void *);
 
 #endif /* NBDKIT_VDDK_H */
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 31e5e23b..09a84908 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -95,6 +95,21 @@ bool unbuffered;                       /* unbuffered */
 const char *username;                  /* user */
 const char *vmx_spec;                  /* vm */
 
+VixDiskLibHandle handle;               /* disk handle */
+
+pthread_t worker_thread;               /* background thread for asynch work */
+
+/* Command queue of commands sent to the background thread.  Use
+ * send_command_and_wait to add a command.  Only the background
+ * thread must make VDDK API calls (apart from opening and closing).
+ * The lock protects all of these fields.
+ */
+pthread_mutex_t commands_lock = PTHREAD_MUTEX_INITIALIZER;
+command_queue commands = empty_vector; /* command queue */
+pthread_cond_t commands_cond = PTHREAD_COND_INITIALIZER;
+                                       /* condition (queue size 0 -> 1) */
+uint64_t next_command_id;              /* next command ID */
+
 /* Unload the plugin. */
 static void
 vddk_unload (void)
@@ -511,15 +526,29 @@ vddk_dump_plugin (void)
  * Before nbdkit 1.22 we used SERIALIZE_ALL_REQUESTS.  In nbdkit
  * 1.22-1.28 we changed this to SERIALIZE_REQUESTS and added a mutex
  * around calls to VixDiskLib_Open and VixDiskLib_Close.  In nbdkit
- * 1.30 and above we assign a background thread per connection to do
- * asynch operations and use the PARALLEL model.  We still need the
- * lock around Open and Close.
+ * 1.30 and above we assign a background thread to asynch operations
+ * and use the PARALLEL model.  We only connect to VDDK at most once.
+ * We still need the lock around Open and Close.
  */
 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
 
 /* Lock protecting open/close calls - see above. */
 static pthread_mutex_t open_close_lock = PTHREAD_MUTEX_INITIALIZER;
 
+static int nr_opened;           /* number of handles opened */
+
+static VixDiskLibConnectParams *params;       /* connection parameters */
+static VixDiskLibConnection connection;       /* connection */
+
+static int
+vddk_can_multi_conn (void *h)
+{
+  /* We support multiple NBD connections, but we will only open one
+   * VDDK connection.
+   */
+  return 1;
+}
+
 static inline VixDiskLibConnectParams *
 allocate_connect_params (void)
 {
@@ -537,64 +566,53 @@ allocate_connect_params (void)
 }
 
 static inline void
-free_connect_params (VixDiskLibConnectParams *params)
+free_connect_params (VixDiskLibConnectParams *p)
 {
   /* Only use FreeConnectParams if AllocateConnectParams was
    * originally called.  Otherwise use free.
    */
   if (VixDiskLib_AllocateConnectParams != NULL) {
     VDDK_CALL_START (VixDiskLib_FreeConnectParams, "params")
-      VixDiskLib_FreeConnectParams (params);
+      VixDiskLib_FreeConnectParams (p);
     VDDK_CALL_END (VixDiskLib_FreeConnectParams, 0);
   }
   else
-    free (params);
+    free (p);
 }
 
-/* Create the per-connection handle. */
-static void *
-vddk_open (int readonly)
+/* Really open the connection. */
+static int
+do_open (int readonly)
 {
-  ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&open_close_lock);
-  struct vddk_handle *h;
   VixError err;
   uint32_t flags;
   const char *transport_mode;
   int pterr;
 
-  h = calloc (1, sizeof *h);
-  if (h == NULL) {
-    nbdkit_error ("calloc: %m");
-    return NULL;
-  }
-  h->commands = (command_queue) empty_vector;
-  pthread_mutex_init (&h->commands_lock, NULL);
-  pthread_cond_init (&h->commands_cond, NULL);
-
-  h->params = allocate_connect_params ();
-  if (h->params == NULL) {
+  params = allocate_connect_params ();
+  if (params == NULL) {
     nbdkit_error ("allocate VixDiskLibConnectParams: %m");
     goto err0;
   }
 
   if (is_remote) {
-    h->params->vmxSpec = (char *) vmx_spec;
-    h->params->serverName = (char *) server_name;
+    params->vmxSpec = (char *) vmx_spec;
+    params->serverName = (char *) server_name;
     if (cookie == NULL) {
-      h->params->credType = VIXDISKLIB_CRED_UID;
-      h->params->creds.uid.userName = (char *) username;
-      h->params->creds.uid.password = password;
+      params->credType = VIXDISKLIB_CRED_UID;
+      params->creds.uid.userName = (char *) username;
+      params->creds.uid.password = password;
     }
     else {
-      h->params->credType = VIXDISKLIB_CRED_SESSIONID;
-      h->params->creds.sessionId.cookie = (char *) cookie;
-      h->params->creds.sessionId.userName = (char *) username;
-      h->params->creds.sessionId.key = password;
+      params->credType = VIXDISKLIB_CRED_SESSIONID;
+      params->creds.sessionId.cookie = (char *) cookie;
+      params->creds.sessionId.userName = (char *) username;
+      params->creds.sessionId.key = password;
     }
-    h->params->thumbPrint = (char *) thumb_print;
-    h->params->port = port;
-    h->params->nfcHostPort = nfc_host_port;
-    h->params->specType = VIXDISKLIB_SPEC_VMX;
+    params->thumbPrint = (char *) thumb_print;
+    params->port = port;
+    params->nfcHostPort = nfc_host_port;
+    params->specType = VIXDISKLIB_SPEC_VMX;
   }
 
   /* XXX We should call VixDiskLib_PrepareForAccess here.  It disables
@@ -603,15 +621,15 @@ vddk_open (int readonly)
    */
 
   VDDK_CALL_START (VixDiskLib_ConnectEx,
-                   "h->params, %d, %s, %s, &connection",
+                   "params, %d, %s, %s, &connection",
                    readonly,
                    snapshot_moref ? : "NULL",
                    transport_modes ? : "NULL")
-    err = VixDiskLib_ConnectEx (h->params,
+    err = VixDiskLib_ConnectEx (params,
                                 readonly,
                                 snapshot_moref,
                                 transport_modes,
-                                &h->connection);
+                                &connection);
   VDDK_CALL_END (VixDiskLib_ConnectEx, 0);
   if (err != VIX_OK) {
     VDDK_ERROR (err, "VixDiskLib_ConnectEx");
@@ -634,7 +652,7 @@ vddk_open (int readonly)
 
   VDDK_CALL_START (VixDiskLib_Open,
                    "connection, %s, %d, &handle", filename, flags)
-    err = VixDiskLib_Open (h->connection, filename, flags, &h->handle);
+    err = VixDiskLib_Open (connection, filename, flags, &handle);
   VDDK_CALL_END (VixDiskLib_Open, 0);
   if (err != VIX_OK) {
     VDDK_ERROR (err, "VixDiskLib_Open: %s", filename);
@@ -642,73 +660,89 @@ vddk_open (int readonly)
   }
 
   VDDK_CALL_START (VixDiskLib_GetTransportMode, "handle")
-    transport_mode = VixDiskLib_GetTransportMode (h->handle);
+    transport_mode = VixDiskLib_GetTransportMode (handle);
   VDDK_CALL_END (VixDiskLib_GetTransportMode, 0);
   nbdkit_debug ("transport mode: %s", transport_mode);
 
   /* Start the background thread which actually does the asynchronous
    * work.
    */
-  pterr = pthread_create (&h->thread, NULL, vddk_worker_thread, h);
+  pterr = pthread_create (&worker_thread, NULL, vddk_worker_thread, NULL);
   if (pterr != 0) {
     errno = pterr;
     nbdkit_error ("pthread_create: %m");
     goto err3;
   }
 
-  return h;
+  return 0;
 
  err3:
   VDDK_CALL_START (VixDiskLib_Close, "handle")
-    VixDiskLib_Close (h->handle);
+    VixDiskLib_Close (handle);
   VDDK_CALL_END (VixDiskLib_Close, 0);
  err2:
   VDDK_CALL_START (VixDiskLib_Disconnect, "connection")
-    VixDiskLib_Disconnect (h->connection);
+    VixDiskLib_Disconnect (connection);
   VDDK_CALL_END (VixDiskLib_Disconnect, 0);
  err1:
-  free_connect_params (h->params);
+  free_connect_params (params);
  err0:
-  pthread_mutex_destroy (&h->commands_lock);
-  pthread_cond_destroy (&h->commands_cond);
-  free (h);
-  return NULL;
+  return -1;
 }
 
-/* Free up the per-connection handle. */
+/* Really close the connection. */
 static void
-vddk_close (void *handle)
+do_close (void)
 {
-  ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&open_close_lock);
-  struct vddk_handle *h = handle;
   struct command stop_cmd = { .type = STOP };
 
-  send_command_and_wait (h, &stop_cmd);
-  pthread_join (h->thread, NULL);
+  send_command_and_wait (&stop_cmd);
+  pthread_join (worker_thread, NULL);
 
   VDDK_CALL_START (VixDiskLib_Close, "handle")
-    VixDiskLib_Close (h->handle);
+    VixDiskLib_Close (handle);
   VDDK_CALL_END (VixDiskLib_Close, 0);
   VDDK_CALL_START (VixDiskLib_Disconnect, "connection")
-    VixDiskLib_Disconnect (h->connection);
+    VixDiskLib_Disconnect (connection);
   VDDK_CALL_END (VixDiskLib_Disconnect, 0);
 
-  free_connect_params (h->params);
-  pthread_mutex_destroy (&h->commands_lock);
-  pthread_cond_destroy (&h->commands_cond);
-  command_queue_reset (&h->commands);
-  free (h);
+  free_connect_params (params);
+  command_queue_reset (&commands);
+}
+
+static void *
+vddk_open (int readonly)
+{
+  ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&open_close_lock);
+
+  if (nr_opened == 0) {
+    if (do_open (readonly) == -1)
+      return NULL;
+  }
+
+  nr_opened++;
+  return NBDKIT_HANDLE_NOT_NEEDED;
+}
+
+static void
+vddk_close (void *h)
+{
+  ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&open_close_lock);
+
+  if (nr_opened == 1)
+    do_close ();
+
+  nr_opened--;
 }
 
 /* Get the file size. */
 static int64_t
-vddk_get_size (void *handle)
+vddk_get_size (void *h)
 {
-  struct vddk_handle *h = handle;
   uint64_t size;
   struct command get_size_cmd = { .type = GET_SIZE, .ptr = &size };
 
-  if (send_command_and_wait (h, &get_size_cmd) == -1)
+  if (send_command_and_wait (&get_size_cmd) == -1)
     return -1;
 
   return (int64_t) size;
@@ -718,13 +752,13 @@ vddk_get_size (void *handle)
  * we are always able to do FUA / flush.
  */
 static int
-vddk_can_fua (void *handle)
+vddk_can_fua (void *h)
 {
   return NBDKIT_FUA_NATIVE;
 }
 
 static int
-vddk_can_flush (void *handle)
+vddk_can_flush (void *h)
 {
   return 1;
 }
@@ -734,10 +768,9 @@ vddk_can_flush (void *handle)
  * Note that reads have to be aligned to sectors (XXX).
  */
 static int
-vddk_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
+vddk_pread (void *h, void *buf, uint32_t count, uint64_t offset,
             uint32_t flags)
 {
-  struct vddk_handle *h = handle;
   struct command read_cmd = {
     .type = READ,
     .ptr = buf,
@@ -745,20 +778,19 @@ vddk_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
     .offset = offset,
   };
 
-  return send_command_and_wait (h, &read_cmd);
+  return send_command_and_wait (&read_cmd);
 }
 
-static int vddk_flush (void *handle, uint32_t flags);
+static int vddk_flush (void *h, uint32_t flags);
 
 /* Write data to the file.
  *
  * Note that writes have to be aligned to sectors (XXX).
  */
 static int
-vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
+vddk_pwrite (void *h, const void *buf, uint32_t count, uint64_t offset,
              uint32_t flags)
 {
-  struct vddk_handle *h = handle;
   const bool fua = flags & NBDKIT_FLAG_FUA;
   struct command write_cmd = {
     .type = WRITE,
@@ -767,7 +799,7 @@ vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
     .offset = offset,
   };
 
-  if (send_command_and_wait (h, &write_cmd) == -1)
+  if (send_command_and_wait (&write_cmd) == -1)
     return -1;
 
   if (fua) {
@@ -780,32 +812,29 @@ vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
 
 /* Flush data to the file. */
 static int
-vddk_flush (void *handle, uint32_t flags)
+vddk_flush (void *h, uint32_t flags)
 {
-  struct vddk_handle *h = handle;
   struct command flush_cmd = { .type = FLUSH };
 
-  return send_command_and_wait (h, &flush_cmd);
+  return send_command_and_wait (&flush_cmd);
 }
 
 static int
-vddk_can_extents (void *handle)
+vddk_can_extents (void *h)
 {
-  struct vddk_handle *h = handle;
   int ret;
   struct command can_extents_cmd = { .type = CAN_EXTENTS, .ptr = &ret };
 
-  if (send_command_and_wait (h, &can_extents_cmd) == -1)
+  if (send_command_and_wait (&can_extents_cmd) == -1)
     return -1;
 
   return ret;
 }
 
 static int
-vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags,
+vddk_extents (void *h, uint32_t count, uint64_t offset, uint32_t flags,
               struct nbdkit_extents *extents)
 {
-  struct vddk_handle *h = handle;
   bool req_one = flags & NBDKIT_FLAG_REQ_ONE;
   struct command extents_cmd = {
     .type = EXTENTS,
@@ -815,7 +844,7 @@ vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags,
     .req_one = req_one,
   };
 
-  return send_command_and_wait (h, &extents_cmd);
+  return send_command_and_wait (&extents_cmd);
 }
 
 static struct nbdkit_plugin plugin = {
@@ -830,6 +859,7 @@ static struct nbdkit_plugin plugin = {
   .dump_plugin       = vddk_dump_plugin,
   .get_ready         = vddk_get_ready,
   .after_fork        = vddk_after_fork,
+  .can_multi_conn    = vddk_can_multi_conn,
   .open              = vddk_open,
   .close             = vddk_close,
   .get_size          = vddk_get_size,
diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c
index c6e2fd22..4bb7d8d7 100644
--- a/plugins/vddk/worker.c
+++ b/plugins/vddk/worker.c
@@ -70,20 +70,20 @@ command_type_string (enum command_type type)
  * On error, calls nbdkit_error and returns -1.
  */
 int
-send_command_and_wait (struct vddk_handle *h, struct command *cmd)
+send_command_and_wait (struct command *cmd)
 {
   /* Add the command to the command queue. */
   {
-    ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&h->commands_lock);
-    cmd->id = h->id++;
+    ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&commands_lock);
+    cmd->id = next_command_id++;
 
-    if (command_queue_append (&h->commands, cmd) == -1)
+    if (command_queue_append (&commands, cmd) == -1)
       /* On error command_queue_append will call nbdkit_error. */
       return -1;
 
     /* Signal the caller if it could be sleeping on an empty queue. */
-    if (h->commands.len == 1)
-      pthread_cond_signal (&h->commands_cond);
+    if (commands.len == 1)
+      pthread_cond_signal (&commands_cond);
 
     /* This will be used to signal command completion back to us. */
     pthread_mutex_init (&cmd->mutex, NULL);
@@ -132,13 +132,13 @@ complete_command (void *vp, VixError result)
 
 /* Wait for any asynchronous commands to complete. */
 static int
-do_stop (struct command *cmd, struct vddk_handle *h)
+do_stop (struct command *cmd)
 {
   VixError err;
 
   /* Because we assume VDDK >= 6.5, VixDiskLib_Wait must exist. */
   VDDK_CALL_START (VixDiskLib_Wait, "handle")
-    err = VixDiskLib_Wait (h->handle);
+    err = VixDiskLib_Wait (handle);
   VDDK_CALL_END (VixDiskLib_Wait, 0);
   if (err != VIX_OK) {
     VDDK_ERROR (err, "VixDiskLib_Wait");
@@ -152,14 +152,14 @@ do_stop (struct command *cmd, struct vddk_handle *h)
 
 /* Get size command. */
 static int64_t
-do_get_size (struct command *cmd, struct vddk_handle *h)
+do_get_size (struct command *cmd)
 {
   VixError err;
   VixDiskLibInfo *info;
   uint64_t size;
 
   VDDK_CALL_START (VixDiskLib_GetInfo, "handle, &info")
-    err = VixDiskLib_GetInfo (h->handle, &info);
+    err = VixDiskLib_GetInfo (handle, &info);
   VDDK_CALL_END (VixDiskLib_GetInfo, 0);
   if (err != VIX_OK) {
     VDDK_ERROR (err, "VixDiskLib_GetInfo");
@@ -203,7 +203,7 @@ do_get_size (struct command *cmd, struct vddk_handle *h)
 }
 
 static int
-do_read (struct command *cmd, struct vddk_handle *h)
+do_read (struct command *cmd)
 {
   VixError err;
   uint32_t count = cmd->count;
@@ -226,7 +226,7 @@ do_read (struct command *cmd, struct vddk_handle *h)
                    "handle, %" PRIu64 " sectors, "
                    "%" PRIu32 " sectors, buffer, callback, %" PRIu64,
                    offset, count, cmd->id)
-    err = VixDiskLib_ReadAsync (h->handle, offset, count, buf,
+    err = VixDiskLib_ReadAsync (handle, offset, count, buf,
                                 complete_command, cmd);
   VDDK_CALL_END (VixDiskLib_ReadAsync, count * VIXDISKLIB_SECTOR_SIZE);
   if (err != VIX_ASYNC) {
@@ -238,7 +238,7 @@ do_read (struct command *cmd, struct vddk_handle *h)
 }
 
 static int
-do_write (struct command *cmd, struct vddk_handle *h)
+do_write (struct command *cmd)
 {
   VixError err;
   uint32_t count = cmd->count;
@@ -261,7 +261,7 @@ do_write (struct command *cmd, struct vddk_handle *h)
                    "handle, %" PRIu64 " sectors, "
                    "%" PRIu32 " sectors, buffer, callback, %" PRIu64,
                    offset, count, cmd->id)
-    err = VixDiskLib_WriteAsync (h->handle, offset, count, buf,
+    err = VixDiskLib_WriteAsync (handle, offset, count, buf,
                                  complete_command, cmd);
   VDDK_CALL_END (VixDiskLib_WriteAsync, count * VIXDISKLIB_SECTOR_SIZE);
   if (err != VIX_ASYNC) {
@@ -273,7 +273,7 @@ do_write (struct command *cmd, struct vddk_handle *h)
 }
 
 static int
-do_flush (struct command *cmd, struct vddk_handle *h)
+do_flush (struct command *cmd)
 {
   VixError err;
 
@@ -282,7 +282,7 @@ do_flush (struct command *cmd, struct vddk_handle *h)
    * except to print them.
    */
   VDDK_CALL_START (VixDiskLib_Wait, "handle")
-    err = VixDiskLib_Wait (h->handle);
+    err = VixDiskLib_Wait (handle);
   VDDK_CALL_END (VixDiskLib_Wait, 0);
   if (err != VIX_OK)
     VDDK_ERROR (err, "VixDiskLib_Wait");
@@ -295,7 +295,7 @@ do_flush (struct command *cmd, struct vddk_handle *h)
    * here.
    */
   VDDK_CALL_START (VixDiskLib_Flush, "handle")
-    err = VixDiskLib_Flush (h->handle);
+    err = VixDiskLib_Flush (handle);
   VDDK_CALL_END (VixDiskLib_Flush, 0);
   if (err != VIX_OK) {
     VDDK_ERROR (err, "VixDiskLib_Flush");
@@ -306,7 +306,7 @@ do_flush (struct command *cmd, struct vddk_handle *h)
 }
 
 static int
-do_can_extents (struct command *cmd, struct vddk_handle *h)
+do_can_extents (struct command *cmd)
 {
   VixError err;
   VixDiskLibBlockList *block_list;
@@ -332,7 +332,7 @@ do_can_extents (struct command *cmd, struct vddk_handle *h)
   VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks,
                    "handle, 0, %d sectors, %d sectors",
                    VIXDISKLIB_MIN_CHUNK_SIZE, VIXDISKLIB_MIN_CHUNK_SIZE)
-    err = VixDiskLib_QueryAllocatedBlocks (h->handle,
+    err = VixDiskLib_QueryAllocatedBlocks (handle,
                                            0, VIXDISKLIB_MIN_CHUNK_SIZE,
                                            VIXDISKLIB_MIN_CHUNK_SIZE,
                                            &block_list);
@@ -389,7 +389,7 @@ add_extent (struct nbdkit_extents *extents,
 }
 
 static int
-do_extents (struct command *cmd, struct vddk_handle *h)
+do_extents (struct command *cmd)
 {
   uint32_t count = cmd->count;
   uint64_t offset = cmd->offset;
@@ -425,7 +425,7 @@ do_extents (struct command *cmd, struct vddk_handle *h)
                      "handle, %" PRIu64 " sectors, %" PRIu64 " sectors, "
                      "%d sectors",
                      start_sector, nr_sectors, VIXDISKLIB_MIN_CHUNK_SIZE)
-      err = VixDiskLib_QueryAllocatedBlocks (h->handle,
+      err = VixDiskLib_QueryAllocatedBlocks (handle,
                                              start_sector, nr_sectors,
                                              VIXDISKLIB_MIN_CHUNK_SIZE,
                                              &block_list);
@@ -484,9 +484,8 @@ do_extents (struct command *cmd, struct vddk_handle *h)
  * VDDK commands are issued.
  */
 void *
-vddk_worker_thread (void *handle)
+vddk_worker_thread (void *unused)
 {
-  struct vddk_handle *h = handle;
   bool stop = false;
 
   while (!stop) {
@@ -496,21 +495,21 @@ vddk_worker_thread (void *handle)
 
     /* Wait until we are sent at least one command. */
     {
-      ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&h->commands_lock);
-      while (h->commands.len == 0)
-        pthread_cond_wait (&h->commands_cond, &h->commands_lock);
-      cmd = h->commands.ptr[0];
-      command_queue_remove (&h->commands, 0);
+      ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&commands_lock);
+      while (commands.len == 0)
+        pthread_cond_wait (&commands_cond, &commands_lock);
+      cmd = commands.ptr[0];
+      command_queue_remove (&commands, 0);
     }
 
     switch (cmd->type) {
     case STOP:
-      r = do_stop (cmd, h);
+      r = do_stop (cmd);
       stop = true;
       break;
 
     case GET_SIZE: {
-      int64_t size = do_get_size (cmd, h);
+      int64_t size = do_get_size (cmd);
       if (size == -1)
         r = -1;
       else {
@@ -521,29 +520,29 @@ vddk_worker_thread (void *handle)
     }
 
     case READ:
-      r = do_read (cmd, h);
+      r = do_read (cmd);
       /* If async is true, don't retire this command now. */
       async = r == 0;
       break;
 
     case WRITE:
-      r = do_write (cmd, h);
+      r = do_write (cmd);
       /* If async is true, don't retire this command now. */
       async = r == 0;
       break;
 
     case FLUSH:
-      r = do_flush (cmd, h);
+      r = do_flush (cmd);
       break;
 
     case CAN_EXTENTS:
-      r = do_can_extents (cmd, h);
+      r = do_can_extents (cmd);
       if (r >= 0)
         *(int *)cmd->ptr = r;
       break;
 
     case EXTENTS:
-      r = do_extents (cmd, h);
+      r = do_extents (cmd);
       break;
 
     default: abort (); /* impossible, but keeps GCC happy */
-- 
2.32.0




More information about the Libguestfs mailing list