diff --git a/0001-vddk-Refactor-how-D-vddk.stats-1-is-collected.patch b/0001-vddk-Refactor-how-D-vddk.stats-1-is-collected.patch deleted file mode 100644 index 066e913..0000000 --- a/0001-vddk-Refactor-how-D-vddk.stats-1-is-collected.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 4f2f557b349ad621e502e304c87280835cf13146 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Oct 2021 14:49:52 +0100 -Subject: [PATCH] vddk: Refactor how -D vddk.stats=1 is collected - -In order to allow us to collect more per-API stats, introduce a global -struct per API for storing these stats. - -(cherry picked from commit 3d8657f3d9a2c1b59284333566428b4c7ce32a74) ---- - plugins/vddk/vddk.c | 36 ++++++++++++++++++------------------ - 1 file changed, 18 insertions(+), 18 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 80f5870e..3d751544 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -1,5 +1,5 @@ - /* nbdkit -- * Copyright (C) 2013-2020 Red Hat Inc. -+ * Copyright (C) 2013-2021 Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are -@@ -103,14 +103,23 @@ static bool is_remote; - /* For each VDDK API define a variable to store the time taken (used - * to implement -D vddk.stats=1). - */ -+struct vddk_stat { -+ const char *name; /* function name */ -+ int64_t usecs; /* total number of usecs consumed */ -+}; - static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; - static void display_stats (void); --#define STUB(fn,ret,args) static int64_t stats_##fn; --#define OPTIONAL_STUB(fn,ret,args) static int64_t stats_##fn; -+#define STUB(fn,ret,args) \ -+ static struct vddk_stat stats_##fn = { .name = #fn } -+#define OPTIONAL_STUB(fn,ret,args) \ -+ static struct vddk_stat stats_##fn = { .name = #fn } - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB - -+/* Macros to bracket each VDDK API call, for printing debugging -+ * information and collecting statistics. -+ */ - #define VDDK_CALL_START(fn, fs, ...) \ - do { \ - struct timeval start_t, end_t; \ -@@ -131,10 +140,11 @@ static void display_stats (void); - if (vddk_debug_stats) { \ - gettimeofday (&end_t, NULL); \ - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ -- stats_##fn += tvdiff_usec (&start_t, &end_t); \ -+ stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ - } \ - } while (0) - -+/* Print VDDK errors. */ - #define VDDK_ERROR(err, fs, ...) \ - do { \ - char *vddk_err_msg; \ -@@ -167,10 +177,6 @@ vddk_unload (void) - free (password); - } - --struct vddk_stat { -- const char *fn; -- int64_t usecs; --}; - DEFINE_VECTOR_TYPE(statlist, struct vddk_stat) - - static int -@@ -179,7 +185,7 @@ stat_compare (const void *vp1, const void *vp2) - const struct vddk_stat *st1 = vp1; - const struct vddk_stat *st2 = vp2; - -- /* Note: sorts in reverse order. */ -+ /* Note: sorts in reverse order of time spent in each API call. */ - if (st1->usecs < st2->usecs) return 1; - else if (st1->usecs > st2->usecs) return -1; - else return 0; -@@ -189,19 +195,13 @@ static void - display_stats (void) - { - statlist stats = empty_vector; -- struct vddk_stat st; - size_t i; - --#define ADD_ONE_STAT(fn_, usecs_) \ -- st.fn = fn_; \ -- st.usecs = usecs_; \ -- statlist_append (&stats, st) --#define STUB(fn,ret,args) ADD_ONE_STAT (#fn, stats_##fn); --#define OPTIONAL_STUB(fn,ret,args) ADD_ONE_STAT (#fn, stats_##fn); -+#define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -+#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB --#undef ADD_ONE_STAT - - qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); - -@@ -209,7 +209,7 @@ display_stats (void) - nbdkit_debug ("%-40s %9s", "", "µs"); - for (i = 0; i < stats.size; ++i) { - if (stats.ptr[i].usecs) -- nbdkit_debug ("%-40s %9" PRIi64, stats.ptr[i].fn, stats.ptr[i].usecs); -+ nbdkit_debug ("%-40s %9" PRIi64, stats.ptr[i].name, stats.ptr[i].usecs); - } - statlist_reset (&stats); - } --- -2.31.1 - diff --git a/0002-vddk-Extend-D-vddk.stats-1-to-show-number-of-calls-a.patch b/0002-vddk-Extend-D-vddk.stats-1-to-show-number-of-calls-a.patch deleted file mode 100644 index 498acf6..0000000 --- a/0002-vddk-Extend-D-vddk.stats-1-to-show-number-of-calls-a.patch +++ /dev/null @@ -1,140 +0,0 @@ -From edfdfff0dae54a41bbfca30fa60f4fa6438d45b9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Oct 2021 15:10:00 +0100 -Subject: [PATCH] vddk: Extend -D vddk.stats=1 to show number of calls and - bytes transferred -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The new output looks like this: - -nbdkit: debug: VDDK function stats (-D vddk.stats=1): -nbdkit: debug: VixDiskLib_... µs calls bytes -nbdkit: debug: Exit 1000854 1 -nbdkit: debug: InitEx 79304 1 -nbdkit: debug: Flush 13577 1 -nbdkit: debug: Write 12534 21 10485760 -nbdkit: debug: Open 4753 3 -nbdkit: debug: Read 966 20 5242880 -nbdkit: debug: Close 574 3 -nbdkit: debug: QueryAllocatedBlocks 116 4 -nbdkit: debug: ConnectEx 103 3 -nbdkit: debug: Disconnect 88 3 -nbdkit: debug: GetTransportMode 68 3 -nbdkit: debug: GetInfo 46 3 -nbdkit: debug: FreeConnectParams 36 3 -nbdkit: debug: FreeInfo 36 3 -nbdkit: debug: FreeBlockList 22 4 -nbdkit: debug: AllocateConnectParams 22 3 -(cherry picked from commit 5c80f0d290db45a679d55baf37ff39bacb8ce7ec) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 3 +-- - plugins/vddk/vddk.c | 41 +++++++++++++++++++++++++---- - 2 files changed, 37 insertions(+), 7 deletions(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 078badcc..e53d3286 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -517,8 +517,7 @@ Suppress debugging of datapath calls (C and C). - - =item B<-D vddk.stats=1> - --When the plugin exits print some statistics about the amount of time --spent waiting on each VDDK call. -+When the plugin exits print some statistics about each VDDK call. - - =back - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 3d751544..5f1d223b 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -106,6 +106,8 @@ static bool is_remote; - struct vddk_stat { - const char *name; /* function name */ - int64_t usecs; /* total number of usecs consumed */ -+ uint64_t calls; /* number of times called */ -+ uint64_t bytes; /* bytes transferred, datapath calls only */ - }; - static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; - static void display_stats (void); -@@ -141,6 +143,17 @@ static void display_stats (void); - gettimeofday (&end_t, NULL); \ - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ - stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ -+ stats_##fn.calls++; \ -+ } \ -+ } while (0) -+#define VDDK_CALL_END_DATAPATH(fn, bytes_) \ -+ while (0); \ -+ if (vddk_debug_stats) { \ -+ gettimeofday (&end_t, NULL); \ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ -+ stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ -+ stats_##fn.calls++; \ -+ stats_##fn.bytes += bytes_; \ - } \ - } while (0) - -@@ -191,6 +204,12 @@ stat_compare (const void *vp1, const void *vp2) - else return 0; - } - -+static const char * -+api_name_without_prefix (const char *name) -+{ -+ return strncmp (name, "VixDiskLib_", 11) == 0 ? name + 11 : name; -+} -+ - static void - display_stats (void) - { -@@ -206,10 +225,22 @@ display_stats (void) - qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); - - nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); -- nbdkit_debug ("%-40s %9s", "", "µs"); -+ nbdkit_debug ("%-24s %15s %5s %15s", -+ "VixDiskLib_...", "µs", "calls", "bytes"); - for (i = 0; i < stats.size; ++i) { -- if (stats.ptr[i].usecs) -- nbdkit_debug ("%-40s %9" PRIi64, stats.ptr[i].name, stats.ptr[i].usecs); -+ if (stats.ptr[i].usecs) { -+ if (stats.ptr[i].bytes > 0) -+ nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, -+ api_name_without_prefix (stats.ptr[i].name), -+ stats.ptr[i].usecs, -+ stats.ptr[i].calls, -+ stats.ptr[i].bytes); -+ else -+ nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64, -+ api_name_without_prefix (stats.ptr[i].name), -+ stats.ptr[i].usecs, -+ stats.ptr[i].calls); -+ } - } - statlist_reset (&stats); - } -@@ -831,7 +862,7 @@ vddk_pread (void *handle, void *buf, uint32_t count, uint64_t offset, - "%" PRIu32 " sectors, buffer", - offset, count) { - err = VixDiskLib_Read (h->handle, offset, count, buf); -- } VDDK_CALL_END (VixDiskLib_Read); -+ } VDDK_CALL_END_DATAPATH (VixDiskLib_Read, count * VIXDISKLIB_SECTOR_SIZE); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Read"); - return -1; -@@ -871,7 +902,7 @@ vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, - "%" PRIu32 " sectors, buffer", - offset, count) { - err = VixDiskLib_Write (h->handle, offset, count, buf); -- } VDDK_CALL_END (VixDiskLib_Write); -+ } VDDK_CALL_END_DATAPATH (VixDiskLib_Write, count * VIXDISKLIB_SECTOR_SIZE); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Write"); - return -1; --- -2.31.1 - diff --git a/0003-vddk-Simplify-and-consolidate-VDDK_CALL_START-END-ma.patch b/0003-vddk-Simplify-and-consolidate-VDDK_CALL_START-END-ma.patch deleted file mode 100644 index f7ed950..0000000 --- a/0003-vddk-Simplify-and-consolidate-VDDK_CALL_START-END-ma.patch +++ /dev/null @@ -1,320 +0,0 @@ -From cbcf2a2f158a9889bd597b31159ab357dea05cd6 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 21 Oct 2021 22:55:17 +0100 -Subject: [PATCH] vddk: Simplify and consolidate VDDK_CALL_START/END macros - -We don't need the VDDK_CALL_*_DATAPATH versions of these macros -because the compiler is able to optimize some static strcmps. -Furthermore we can remove extra { .. } when the macros are applied. - -(cherry picked from commit 3ea0ed6582faa8f800b7a2a15d58032917a21bd5) ---- - plugins/vddk/vddk.c | 124 ++++++++++++++++++++------------------------ - 1 file changed, 56 insertions(+), 68 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 5f1d223b..993f2d76 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -125,28 +125,16 @@ static void display_stats (void); - #define VDDK_CALL_START(fn, fs, ...) \ - do { \ - struct timeval start_t, end_t; \ -+ /* GCC can optimize this away at compile time: */ \ -+ const bool datapath = \ -+ strcmp (#fn, "VixDiskLib_Read") == 0 || \ -+ strcmp (#fn, "VixDiskLib_Write") == 0; \ - if (vddk_debug_stats) \ - gettimeofday (&start_t, NULL); \ -- nbdkit_debug ("VDDK call: %s (" fs ")", #fn, ##__VA_ARGS__); \ -- do --#define VDDK_CALL_START_DATAPATH(fn, fs, ...) \ -- do { \ -- struct timeval start_t, end_t; \ -- if (vddk_debug_stats) \ -- gettimeofday (&start_t, NULL); \ -- if (vddk_debug_datapath) \ -+ if (!datapath || vddk_debug_datapath) \ - nbdkit_debug ("VDDK call: %s (" fs ")", #fn, ##__VA_ARGS__); \ - do --#define VDDK_CALL_END(fn) \ -- while (0); \ -- if (vddk_debug_stats) { \ -- gettimeofday (&end_t, NULL); \ -- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ -- stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ -- stats_##fn.calls++; \ -- } \ -- } while (0) --#define VDDK_CALL_END_DATAPATH(fn, bytes_) \ -+#define VDDK_CALL_END(fn, bytes_) \ - while (0); \ - if (vddk_debug_stats) { \ - gettimeofday (&end_t, NULL); \ -@@ -161,13 +149,13 @@ static void display_stats (void); - #define VDDK_ERROR(err, fs, ...) \ - do { \ - char *vddk_err_msg; \ -- VDDK_CALL_START (VixDiskLib_GetErrorText, "%lu", err) { \ -+ VDDK_CALL_START (VixDiskLib_GetErrorText, "%lu", err) \ - vddk_err_msg = VixDiskLib_GetErrorText ((err), NULL); \ -- } VDDK_CALL_END (VixDiskLib_GetErrorText); \ -+ VDDK_CALL_END (VixDiskLib_GetErrorText, 0); \ - nbdkit_error (fs ": %s", ##__VA_ARGS__, vddk_err_msg); \ -- VDDK_CALL_START (VixDiskLib_FreeErrorText, "") { \ -+ VDDK_CALL_START (VixDiskLib_FreeErrorText, "") \ - VixDiskLib_FreeErrorText (vddk_err_msg); \ -- } VDDK_CALL_END (VixDiskLib_FreeErrorText); \ -+ VDDK_CALL_END (VixDiskLib_FreeErrorText, 0); \ - } while (0) - - /* Unload the plugin. */ -@@ -175,9 +163,9 @@ static void - vddk_unload (void) - { - if (init_called) { -- VDDK_CALL_START (VixDiskLib_Exit, "") { -+ VDDK_CALL_START (VixDiskLib_Exit, "") - VixDiskLib_Exit (); -- } VDDK_CALL_END (VixDiskLib_Exit); -+ VDDK_CALL_END (VixDiskLib_Exit, 0); - } - if (dl) - dlclose (dl); -@@ -572,13 +560,13 @@ vddk_after_fork (void) - VDDK_CALL_START (VixDiskLib_InitEx, - "%d, %d, &debug_fn, &error_fn, &error_fn, %s, %s", - VDDK_MAJOR, VDDK_MINOR, -- libdir, config ? : "NULL") { -+ libdir, config ? : "NULL") - err = VixDiskLib_InitEx (VDDK_MAJOR, VDDK_MINOR, - &debug_function, /* log function */ - &error_function, /* warn function */ - &error_function, /* panic function */ - libdir, config); -- } VDDK_CALL_END (VixDiskLib_InitEx); -+ VDDK_CALL_END (VixDiskLib_InitEx, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_InitEx"); - exit (EXIT_FAILURE); -@@ -640,9 +628,9 @@ allocate_connect_params (void) - VixDiskLibConnectParams *ret; - - if (VixDiskLib_AllocateConnectParams != NULL) { -- VDDK_CALL_START (VixDiskLib_AllocateConnectParams, "") { -+ VDDK_CALL_START (VixDiskLib_AllocateConnectParams, "") - ret = VixDiskLib_AllocateConnectParams (); -- } VDDK_CALL_END (VixDiskLib_AllocateConnectParams); -+ VDDK_CALL_END (VixDiskLib_AllocateConnectParams, 0); - } - else - ret = calloc (1, sizeof (VixDiskLibConnectParams)); -@@ -657,9 +645,9 @@ free_connect_params (VixDiskLibConnectParams *params) - * originally called. Otherwise use free. - */ - if (VixDiskLib_AllocateConnectParams != NULL) { -- VDDK_CALL_START (VixDiskLib_FreeConnectParams, "params") { -+ VDDK_CALL_START (VixDiskLib_FreeConnectParams, "params") - VixDiskLib_FreeConnectParams (params); -- } VDDK_CALL_END (VixDiskLib_FreeConnectParams); -+ VDDK_CALL_END (VixDiskLib_FreeConnectParams, 0); - } - else - free (params); -@@ -716,13 +704,13 @@ vddk_open (int readonly) - "h->params, %d, %s, %s, &connection", - readonly, - snapshot_moref ? : "NULL", -- transport_modes ? : "NULL") { -+ transport_modes ? : "NULL") - err = VixDiskLib_ConnectEx (h->params, - readonly, - snapshot_moref, - transport_modes, - &h->connection); -- } VDDK_CALL_END (VixDiskLib_ConnectEx); -+ VDDK_CALL_END (VixDiskLib_ConnectEx, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_ConnectEx"); - goto err1; -@@ -743,25 +731,25 @@ vddk_open (int readonly) - } - - VDDK_CALL_START (VixDiskLib_Open, -- "connection, %s, %d, &handle", filename, flags) { -+ "connection, %s, %d, &handle", filename, flags) - err = VixDiskLib_Open (h->connection, filename, flags, &h->handle); -- } VDDK_CALL_END (VixDiskLib_Open); -+ VDDK_CALL_END (VixDiskLib_Open, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Open: %s", filename); - goto err2; - } - -- VDDK_CALL_START (VixDiskLib_GetTransportMode, "handle") { -+ VDDK_CALL_START (VixDiskLib_GetTransportMode, "handle") - transport_mode = VixDiskLib_GetTransportMode (h->handle); -- } VDDK_CALL_END (VixDiskLib_GetTransportMode); -+ VDDK_CALL_END (VixDiskLib_GetTransportMode, 0); - nbdkit_debug ("transport mode: %s", transport_mode); - - return h; - - err2: -- VDDK_CALL_START (VixDiskLib_Disconnect, "connection") { -+ VDDK_CALL_START (VixDiskLib_Disconnect, "connection") - VixDiskLib_Disconnect (h->connection); -- } VDDK_CALL_END (VixDiskLib_Disconnect); -+ VDDK_CALL_END (VixDiskLib_Disconnect, 0); - err1: - free_connect_params (h->params); - err0: -@@ -776,12 +764,12 @@ vddk_close (void *handle) - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&open_close_lock); - struct vddk_handle *h = handle; - -- VDDK_CALL_START (VixDiskLib_Close, "handle") { -+ VDDK_CALL_START (VixDiskLib_Close, "handle") - VixDiskLib_Close (h->handle); -- } VDDK_CALL_END (VixDiskLib_Close); -- VDDK_CALL_START (VixDiskLib_Disconnect, "connection") { -+ VDDK_CALL_END (VixDiskLib_Close, 0); -+ VDDK_CALL_START (VixDiskLib_Disconnect, "connection") - VixDiskLib_Disconnect (h->connection); -- } VDDK_CALL_END (VixDiskLib_Disconnect); -+ VDDK_CALL_END (VixDiskLib_Disconnect, 0); - - free_connect_params (h->params); - free (h); -@@ -796,9 +784,9 @@ vddk_get_size (void *handle) - VixError err; - uint64_t size; - -- VDDK_CALL_START (VixDiskLib_GetInfo, "handle, &info") { -+ VDDK_CALL_START (VixDiskLib_GetInfo, "handle, &info") - err = VixDiskLib_GetInfo (h->handle, &info); -- } VDDK_CALL_END (VixDiskLib_GetInfo); -+ VDDK_CALL_END (VixDiskLib_GetInfo, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_GetInfo"); - return -1; -@@ -827,9 +815,9 @@ vddk_get_size (void *handle) - info->uuid ? : "NULL"); - } - -- VDDK_CALL_START (VixDiskLib_FreeInfo, "info") { -+ VDDK_CALL_START (VixDiskLib_FreeInfo, "info") - VixDiskLib_FreeInfo (info); -- } VDDK_CALL_END (VixDiskLib_FreeInfo); -+ VDDK_CALL_END (VixDiskLib_FreeInfo, 0); - - return (int64_t) size; - } -@@ -857,12 +845,12 @@ vddk_pread (void *handle, void *buf, uint32_t count, uint64_t offset, - offset /= VIXDISKLIB_SECTOR_SIZE; - count /= VIXDISKLIB_SECTOR_SIZE; - -- VDDK_CALL_START_DATAPATH (VixDiskLib_Read, -- "handle, %" PRIu64 " sectors, " -- "%" PRIu32 " sectors, buffer", -- offset, count) { -+ VDDK_CALL_START (VixDiskLib_Read, -+ "handle, %" PRIu64 " sectors, " -+ "%" PRIu32 " sectors, buffer", -+ offset, count) - err = VixDiskLib_Read (h->handle, offset, count, buf); -- } VDDK_CALL_END_DATAPATH (VixDiskLib_Read, count * VIXDISKLIB_SECTOR_SIZE); -+ VDDK_CALL_END (VixDiskLib_Read, count * VIXDISKLIB_SECTOR_SIZE); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Read"); - return -1; -@@ -897,12 +885,12 @@ vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, - offset /= VIXDISKLIB_SECTOR_SIZE; - count /= VIXDISKLIB_SECTOR_SIZE; - -- VDDK_CALL_START_DATAPATH (VixDiskLib_Write, -- "handle, %" PRIu64 " sectors, " -- "%" PRIu32 " sectors, buffer", -- offset, count) { -+ VDDK_CALL_START (VixDiskLib_Write, -+ "handle, %" PRIu64 " sectors, " -+ "%" PRIu32 " sectors, buffer", -+ offset, count) - err = VixDiskLib_Write (h->handle, offset, count, buf); -- } VDDK_CALL_END_DATAPATH (VixDiskLib_Write, count * VIXDISKLIB_SECTOR_SIZE); -+ VDDK_CALL_END (VixDiskLib_Write, count * VIXDISKLIB_SECTOR_SIZE); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Write"); - return -1; -@@ -945,9 +933,9 @@ vddk_flush (void *handle, uint32_t flags) - * file so it appears to be the correct call to use here. - */ - -- VDDK_CALL_START (VixDiskLib_Flush, "handle") { -+ VDDK_CALL_START (VixDiskLib_Flush, "handle") - err = VixDiskLib_Flush (h->handle); -- } VDDK_CALL_END (VixDiskLib_Flush); -+ VDDK_CALL_END (VixDiskLib_Flush, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_Flush"); - return -1; -@@ -983,17 +971,17 @@ vddk_can_extents (void *handle) - */ - VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, - "handle, 0, %d sectors, %d sectors", -- VIXDISKLIB_MIN_CHUNK_SIZE, VIXDISKLIB_MIN_CHUNK_SIZE) { -+ VIXDISKLIB_MIN_CHUNK_SIZE, VIXDISKLIB_MIN_CHUNK_SIZE) - err = VixDiskLib_QueryAllocatedBlocks (h->handle, - 0, VIXDISKLIB_MIN_CHUNK_SIZE, - VIXDISKLIB_MIN_CHUNK_SIZE, - &block_list); -- } VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks); -+ VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); - error_suppression = 0; - if (err == VIX_OK) { -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") { -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") - VixDiskLib_FreeBlockList (block_list); -- } VDDK_CALL_END (VixDiskLib_FreeBlockList); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); - } - if (err != VIX_OK) { - char *errmsg = VixDiskLib_GetErrorText (err, NULL); -@@ -1073,12 +1061,12 @@ vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags, - VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, - "handle, %" PRIu64 " sectors, %" PRIu64 " sectors, " - "%d sectors", -- start_sector, nr_sectors, VIXDISKLIB_MIN_CHUNK_SIZE) { -+ start_sector, nr_sectors, VIXDISKLIB_MIN_CHUNK_SIZE) - err = VixDiskLib_QueryAllocatedBlocks (h->handle, - start_sector, nr_sectors, - VIXDISKLIB_MIN_CHUNK_SIZE, - &block_list); -- } VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks); -+ VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); - if (err != VIX_OK) { - VDDK_ERROR (err, "VixDiskLib_QueryAllocatedBlocks"); - return -1; -@@ -1097,15 +1085,15 @@ vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags, - add_extent (extents, &position, blk_offset, true) == -1) || - (add_extent (extents, - &position, blk_offset + blk_length, false) == -1)) { -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") { -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") - VixDiskLib_FreeBlockList (block_list); -- } VDDK_CALL_END (VixDiskLib_FreeBlockList); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); - return -1; - } - } -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") { -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") - VixDiskLib_FreeBlockList (block_list); -- } VDDK_CALL_END (VixDiskLib_FreeBlockList); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); - - /* There's an implicit hole after the returned list of blocks, up - * to the end of the QueryAllocatedBlocks request. --- -2.31.1 - diff --git a/0004-vddk-Document-troubleshooting-performance-problems.patch b/0004-vddk-Document-troubleshooting-performance-problems.patch deleted file mode 100644 index b1d94a0..0000000 --- a/0004-vddk-Document-troubleshooting-performance-problems.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 8353ab55b8c6e7f1dc9ea27260fd7ec90b9d75af Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 22 Oct 2021 18:00:27 +0100 -Subject: [PATCH] vddk: Document troubleshooting performance problems - -Document how to use -D vddk.stats=1 to diagnose performance problems -with VDDK. - -(cherry picked from commit e491978c193f49010cc28ad344d0fb3c1b5ede35) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 57 +++++++++++++++++++++++++++++ - 1 file changed, 57 insertions(+) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index e53d3286..5a426135 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -475,6 +475,63 @@ and restarting the C service: - - For more information see L. - -+=head2 Troubleshooting performance problems -+ -+VDDK has very uneven performance with some operations being very slow. -+This plugin has options to allow you to debug performance issues. If -+your application has a debug or diagnostic setting, add the following -+nbdkit command line options: -+ -+ -v -D nbdkit.backend.datapath=0 -D vddk.datapath=0 -D vddk.stats=1 -+ -+C<-v> enables verbose messages and the two datapath options I -+the very verbose per-read/-write messages. C<-D vddk.stats=1> enables -+a summary when nbdkit exits of the cumulative time taken in each VDDK -+function, the number of times each function was called, and (for read -+and write) the number of bytes transferred. An example of what those -+stats look like can be found here: -+L -+ -+You can interpret the stats as follows: -+ -+=over 4 -+ -+=item C -+ -+The cumulative time spent waiting for VDDK to return from -+C calls, the number of times this function was -+called, and the total bytes read. You can use this to determine the -+read bandwidth to the VMware server. -+ -+=item C -+ -+=item C -+ -+Same as above, but for writing and flushing writes. -+ -+=item C -+ -+This call is used to query information about the sparseness of the -+remote disk. It is only available in VDDK E 6.7. The call is -+notably very slow in all versions of VMware we have tested. -+ -+=item C -+ -+=item C -+ -+=item C -+ -+=item C -+ -+=item C -+ -+=item C -+ -+The cumulative time spent connecting and disconnecting from the VMware -+server, which can also be very slow. -+ -+=back -+ - =head1 SUPPORTED VERSIONS OF VDDK - - This plugin requires VDDK E 5.5.5, which in turn means that it --- -2.31.1 - diff --git a/0005-vddk-Include-VDDK-major-library-version-in-dump-plug.patch b/0005-vddk-Include-VDDK-major-library-version-in-dump-plug.patch deleted file mode 100644 index 85b3f1c..0000000 --- a/0005-vddk-Include-VDDK-major-library-version-in-dump-plug.patch +++ /dev/null @@ -1,141 +0,0 @@ -From d994773724266dd5f0a8b4282cc604f6b75e077c Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 23 Oct 2021 16:16:39 +0100 -Subject: [PATCH] vddk: Include VDDK major library version in --dump-plugin - output - -Although it doesn't seem to be possible to get the precise VDDK -version, With a relatively simple change we can at least return the -VDDK major version. Currently this can be 5, 6 or 7. - -(cherry picked from commit 8700649d147948897f3b97810a1dff37924bdd6e) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 4 ++++ - plugins/vddk/vddk.c | 29 +++++++++++++++++++---------- - tests/test-vddk-real-dump-plugin.sh | 2 ++ - 3 files changed, 25 insertions(+), 10 deletions(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 5a426135..bc3c3c94 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -422,6 +422,10 @@ at runtime. - If this is printed then the C parameter is supported - by this build. - -+=item C -+ -+The VDDK major library version: 5, 6, 7, ... -+ - =item C - - Prints the full path to the VDDK shared library. Since this requires -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 993f2d76..d74a484d 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -81,6 +81,7 @@ NBDKIT_DLL_PUBLIC int vddk_debug_stats; - static void *dl; /* dlopen handle */ - static bool init_called; /* was InitEx called */ - static __thread int error_suppression; /* threadlocal error suppression */ -+static int library_version; /* VDDK major: 5, 6, 7, ... */ - - static enum { NONE = 0, ZLIB, FASTLZ, SKIPZ } compression; /* compression */ - static char *config; /* config */ -@@ -405,7 +406,10 @@ vddk_config (const char *key, const char *value) - static void - load_library (bool load_error_is_fatal) - { -- static const char *sonames[] = { -+ static struct { -+ const char *soname; -+ int library_version; -+ } libs[] = { - /* Prefer the newest library in case multiple exist. Check two - * possible directories: the usual VDDK installation puts .so - * files in an arch-specific subdirectory of $libdir (our minimum -@@ -413,12 +417,13 @@ load_library (bool load_error_is_fatal) - * but our testsuite is easier to write if we point libdir - * directly to a stub .so. - */ -- "lib64/libvixDiskLib.so.7", -- "libvixDiskLib.so.7", -- "lib64/libvixDiskLib.so.6", -- "libvixDiskLib.so.6", -- "lib64/libvixDiskLib.so.5", -- "libvixDiskLib.so.5", -+ { "lib64/libvixDiskLib.so.7", 7 }, -+ { "libvixDiskLib.so.7", 7 }, -+ { "lib64/libvixDiskLib.so.6", 6 }, -+ { "libvixDiskLib.so.6", 6 }, -+ { "lib64/libvixDiskLib.so.5", 5 }, -+ { "libvixDiskLib.so.5", 5 }, -+ { NULL } - }; - size_t i; - CLEANUP_FREE char *orig_error = NULL; -@@ -431,19 +436,20 @@ load_library (bool load_error_is_fatal) - } - } - -- for (i = 0; i < sizeof sonames / sizeof sonames[0]; ++i) { -+ for (i = 0; libs[i].soname != NULL; ++i) { - CLEANUP_FREE char *path; - - /* Set the full path so that dlopen will preferentially load the - * system libraries from the same directory. - */ -- if (asprintf (&path, "%s/%s", libdir, sonames[i]) == -1) { -+ if (asprintf (&path, "%s/%s", libdir, libs[i].soname) == -1) { - nbdkit_error ("asprintf: %m"); - exit (EXIT_FAILURE); - } - - dl = dlopen (path, RTLD_NOW); - if (dl != NULL) { -+ library_version = libs[i].library_version; - /* Now that we found the library, ensure that LD_LIBRARY_PATH - * includes its directory for all future loads. This may modify - * path in-place and/or re-exec nbdkit, but that's okay. -@@ -464,10 +470,12 @@ load_library (bool load_error_is_fatal) - "If '%s' is located on a non-standard path you may need to\n" - "set libdir=/path/to/vmware-vix-disklib-distrib.\n\n" - "See nbdkit-vddk-plugin(1) man page section \"LIBRARY LOCATION\" for details.", -- orig_error ? : "(unknown error)", sonames[0]); -+ orig_error ? : "(unknown error)", libs[0].soname); - exit (EXIT_FAILURE); - } - -+ assert (library_version >= 5); -+ - /* Load symbols. */ - #define STUB(fn,ret,args) \ - do { \ -@@ -583,6 +591,7 @@ vddk_dump_plugin (void) - - printf ("vddk_default_libdir=%s\n", VDDK_LIBDIR); - printf ("vddk_has_nfchostport=1\n"); -+ printf ("vddk_library_version=%d\n", library_version); - - #if defined(HAVE_DLADDR) - /* It would be nice to print the version of VDDK from the shared -diff --git a/tests/test-vddk-real-dump-plugin.sh b/tests/test-vddk-real-dump-plugin.sh -index 2cb7724e..0a079c6c 100755 ---- a/tests/test-vddk-real-dump-plugin.sh -+++ b/tests/test-vddk-real-dump-plugin.sh -@@ -58,10 +58,12 @@ rm -f $files - cleanup_fn rm -f $files - - nbdkit -f -v vddk libdir="$vddkdir" --dump-plugin > $out -+cat $out - - # Check the vddk_* entries are set. - grep ^vddk_default_libdir= $out - grep ^vddk_has_nfchostport= $out -+grep ^vddk_library_version= $out - grep ^vddk_dll= $out - - dll="$(grep ^vddk_dll $out | cut -d= -f2)" --- -2.31.1 - diff --git a/0006-vddk-Add-logical-and-physical-sector-size-to-D-vddk..patch b/0006-vddk-Add-logical-and-physical-sector-size-to-D-vddk..patch deleted file mode 100644 index dd44d14..0000000 --- a/0006-vddk-Add-logical-and-physical-sector-size-to-D-vddk..patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4c80b474a2c2a552e5bdfcaabfa2981540afe8d8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 23 Oct 2021 16:24:27 +0100 -Subject: [PATCH] vddk: Add logical and physical sector size to -D - vddk.diskinfo output - -In VDDK >= 7 it is possible to display the logical and physical sector -size in debug output. - -This commit also extends the test since this flag was not tested -before. - -(cherry picked from commit 5bb8f0586e1faabcbf4f43d722a3b3cb5b352e33) ---- - plugins/vddk/vddk.c | 6 ++++++ - tests/test-vddk-real.sh | 3 ++- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index d74a484d..50bdde26 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -822,6 +822,12 @@ vddk_get_size (void *handle) - info->parentFileNameHint ? : "NULL"); - nbdkit_debug ("disk info: uuid: %s", - info->uuid ? : "NULL"); -+ if (library_version >= 7) { -+ nbdkit_debug ("disk info: sectory size: " -+ "logical %" PRIu32 " physical %" PRIu32, -+ info->logicalSectorSize, -+ info->physicalSectorSize); -+ } - } - - VDDK_CALL_START (VixDiskLib_FreeInfo, "info") -diff --git a/tests/test-vddk-real.sh b/tests/test-vddk-real.sh -index a6aceac9..ae965245 100755 ---- a/tests/test-vddk-real.sh -+++ b/tests/test-vddk-real.sh -@@ -89,7 +89,8 @@ if grep 'cannot open shared object file' $log; then - fi - - # Now run nbdkit for the test. --start_nbdkit -P $pid -U $sock -D vddk.stats=1 vddk libdir="$vddkdir" $vmdk -+start_nbdkit -P $pid -U $sock -D vddk.stats=1 -D vddk.diskinfo=1 \ -+ vddk libdir="$vddkdir" $vmdk - uri="nbd+unix:///?socket=$sock" - - # VDDK < 6.0 did not support flush, so disable flush test there. Also --- -2.31.1 - diff --git a/0007-vddk-Fix-typo-in-debug-message.patch b/0007-vddk-Fix-typo-in-debug-message.patch deleted file mode 100644 index 8ef9f10..0000000 --- a/0007-vddk-Fix-typo-in-debug-message.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4b0d278f3851baf37affa26d34e52963dc8c7c04 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 23 Oct 2021 19:41:07 +0100 -Subject: [PATCH] vddk: Fix typo in debug message - -Fixes: commit 5bb8f0586e1faabcbf4f43d722a3b3cb5b352e33 -(cherry picked from commit 343dadeb7340d7b8c5730e2bbab33c829b569122) ---- - plugins/vddk/vddk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 50bdde26..65399a91 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -823,7 +823,7 @@ vddk_get_size (void *handle) - nbdkit_debug ("disk info: uuid: %s", - info->uuid ? : "NULL"); - if (library_version >= 7) { -- nbdkit_debug ("disk info: sectory size: " -+ nbdkit_debug ("disk info: sector size: " - "logical %" PRIu32 " physical %" PRIu32, - info->logicalSectorSize, - info->physicalSectorSize); --- -2.31.1 - diff --git a/0008-vddk-Only-print-vddk_library_version-when-we-managed.patch b/0008-vddk-Only-print-vddk_library_version-when-we-managed.patch deleted file mode 100644 index 9067eef..0000000 --- a/0008-vddk-Only-print-vddk_library_version-when-we-managed.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 670c1ddb6591046256511a680605c5e2349746e8 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 23 Oct 2021 19:50:52 +0100 -Subject: [PATCH] vddk: Only print vddk_library_version when we managed to load - the library - -Because --dump-plugin calls load_library (false) it won't fail if we -didn't manage to load the library. This results in library_version -being 0, which we printed incorrectly. - -Resolve this problem by not printing the vddk_library_version entry in -this case. - -Fixes: commit 8700649d147948897f3b97810a1dff37924bdd6e -(cherry picked from commit a3fba12c3e9c2113009f556360ae0bd04c45f6bb) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 1 + - plugins/vddk/vddk.c | 9 ++++++++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index bc3c3c94..49e3d75d 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -425,6 +425,7 @@ by this build. - =item C - - The VDDK major library version: 5, 6, 7, ... -+If this is omitted it means the library could not be loaded. - - =item C - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 65399a91..39a7d261 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -591,7 +591,14 @@ vddk_dump_plugin (void) - - printf ("vddk_default_libdir=%s\n", VDDK_LIBDIR); - printf ("vddk_has_nfchostport=1\n"); -- printf ("vddk_library_version=%d\n", library_version); -+ -+ /* Because load_library (false) we might not have loaded VDDK, in -+ * which case we didn't set library_version. Note this cannot -+ * happen in the normal (non-debug-plugin) path because there we use -+ * load_library (true). -+ */ -+ if (library_version > 0) -+ printf ("vddk_library_version=%d\n", library_version); - - #if defined(HAVE_DLADDR) - /* It would be nice to print the version of VDDK from the shared --- -2.31.1 - diff --git a/0009-vddk-Print-one-line-in-dump-plugin-output-for-each-V.patch b/0009-vddk-Print-one-line-in-dump-plugin-output-for-each-V.patch deleted file mode 100644 index 1be4831..0000000 --- a/0009-vddk-Print-one-line-in-dump-plugin-output-for-each-V.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 21d6c2f8f29f0d7f98852b72ee33751814be49fe Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 25 Oct 2021 08:36:53 +0100 -Subject: [PATCH] vddk: Print one line in --dump-plugin output for each VDDK - API - -Helps when detecting if certain optional features are being used, such -as flush and extents. - -(cherry picked from commit 4ee13559e46cf622410d0bdd7db29bb00908b40a) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 9 +++++++++ - plugins/vddk/vddk.c | 10 ++++++++++ - tests/test-vddk-real-dump-plugin.sh | 1 + - 3 files changed, 20 insertions(+) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 49e3d75d..0702aa75 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -432,6 +432,15 @@ If this is omitted it means the library could not be loaded. - Prints the full path to the VDDK shared library. Since this requires - a glibc extension it may not be available in all builds of the plugin. - -+=item C -+ -+For each VDDK API that the plugin uses I which is present in the -+VDDK library that was loaded, we print the name of the API -+(eg. C). This lets you see which optional APIs are -+available, such as C and -+C. If the library could not be -+loaded then these lines are not printed. -+ - =back - - =head1 NOTES -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 39a7d261..096b04bf 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -616,6 +616,16 @@ vddk_dump_plugin (void) - printf ("vddk_dll=%s\n", p); - } - #endif -+ -+ /* Note we print all VDDK APIs found here, not just the optional -+ * ones. That is so if we update the baseline VDDK in future and -+ * make optional into required APIs, the output doesn't change. -+ */ -+#define STUB(fn,ret,args) if (fn != NULL) printf ("%s=1\n", #fn); -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) -+#include "vddk-stubs.h" -+#undef STUB -+#undef OPTIONAL_STUB - } - - /* The rules on threads and VDDK are here: -diff --git a/tests/test-vddk-real-dump-plugin.sh b/tests/test-vddk-real-dump-plugin.sh -index 0a079c6c..e37c8b54 100755 ---- a/tests/test-vddk-real-dump-plugin.sh -+++ b/tests/test-vddk-real-dump-plugin.sh -@@ -65,6 +65,7 @@ grep ^vddk_default_libdir= $out - grep ^vddk_has_nfchostport= $out - grep ^vddk_library_version= $out - grep ^vddk_dll= $out -+grep ^VixDiskLib_Open=1 $out - - dll="$(grep ^vddk_dll $out | cut -d= -f2)" - test -f "$dll" --- -2.31.1 - diff --git a/0010-vddk-Move-minimum-version-to-VDDK-6.5.patch b/0010-vddk-Move-minimum-version-to-VDDK-6.5.patch deleted file mode 100644 index d0a4222..0000000 --- a/0010-vddk-Move-minimum-version-to-VDDK-6.5.patch +++ /dev/null @@ -1,147 +0,0 @@ -From f4379f04ea27e25c00e98db2e60d0fdb647442e9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 26 Oct 2021 19:46:32 +0100 -Subject: [PATCH] vddk: Move minimum version to VDDK 6.5 - -Drop support for VDDK 5.5.5 (released in 2015) and 6.0 (released the -same year). Move minimum supported version to 6.5 (released Nov -2016). This is so we can use asynchronous operations. - -Acked-by: Laszlo Ersek -(cherry picked from commit 5ed23616762a72e039531a9a7cd81353cd4f436e) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 10 +++------- - plugins/vddk/vddk-stubs.h | 3 +-- - plugins/vddk/vddk.c | 24 ++++++++++++++++-------- - tests/dummy-vddk.c | 6 ++++++ - 4 files changed, 26 insertions(+), 17 deletions(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 0702aa75..1c16d096 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -424,7 +424,7 @@ by this build. - - =item C - --The VDDK major library version: 5, 6, 7, ... -+The VDDK major library version: 6, 7, ... - If this is omitted it means the library could not be loaded. - - =item C -@@ -548,16 +548,12 @@ server, which can also be very slow. - - =head1 SUPPORTED VERSIONS OF VDDK - --This plugin requires VDDK E 5.5.5, which in turn means that it --is only supported on x64-64 platforms. -+This plugin requires VDDK E 6.5 (released Nov 2016). It is only -+supported on the x64-64 archtecture. - - It has been tested with all versions up to 7.0.3 (but should work with - future versions). - --VDDK E 6.0 should be used if possible. This is the first version --which added Flush support which is crucial for data integrity when --writing. -- - VDDK 6.7 was the first version that supported the - C API, required to provide extent - information over NBD. -diff --git a/plugins/vddk/vddk-stubs.h b/plugins/vddk/vddk-stubs.h -index 5e70238d..a94df9cd 100644 ---- a/plugins/vddk/vddk-stubs.h -+++ b/plugins/vddk/vddk-stubs.h -@@ -40,8 +40,7 @@ - */ - - /* Required stubs, present in all versions of VDDK that we support. I -- * have checked that all these exist in at least VDDK 5.5.5 (2015) -- * which is the earliest version of VDDK that we support. -+ * have checked that all these exist in at least VDDK 5.5.5 (2015). - */ - - STUB (VixDiskLib_InitEx, -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 096b04bf..babffc28 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -75,13 +75,13 @@ NBDKIT_DLL_PUBLIC int vddk_debug_stats; - #undef OPTIONAL_STUB - - /* Parameters passed to InitEx. */ --#define VDDK_MAJOR 5 -+#define VDDK_MAJOR 6 - #define VDDK_MINOR 5 - - static void *dl; /* dlopen handle */ - static bool init_called; /* was InitEx called */ - static __thread int error_suppression; /* threadlocal error suppression */ --static int library_version; /* VDDK major: 5, 6, 7, ... */ -+static int library_version; /* VDDK major: 6, 7, ... */ - - static enum { NONE = 0, ZLIB, FASTLZ, SKIPZ } compression; /* compression */ - static char *config; /* config */ -@@ -413,16 +413,14 @@ load_library (bool load_error_is_fatal) - /* Prefer the newest library in case multiple exist. Check two - * possible directories: the usual VDDK installation puts .so - * files in an arch-specific subdirectory of $libdir (our minimum -- * supported version is VDDK 5.5.5, which only supports x64-64); -- * but our testsuite is easier to write if we point libdir -- * directly to a stub .so. -+ * supported version is VDDK 6.5, which only supports x64-64); but -+ * our testsuite is easier to write if we point libdir directly to -+ * a stub .so. - */ - { "lib64/libvixDiskLib.so.7", 7 }, - { "libvixDiskLib.so.7", 7 }, - { "lib64/libvixDiskLib.so.6", 6 }, - { "libvixDiskLib.so.6", 6 }, -- { "lib64/libvixDiskLib.so.5", 5 }, -- { "libvixDiskLib.so.5", 5 }, - { NULL } - }; - size_t i; -@@ -474,7 +472,7 @@ load_library (bool load_error_is_fatal) - exit (EXIT_FAILURE); - } - -- assert (library_version >= 5); -+ assert (library_version >= 6); - - /* Load symbols. */ - #define STUB(fn,ret,args) \ -@@ -490,6 +488,16 @@ load_library (bool load_error_is_fatal) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB -+ -+ /* Additionally, VDDK version must be >= 6.5. This was the first -+ * version which introduced VixDiskLib_Wait symbol so we can check -+ * for that. -+ */ -+ if (VixDiskLib_Wait == NULL) { -+ nbdkit_error ("VDDK version must be >= 6.5. " -+ "See nbdkit-vddk-plugin(1) man page section \"SUPPORTED VERSIONS OF VDDK\"."); -+ exit (EXIT_FAILURE); -+ } - } - - static int -diff --git a/tests/dummy-vddk.c b/tests/dummy-vddk.c -index 9b5ae0a2..cb88380c 100644 ---- a/tests/dummy-vddk.c -+++ b/tests/dummy-vddk.c -@@ -198,3 +198,9 @@ VixDiskLib_Write (VixDiskLibHandle handle, - memcpy (disk + offset, buf, nr_sectors * VIXDISKLIB_SECTOR_SIZE); - return VIX_OK; - } -+ -+NBDKIT_DLL_PUBLIC VixError -+VixDiskLib_Wait (VixDiskLibHandle handle) -+{ -+ return VIX_OK; -+} --- -2.31.1 - diff --git a/0011-vddk-Add-read-write-and-wait-asynchronous-functions.patch b/0011-vddk-Add-read-write-and-wait-asynchronous-functions.patch deleted file mode 100644 index fc5b20c..0000000 --- a/0011-vddk-Add-read-write-and-wait-asynchronous-functions.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 90dc3311582784f8b078a30a7207c15c6298b1e2 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Oct 2021 11:57:35 +0100 -Subject: [PATCH] vddk: Add read, write and wait asynchronous functions - -These functions added in VDDK 6.0 - 6.5 implement asynchronous read -and write. - -Acked-by: Laszlo Ersek -(cherry picked from commit ad53e7becafed6ca3573795a79c534281fe9c274) ---- - plugins/vddk/vddk-structs.h | 3 +++ - plugins/vddk/vddk-stubs.h | 19 ++++++++++++++++++- - 2 files changed, 21 insertions(+), 1 deletion(-) - -diff --git a/plugins/vddk/vddk-structs.h b/plugins/vddk/vddk-structs.h -index aeb5bfd0..e97f017c 100644 ---- a/plugins/vddk/vddk-structs.h -+++ b/plugins/vddk/vddk-structs.h -@@ -43,6 +43,7 @@ - - typedef uint64_t VixError; - #define VIX_OK 0 -+#define VIX_ASYNC 25000 - - #define VIXDISKLIB_FLAG_OPEN_UNBUFFERED 1 - #define VIXDISKLIB_FLAG_OPEN_SINGLE_LINK 2 -@@ -61,6 +62,8 @@ typedef void *VixDiskLibHandle; - - typedef void VixDiskLibGenericLogFunc (const char *fmt, va_list args); - -+typedef void (*VixDiskLibCompletionCB) (void *data, VixError result); -+ - enum VixDiskLibCredType { - VIXDISKLIB_CRED_UID = 1, - VIXDISKLIB_CRED_SESSIONID = 2, -diff --git a/plugins/vddk/vddk-stubs.h b/plugins/vddk/vddk-stubs.h -index a94df9cd..66353691 100644 ---- a/plugins/vddk/vddk-stubs.h -+++ b/plugins/vddk/vddk-stubs.h -@@ -103,10 +103,27 @@ STUB (VixDiskLib_Write, - uint64_t start_sector, uint64_t nr_sectors, - const unsigned char *buf)); - --/* Added in VDDK 6.0, this will be NULL in earlier versions. */ -+/* Added in VDDK 6.0, these will be NULL in earlier versions. */ - OPTIONAL_STUB (VixDiskLib_Flush, - VixError, - (VixDiskLibHandle handle)); -+OPTIONAL_STUB (VixDiskLib_ReadAsync, -+ VixError, -+ (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data)); -+OPTIONAL_STUB (VixDiskLib_WriteAsync, -+ VixError, -+ (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ const unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data)); -+ -+/* Added in VDDK 6.5, this will be NULL in earlier versions. */ -+OPTIONAL_STUB (VixDiskLib_Wait, -+ VixError, -+ (VixDiskLibHandle handle)); - - /* Added in VDDK 6.7, these will be NULL for earlier versions: */ - OPTIONAL_STUB (VixDiskLib_QueryAllocatedBlocks, --- -2.31.1 - diff --git a/0012-vddk-Start-to-split-VDDK-over-several-files.patch b/0012-vddk-Start-to-split-VDDK-over-several-files.patch deleted file mode 100644 index 805b695..0000000 --- a/0012-vddk-Start-to-split-VDDK-over-several-files.patch +++ /dev/null @@ -1,259 +0,0 @@ -From c9e432e08e889d9e6edea52344b2452f0141f56b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Oct 2021 12:20:31 +0100 -Subject: [PATCH] vddk: Start to split VDDK over several files - -This change doesn't do anything except move some definitions into the -header file vddk.h, but it allows future commits to split up the very -large vddk.c file. - -Acked-by: Laszlo Ersek -(cherry picked from commit 117634dccf4e29394e8718a8d62e93a9edf0a39c) ---- - plugins/vddk/vddk.c | 91 +++++++++++++-------------------------------- - plugins/vddk/vddk.h | 89 +++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 112 insertions(+), 68 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index babffc28..041bff1a 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -50,14 +50,12 @@ - #include - - #include "cleanup.h" --#include "isaligned.h" - #include "minmax.h" - #include "rounding.h" - #include "tvdiff.h" - #include "vector.h" - - #include "vddk.h" --#include "vddk-structs.h" - - /* Debug flags. */ - NBDKIT_DLL_PUBLIC int vddk_debug_diskinfo; -@@ -65,11 +63,11 @@ NBDKIT_DLL_PUBLIC int vddk_debug_extents; - NBDKIT_DLL_PUBLIC int vddk_debug_datapath = 1; - NBDKIT_DLL_PUBLIC int vddk_debug_stats; - --/* For each VDDK API define a static global variable. These globals -- * are initialized when the plugin is loaded (by vddk_get_ready). -+/* For each VDDK API define a global variable. These globals are -+ * initialized when the plugin is loaded (by vddk_get_ready). - */ --#define STUB(fn,ret,args) static ret (*fn) args --#define OPTIONAL_STUB(fn,ret,args) static ret (*fn) args -+#define STUB(fn,ret,args) ret (*fn) args -+#define OPTIONAL_STUB(fn,ret,args) ret (*fn) args - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB -@@ -78,28 +76,28 @@ NBDKIT_DLL_PUBLIC int vddk_debug_stats; - #define VDDK_MAJOR 6 - #define VDDK_MINOR 5 - --static void *dl; /* dlopen handle */ --static bool init_called; /* was InitEx called */ --static __thread int error_suppression; /* threadlocal error suppression */ --static int library_version; /* VDDK major: 6, 7, ... */ -+void *dl; /* dlopen handle */ -+bool init_called; /* was InitEx called */ -+__thread int error_suppression; /* threadlocal error suppression */ -+int library_version; /* VDDK major: 6, 7, ... */ -+bool is_remote; /* true if remote connection */ - --static enum { NONE = 0, ZLIB, FASTLZ, SKIPZ } compression; /* compression */ --static char *config; /* config */ --static const char *cookie; /* cookie */ --static const char *filename; /* file */ --char *libdir; /* libdir */ --static uint16_t nfc_host_port; /* nfchostport */ --char *password; /* password */ --static uint16_t port; /* port */ --static const char *server_name; /* server */ --static bool single_link; /* single-link */ --static const char *snapshot_moref; /* snapshot */ --static const char *thumb_print; /* thumbprint */ --static const char *transport_modes; /* transports */ --static bool unbuffered; /* unbuffered */ --static const char *username; /* user */ --static const char *vmx_spec; /* vm */ --static bool is_remote; -+enum compression_type compression; /* compression */ -+char *config; /* config */ -+const char *cookie; /* cookie */ -+const char *filename; /* file */ -+char *libdir; /* libdir */ -+uint16_t nfc_host_port; /* nfchostport */ -+char *password; /* password */ -+uint16_t port; /* port */ -+const char *server_name; /* server */ -+bool single_link; /* single-link */ -+const char *snapshot_moref; /* snapshot */ -+const char *thumb_print; /* thumbprint */ -+const char *transport_modes; /* transports */ -+bool unbuffered; /* unbuffered */ -+const char *username; /* user */ -+const char *vmx_spec; /* vm */ - - /* For each VDDK API define a variable to store the time taken (used - * to implement -D vddk.stats=1). -@@ -120,45 +118,6 @@ static void display_stats (void); - #undef STUB - #undef OPTIONAL_STUB - --/* Macros to bracket each VDDK API call, for printing debugging -- * information and collecting statistics. -- */ --#define VDDK_CALL_START(fn, fs, ...) \ -- do { \ -- struct timeval start_t, end_t; \ -- /* GCC can optimize this away at compile time: */ \ -- const bool datapath = \ -- strcmp (#fn, "VixDiskLib_Read") == 0 || \ -- strcmp (#fn, "VixDiskLib_Write") == 0; \ -- if (vddk_debug_stats) \ -- gettimeofday (&start_t, NULL); \ -- if (!datapath || vddk_debug_datapath) \ -- nbdkit_debug ("VDDK call: %s (" fs ")", #fn, ##__VA_ARGS__); \ -- do --#define VDDK_CALL_END(fn, bytes_) \ -- while (0); \ -- if (vddk_debug_stats) { \ -- gettimeofday (&end_t, NULL); \ -- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ -- stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ -- stats_##fn.calls++; \ -- stats_##fn.bytes += bytes_; \ -- } \ -- } while (0) -- --/* Print VDDK errors. */ --#define VDDK_ERROR(err, fs, ...) \ -- do { \ -- char *vddk_err_msg; \ -- VDDK_CALL_START (VixDiskLib_GetErrorText, "%lu", err) \ -- vddk_err_msg = VixDiskLib_GetErrorText ((err), NULL); \ -- VDDK_CALL_END (VixDiskLib_GetErrorText, 0); \ -- nbdkit_error (fs ": %s", ##__VA_ARGS__, vddk_err_msg); \ -- VDDK_CALL_START (VixDiskLib_FreeErrorText, "") \ -- VixDiskLib_FreeErrorText (vddk_err_msg); \ -- VDDK_CALL_END (VixDiskLib_FreeErrorText, 0); \ -- } while (0) -- - /* Unload the plugin. */ - static void - vddk_unload (void) -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index 8c63b4ee..29775eb4 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -1,5 +1,5 @@ - /* nbdkit -- * Copyright (C) 2013-2020 Red Hat Inc. -+ * Copyright (C) 2013-2021 Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are -@@ -33,11 +33,96 @@ - #ifndef NBDKIT_VDDK_H - #define NBDKIT_VDDK_H - -+#include -+#include -+#include -+ -+#include -+ -+#include "isaligned.h" -+#include "tvdiff.h" -+#include "vector.h" -+ -+#include "vddk-structs.h" -+ -+enum compression_type { NONE = 0, ZLIB, FASTLZ, SKIPZ }; -+ -+extern void *dl; -+extern bool init_called; -+extern __thread int error_suppression; -+extern int library_version; -+extern bool is_remote; -+ -+extern enum compression_type compression; -+extern char *config; -+extern const char *cookie; -+extern const char *filename; - extern char *libdir; -+extern uint16_t nfc_host_port; - extern char *password; -+extern uint16_t port; -+extern const char *server_name; -+extern bool single_link; -+extern const char *snapshot_moref; -+extern const char *thumb_print; -+extern const char *transport_modes; -+extern bool unbuffered; -+extern const char *username; -+extern const char *vmx_spec; -+ -+extern int vddk_debug_diskinfo; -+extern int vddk_debug_extents; -+extern int vddk_debug_datapath; -+extern int vddk_debug_stats; -+ -+#define STUB(fn,ret,args) extern ret (*fn) args -+#define OPTIONAL_STUB(fn,ret,args) extern ret (*fn) args -+#include "vddk-stubs.h" -+#undef STUB -+#undef OPTIONAL_STUB -+ -+/* Macros to bracket each VDDK API call, for printing debugging -+ * information and collecting statistics. -+ */ -+#define VDDK_CALL_START(fn, fs, ...) \ -+ do { \ -+ struct timeval start_t, end_t; \ -+ /* GCC can optimize this away at compile time: */ \ -+ const bool datapath = \ -+ strcmp (#fn, "VixDiskLib_Read") == 0 || \ -+ strcmp (#fn, "VixDiskLib_Write") == 0; \ -+ if (vddk_debug_stats) \ -+ gettimeofday (&start_t, NULL); \ -+ if (!datapath || vddk_debug_datapath) \ -+ nbdkit_debug ("VDDK call: %s (" fs ")", #fn, ##__VA_ARGS__); \ -+ do -+#define VDDK_CALL_END(fn, bytes_) \ -+ while (0); \ -+ if (vddk_debug_stats) { \ -+ gettimeofday (&end_t, NULL); \ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&stats_lock); \ -+ stats_##fn.usecs += tvdiff_usec (&start_t, &end_t); \ -+ stats_##fn.calls++; \ -+ stats_##fn.bytes += bytes_; \ -+ } \ -+ } while (0) -+ -+/* Print VDDK errors. */ -+#define VDDK_ERROR(err, fs, ...) \ -+ do { \ -+ char *vddk_err_msg; \ -+ VDDK_CALL_START (VixDiskLib_GetErrorText, "%lu", err) \ -+ vddk_err_msg = VixDiskLib_GetErrorText ((err), NULL); \ -+ VDDK_CALL_END (VixDiskLib_GetErrorText, 0); \ -+ nbdkit_error (fs ": %s", ##__VA_ARGS__, vddk_err_msg); \ -+ VDDK_CALL_START (VixDiskLib_FreeErrorText, "") \ -+ VixDiskLib_FreeErrorText (vddk_err_msg); \ -+ VDDK_CALL_END (VixDiskLib_FreeErrorText, 0); \ -+ } while (0) -+ -+/* reexec.c */ - extern bool noreexec; - extern char *reexeced; -- - extern void reexec_if_needed (const char *prepend); - extern int restore_ld_library_path (void); - --- -2.31.1 - diff --git a/0013-vddk-Refactor-D-vddk.stats-1-into-a-new-file.patch b/0013-vddk-Refactor-D-vddk.stats-1-into-a-new-file.patch deleted file mode 100644 index d5f3813..0000000 --- a/0013-vddk-Refactor-D-vddk.stats-1-into-a-new-file.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 66945d24e9192a67af421eecbb1835d42636ab93 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Oct 2021 12:30:41 +0100 -Subject: [PATCH] vddk: Refactor -D vddk.stats=1 into a new file - -Acked-by: Laszlo Ersek -(cherry picked from commit dcd5bc51ed7710c32d956345ea8da14ba15ef8f5) ---- - plugins/vddk/Makefile.am | 1 + - plugins/vddk/stats.c | 118 +++++++++++++++++++++++++++++++++++++++ - plugins/vddk/vddk.c | 78 +------------------------- - plugins/vddk/vddk.h | 15 +++++ - 4 files changed, 135 insertions(+), 77 deletions(-) - create mode 100644 plugins/vddk/stats.c - -diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am -index 232aaedd..4f470ff9 100644 ---- a/plugins/vddk/Makefile.am -+++ b/plugins/vddk/Makefile.am -@@ -46,6 +46,7 @@ nbdkit_vddk_plugin_la_SOURCES = \ - vddk.c \ - vddk.h \ - reexec.c \ -+ stats.c \ - vddk-structs.h \ - vddk-stubs.h \ - $(top_srcdir)/include/nbdkit-plugin.h \ -diff --git a/plugins/vddk/stats.c b/plugins/vddk/stats.c -new file mode 100644 -index 00000000..18a42714 ---- /dev/null -+++ b/plugins/vddk/stats.c -@@ -0,0 +1,118 @@ -+/* nbdkit -+ * Copyright (C) 2013-2021 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define NBDKIT_API_VERSION 2 -+#include -+ -+#include "vector.h" -+ -+#include "vddk.h" -+ -+/* Debug flags. */ -+NBDKIT_DLL_PUBLIC int vddk_debug_stats; -+ -+pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; -+ -+/* For each VDDK API define a variable to store the time taken (used -+ * to implement -D vddk.stats=1). -+ */ -+#define STUB(fn,ret,args) struct vddk_stat stats_##fn = { .name = #fn } -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) -+#include "vddk-stubs.h" -+#undef STUB -+#undef OPTIONAL_STUB -+ -+DEFINE_VECTOR_TYPE(statlist, struct vddk_stat) -+ -+static int -+stat_compare (const void *vp1, const void *vp2) -+{ -+ const struct vddk_stat *st1 = vp1; -+ const struct vddk_stat *st2 = vp2; -+ -+ /* Note: sorts in reverse order of time spent in each API call. */ -+ if (st1->usecs < st2->usecs) return 1; -+ else if (st1->usecs > st2->usecs) return -1; -+ else return 0; -+} -+ -+static const char * -+api_name_without_prefix (const char *name) -+{ -+ return strncmp (name, "VixDiskLib_", 11) == 0 ? name + 11 : name; -+} -+ -+void -+display_stats (void) -+{ -+ statlist stats = empty_vector; -+ size_t i; -+ -+ if (!vddk_debug_stats) return; -+ -+#define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -+#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -+#include "vddk-stubs.h" -+#undef STUB -+#undef OPTIONAL_STUB -+ -+ qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); -+ -+ nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); -+ nbdkit_debug ("%-24s %15s %5s %15s", -+ "VixDiskLib_...", "µs", "calls", "bytes"); -+ for (i = 0; i < stats.size; ++i) { -+ if (stats.ptr[i].usecs) { -+ if (stats.ptr[i].bytes > 0) -+ nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, -+ api_name_without_prefix (stats.ptr[i].name), -+ stats.ptr[i].usecs, -+ stats.ptr[i].calls, -+ stats.ptr[i].bytes); -+ else -+ nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64, -+ api_name_without_prefix (stats.ptr[i].name), -+ stats.ptr[i].usecs, -+ stats.ptr[i].calls); -+ } -+ } -+ statlist_reset (&stats); -+} -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 041bff1a..67ac775c 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -61,7 +61,6 @@ - NBDKIT_DLL_PUBLIC int vddk_debug_diskinfo; - NBDKIT_DLL_PUBLIC int vddk_debug_extents; - NBDKIT_DLL_PUBLIC int vddk_debug_datapath = 1; --NBDKIT_DLL_PUBLIC int vddk_debug_stats; - - /* For each VDDK API define a global variable. These globals are - * initialized when the plugin is loaded (by vddk_get_ready). -@@ -99,25 +98,6 @@ bool unbuffered; /* unbuffered */ - const char *username; /* user */ - const char *vmx_spec; /* vm */ - --/* For each VDDK API define a variable to store the time taken (used -- * to implement -D vddk.stats=1). -- */ --struct vddk_stat { -- const char *name; /* function name */ -- int64_t usecs; /* total number of usecs consumed */ -- uint64_t calls; /* number of times called */ -- uint64_t bytes; /* bytes transferred, datapath calls only */ --}; --static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; --static void display_stats (void); --#define STUB(fn,ret,args) \ -- static struct vddk_stat stats_##fn = { .name = #fn } --#define OPTIONAL_STUB(fn,ret,args) \ -- static struct vddk_stat stats_##fn = { .name = #fn } --#include "vddk-stubs.h" --#undef STUB --#undef OPTIONAL_STUB -- - /* Unload the plugin. */ - static void - vddk_unload (void) -@@ -130,69 +110,13 @@ vddk_unload (void) - if (dl) - dlclose (dl); - -- if (vddk_debug_stats) -- display_stats (); -+ display_stats (); - - free (config); - free (libdir); - free (password); - } - --DEFINE_VECTOR_TYPE(statlist, struct vddk_stat) -- --static int --stat_compare (const void *vp1, const void *vp2) --{ -- const struct vddk_stat *st1 = vp1; -- const struct vddk_stat *st2 = vp2; -- -- /* Note: sorts in reverse order of time spent in each API call. */ -- if (st1->usecs < st2->usecs) return 1; -- else if (st1->usecs > st2->usecs) return -1; -- else return 0; --} -- --static const char * --api_name_without_prefix (const char *name) --{ -- return strncmp (name, "VixDiskLib_", 11) == 0 ? name + 11 : name; --} -- --static void --display_stats (void) --{ -- statlist stats = empty_vector; -- size_t i; -- --#define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) --#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) --#include "vddk-stubs.h" --#undef STUB --#undef OPTIONAL_STUB -- -- qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); -- -- nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); -- nbdkit_debug ("%-24s %15s %5s %15s", -- "VixDiskLib_...", "µs", "calls", "bytes"); -- for (i = 0; i < stats.size; ++i) { -- if (stats.ptr[i].usecs) { -- if (stats.ptr[i].bytes > 0) -- nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, -- api_name_without_prefix (stats.ptr[i].name), -- stats.ptr[i].usecs, -- stats.ptr[i].calls, -- stats.ptr[i].bytes); -- else -- nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64, -- api_name_without_prefix (stats.ptr[i].name), -- stats.ptr[i].usecs, -- stats.ptr[i].calls); -- } -- } -- statlist_reset (&stats); --} -- - static void - trim (char *str) - { -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index 29775eb4..1400589d 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -126,4 +126,19 @@ extern char *reexeced; - extern void reexec_if_needed (const char *prepend); - extern int restore_ld_library_path (void); - -+/* stats.c */ -+struct vddk_stat { -+ const char *name; /* function name */ -+ int64_t usecs; /* total number of usecs consumed */ -+ uint64_t calls; /* number of times called */ -+ uint64_t bytes; /* bytes transferred, datapath calls only */ -+}; -+extern pthread_mutex_t stats_lock; -+#define STUB(fn,ret,args) extern struct vddk_stat stats_##fn; -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) -+#include "vddk-stubs.h" -+#undef STUB -+#undef OPTIONAL_STUB -+extern void display_stats (void); -+ - #endif /* NBDKIT_VDDK_H */ --- -2.31.1 - diff --git a/0014-vddk-Implement-parallel-thread-model.patch b/0014-vddk-Implement-parallel-thread-model.patch deleted file mode 100644 index 0deb820..0000000 --- a/0014-vddk-Implement-parallel-thread-model.patch +++ /dev/null @@ -1,1287 +0,0 @@ -From 11a40792fde602861b987dc5a2c91a0539abfe78 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Wed, 27 Oct 2021 10:17:22 +0100 -Subject: [PATCH] vddk: Implement parallel thread model - -Since VDDK 6.0, asynchronous read and write operations are available. -This commit makes use of these, allowing us to use the parallel thread -model for increased performance. - -Note that at least VDDK 6.5 is required because VDDK 6.0 had a -different and incompatible signature for VixDiskLibCompletionCB. - -Also note at least vSphere 6.7 is required for asynch calls to make -any performance difference. In older versions they work -synchronously. - -In the parallel thread model, nbdkit will be calling us in parallel -from multiple nbdkit threads. VDDK does not allow multiple threads to -simultaneously call VDDK operations on the same handle. So we create -a background thread per handle (== connection). - -Only the background thread makes VDDK calls[1]. The background thread -handles a mix of synchronous (like extents, flush) and asynchronous -(like read, write) operations, but all from one thread. - -Parallel nbdkit threads issue commands to the background thread -associated with each handle, and wait until they are retired. - -[1] All VDDK calls except for connecting and disconnecting which for -different reasons are protected by a global lock, so I did not need to -change those. - -(cherry picked from commit 1eecf15fc3d8ea253ccec4f5883fdbb9aa6f8c2b) ---- - plugins/vddk/Makefile.am | 1 + - plugins/vddk/nbdkit-vddk-plugin.pod | 11 +- - plugins/vddk/vddk.c | 380 +++++-------------- - plugins/vddk/vddk.h | 49 ++- - plugins/vddk/worker.c | 567 ++++++++++++++++++++++++++++ - tests/dummy-vddk.c | 32 ++ - 6 files changed, 745 insertions(+), 295 deletions(-) - create mode 100644 plugins/vddk/worker.c - -diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am -index 4f470ff9..f8382fc9 100644 ---- a/plugins/vddk/Makefile.am -+++ b/plugins/vddk/Makefile.am -@@ -49,6 +49,7 @@ nbdkit_vddk_plugin_la_SOURCES = \ - stats.c \ - vddk-structs.h \ - vddk-stubs.h \ -+ worker.c \ - $(top_srcdir)/include/nbdkit-plugin.h \ - $(NULL) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 1c16d096..ce82a734 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -523,6 +523,14 @@ read bandwidth to the VMware server. - - Same as above, but for writing and flushing writes. - -+=item C -+ -+=item C -+ -+Same as above, but for asynchronous read and write calls introduced in -+nbdkit 1.30. Unfortunately at the moment the amount of time spent in -+these calls is not accounted for correctly. -+ - =item C - - This call is used to query information about the sparseness of the -@@ -580,7 +588,8 @@ Debug extents returned by C. - - =item B<-D vddk.datapath=0> - --Suppress debugging of datapath calls (C and C). -+Suppress debugging of datapath calls (C, C, C -+and C). - - =item B<-D vddk.stats=1> - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 67ac775c..9f223db0 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -50,9 +50,6 @@ - #include - - #include "cleanup.h" --#include "minmax.h" --#include "rounding.h" --#include "tvdiff.h" - #include "vector.h" - - #include "vddk.h" -@@ -522,23 +519,18 @@ vddk_dump_plugin (void) - /* The rules on threads and VDDK are here: - * https://code.vmware.com/docs/11750/virtual-disk-development-kit-programming-guide/GUID-6BE903E8-DC70-46D9-98E4-E34A2002C2AD.html - * -- * Before nbdkit 1.22 we used SERIALIZE_ALL_REQUESTS. Since nbdkit -- * 1.22 we changed this to SERIALIZE_REQUESTS and added a mutex around -- * calls to VixDiskLib_Open and VixDiskLib_Close. This is not quite -- * within the letter of the rules, but is within the spirit. -+ * 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. - */ --#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS -+#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL - - /* Lock protecting open/close calls - see above. */ - static pthread_mutex_t open_close_lock = PTHREAD_MUTEX_INITIALIZER; - --/* The per-connection handle. */ --struct vddk_handle { -- VixDiskLibConnectParams *params; /* connection parameters */ -- VixDiskLibConnection connection; /* connection */ -- VixDiskLibHandle handle; /* disk handle */ --}; -- - static inline VixDiskLibConnectParams * - allocate_connect_params (void) - { -@@ -579,12 +571,16 @@ vddk_open (int readonly) - VixError err; - uint32_t flags; - const char *transport_mode; -+ int pterr; - -- h = malloc (sizeof *h); -+ h = calloc (1, sizeof *h); - if (h == NULL) { -- nbdkit_error ("malloc: %m"); -+ 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) { -@@ -661,8 +657,22 @@ vddk_open (int readonly) - 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); -+ if (pterr != 0) { -+ errno = pterr; -+ nbdkit_error ("pthread_create: %m"); -+ goto err3; -+ } -+ - return h; - -+ err3: -+ VDDK_CALL_START (VixDiskLib_Close, "handle") -+ VixDiskLib_Close (h->handle); -+ VDDK_CALL_END (VixDiskLib_Close, 0); - err2: - VDDK_CALL_START (VixDiskLib_Disconnect, "connection") - VixDiskLib_Disconnect (h->connection); -@@ -670,6 +680,8 @@ vddk_open (int readonly) - err1: - free_connect_params (h->params); - err0: -+ pthread_mutex_destroy (&h->commands_lock); -+ pthread_cond_destroy (&h->commands_cond); - free (h); - return NULL; - } -@@ -680,6 +692,10 @@ vddk_close (void *handle) - { - 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); - - VDDK_CALL_START (VixDiskLib_Close, "handle") - VixDiskLib_Close (h->handle); -@@ -689,6 +705,9 @@ vddk_close (void *handle) - 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); - } - -@@ -697,54 +716,29 @@ static int64_t - vddk_get_size (void *handle) - { - struct vddk_handle *h = handle; -- VixDiskLibInfo *info; -- VixError err; - uint64_t size; -+ struct command get_size_cmd = { .type = GET_SIZE, .ptr = &size }; - -- VDDK_CALL_START (VixDiskLib_GetInfo, "handle, &info") -- err = VixDiskLib_GetInfo (h->handle, &info); -- VDDK_CALL_END (VixDiskLib_GetInfo, 0); -- if (err != VIX_OK) { -- VDDK_ERROR (err, "VixDiskLib_GetInfo"); -+ if (send_command_and_wait (h, &get_size_cmd) == -1) - return -1; -- } -- -- size = info->capacity * (uint64_t)VIXDISKLIB_SECTOR_SIZE; -- -- if (vddk_debug_diskinfo) { -- nbdkit_debug ("disk info: capacity: %" PRIu64 " sectors " -- "(%" PRIi64 " bytes)", -- info->capacity, size); -- nbdkit_debug ("disk info: biosGeo: C:%" PRIu32 " H:%" PRIu32 " S:%" PRIu32, -- info->biosGeo.cylinders, -- info->biosGeo.heads, -- info->biosGeo.sectors); -- nbdkit_debug ("disk info: physGeo: C:%" PRIu32 " H:%" PRIu32 " S:%" PRIu32, -- info->physGeo.cylinders, -- info->physGeo.heads, -- info->physGeo.sectors); -- nbdkit_debug ("disk info: adapter type: %d", -- (int) info->adapterType); -- nbdkit_debug ("disk info: num links: %d", info->numLinks); -- nbdkit_debug ("disk info: parent filename hint: %s", -- info->parentFileNameHint ? : "NULL"); -- nbdkit_debug ("disk info: uuid: %s", -- info->uuid ? : "NULL"); -- if (library_version >= 7) { -- nbdkit_debug ("disk info: sector size: " -- "logical %" PRIu32 " physical %" PRIu32, -- info->logicalSectorSize, -- info->physicalSectorSize); -- } -- } -- -- VDDK_CALL_START (VixDiskLib_FreeInfo, "info") -- VixDiskLib_FreeInfo (info); -- VDDK_CALL_END (VixDiskLib_FreeInfo, 0); - - return (int64_t) size; - } - -+static int -+vddk_can_fua (void *handle) -+{ -+ /* The Flush call was not available in VDDK < 6.0. */ -+ return VixDiskLib_Flush != NULL ? NBDKIT_FUA_NATIVE : NBDKIT_FUA_NONE; -+} -+ -+static int -+vddk_can_flush (void *handle) -+{ -+ /* The Flush call was not available in VDDK < 6.0. */ -+ return VixDiskLib_Flush != NULL; -+} -+ - /* Read data from the file. - * - * Note that reads have to be aligned to sectors (XXX). -@@ -754,32 +748,14 @@ vddk_pread (void *handle, void *buf, uint32_t count, uint64_t offset, - uint32_t flags) - { - struct vddk_handle *h = handle; -- VixError err; -+ struct command read_cmd = { -+ .type = READ, -+ .ptr = buf, -+ .count = count, -+ .offset = offset, -+ }; - -- /* Align to sectors. */ -- if (!IS_ALIGNED (offset, VIXDISKLIB_SECTOR_SIZE)) { -- nbdkit_error ("%s is not aligned to sectors", "read"); -- return -1; -- } -- if (!IS_ALIGNED (count, VIXDISKLIB_SECTOR_SIZE)) { -- nbdkit_error ("%s is not aligned to sectors", "read"); -- return -1; -- } -- offset /= VIXDISKLIB_SECTOR_SIZE; -- count /= VIXDISKLIB_SECTOR_SIZE; -- -- VDDK_CALL_START (VixDiskLib_Read, -- "handle, %" PRIu64 " sectors, " -- "%" PRIu32 " sectors, buffer", -- offset, count) -- err = VixDiskLib_Read (h->handle, offset, count, buf); -- VDDK_CALL_END (VixDiskLib_Read, count * VIXDISKLIB_SECTOR_SIZE); -- if (err != VIX_OK) { -- VDDK_ERROR (err, "VixDiskLib_Read"); -- return -1; -- } -- -- return 0; -+ return send_command_and_wait (h, &read_cmd); - } - - static int vddk_flush (void *handle, uint32_t flags); -@@ -792,32 +768,17 @@ static int - vddk_pwrite (void *handle, 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 vddk_handle *h = handle; -- VixError err; -+ struct command write_cmd = { -+ .type = WRITE, -+ .ptr = (void *) buf, -+ .count = count, -+ .offset = offset, -+ }; - -- /* Align to sectors. */ -- if (!IS_ALIGNED (offset, VIXDISKLIB_SECTOR_SIZE)) { -- nbdkit_error ("%s is not aligned to sectors", "write"); -+ if (send_command_and_wait (h, &write_cmd) == -1) - return -1; -- } -- if (!IS_ALIGNED (count, VIXDISKLIB_SECTOR_SIZE)) { -- nbdkit_error ("%s is not aligned to sectors", "write"); -- return -1; -- } -- offset /= VIXDISKLIB_SECTOR_SIZE; -- count /= VIXDISKLIB_SECTOR_SIZE; -- -- VDDK_CALL_START (VixDiskLib_Write, -- "handle, %" PRIu64 " sectors, " -- "%" PRIu32 " sectors, buffer", -- offset, count) -- err = VixDiskLib_Write (h->handle, offset, count, buf); -- VDDK_CALL_END (VixDiskLib_Write, count * VIXDISKLIB_SECTOR_SIZE); -- if (err != VIX_OK) { -- VDDK_ERROR (err, "VixDiskLib_Write"); -- return -1; -- } - - if (fua) { - if (vddk_flush (handle, 0) == -1) -@@ -827,126 +788,32 @@ vddk_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, - return 0; - } - --static int --vddk_can_fua (void *handle) --{ -- /* The Flush call was not available in VDDK < 6.0. */ -- return VixDiskLib_Flush != NULL ? NBDKIT_FUA_NATIVE : NBDKIT_FUA_NONE; --} -- --static int --vddk_can_flush (void *handle) --{ -- /* The Flush call was not available in VDDK < 6.0. */ -- return VixDiskLib_Flush != NULL; --} -- - /* Flush data to the file. */ - static int - vddk_flush (void *handle, uint32_t flags) - { - struct vddk_handle *h = handle; -- VixError err; -+ struct command flush_cmd = { -+ .type = FLUSH, -+ }; - -- /* The documentation for Flush is missing, but the comment in the -- * header file seems to indicate that it waits for WriteAsync -- * commands to finish. We don't use WriteAsync, and in any case -- * there's a new function Wait to wait for those. However I -- * verified using strace that in fact Flush does call fsync on the -- * file so it appears to be the correct call to use here. -- */ -- -- VDDK_CALL_START (VixDiskLib_Flush, "handle") -- err = VixDiskLib_Flush (h->handle); -- VDDK_CALL_END (VixDiskLib_Flush, 0); -- if (err != VIX_OK) { -- VDDK_ERROR (err, "VixDiskLib_Flush"); -- return -1; -- } -- -- return 0; -+ return send_command_and_wait (h, &flush_cmd); - } - - static int - vddk_can_extents (void *handle) - { - struct vddk_handle *h = handle; -- VixError err; -- VixDiskLibBlockList *block_list; -+ int ret; -+ struct command can_extents_cmd = { -+ .type = CAN_EXTENTS, -+ .ptr = &ret, -+ }; - -- /* This call was added in VDDK 6.7. In earlier versions the -- * function pointer will be NULL and we cannot query extents. -- */ -- if (VixDiskLib_QueryAllocatedBlocks == NULL) { -- nbdkit_debug ("can_extents: VixDiskLib_QueryAllocatedBlocks == NULL, " -- "probably this is VDDK < 6.7"); -- return 0; -- } -- -- /* Suppress errors around this call. See: -- * https://bugzilla.redhat.com/show_bug.cgi?id=1709211#c7 -- */ -- error_suppression = 1; -- -- /* However even when the call is available it rarely works well so -- * the best thing we can do here is to try the call and if it's -- * non-functional return false. -- */ -- VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, -- "handle, 0, %d sectors, %d sectors", -- VIXDISKLIB_MIN_CHUNK_SIZE, VIXDISKLIB_MIN_CHUNK_SIZE) -- err = VixDiskLib_QueryAllocatedBlocks (h->handle, -- 0, VIXDISKLIB_MIN_CHUNK_SIZE, -- VIXDISKLIB_MIN_CHUNK_SIZE, -- &block_list); -- VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); -- error_suppression = 0; -- if (err == VIX_OK) { -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -- VixDiskLib_FreeBlockList (block_list); -- VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -- } -- if (err != VIX_OK) { -- char *errmsg = VixDiskLib_GetErrorText (err, NULL); -- nbdkit_debug ("can_extents: VixDiskLib_QueryAllocatedBlocks test failed, " -- "extents support will be disabled: " -- "original error: %s", -- errmsg); -- VixDiskLib_FreeErrorText (errmsg); -- return 0; -- } -- -- return 1; --} -- --static int --add_extent (struct nbdkit_extents *extents, -- uint64_t *position, uint64_t next_position, bool is_hole) --{ -- uint32_t type = 0; -- const uint64_t length = next_position - *position; -- -- if (is_hole) { -- type = NBDKIT_EXTENT_HOLE; -- /* Images opened as single link might be backed by another file in the -- chain, so the holes are not guaranteed to be zeroes. */ -- if (!single_link) -- type |= NBDKIT_EXTENT_ZERO; -- } -- -- assert (*position <= next_position); -- if (*position == next_position) -- return 0; -- -- if (vddk_debug_extents) -- nbdkit_debug ("adding extent type %s at [%" PRIu64 "...%" PRIu64 "]", -- is_hole ? "hole" : "allocated data", -- *position, next_position-1); -- if (nbdkit_add_extent (extents, *position, length, type) == -1) -+ if (send_command_and_wait (h, &can_extents_cmd) == -1) - return -1; - -- *position = next_position; -- return 0; -+ return ret; - } - - static int -@@ -955,88 +822,15 @@ vddk_extents (void *handle, uint32_t count, uint64_t offset, uint32_t flags, - { - struct vddk_handle *h = handle; - bool req_one = flags & NBDKIT_FLAG_REQ_ONE; -- uint64_t position, end, start_sector; -- -- position = offset; -- end = offset + count; -- -- /* We can only query whole chunks. Therefore start with the first -- * chunk before offset. -- */ -- start_sector = -- ROUND_DOWN (offset, VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE) -- / VIXDISKLIB_SECTOR_SIZE; -- while (start_sector * VIXDISKLIB_SECTOR_SIZE < end) { -- VixError err; -- uint32_t i; -- uint64_t nr_chunks, nr_sectors; -- VixDiskLibBlockList *block_list; -- -- assert (IS_ALIGNED (start_sector, VIXDISKLIB_MIN_CHUNK_SIZE)); -- -- nr_chunks = -- ROUND_UP (end - start_sector * VIXDISKLIB_SECTOR_SIZE, -- VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE) -- / (VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE); -- nr_chunks = MIN (nr_chunks, VIXDISKLIB_MAX_CHUNK_NUMBER); -- nr_sectors = nr_chunks * VIXDISKLIB_MIN_CHUNK_SIZE; -- -- VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, -- "handle, %" PRIu64 " sectors, %" PRIu64 " sectors, " -- "%d sectors", -- start_sector, nr_sectors, VIXDISKLIB_MIN_CHUNK_SIZE) -- err = VixDiskLib_QueryAllocatedBlocks (h->handle, -- start_sector, nr_sectors, -- VIXDISKLIB_MIN_CHUNK_SIZE, -- &block_list); -- VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); -- if (err != VIX_OK) { -- VDDK_ERROR (err, "VixDiskLib_QueryAllocatedBlocks"); -- return -1; -- } -- -- for (i = 0; i < block_list->numBlocks; ++i) { -- uint64_t blk_offset, blk_length; -- -- blk_offset = block_list->blocks[i].offset * VIXDISKLIB_SECTOR_SIZE; -- blk_length = block_list->blocks[i].length * VIXDISKLIB_SECTOR_SIZE; -- -- /* The query returns allocated blocks. We must insert holes -- * between the blocks as necessary. -- */ -- if ((position < blk_offset && -- add_extent (extents, &position, blk_offset, true) == -1) || -- (add_extent (extents, -- &position, blk_offset + blk_length, false) == -1)) { -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -- VixDiskLib_FreeBlockList (block_list); -- VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -- return -1; -- } -- } -- VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -- VixDiskLib_FreeBlockList (block_list); -- VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -- -- /* There's an implicit hole after the returned list of blocks, up -- * to the end of the QueryAllocatedBlocks request. -- */ -- if (add_extent (extents, -- &position, -- (start_sector + nr_sectors) * VIXDISKLIB_SECTOR_SIZE, -- true) == -1) -- return -1; -- -- start_sector += nr_sectors; -- -- /* If one extent was requested, as long as we've added an extent -- * overlapping the original offset we're done. -- */ -- if (req_one && position > offset) -- break; -- } -- -- return 0; -+ struct command extents_cmd = { -+ .type = EXTENTS, -+ .ptr = extents, -+ .count = count, -+ .offset = offset, -+ .req_one = req_one, -+ }; -+ -+ return send_command_and_wait (h, &extents_cmd); - } - - static struct nbdkit_plugin plugin = { -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index 1400589d..be0b3492 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -90,7 +90,9 @@ extern int vddk_debug_stats; - /* GCC can optimize this away at compile time: */ \ - const bool datapath = \ - strcmp (#fn, "VixDiskLib_Read") == 0 || \ -- strcmp (#fn, "VixDiskLib_Write") == 0; \ -+ strcmp (#fn, "VixDiskLib_ReadAsync") == 0 || \ -+ strcmp (#fn, "VixDiskLib_Write") == 0 || \ -+ strcmp (#fn, "VixDiskLib_WriteAsync") == 0; \ - if (vddk_debug_stats) \ - gettimeofday (&start_t, NULL); \ - if (!datapath || vddk_debug_datapath) \ -@@ -120,6 +122,46 @@ extern int vddk_debug_stats; - VDDK_CALL_END (VixDiskLib_FreeErrorText, 0); \ - } while (0) - -+/* Queue of asynchronous commands sent to the background thread. */ -+enum command_type { GET_SIZE, READ, WRITE, FLUSH, CAN_EXTENTS, EXTENTS, STOP }; -+struct command { -+ /* These fields are set by the caller. */ -+ enum command_type type; /* command */ -+ void *ptr; /* buffer, extents list, return values */ -+ uint32_t count; /* READ, WRITE, EXTENTS */ -+ uint64_t offset; /* READ, WRITE, EXTENTS */ -+ bool req_one; /* EXTENTS NBDKIT_FLAG_REQ_ONE */ -+ -+ /* This field is set to a unique value by send_command_and_wait. */ -+ uint64_t id; /* serial number */ -+ -+ /* These fields are used by the internal implementation. */ -+ pthread_mutex_t mutex; /* completion mutex */ -+ pthread_cond_t cond; /* completion condition */ -+ enum { SUBMITTED, SUCCEEDED, FAILED } status; -+}; -+ -+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 */ -+}; -+ - /* reexec.c */ - extern bool noreexec; - extern char *reexeced; -@@ -141,4 +183,9 @@ extern pthread_mutex_t stats_lock; - #undef OPTIONAL_STUB - extern void display_stats (void); - -+/* 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); -+ - #endif /* NBDKIT_VDDK_H */ -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -new file mode 100644 -index 00000000..2a1d4f26 ---- /dev/null -+++ b/plugins/vddk/worker.c -@@ -0,0 +1,567 @@ -+/* nbdkit -+ * Copyright (C) 2013-2021 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define NBDKIT_API_VERSION 2 -+#include -+ -+#include "cleanup.h" -+#include "minmax.h" -+#include "rounding.h" -+#include "vector.h" -+ -+#include "vddk.h" -+ -+const char * -+command_type_string (enum command_type type) -+{ -+ switch (type) { -+ case GET_SIZE: return "get_size"; -+ case READ: return "read"; -+ case WRITE: return "write"; -+ case FLUSH: return "flush"; -+ case CAN_EXTENTS: return "can_extents"; -+ case EXTENTS: return "extents"; -+ case STOP: return "stop"; -+ default: abort (); -+ } -+} -+ -+/* Send command to the background thread and wait for completion. -+ * -+ * Returns 0 for OK -+ * On error, calls nbdkit_error and returns -1. -+ */ -+int -+send_command_and_wait (struct vddk_handle *h, struct command *cmd) -+{ -+ /* Add the command to the command queue. */ -+ { -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&h->commands_lock); -+ cmd->id = h->id++; -+ -+ if (command_queue_append (&h->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.size == 1) -+ pthread_cond_signal (&h->commands_cond); -+ -+ /* This will be used to signal command completion back to us. */ -+ pthread_mutex_init (&cmd->mutex, NULL); -+ pthread_cond_init (&cmd->cond, NULL); -+ } -+ -+ /* Wait for the command to be completed by the background thread. */ -+ { -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&cmd->mutex); -+ while (cmd->status == SUBMITTED) -+ pthread_cond_wait (&cmd->cond, &cmd->mutex); -+ } -+ -+ pthread_mutex_destroy (&cmd->mutex); -+ pthread_cond_destroy (&cmd->cond); -+ -+ /* On error the background thread will call nbdkit_error. */ -+ switch (cmd->status) { -+ case SUCCEEDED: return 0; -+ case FAILED: return -1; -+ default: abort (); -+ } -+} -+ -+/* Asynchronous commands are completed when this function is called. */ -+static void -+complete_command (void *vp, VixError result) -+{ -+ struct command *cmd = vp; -+ -+ if (vddk_debug_datapath) -+ nbdkit_debug ("command %" PRIu64 " completed", cmd->id); -+ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&cmd->mutex); -+ -+ if (result == VIX_OK) { -+ cmd->status = SUCCEEDED; -+ } else { -+ VDDK_ERROR (result, "command %" PRIu64 ": asynchronous %s failed", -+ cmd->id, command_type_string (cmd->type)); -+ cmd->status = FAILED; -+ } -+ -+ pthread_cond_signal (&cmd->cond); -+} -+ -+/* Wait for any asynchronous commands to complete. */ -+static int -+do_stop (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ -+ /* Because we assume VDDK >= 6.5, VixDiskLib_Wait must exist. */ -+ VDDK_CALL_START (VixDiskLib_Wait, "handle") -+ err = VixDiskLib_Wait (h->handle); -+ VDDK_CALL_END (VixDiskLib_Wait, 0); -+ if (err != VIX_OK) { -+ VDDK_ERROR (err, "VixDiskLib_Wait"); -+ /* In the end this error indication is ignored because it only -+ * happens on the close path when we cannot handle errors. -+ */ -+ return -1; -+ } -+ return 0; -+} -+ -+/* Get size command. */ -+static int64_t -+do_get_size (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ VixDiskLibInfo *info; -+ uint64_t size; -+ -+ VDDK_CALL_START (VixDiskLib_GetInfo, "handle, &info") -+ err = VixDiskLib_GetInfo (h->handle, &info); -+ VDDK_CALL_END (VixDiskLib_GetInfo, 0); -+ if (err != VIX_OK) { -+ VDDK_ERROR (err, "VixDiskLib_GetInfo"); -+ return -1; -+ } -+ -+ size = info->capacity * (uint64_t)VIXDISKLIB_SECTOR_SIZE; -+ -+ if (vddk_debug_diskinfo) { -+ nbdkit_debug ("disk info: capacity: %" PRIu64 " sectors " -+ "(%" PRIi64 " bytes)", -+ info->capacity, size); -+ nbdkit_debug ("disk info: biosGeo: C:%" PRIu32 " H:%" PRIu32 " S:%" PRIu32, -+ info->biosGeo.cylinders, -+ info->biosGeo.heads, -+ info->biosGeo.sectors); -+ nbdkit_debug ("disk info: physGeo: C:%" PRIu32 " H:%" PRIu32 " S:%" PRIu32, -+ info->physGeo.cylinders, -+ info->physGeo.heads, -+ info->physGeo.sectors); -+ nbdkit_debug ("disk info: adapter type: %d", -+ (int) info->adapterType); -+ nbdkit_debug ("disk info: num links: %d", info->numLinks); -+ nbdkit_debug ("disk info: parent filename hint: %s", -+ info->parentFileNameHint ? : "NULL"); -+ nbdkit_debug ("disk info: uuid: %s", -+ info->uuid ? : "NULL"); -+ if (library_version >= 7) { -+ nbdkit_debug ("disk info: sector size: " -+ "logical %" PRIu32 " physical %" PRIu32, -+ info->logicalSectorSize, -+ info->physicalSectorSize); -+ } -+ } -+ -+ VDDK_CALL_START (VixDiskLib_FreeInfo, "info") -+ VixDiskLib_FreeInfo (info); -+ VDDK_CALL_END (VixDiskLib_FreeInfo, 0); -+ -+ return (int64_t) size; -+} -+ -+static int -+do_read (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ uint32_t count = cmd->count; -+ uint64_t offset = cmd->offset; -+ void *buf = cmd->ptr; -+ -+ /* Align to sectors. */ -+ if (!IS_ALIGNED (offset, VIXDISKLIB_SECTOR_SIZE)) { -+ nbdkit_error ("%s is not aligned to sectors", "read"); -+ return -1; -+ } -+ if (!IS_ALIGNED (count, VIXDISKLIB_SECTOR_SIZE)) { -+ nbdkit_error ("%s is not aligned to sectors", "read"); -+ return -1; -+ } -+ offset /= VIXDISKLIB_SECTOR_SIZE; -+ count /= VIXDISKLIB_SECTOR_SIZE; -+ -+ VDDK_CALL_START (VixDiskLib_ReadAsync, -+ "handle, %" PRIu64 " sectors, " -+ "%" PRIu32 " sectors, buffer, callback, %" PRIu64, -+ offset, count, cmd->id) -+ err = VixDiskLib_ReadAsync (h->handle, offset, count, buf, -+ complete_command, cmd); -+ VDDK_CALL_END (VixDiskLib_ReadAsync, count * VIXDISKLIB_SECTOR_SIZE); -+ if (err != VIX_ASYNC) { -+ VDDK_ERROR (err, "VixDiskLib_ReadAsync"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+do_write (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ uint32_t count = cmd->count; -+ uint64_t offset = cmd->offset; -+ const void *buf = cmd->ptr; -+ -+ /* Align to sectors. */ -+ if (!IS_ALIGNED (offset, VIXDISKLIB_SECTOR_SIZE)) { -+ nbdkit_error ("%s is not aligned to sectors", "write"); -+ return -1; -+ } -+ if (!IS_ALIGNED (count, VIXDISKLIB_SECTOR_SIZE)) { -+ nbdkit_error ("%s is not aligned to sectors", "write"); -+ return -1; -+ } -+ offset /= VIXDISKLIB_SECTOR_SIZE; -+ count /= VIXDISKLIB_SECTOR_SIZE; -+ -+ VDDK_CALL_START (VixDiskLib_WriteAsync, -+ "handle, %" PRIu64 " sectors, " -+ "%" PRIu32 " sectors, buffer, callback, %" PRIu64, -+ offset, count, cmd->id) -+ err = VixDiskLib_WriteAsync (h->handle, offset, count, buf, -+ complete_command, cmd); -+ VDDK_CALL_END (VixDiskLib_WriteAsync, count * VIXDISKLIB_SECTOR_SIZE); -+ if (err != VIX_ASYNC) { -+ VDDK_ERROR (err, "VixDiskLib_WriteAsync"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+do_flush (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ -+ /* It seems safer to wait for outstanding asynchronous commands to -+ * complete before doing a flush, so do this but ignore errors -+ * except to print them. -+ */ -+ VDDK_CALL_START (VixDiskLib_Wait, "handle") -+ err = VixDiskLib_Wait (h->handle); -+ VDDK_CALL_END (VixDiskLib_Wait, 0); -+ if (err != VIX_OK) -+ VDDK_ERROR (err, "VixDiskLib_Wait"); -+ -+ /* The documentation for Flush is missing, but the comment in the -+ * header file seems to indicate that it waits for WriteAsync -+ * commands to finish. There's a new function Wait to wait for -+ * those. However I verified using strace that in fact Flush calls -+ * fsync on the file so it appears to be the correct call to use -+ * here. -+ */ -+ VDDK_CALL_START (VixDiskLib_Flush, "handle") -+ err = VixDiskLib_Flush (h->handle); -+ VDDK_CALL_END (VixDiskLib_Flush, 0); -+ if (err != VIX_OK) { -+ VDDK_ERROR (err, "VixDiskLib_Flush"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+do_can_extents (struct command *cmd, struct vddk_handle *h) -+{ -+ VixError err; -+ VixDiskLibBlockList *block_list; -+ -+ /* This call was added in VDDK 6.7. In earlier versions the -+ * function pointer will be NULL and we cannot query extents. -+ */ -+ if (VixDiskLib_QueryAllocatedBlocks == NULL) { -+ nbdkit_debug ("can_extents: VixDiskLib_QueryAllocatedBlocks == NULL, " -+ "probably this is VDDK < 6.7"); -+ return 0; -+ } -+ -+ /* Suppress errors around this call. See: -+ * https://bugzilla.redhat.com/show_bug.cgi?id=1709211#c7 -+ */ -+ error_suppression = 1; -+ -+ /* However even when the call is available it rarely works well so -+ * the best thing we can do here is to try the call and if it's -+ * non-functional return false. -+ */ -+ VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, -+ "handle, 0, %d sectors, %d sectors", -+ VIXDISKLIB_MIN_CHUNK_SIZE, VIXDISKLIB_MIN_CHUNK_SIZE) -+ err = VixDiskLib_QueryAllocatedBlocks (h->handle, -+ 0, VIXDISKLIB_MIN_CHUNK_SIZE, -+ VIXDISKLIB_MIN_CHUNK_SIZE, -+ &block_list); -+ VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); -+ error_suppression = 0; -+ if (err == VIX_OK) { -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -+ VixDiskLib_FreeBlockList (block_list); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -+ } -+ if (err != VIX_OK) { -+ char *errmsg = VixDiskLib_GetErrorText (err, NULL); -+ nbdkit_debug ("can_extents: " -+ "VixDiskLib_QueryAllocatedBlocks test failed, " -+ "extents support will be disabled: " -+ "original error: %s", -+ errmsg); -+ VixDiskLib_FreeErrorText (errmsg); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* Add an extent to the list of extents. */ -+static int -+add_extent (struct nbdkit_extents *extents, -+ uint64_t *position, uint64_t next_position, bool is_hole) -+{ -+ uint32_t type = 0; -+ const uint64_t length = next_position - *position; -+ -+ if (is_hole) { -+ type = NBDKIT_EXTENT_HOLE; -+ /* Images opened as single link might be backed by another file in the -+ chain, so the holes are not guaranteed to be zeroes. */ -+ if (!single_link) -+ type |= NBDKIT_EXTENT_ZERO; -+ } -+ -+ assert (*position <= next_position); -+ if (*position == next_position) -+ return 0; -+ -+ if (vddk_debug_extents) -+ nbdkit_debug ("adding extent type %s at [%" PRIu64 "...%" PRIu64 "]", -+ is_hole ? "hole" : "allocated data", -+ *position, next_position-1); -+ if (nbdkit_add_extent (extents, *position, length, type) == -1) -+ return -1; -+ -+ *position = next_position; -+ return 0; -+} -+ -+static int -+do_extents (struct command *cmd, struct vddk_handle *h) -+{ -+ uint32_t count = cmd->count; -+ uint64_t offset = cmd->offset; -+ bool req_one = cmd->req_one; -+ struct nbdkit_extents *extents = cmd->ptr; -+ uint64_t position, end, start_sector; -+ -+ position = offset; -+ end = offset + count; -+ -+ /* We can only query whole chunks. Therefore start with the -+ * first chunk before offset. -+ */ -+ start_sector = -+ ROUND_DOWN (offset, VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE) -+ / VIXDISKLIB_SECTOR_SIZE; -+ while (start_sector * VIXDISKLIB_SECTOR_SIZE < end) { -+ VixError err; -+ uint32_t i; -+ uint64_t nr_chunks, nr_sectors; -+ VixDiskLibBlockList *block_list; -+ -+ assert (IS_ALIGNED (start_sector, VIXDISKLIB_MIN_CHUNK_SIZE)); -+ -+ nr_chunks = -+ ROUND_UP (end - start_sector * VIXDISKLIB_SECTOR_SIZE, -+ VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE) -+ / (VIXDISKLIB_MIN_CHUNK_SIZE * VIXDISKLIB_SECTOR_SIZE); -+ nr_chunks = MIN (nr_chunks, VIXDISKLIB_MAX_CHUNK_NUMBER); -+ nr_sectors = nr_chunks * VIXDISKLIB_MIN_CHUNK_SIZE; -+ -+ VDDK_CALL_START (VixDiskLib_QueryAllocatedBlocks, -+ "handle, %" PRIu64 " sectors, %" PRIu64 " sectors, " -+ "%d sectors", -+ start_sector, nr_sectors, VIXDISKLIB_MIN_CHUNK_SIZE) -+ err = VixDiskLib_QueryAllocatedBlocks (h->handle, -+ start_sector, nr_sectors, -+ VIXDISKLIB_MIN_CHUNK_SIZE, -+ &block_list); -+ VDDK_CALL_END (VixDiskLib_QueryAllocatedBlocks, 0); -+ if (err != VIX_OK) { -+ VDDK_ERROR (err, "VixDiskLib_QueryAllocatedBlocks"); -+ return -1; -+ } -+ -+ for (i = 0; i < block_list->numBlocks; ++i) { -+ uint64_t blk_offset, blk_length; -+ -+ blk_offset = block_list->blocks[i].offset * VIXDISKLIB_SECTOR_SIZE; -+ blk_length = block_list->blocks[i].length * VIXDISKLIB_SECTOR_SIZE; -+ -+ /* The query returns allocated blocks. We must insert holes -+ * between the blocks as necessary. -+ */ -+ if ((position < blk_offset && -+ add_extent (extents, &position, blk_offset, true) == -1) || -+ (add_extent (extents, -+ &position, blk_offset + blk_length, false) == -1)) { -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -+ VixDiskLib_FreeBlockList (block_list); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -+ return -1; -+ } -+ } -+ VDDK_CALL_START (VixDiskLib_FreeBlockList, "block_list") -+ VixDiskLib_FreeBlockList (block_list); -+ VDDK_CALL_END (VixDiskLib_FreeBlockList, 0); -+ -+ /* There's an implicit hole after the returned list of blocks, -+ * up to the end of the QueryAllocatedBlocks request. -+ */ -+ if (add_extent (extents, -+ &position, -+ (start_sector + nr_sectors) * VIXDISKLIB_SECTOR_SIZE, -+ true) == -1) { -+ return -1; -+ } -+ -+ start_sector += nr_sectors; -+ -+ /* If one extent was requested, as long as we've added an extent -+ * overlapping the original offset we're done. -+ */ -+ if (req_one && position > offset) -+ break; -+ } -+ -+ return 0; -+} -+ -+/* Background worker thread, one per connection, which is where the -+ * VDDK commands are issued. -+ */ -+void * -+vddk_worker_thread (void *handle) -+{ -+ struct vddk_handle *h = handle; -+ bool stop = false; -+ -+ while (!stop) { -+ struct command *cmd; -+ int r; -+ bool async = false; -+ -+ /* Wait until we are sent at least one command. */ -+ { -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&h->commands_lock); -+ while (h->commands.size == 0) -+ pthread_cond_wait (&h->commands_cond, &h->commands_lock); -+ cmd = h->commands.ptr[0]; -+ command_queue_remove (&h->commands, 0); -+ } -+ -+ switch (cmd->type) { -+ case STOP: -+ r = do_stop (cmd, h); -+ stop = true; -+ break; -+ -+ case GET_SIZE: { -+ int64_t size = do_get_size (cmd, h); -+ if (size == -1) -+ r = -1; -+ else { -+ r = 0; -+ *(uint64_t *)cmd->ptr = size; -+ } -+ break; -+ } -+ -+ case READ: -+ r = do_read (cmd, h); -+ /* If async is true, don't retire this command now. */ -+ async = r == 0; -+ break; -+ -+ case WRITE: -+ r = do_write (cmd, h); -+ /* If async is true, don't retire this command now. */ -+ async = r == 0; -+ break; -+ -+ case FLUSH: -+ r = do_flush (cmd, h); -+ break; -+ -+ case CAN_EXTENTS: -+ r = do_can_extents (cmd, h); -+ if (r >= 0) -+ *(int *)cmd->ptr = r; -+ break; -+ -+ case EXTENTS: -+ r = do_extents (cmd, h); -+ break; -+ -+ default: abort (); /* impossible, but keeps GCC happy */ -+ } /* switch */ -+ -+ if (!async) { -+ /* Update the command status. */ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&cmd->mutex); -+ cmd->status = r >= 0 ? SUCCEEDED : FAILED; -+ -+ /* For synchronous commands signal the caller thread that the -+ * command has completed. (Asynchronous commands are completed in -+ * the callback handler). -+ */ -+ pthread_cond_signal (&cmd->cond); -+ } -+ } /* while (!stop) */ -+ -+ /* Exit the worker thread. */ -+ return NULL; -+} -diff --git a/tests/dummy-vddk.c b/tests/dummy-vddk.c -index cb88380c..b6f12042 100644 ---- a/tests/dummy-vddk.c -+++ b/tests/dummy-vddk.c -@@ -188,6 +188,19 @@ VixDiskLib_Read (VixDiskLibHandle handle, - return VIX_OK; - } - -+NBDKIT_DLL_PUBLIC VixError -+VixDiskLib_ReadAsync (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data) -+{ -+ size_t offset = start_sector * VIXDISKLIB_SECTOR_SIZE; -+ -+ memcpy (buf, disk + offset, nr_sectors * VIXDISKLIB_SECTOR_SIZE); -+ callback (data, VIX_OK); -+ return VIX_ASYNC; -+} -+ - NBDKIT_DLL_PUBLIC VixError - VixDiskLib_Write (VixDiskLibHandle handle, - uint64_t start_sector, uint64_t nr_sectors, -@@ -199,6 +212,25 @@ VixDiskLib_Write (VixDiskLibHandle handle, - return VIX_OK; - } - -+NBDKIT_DLL_PUBLIC VixError -+VixDiskLib_WriteAsync (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ const unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data) -+{ -+ size_t offset = start_sector * VIXDISKLIB_SECTOR_SIZE; -+ -+ memcpy (disk + offset, buf, nr_sectors * VIXDISKLIB_SECTOR_SIZE); -+ callback (data, VIX_OK); -+ return VIX_ASYNC; -+} -+ -+NBDKIT_DLL_PUBLIC VixError -+VixDiskLib_Flush (VixDiskLibHandle handle) -+{ -+ return VIX_OK; -+} -+ - NBDKIT_DLL_PUBLIC VixError - VixDiskLib_Wait (VixDiskLibHandle handle) - { --- -2.31.1 - diff --git a/0015-vddk-Assume-that-VixDiskLib_Flush-is-available.patch b/0015-vddk-Assume-that-VixDiskLib_Flush-is-available.patch deleted file mode 100644 index 8741479..0000000 --- a/0015-vddk-Assume-that-VixDiskLib_Flush-is-available.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c91ac233f6474b07ef181a08093c5d0f2f4ec4c3 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 29 Oct 2021 20:56:55 +0100 -Subject: [PATCH] vddk: Assume that VixDiskLib_Flush is available - -Since we now require and check that VDDK >= 6.5, we can assume that -VixDiskLib_Flush is always available. - -(cherry picked from commit e3685e6f0d0b71ab24b96fe85430a3b75da58736) ---- - plugins/vddk/vddk.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 9f223db0..f967e2d9 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -378,6 +378,12 @@ load_library (bool load_error_is_fatal) - "See nbdkit-vddk-plugin(1) man page section \"SUPPORTED VERSIONS OF VDDK\"."); - exit (EXIT_FAILURE); - } -+ -+ /* Added in VDDK 6.0 so it must always be present. Since we are -+ * going to call this function unconditionally, fail early and hard -+ * if for some reason it's not present. -+ */ -+ assert (VixDiskLib_Flush != NULL); - } - - static int -@@ -725,18 +731,19 @@ vddk_get_size (void *handle) - return (int64_t) size; - } - -+/* The Flush call was added in VDDK 6.0, since we support minimum 6.5 -+ * we are always able to do FUA / flush. -+ */ - static int - vddk_can_fua (void *handle) - { -- /* The Flush call was not available in VDDK < 6.0. */ -- return VixDiskLib_Flush != NULL ? NBDKIT_FUA_NATIVE : NBDKIT_FUA_NONE; -+ return NBDKIT_FUA_NATIVE; - } - - static int - vddk_can_flush (void *handle) - { -- /* The Flush call was not available in VDDK < 6.0. */ -- return VixDiskLib_Flush != NULL; -+ return 1; - } - - /* Read data from the file. --- -2.31.1 - diff --git a/0016-vddk-Simplify-detection-of-VDDK-symbols-and-baseline.patch b/0016-vddk-Simplify-detection-of-VDDK-symbols-and-baseline.patch deleted file mode 100644 index 0421316..0000000 --- a/0016-vddk-Simplify-detection-of-VDDK-symbols-and-baseline.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 984e95fcbdb19c2495851322a4c33f34291ecfab Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 29 Oct 2021 21:02:54 +0100 -Subject: [PATCH] vddk: Simplify detection of VDDK symbols and baseline 6.5 - -Make all symbols from VDDK 6.5 into required symbols and use a single -error message function if one of these is missing. The new error is: - - nbdkit: error: required VDDK symbol "VixDiskLib_Wait" is - missing. VDDK version must be >= 6.5. See nbdkit-vddk-plugin(1) man - page section "SUPPORTED VERSIONS OF VDDK". Original dlopen error: - vmware-vix-disklib-distrib/lib64/libvixDiskLib.so.6: undefined - symbol: VixDiskLib_Wait - -Remove the extra check and assert. - -Be more consistent about #define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) -when we want the optional and required stubs to do the same thing. - -(cherry picked from commit ec0d22e61881efa39a69d02ccb9e4ede8bf95e75) ---- - plugins/vddk/stats.c | 2 +- - plugins/vddk/vddk-stubs.h | 45 ++++++++++++++++++--------------------- - plugins/vddk/vddk.c | 36 ++++++++++++------------------- - plugins/vddk/vddk.h | 2 +- - 4 files changed, 37 insertions(+), 48 deletions(-) - -diff --git a/plugins/vddk/stats.c b/plugins/vddk/stats.c -index 18a42714..76e0c244 100644 ---- a/plugins/vddk/stats.c -+++ b/plugins/vddk/stats.c -@@ -89,7 +89,7 @@ display_stats (void) - if (!vddk_debug_stats) return; - - #define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) --#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB -diff --git a/plugins/vddk/vddk-stubs.h b/plugins/vddk/vddk-stubs.h -index 66353691..7d8644c3 100644 ---- a/plugins/vddk/vddk-stubs.h -+++ b/plugins/vddk/vddk-stubs.h -@@ -39,10 +39,7 @@ - * function name, return value, arguments. - */ - --/* Required stubs, present in all versions of VDDK that we support. I -- * have checked that all these exist in at least VDDK 5.5.5 (2015). -- */ -- -+/* Required stubs, present in all versions of VDDK since 6.5 (Nov 2016). */ - STUB (VixDiskLib_InitEx, - VixError, - (uint32_t major, uint32_t minor, -@@ -103,27 +100,27 @@ STUB (VixDiskLib_Write, - uint64_t start_sector, uint64_t nr_sectors, - const unsigned char *buf)); - --/* Added in VDDK 6.0, these will be NULL in earlier versions. */ --OPTIONAL_STUB (VixDiskLib_Flush, -- VixError, -- (VixDiskLibHandle handle)); --OPTIONAL_STUB (VixDiskLib_ReadAsync, -- VixError, -- (VixDiskLibHandle handle, -- uint64_t start_sector, uint64_t nr_sectors, -- unsigned char *buf, -- VixDiskLibCompletionCB callback, void *data)); --OPTIONAL_STUB (VixDiskLib_WriteAsync, -- VixError, -- (VixDiskLibHandle handle, -- uint64_t start_sector, uint64_t nr_sectors, -- const unsigned char *buf, -- VixDiskLibCompletionCB callback, void *data)); -+/* Added in VDDK 6.0. */ -+STUB (VixDiskLib_Flush, -+ VixError, -+ (VixDiskLibHandle handle)); -+STUB (VixDiskLib_ReadAsync, -+ VixError, -+ (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data)); -+STUB (VixDiskLib_WriteAsync, -+ VixError, -+ (VixDiskLibHandle handle, -+ uint64_t start_sector, uint64_t nr_sectors, -+ const unsigned char *buf, -+ VixDiskLibCompletionCB callback, void *data)); - --/* Added in VDDK 6.5, this will be NULL in earlier versions. */ --OPTIONAL_STUB (VixDiskLib_Wait, -- VixError, -- (VixDiskLibHandle handle)); -+/* Added in VDDK 6.5. */ -+STUB (VixDiskLib_Wait, -+ VixError, -+ (VixDiskLibHandle handle)); - - /* Added in VDDK 6.7, these will be NULL for earlier versions: */ - OPTIONAL_STUB (VixDiskLib_QueryAllocatedBlocks, -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index f967e2d9..271b5ee0 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -63,7 +63,7 @@ NBDKIT_DLL_PUBLIC int vddk_debug_datapath = 1; - * initialized when the plugin is loaded (by vddk_get_ready). - */ - #define STUB(fn,ret,args) ret (*fn) args --#define OPTIONAL_STUB(fn,ret,args) ret (*fn) args -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB -@@ -282,6 +282,17 @@ vddk_config (const char *key, const char *value) - return 0; - } - -+static void -+missing_required_symbol (const char *fn) -+{ -+ nbdkit_error ("required VDDK symbol \"%s\" is missing. " -+ "VDDK version must be >= 6.5. " -+ "See nbdkit-vddk-plugin(1) man page section \"SUPPORTED VERSIONS OF VDDK\". " -+ "Original dlopen error: %s\n", -+ fn, dlerror ()); -+ exit (EXIT_FAILURE); -+} -+ - /* Load the VDDK library. */ - static void - load_library (bool load_error_is_fatal) -@@ -358,32 +369,13 @@ load_library (bool load_error_is_fatal) - #define STUB(fn,ret,args) \ - do { \ - fn = dlsym (dl, #fn); \ -- if (fn == NULL) { \ -- nbdkit_error ("required VDDK symbol \"%s\" is missing: %s", \ -- #fn, dlerror ()); \ -- exit (EXIT_FAILURE); \ -- } \ -+ if (fn == NULL) \ -+ missing_required_symbol (#fn); \ - } while (0) - #define OPTIONAL_STUB(fn,ret,args) fn = dlsym (dl, #fn) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB -- -- /* Additionally, VDDK version must be >= 6.5. This was the first -- * version which introduced VixDiskLib_Wait symbol so we can check -- * for that. -- */ -- if (VixDiskLib_Wait == NULL) { -- nbdkit_error ("VDDK version must be >= 6.5. " -- "See nbdkit-vddk-plugin(1) man page section \"SUPPORTED VERSIONS OF VDDK\"."); -- exit (EXIT_FAILURE); -- } -- -- /* Added in VDDK 6.0 so it must always be present. Since we are -- * going to call this function unconditionally, fail early and hard -- * if for some reason it's not present. -- */ -- assert (VixDiskLib_Flush != NULL); - } - - static int -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index be0b3492..0e3dd79e 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -76,7 +76,7 @@ extern int vddk_debug_datapath; - extern int vddk_debug_stats; - - #define STUB(fn,ret,args) extern ret (*fn) args --#define OPTIONAL_STUB(fn,ret,args) extern ret (*fn) args -+#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) - #include "vddk-stubs.h" - #undef STUB - #undef OPTIONAL_STUB --- -2.31.1 - diff --git a/0017-vddk-Remove-some-whitespace-from-a-couple-of-functio.patch b/0017-vddk-Remove-some-whitespace-from-a-couple-of-functio.patch deleted file mode 100644 index f9c1a1d..0000000 --- a/0017-vddk-Remove-some-whitespace-from-a-couple-of-functio.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 342efed6bb9f8f0c8d2cb4aa2b09da64ed2e7ed4 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Oct 2021 08:34:28 +0100 -Subject: [PATCH] vddk: Remove some whitespace from a couple of functions - -(cherry picked from commit 974dce2c2ef84fc096ee319f340054234a29df91) ---- - plugins/vddk/vddk.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 271b5ee0..184f1a9c 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -792,9 +792,7 @@ static int - vddk_flush (void *handle, uint32_t flags) - { - struct vddk_handle *h = handle; -- struct command flush_cmd = { -- .type = FLUSH, -- }; -+ struct command flush_cmd = { .type = FLUSH }; - - return send_command_and_wait (h, &flush_cmd); - } -@@ -804,10 +802,7 @@ vddk_can_extents (void *handle) - { - struct vddk_handle *h = handle; - int ret; -- struct command can_extents_cmd = { -- .type = CAN_EXTENTS, -- .ptr = &ret, -- }; -+ struct command can_extents_cmd = { .type = CAN_EXTENTS, .ptr = &ret }; - - if (send_command_and_wait (h, &can_extents_cmd) == -1) - return -1; --- -2.31.1 - diff --git a/0018-vddk-Move-config-debug-error-and-utility-functions-a.patch b/0018-vddk-Move-config-debug-error-and-utility-functions-a.patch deleted file mode 100644 index bb03b19..0000000 --- a/0018-vddk-Move-config-debug-error-and-utility-functions-a.patch +++ /dev/null @@ -1,338 +0,0 @@ -From edbded52b144ce3c8c45c7ef352f8969a1f5d1bb Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 30 Oct 2021 08:27:39 +0100 -Subject: [PATCH] vddk: Move config, debug/error and utility functions around - -Move the functions so they are nearer to where they are used. -Introduce a utils.c file for utility functions. - -This is just code rearrangement with no other effects. - -(cherry picked from commit c59be086210a06688b9195e0b91f8603a668654a) ---- - plugins/vddk/Makefile.am | 1 + - plugins/vddk/utils.c | 51 ++++++++++ - plugins/vddk/vddk.c | 201 +++++++++++++++++++-------------------- - plugins/vddk/vddk.h | 3 + - 4 files changed, 151 insertions(+), 105 deletions(-) - create mode 100644 plugins/vddk/utils.c - -diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am -index f8382fc9..02113da0 100644 ---- a/plugins/vddk/Makefile.am -+++ b/plugins/vddk/Makefile.am -@@ -47,6 +47,7 @@ nbdkit_vddk_plugin_la_SOURCES = \ - vddk.h \ - reexec.c \ - stats.c \ -+ utils.c \ - vddk-structs.h \ - vddk-stubs.h \ - worker.c \ -diff --git a/plugins/vddk/utils.c b/plugins/vddk/utils.c -new file mode 100644 -index 00000000..f0c19950 ---- /dev/null -+++ b/plugins/vddk/utils.c -@@ -0,0 +1,51 @@ -+/* nbdkit -+ * Copyright (C) 2013-2021 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#define NBDKIT_API_VERSION 2 -+#include -+ -+#include "vddk.h" -+ -+void -+trim (char *str) -+{ -+ size_t len = strlen (str); -+ -+ if (len > 0 && str[len-1] == '\n') -+ str[len-1] = '\0'; -+} -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 184f1a9c..31e5e23b 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -114,61 +114,6 @@ vddk_unload (void) - free (password); - } - --static void --trim (char *str) --{ -- size_t len = strlen (str); -- -- if (len > 0 && str[len-1] == '\n') -- str[len-1] = '\0'; --} -- --/* Turn log messages from the library into nbdkit_debug. */ --static void --debug_function (const char *fs, va_list args) --{ -- CLEANUP_FREE char *str = NULL; -- -- if (vasprintf (&str, fs, args) == -1) { -- nbdkit_debug ("lost debug message: %s", fs); -- return; -- } -- -- trim (str); -- -- nbdkit_debug ("%s", str); --} -- --/* Turn error messages from the library into nbdkit_error. */ --static void --error_function (const char *fs, va_list args) --{ -- CLEANUP_FREE char *str = NULL; -- -- /* If the thread-local error_suppression flag is non-zero then we -- * will suppress error messages from VDDK in this thread. -- */ -- if (error_suppression) return; -- -- if (vasprintf (&str, fs, args) == -1) { -- nbdkit_error ("lost error message: %s", fs); -- return; -- } -- -- trim (str); -- -- /* VDDK 7 added a useless error message about their "phone home" -- * system called CEIP which only panics users. Demote it to a debug -- * statement. https://bugzilla.redhat.com/show_bug.cgi?id=1834267 -- */ -- if (strstr (str, "Get CEIP status failed") != NULL) { -- nbdkit_debug ("%s", str); -- return; -- } -- -- nbdkit_error ("%s", str); --} -- - /* Configuration. */ - static int - vddk_config (const char *key, const char *value) -@@ -282,6 +227,56 @@ vddk_config (const char *key, const char *value) - return 0; - } - -+static int -+vddk_config_complete (void) -+{ -+ if (filename == NULL) { -+ nbdkit_error ("you must supply the file= parameter " -+ "after the plugin name on the command line"); -+ return -1; -+ } -+ -+ /* For remote connections, check all the parameters have been -+ * passed. Note that VDDK will segfault if parameters that it -+ * expects are NULL (and there's no real way to tell what parameters -+ * it is expecting). This implements the same test that the VDDK -+ * sample program does. -+ */ -+ is_remote = -+ vmx_spec || -+ server_name || -+ username || -+ password || -+ cookie || -+ thumb_print || -+ port || -+ nfc_host_port; -+ -+ if (is_remote) { -+#define missing(test, param) \ -+ if (test) { \ -+ nbdkit_error ("remote connection requested, missing parameter: %s", \ -+ param); \ -+ return -1; \ -+ } -+ missing (!server_name, "server"); -+ missing (!username, "user"); -+ missing (!password, "password"); -+ missing (!vmx_spec, "vm"); -+#undef missing -+ } -+ -+ /* Restore original LD_LIBRARY_PATH after reexec. */ -+ if (restore_ld_library_path () == -1) -+ return -1; -+ -+ return 0; -+} -+ -+#define vddk_config_help \ -+ "[file=] (required) The filename (eg. VMDK file) to serve.\n" \ -+ "Many optional parameters are supported, see nbdkit-vddk-plugin(1)." -+ - static void - missing_required_symbol (const char *fn) - { -@@ -378,56 +373,6 @@ load_library (bool load_error_is_fatal) - #undef OPTIONAL_STUB - } - --static int --vddk_config_complete (void) --{ -- if (filename == NULL) { -- nbdkit_error ("you must supply the file= parameter " -- "after the plugin name on the command line"); -- return -1; -- } -- -- /* For remote connections, check all the parameters have been -- * passed. Note that VDDK will segfault if parameters that it -- * expects are NULL (and there's no real way to tell what parameters -- * it is expecting). This implements the same test that the VDDK -- * sample program does. -- */ -- is_remote = -- vmx_spec || -- server_name || -- username || -- password || -- cookie || -- thumb_print || -- port || -- nfc_host_port; -- -- if (is_remote) { --#define missing(test, param) \ -- if (test) { \ -- nbdkit_error ("remote connection requested, missing parameter: %s", \ -- param); \ -- return -1; \ -- } -- missing (!server_name, "server"); -- missing (!username, "user"); -- missing (!password, "password"); -- missing (!vmx_spec, "vm"); --#undef missing -- } -- -- /* Restore original LD_LIBRARY_PATH after reexec. */ -- if (restore_ld_library_path () == -1) -- return -1; -- -- return 0; --} -- --#define vddk_config_help \ -- "[file=] (required) The filename (eg. VMDK file) to serve.\n" \ -- "Many optional parameters are supported, see nbdkit-vddk-plugin(1)." -- - static int - vddk_get_ready (void) - { -@@ -435,6 +380,52 @@ vddk_get_ready (void) - return 0; - } - -+/* Turn log messages from the library into nbdkit_debug. */ -+static void -+debug_function (const char *fs, va_list args) -+{ -+ CLEANUP_FREE char *str = NULL; -+ -+ if (vasprintf (&str, fs, args) == -1) { -+ nbdkit_debug ("lost debug message: %s", fs); -+ return; -+ } -+ -+ trim (str); -+ -+ nbdkit_debug ("%s", str); -+} -+ -+/* Turn error messages from the library into nbdkit_error. */ -+static void -+error_function (const char *fs, va_list args) -+{ -+ CLEANUP_FREE char *str = NULL; -+ -+ /* If the thread-local error_suppression flag is non-zero then we -+ * will suppress error messages from VDDK in this thread. -+ */ -+ if (error_suppression) return; -+ -+ if (vasprintf (&str, fs, args) == -1) { -+ nbdkit_error ("lost error message: %s", fs); -+ return; -+ } -+ -+ trim (str); -+ -+ /* VDDK 7 added a useless error message about their "phone home" -+ * system called CEIP which only panics users. Demote it to a debug -+ * statement. https://bugzilla.redhat.com/show_bug.cgi?id=1834267 -+ */ -+ if (strstr (str, "Get CEIP status failed") != NULL) { -+ nbdkit_debug ("%s", str); -+ return; -+ } -+ -+ nbdkit_error ("%s", str); -+} -+ - /* Defer VDDK initialization until after fork because it is known to - * create background threads from VixDiskLib_InitEx. Unfortunately - * error reporting from this callback is difficult, but we have -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index 0e3dd79e..d99b6f4b 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -183,6 +183,9 @@ extern pthread_mutex_t stats_lock; - #undef OPTIONAL_STUB - extern void display_stats (void); - -+/* utils.c */ -+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); --- -2.31.1 - diff --git a/0019-common-utils-test-vector.c-Add-vector-benchmarks.patch b/0019-common-utils-test-vector.c-Add-vector-benchmarks.patch deleted file mode 100644 index 8fd61b1..0000000 --- a/0019-common-utils-test-vector.c-Add-vector-benchmarks.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 239df6ee9583bc520e9a3e18f0c0d8e58602fb5c Mon Sep 17 00:00:00 2001 -From: Nir Soffer -Date: Fri, 5 Nov 2021 20:36:42 +0200 -Subject: [PATCH] common/utils/test-vector.c: Add vector benchmarks - -The generic vector reallocs on every append. Add benchmarks to measure -the cost with uint32 vector (used for copying extents) and the effect of -reserving space upfront. - -The tests show that realloc is pretty efficient, but calling reserve -before the appends speeds the appends up significantly. - - NBDKIT_BENCH=1 ./test-vector - bench_reserve: 1000000 appends in 0.004503 s - bench_append: 1000000 appends in 0.014986 s - -The new benchmarks do not run by default to avoid trouble in CI on -overloaded machines or under qemu emulation. - -A new target added to run all benchmaks: - - make bench - -Ported from libnbd: -- commit dc9ae0174ab1384081a57a8d54b10f8147ea6430 -- commit f6c06a3b4d87fe976a96ea04f8da1f22b2531dbd - -(cherry picked from commit a227af7921c9a51c4f1ab699a3b9f06a9a645126) ---- - Makefile.am | 5 +++ - README | 7 ++++ - common/utils/Makefile.am | 5 ++- - common/utils/bench.h | 72 ++++++++++++++++++++++++++++++++++++++ - common/utils/test-vector.c | 55 +++++++++++++++++++++++++++-- - 5 files changed, 141 insertions(+), 3 deletions(-) - create mode 100644 common/utils/bench.h - -diff --git a/Makefile.am b/Makefile.am -index b21d69ed..49f5d91c 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -102,6 +102,11 @@ check-root: - check-vddk: - $(MAKE) -C tests check-vddk - -+bench: all -+ @for d in common/utils; do \ -+ $(MAKE) -C $$d bench || exit 1; \ -+ done -+ - #---------------------------------------------------------------------- - # Maintainers only! - -diff --git a/README b/README -index a04325be..b001620c 100644 ---- a/README -+++ b/README -@@ -274,6 +274,13 @@ nbdkit-vddk-plugin against the library like this: - - make check-vddk vddkdir=vmware-vix-disklib-distrib - -+Running the benchmarks -+---------------------- -+ -+To run benchmarks: -+ -+ make bench -+ - DOWNLOAD TARBALLS - ================= - -diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am -index c33811fc..b2f08cb4 100644 ---- a/common/utils/Makefile.am -+++ b/common/utils/Makefile.am -@@ -101,6 +101,9 @@ test_quotes_SOURCES = test-quotes.c quote.c utils.h - test_quotes_CPPFLAGS = -I$(srcdir) - test_quotes_CFLAGS = $(WARNINGS_CFLAGS) - --test_vector_SOURCES = test-vector.c vector.c vector.h -+test_vector_SOURCES = test-vector.c vector.c vector.h bench.h - test_vector_CPPFLAGS = -I$(srcdir) - test_vector_CFLAGS = $(WARNINGS_CFLAGS) -+ -+bench: test-vector -+ NBDKIT_BENCH=1 ./test-vector -diff --git a/common/utils/bench.h b/common/utils/bench.h -new file mode 100644 -index 00000000..496a3614 ---- /dev/null -+++ b/common/utils/bench.h -@@ -0,0 +1,72 @@ -+/* libnbd -+ * Copyright (C) 2021 Red Hat Inc. -+ * -+ * 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. -+ */ -+ -+#ifndef LIBNBD_BENCH_H -+#define LIBNBD_BENCH_H -+ -+#include -+ -+#define MICROSECONDS 1000000 -+ -+struct bench { -+ struct timeval start, stop; -+}; -+ -+static inline void -+bench_start(struct bench *b) -+{ -+ gettimeofday (&b->start, NULL); -+} -+ -+static inline void -+bench_stop(struct bench *b) -+{ -+ gettimeofday (&b->stop, NULL); -+} -+ -+static inline double -+bench_sec(struct bench *b) -+{ -+ struct timeval dt; -+ -+ dt.tv_sec = b->stop.tv_sec - b->start.tv_sec; -+ dt.tv_usec = b->stop.tv_usec - b->start.tv_usec; -+ -+ if (dt.tv_usec < 0) { -+ dt.tv_sec -= 1; -+ dt.tv_usec += MICROSECONDS; -+ } -+ -+ return ((double)dt.tv_sec * MICROSECONDS + dt.tv_usec) / MICROSECONDS; -+} -+ -+#endif /* LIBNBD_BENCH_H */ -diff --git a/common/utils/test-vector.c b/common/utils/test-vector.c -index 94b2aeb7..28af59b8 100644 ---- a/common/utils/test-vector.c -+++ b/common/utils/test-vector.c -@@ -38,9 +38,13 @@ - #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */ - #include - -+#include "bench.h" - #include "vector.h" - -+#define APPENDS 1000000 -+ - DEFINE_VECTOR_TYPE(int64_vector, int64_t); -+DEFINE_VECTOR_TYPE(uint32_vector, uint32_t); - DEFINE_VECTOR_TYPE(string_vector, char *); - - static int -@@ -113,10 +117,57 @@ test_string_vector (void) - free (v.ptr); - } - -+static void -+bench_reserve (void) -+{ -+ uint32_vector v = empty_vector; -+ struct bench b; -+ -+ bench_start(&b); -+ -+ uint32_vector_reserve(&v, APPENDS); -+ -+ for (uint32_t i = 0; i < APPENDS; i++) { -+ uint32_vector_append (&v, i); -+ } -+ -+ bench_stop(&b); -+ -+ assert (v.ptr[APPENDS - 1] == APPENDS - 1); -+ free (v.ptr); -+ -+ printf ("bench_reserve: %d appends in %.6f s\n", APPENDS, bench_sec (&b)); -+} -+ -+static void -+bench_append (void) -+{ -+ uint32_vector v = empty_vector; -+ struct bench b; -+ -+ bench_start(&b); -+ -+ for (uint32_t i = 0; i < APPENDS; i++) { -+ uint32_vector_append (&v, i); -+ } -+ -+ bench_stop(&b); -+ -+ assert (v.ptr[APPENDS - 1] == APPENDS - 1); -+ free (v.ptr); -+ -+ printf ("bench_append: %d appends in %.6f s\n", APPENDS, bench_sec (&b)); -+} -+ - int - main (int argc, char *argv[]) - { -- test_int64_vector (); -- test_string_vector (); -+ if (getenv("NBDKIT_BENCH")) { -+ bench_reserve (); -+ bench_append (); -+ } else { -+ test_int64_vector (); -+ test_string_vector (); -+ } - return 0; - } --- -2.31.1 - diff --git a/0020-common-urils-vector.c-Optimize-vector-append.patch b/0020-common-urils-vector.c-Optimize-vector-append.patch deleted file mode 100644 index bc4c8f9..0000000 --- a/0020-common-urils-vector.c-Optimize-vector-append.patch +++ /dev/null @@ -1,54 +0,0 @@ -From e544d86c797edec613673c7272f8d4f8b05d87f8 Mon Sep 17 00:00:00 2001 -From: Nir Soffer -Date: Fri, 5 Nov 2021 22:16:26 +0200 -Subject: [PATCH] common/urils/vector.c: Optimize vector append - -Minimize reallocs by growing the backing array by factor of 1.5. - -Testing show that now append() is fast without calling reserve() -upfront, simplifying code using vector. - - NBDKIT_BENCH=1 ./test-vector - bench_reserve: 1000000 appends in 0.004496 s - bench_append: 1000000 appends in 0.004180 s - -This can make a difference in code appending millions of items. - -Ported from libnbd commit 985dfa72ae2e41901f0af21e7205ef85428cd4bd. - -(cherry picked from commit 12356fa97a840de19bb61e0abedd6e7c7e578e5a) ---- - common/utils/vector.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/common/utils/vector.c b/common/utils/vector.c -index 00cd2546..7df17e1b 100644 ---- a/common/utils/vector.c -+++ b/common/utils/vector.c -@@ -41,11 +41,21 @@ int - generic_vector_reserve (struct generic_vector *v, size_t n, size_t itemsize) - { - void *newptr; -+ size_t reqalloc, newalloc; - -- newptr = realloc (v->ptr, (n + v->alloc) * itemsize); -+ reqalloc = v->alloc + n; -+ if (reqalloc < v->alloc) -+ return -1; /* overflow */ -+ -+ newalloc = (v->alloc * 3 + 1) / 2; -+ -+ if (newalloc < reqalloc) -+ newalloc = reqalloc; -+ -+ newptr = realloc (v->ptr, newalloc * itemsize); - if (newptr == NULL) - return -1; - v->ptr = newptr; -- v->alloc += n; -+ v->alloc = newalloc; - return 0; - } --- -2.31.1 - diff --git a/0021-common-utils-vector-Rename-alloc-to-cap.patch b/0021-common-utils-vector-Rename-alloc-to-cap.patch deleted file mode 100644 index 569e302..0000000 --- a/0021-common-utils-vector-Rename-alloc-to-cap.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 24e2694b302f6602e0fc7808a53a766cb983dfb4 Mon Sep 17 00:00:00 2001 -From: Nir Soffer -Date: Fri, 5 Nov 2021 22:59:38 +0200 -Subject: [PATCH] common/utils/vector: Rename `alloc` to `cap` - -The `alloc` field is the maximum number of items you can append to a -vector before it need to be resized. This may confuse users with the -size of the `ptr` array which is `alloc * itemsize`. Rename to "cap", -common term for this property in many languages (e.g C++, Rust, Go). - -Tested with "make check". Tests requiring root or external libraries -(vddk) not tested. - -Ported from libnbd commit e3c7f02a2a844295564c832108d36c939c4e4ecf. - -(cherry picked from commit 75a44237c4463524dbf7951bb62b59c373c85865) ---- - common/allocators/malloc.c | 24 ++++++++++++------------ - common/utils/vector.c | 16 ++++++++-------- - common/utils/vector.h | 12 ++++++------ - plugins/vddk/reexec.c | 2 +- - 4 files changed, 27 insertions(+), 27 deletions(-) - -diff --git a/common/allocators/malloc.c b/common/allocators/malloc.c -index 59409c24..f7474465 100644 ---- a/common/allocators/malloc.c -+++ b/common/allocators/malloc.c -@@ -88,16 +88,16 @@ extend (struct m_alloc *ma, uint64_t new_size) - ACQUIRE_WRLOCK_FOR_CURRENT_SCOPE (&ma->lock); - size_t old_size, n; - -- if (ma->ba.alloc < new_size) { -- old_size = ma->ba.alloc; -- n = new_size - ma->ba.alloc; -+ if (ma->ba.cap < new_size) { -+ old_size = ma->ba.cap; -+ n = new_size - ma->ba.cap; - - #ifdef HAVE_MUNLOCK - /* Since the memory might be moved by realloc, we must unlock the - * original array. - */ - if (ma->use_mlock) -- munlock (ma->ba.ptr, ma->ba.alloc); -+ munlock (ma->ba.ptr, ma->ba.cap); - #endif - - if (bytearray_reserve (&ma->ba, n) == -1) { -@@ -110,7 +110,7 @@ extend (struct m_alloc *ma, uint64_t new_size) - - #ifdef HAVE_MLOCK - if (ma->use_mlock) { -- if (mlock (ma->ba.ptr, ma->ba.alloc) == -1) { -+ if (mlock (ma->ba.ptr, ma->ba.cap) == -1) { - nbdkit_error ("allocator=malloc: mlock: %m"); - return -1; - } -@@ -138,11 +138,11 @@ m_alloc_read (struct allocator *a, void *buf, - /* Avoid reading beyond the end of the allocated array. Return - * zeroes for that part. - */ -- if (offset >= ma->ba.alloc) -+ if (offset >= ma->ba.cap) - memset (buf, 0, count); -- else if (offset + count > ma->ba.alloc) { -- memcpy (buf, ma->ba.ptr + offset, ma->ba.alloc - offset); -- memset (buf + ma->ba.alloc - offset, 0, offset + count - ma->ba.alloc); -+ else if (offset + count > ma->ba.cap) { -+ memcpy (buf, ma->ba.ptr + offset, ma->ba.cap - offset); -+ memset (buf + ma->ba.cap - offset, 0, offset + count - ma->ba.cap); - } - else - memcpy (buf, ma->ba.ptr + offset, count); -@@ -191,9 +191,9 @@ m_alloc_zero (struct allocator *a, uint64_t count, uint64_t offset) - /* Try to avoid extending the array, since the unallocated part - * always reads as zero. - */ -- if (offset < ma->ba.alloc) { -- if (offset + count > ma->ba.alloc) -- memset (ma->ba.ptr + offset, 0, ma->ba.alloc - offset); -+ if (offset < ma->ba.cap) { -+ if (offset + count > ma->ba.cap) -+ memset (ma->ba.ptr + offset, 0, ma->ba.cap - offset); - else - memset (ma->ba.ptr + offset, 0, count); - } -diff --git a/common/utils/vector.c b/common/utils/vector.c -index 7df17e1b..a4b43ce7 100644 ---- a/common/utils/vector.c -+++ b/common/utils/vector.c -@@ -41,21 +41,21 @@ int - generic_vector_reserve (struct generic_vector *v, size_t n, size_t itemsize) - { - void *newptr; -- size_t reqalloc, newalloc; -+ size_t reqcap, newcap; - -- reqalloc = v->alloc + n; -- if (reqalloc < v->alloc) -+ reqcap = v->cap + n; -+ if (reqcap < v->cap) - return -1; /* overflow */ - -- newalloc = (v->alloc * 3 + 1) / 2; -+ newcap = (v->cap * 3 + 1) / 2; - -- if (newalloc < reqalloc) -- newalloc = reqalloc; -+ if (newcap < reqcap) -+ newcap = reqcap; - -- newptr = realloc (v->ptr, newalloc * itemsize); -+ newptr = realloc (v->ptr, newcap * itemsize); - if (newptr == NULL) - return -1; - v->ptr = newptr; -- v->alloc = newalloc; -+ v->cap = newcap; - return 0; - } -diff --git a/common/utils/vector.h b/common/utils/vector.h -index f6a0af78..782dcba6 100644 ---- a/common/utils/vector.h -+++ b/common/utils/vector.h -@@ -86,7 +86,7 @@ - struct name { \ - type *ptr; /* Pointer to array of items. */ \ - size_t size; /* Number of valid items in the array. */ \ -- size_t alloc; /* Number of items allocated. */ \ -+ size_t cap; /* Maximum number of items. */ \ - }; \ - typedef struct name name; \ - \ -@@ -106,7 +106,7 @@ - name##_insert (name *v, type elem, size_t i) \ - { \ - assert (i <= v->size); \ -- if (v->size >= v->alloc) { \ -+ if (v->size >= v->cap) { \ - if (name##_reserve (v, 1) == -1) return -1; \ - } \ - memmove (&v->ptr[i+1], &v->ptr[i], (v->size-i) * sizeof (elem)); \ -@@ -137,7 +137,7 @@ - { \ - free (v->ptr); \ - v->ptr = NULL; \ -- v->size = v->alloc = 0; \ -+ v->size = v->cap = 0; \ - } \ - \ - /* Iterate over the vector, calling f() on each element. */ \ -@@ -181,17 +181,17 @@ - if (newptr == NULL) return -1; \ - memcpy (newptr, vptr, len); \ - copy->ptr = newptr; \ -- copy->size = copy->alloc = v->size; \ -+ copy->size = copy->cap = v->size; \ - return 0; \ - } \ - \ - --#define empty_vector { .ptr = NULL, .size = 0, .alloc = 0 } -+#define empty_vector { .ptr = NULL, .size = 0, .cap = 0 } - - struct generic_vector { - void *ptr; - size_t size; -- size_t alloc; -+ size_t cap; - }; - - extern int generic_vector_reserve (struct generic_vector *v, -diff --git a/plugins/vddk/reexec.c b/plugins/vddk/reexec.c -index 46acdb62..9e87025e 100644 ---- a/plugins/vddk/reexec.c -+++ b/plugins/vddk/reexec.c -@@ -116,7 +116,7 @@ perform_reexec (const char *env, const char *prepend) - nbdkit_error ("realloc: %m"); - exit (EXIT_FAILURE); - } -- r = read (fd, buf.ptr + buf.size, buf.alloc - buf.size); -+ r = read (fd, buf.ptr + buf.size, buf.cap - buf.size); - if (r == -1) { - nbdkit_error ("read: %s: %m", cmdline_file); - exit (EXIT_FAILURE); --- -2.31.1 - diff --git a/0022-common-utils-vector-Rename-size-to-len.patch b/0022-common-utils-vector-Rename-size-to-len.patch deleted file mode 100644 index da3f1cd..0000000 --- a/0022-common-utils-vector-Rename-size-to-len.patch +++ /dev/null @@ -1,1747 +0,0 @@ -From 1674e453d5652018c989059ea19eb79bed7e12c8 Mon Sep 17 00:00:00 2001 -From: Nir Soffer -Date: Sat, 6 Nov 2021 00:03:11 +0200 -Subject: [PATCH] common/utils/vector: Rename `size` to `len` - -The field `size` may be confusing with the size of the underlying array. -Rename to `len`, a common term for this concept. - -Tested with "make check" as regular user, tests that need root or -external libraries (vddk) are not tested. - -Ported from libnbd commit cc0567e9aed7e6b40a44bf8eac0a262ac7314fec. - -(cherry picked from commit 0b0eece73f04963a66b9adc507e5cbaba608660b) ---- - common/allocators/allocator.c | 2 +- - common/allocators/malloc.c | 2 +- - common/allocators/sparse.c | 6 +- - common/allocators/zstd.c | 6 +- - common/regions/regions.h | 6 +- - common/utils/environ.c | 2 +- - common/utils/test-vector.c | 2 +- - common/utils/vector.h | 52 ++++++------ - filters/ddrescue/ddrescue.c | 2 +- - filters/exitwhen/exitwhen.c | 2 +- - filters/extentlist/extentlist.c | 14 ++-- - filters/multi-conn/multi-conn.c | 16 ++-- - plugins/cc/cc.c | 4 +- - plugins/data/data.c | 4 +- - plugins/data/format.c | 114 +++++++++++++-------------- - plugins/eval/eval.c | 2 +- - plugins/floppy/directory-lfn.c | 24 +++--- - plugins/floppy/floppy.c | 2 +- - plugins/floppy/virtual-floppy.c | 32 ++++---- - plugins/iso/iso.c | 4 +- - plugins/nbd/nbd.c | 6 +- - plugins/partitioning/partition-mbr.c | 8 +- - plugins/partitioning/partitioning.c | 18 ++--- - plugins/partitioning/virtual-disk.c | 12 +-- - plugins/partitioning/virtual-disk.h | 2 +- - plugins/split/split.c | 14 ++-- - plugins/ssh/ssh.c | 2 +- - plugins/vddk/reexec.c | 8 +- - plugins/vddk/stats.c | 4 +- - plugins/vddk/worker.c | 4 +- - server/exports.c | 6 +- - server/extents.c | 22 +++--- - server/main.c | 2 +- - server/sockets.c | 8 +- - wrapper.c | 4 +- - 35 files changed, 209 insertions(+), 209 deletions(-) - -diff --git a/common/allocators/allocator.c b/common/allocators/allocator.c -index d306a842..019c68cd 100644 ---- a/common/allocators/allocator.c -+++ b/common/allocators/allocator.c -@@ -137,7 +137,7 @@ create_allocator (const char *type, bool debug) - return NULL; - - /* See if we can find the allocator. */ -- for (i = 0; i < allocators.size; ++i) { -+ for (i = 0; i < allocators.len; ++i) { - if (strncmp (type, allocators.ptr[i]->type, type_len) == 0) { - ret = allocators.ptr[i]->create (¶ms); - break; -diff --git a/common/allocators/malloc.c b/common/allocators/malloc.c -index f7474465..eea44432 100644 ---- a/common/allocators/malloc.c -+++ b/common/allocators/malloc.c -@@ -241,7 +241,7 @@ m_alloc_create (const void *paramsv) - size_t i; - - /* Parse the optional mlock=true|false parameter. */ -- for (i = 0; i < params->size; ++i) { -+ for (i = 0; i < params->len; ++i) { - if (strcmp (params->ptr[i].key, "mlock") == 0) { - int r = nbdkit_parse_bool (params->ptr[i].value); - if (r == -1) return NULL; -diff --git a/common/allocators/sparse.c b/common/allocators/sparse.c -index ca508c35..7c6d1636 100644 ---- a/common/allocators/sparse.c -+++ b/common/allocators/sparse.c -@@ -150,7 +150,7 @@ sparse_array_free (struct allocator *a) - size_t i; - - if (sa) { -- for (i = 0; i < sa->l1_dir.size; ++i) -+ for (i = 0; i < sa->l1_dir.len; ++i) - free_l2_dir (sa->l1_dir.ptr[i].l2_dir); - free (sa->l1_dir.ptr); - pthread_mutex_destroy (&sa->lock); -@@ -184,7 +184,7 @@ insert_l1_entry (struct sparse_array *sa, const struct l1_entry *entry) - { - size_t i; - -- for (i = 0; i < sa->l1_dir.size; ++i) { -+ for (i = 0; i < sa->l1_dir.len; ++i) { - if (entry->offset < sa->l1_dir.ptr[i].offset) { - /* Insert new entry before i'th directory entry. */ - if (l1_dir_insert (&sa->l1_dir, *entry, i) == -1) { -@@ -508,7 +508,7 @@ sparse_array_create (const void *paramsv) - const allocator_parameters *params = paramsv; - struct sparse_array *sa; - -- if (params->size > 0) { -+ if (params->len > 0) { - nbdkit_error ("allocator=sparse does not take extra parameters"); - return NULL; - } -diff --git a/common/allocators/zstd.c b/common/allocators/zstd.c -index 81fe4ed0..1675d21c 100644 ---- a/common/allocators/zstd.c -+++ b/common/allocators/zstd.c -@@ -136,7 +136,7 @@ zstd_array_free (struct allocator *a) - - ZSTD_freeCCtx (za->zcctx); - ZSTD_freeDStream (za->zdstrm); -- for (i = 0; i < za->l1_dir.size; ++i) -+ for (i = 0; i < za->l1_dir.len; ++i) - free_l2_dir (za->l1_dir.ptr[i].l2_dir); - free (za->l1_dir.ptr); - pthread_mutex_destroy (&za->lock); -@@ -170,7 +170,7 @@ insert_l1_entry (struct zstd_array *za, const struct l1_entry *entry) - { - size_t i; - -- for (i = 0; i < za->l1_dir.size; ++i) { -+ for (i = 0; i < za->l1_dir.len; ++i) { - if (entry->offset < za->l1_dir.ptr[i].offset) { - /* Insert new entry before i'th directory entry. */ - if (l1_dir_insert (&za->l1_dir, *entry, i) == -1) { -@@ -600,7 +600,7 @@ zstd_array_create (const void *paramsv) - const allocator_parameters *params = paramsv; - struct zstd_array *za; - -- if (params->size > 0) { -+ if (params->len > 0) { - nbdkit_error ("allocator=zstd does not take extra parameters"); - return NULL; - } -diff --git a/common/regions/regions.h b/common/regions/regions.h -index 6dfd5d88..3d562316 100644 ---- a/common/regions/regions.h -+++ b/common/regions/regions.h -@@ -84,17 +84,17 @@ extern void free_regions (regions *regions) - static inline size_t __attribute__((__nonnull__ (1))) - nr_regions (regions *rs) - { -- return rs->size; -+ return rs->len; - } - - /* Return the virtual size of the disk. */ - static inline int64_t __attribute__((__nonnull__ (1))) - virtual_size (regions *rs) - { -- if (rs->size == 0) -+ if (rs->len == 0) - return 0; - else -- return rs->ptr[rs->size-1].end + 1; -+ return rs->ptr[rs->len-1].end + 1; - } - - /* Look up the region corresponding to the given offset. If the -diff --git a/common/utils/environ.c b/common/utils/environ.c -index e70976cb..2ad996eb 100644 ---- a/common/utils/environ.c -+++ b/common/utils/environ.c -@@ -82,7 +82,7 @@ copy_environ (char **env, ...) - - /* Search for key in the existing environment. It's O(n^2) ... */ - len = strlen (key); -- for (i = 0; i < ret.size; ++i) { -+ for (i = 0; i < ret.len; ++i) { - if (strncmp (key, ret.ptr[i], len) == 0 && ret.ptr[i][len] == '=') { - /* Replace the existing key. */ - free (ret.ptr[i]); -diff --git a/common/utils/test-vector.c b/common/utils/test-vector.c -index 28af59b8..6d89a281 100644 ---- a/common/utils/test-vector.c -+++ b/common/utils/test-vector.c -@@ -73,7 +73,7 @@ test_int64_vector (void) - assert (v.ptr[i] == i); - - int64_vector_remove (&v, 1); -- assert (v.size == 9); -+ assert (v.len == 9); - assert (v.ptr[1] == 2); - - tmp = 10; -diff --git a/common/utils/vector.h b/common/utils/vector.h -index 782dcba6..1d04f812 100644 ---- a/common/utils/vector.h -+++ b/common/utils/vector.h -@@ -59,14 +59,14 @@ - * - * string_vector names = empty_vector; - * -- * where ‘names.ptr[]’ will be an array of strings and ‘names.size’ -+ * where ‘names.ptr[]’ will be an array of strings and ‘names.len’ - * will be the number of strings. There are no get/set accessors. To - * iterate over the strings you can use the ‘.ptr’ field directly: - * -- * for (size_t i = 0; i < names.size; ++i) -+ * for (size_t i = 0; i < names.len; ++i) - * printf ("%s\n", names.ptr[i]); - * -- * Initializing with ‘empty_vector’ sets ‘.ptr = NULL’ and ‘.size = 0’. -+ * Initializing with ‘empty_vector’ sets ‘.ptr = NULL’ and ‘.len = 0’. - * - * DEFINE_VECTOR_TYPE also defines utility functions. For the full - * list see the definition below, but useful functions include: -@@ -84,15 +84,15 @@ - */ - #define DEFINE_VECTOR_TYPE(name, type) \ - struct name { \ -- type *ptr; /* Pointer to array of items. */ \ -- size_t size; /* Number of valid items in the array. */ \ -- size_t cap; /* Maximum number of items. */ \ -+ type *ptr; /* Pointer to array of items. */ \ -+ size_t len; /* Number of valid items in the array. */ \ -+ size_t cap; /* Maximum number of items. */ \ - }; \ - typedef struct name name; \ - \ - /* Reserve n elements at the end of the vector. Note space is \ -- * allocated but the vector size is not increased and the new \ -- * elements are not initialized. \ -+ * allocated and capacity is increased, but the vector length \ -+ * is not increased and the new elements are not initialized. \ - */ \ - static inline int \ - name##_reserve (name *v, size_t n) \ -@@ -101,17 +101,17 @@ - sizeof (type)); \ - } \ - \ -- /* Insert at i'th element. i=0 => beginning i=size => append */ \ -+ /* Insert at i'th element. i=0 => beginning i=len => append */ \ - static inline int \ - name##_insert (name *v, type elem, size_t i) \ - { \ -- assert (i <= v->size); \ -- if (v->size >= v->cap) { \ -+ assert (i <= v->len); \ -+ if (v->len >= v->cap) { \ - if (name##_reserve (v, 1) == -1) return -1; \ - } \ -- memmove (&v->ptr[i+1], &v->ptr[i], (v->size-i) * sizeof (elem)); \ -+ memmove (&v->ptr[i+1], &v->ptr[i], (v->len-i) * sizeof (elem)); \ - v->ptr[i] = elem; \ -- v->size++; \ -+ v->len++; \ - return 0; \ - } \ - \ -@@ -119,16 +119,16 @@ - static inline int \ - name##_append (name *v, type elem) \ - { \ -- return name##_insert (v, elem, v->size); \ -+ return name##_insert (v, elem, v->len); \ - } \ - \ -- /* Remove i'th element. i=0 => beginning i=size-1 => end */ \ -+ /* Remove i'th element. i=0 => beginning i=len-1 => end */ \ - static inline void \ - name##_remove (name *v, size_t i) \ - { \ -- assert (i < v->size); \ -- memmove (&v->ptr[i], &v->ptr[i+1], (v->size-i-1) * sizeof (type)); \ -- v->size--; \ -+ assert (i < v->len); \ -+ memmove (&v->ptr[i], &v->ptr[i+1], (v->len-i-1) * sizeof (type)); \ -+ v->len--; \ - } \ - \ - /* Remove all elements and deallocate the vector. */ \ -@@ -137,7 +137,7 @@ - { \ - free (v->ptr); \ - v->ptr = NULL; \ -- v->size = v->cap = 0; \ -+ v->len = v->cap = 0; \ - } \ - \ - /* Iterate over the vector, calling f() on each element. */ \ -@@ -145,7 +145,7 @@ - name##_iter (name *v, void (*f) (type elem)) \ - { \ - size_t i; \ -- for (i = 0; i < v->size; ++i) \ -+ for (i = 0; i < v->len; ++i) \ - f (v->ptr[i]); \ - } \ - \ -@@ -154,7 +154,7 @@ - name##_sort (name *v, \ - int (*compare) (const type *p1, const type *p2)) \ - { \ -- qsort (v->ptr, v->size, sizeof (type), (void *) compare); \ -+ qsort (v->ptr, v->len, sizeof (type), (void *) compare); \ - } \ - \ - /* Search for an exactly matching element in the vector using a \ -@@ -164,7 +164,7 @@ - name##_search (const name *v, const void *key, \ - int (*compare) (const void *key, const type *v)) \ - { \ -- return bsearch (key, v->ptr, v->size, sizeof (type), \ -+ return bsearch (key, v->ptr, v->len, sizeof (type), \ - (void *) compare); \ - } \ - \ -@@ -175,22 +175,22 @@ - /* Note it's allowed for v and copy to be the same pointer. */ \ - type *vptr = v->ptr; \ - type *newptr; \ -- size_t len = v->size * sizeof (type); \ -+ size_t len = v->len * sizeof (type); \ - \ - newptr = malloc (len); \ - if (newptr == NULL) return -1; \ - memcpy (newptr, vptr, len); \ - copy->ptr = newptr; \ -- copy->size = copy->cap = v->size; \ -+ copy->len = copy->cap = v->len; \ - return 0; \ - } \ - \ - --#define empty_vector { .ptr = NULL, .size = 0, .cap = 0 } -+#define empty_vector { .ptr = NULL, .len = 0, .cap = 0 } - - struct generic_vector { - void *ptr; -- size_t size; -+ size_t len; - size_t cap; - }; - -diff --git a/filters/ddrescue/ddrescue.c b/filters/ddrescue/ddrescue.c -index 7b1c9c1e..218c8ee5 100644 ---- a/filters/ddrescue/ddrescue.c -+++ b/filters/ddrescue/ddrescue.c -@@ -180,7 +180,7 @@ ddrescue_pread (nbdkit_next *next, - { - size_t i; - -- for (i = 0; i < map.ranges.size; i++) { -+ for (i = 0; i < map.ranges.len; i++) { - if (map.ranges.ptr[i].status != '+') - continue; - if (offset >= map.ranges.ptr[i].start && offset <= map.ranges.ptr[i].end) { -diff --git a/filters/exitwhen/exitwhen.c b/filters/exitwhen/exitwhen.c -index 543af058..83e99953 100644 ---- a/filters/exitwhen/exitwhen.c -+++ b/filters/exitwhen/exitwhen.c -@@ -143,7 +143,7 @@ check_for_event (void) - size_t i; - - if (!exiting) { -- for (i = 0; i < events.size; ++i) { -+ for (i = 0; i < events.len; ++i) { - const struct event *event = &events.ptr[i]; - - switch (event->type) { -diff --git a/filters/extentlist/extentlist.c b/filters/extentlist/extentlist.c -index 7e6f1b78..c91fbfea 100644 ---- a/filters/extentlist/extentlist.c -+++ b/filters/extentlist/extentlist.c -@@ -134,7 +134,7 @@ parse_extentlist (void) - - assert (extentlist != NULL); - assert (extents.ptr == NULL); -- assert (extents.size == 0); -+ assert (extents.len == 0); - - fp = fopen (extentlist, "r"); - if (!fp) { -@@ -200,7 +200,7 @@ parse_extentlist (void) - - /* There must not be overlaps at this point. */ - end = 0; -- for (i = 0; i < extents.size; ++i) { -+ for (i = 0; i < extents.len; ++i) { - if (extents.ptr[i].offset < end || - extents.ptr[i].offset + extents.ptr[i].length < extents.ptr[i].offset) { - nbdkit_error ("extents in the extent list are overlapping"); -@@ -210,8 +210,8 @@ parse_extentlist (void) - } - - /* If there's a gap at the beginning, insert a hole|zero extent. */ -- if (extents.size == 0 || extents.ptr[0].offset > 0) { -- end = extents.size == 0 ? UINT64_MAX : extents.ptr[0].offset; -+ if (extents.len == 0 || extents.ptr[0].offset > 0) { -+ end = extents.len == 0 ? UINT64_MAX : extents.ptr[0].offset; - if (extent_list_insert (&extents, - (struct extent){.offset = 0, .length = end, - .type = HOLE}, -@@ -224,7 +224,7 @@ parse_extentlist (void) - /* Now insert hole|zero extents after every extent where there - * is a gap between that extent and the next one. - */ -- for (i = 0; i < extents.size-1; ++i) { -+ for (i = 0; i < extents.len-1; ++i) { - end = extents.ptr[i].offset + extents.ptr[i].length; - if (end < extents.ptr[i+1].offset) - if (extent_list_insert (&extents, -@@ -238,7 +238,7 @@ parse_extentlist (void) - } - - /* If there's a gap at the end, insert a hole|zero extent. */ -- end = extents.ptr[extents.size-1].offset + extents.ptr[extents.size-1].length; -+ end = extents.ptr[extents.len-1].offset + extents.ptr[extents.len-1].length; - if (end < UINT64_MAX) { - if (extent_list_append (&extents, - (struct extent){.offset = end, -@@ -250,7 +250,7 @@ parse_extentlist (void) - } - - /* Debug the final list. */ -- for (i = 0; i < extents.size; ++i) { -+ for (i = 0; i < extents.len; ++i) { - nbdkit_debug ("extentlist: " - "extent[%zu] = %" PRIu64 "-%" PRIu64 " (length %" PRIu64 ")" - " type %" PRIu32, -diff --git a/filters/multi-conn/multi-conn.c b/filters/multi-conn/multi-conn.c -index a6a25ef9..c7421a39 100644 ---- a/filters/multi-conn/multi-conn.c -+++ b/filters/multi-conn/multi-conn.c -@@ -207,14 +207,14 @@ multi_conn_prepare (nbdkit_next *next, void *handle, int readonly) - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock); - if (byname) { - g = NULL; -- for (i = 0; i < groups.size; i++) -+ for (i = 0; i < groups.len; i++) - if (strcmp (groups.ptr[i]->name, h->name) == 0) { - g = groups.ptr[i]; - break; - } - } - else -- g = groups.size ? groups.ptr[0] : NULL; -+ g = groups.len ? groups.ptr[0] : NULL; - - if (!g) { - g = calloc (1, sizeof *g); -@@ -230,7 +230,7 @@ multi_conn_prepare (nbdkit_next *next, void *handle, int readonly) - } - if (conns_vector_append (&g->conns, h) == -1) { - if (new_group) { -- group_vector_remove (&groups, groups.size - 1); -+ group_vector_remove (&groups, groups.len - 1); - free (g->name); - free (g); - } -@@ -251,14 +251,14 @@ multi_conn_finalize (nbdkit_next *next, void *handle) - assert (h->group); - - /* XXX should we add a config param to flush if the client forgot? */ -- for (i = 0; i < h->group->conns.size; i++) { -+ for (i = 0; i < h->group->conns.len; i++) { - if (h->group->conns.ptr[i] == h) { - conns_vector_remove (&h->group->conns, i); - break; - } - } -- if (h->group->conns.size == 0) { -- for (i = 0; i < groups.size; i++) -+ if (h->group->conns.len == 0) { -+ for (i = 0; i < groups.len; i++) - if (groups.ptr[i] == h->group) { - group_vector_remove (&groups, i); - free (h->group->name); -@@ -451,7 +451,7 @@ multi_conn_flush (nbdkit_next *next, - assert (h->group); - if (h->mode == EMULATE) { - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock); -- for (i = 0; i < h->group->conns.size; i++) { -+ for (i = 0; i < h->group->conns.len; i++) { - h2 = h->group->conns.ptr[i]; - if (track == OFF || (h->group->dirty && - (track == FAST || h2->dirty & READ)) || -@@ -474,7 +474,7 @@ multi_conn_flush (nbdkit_next *next, - case CONN: - if (next->can_multi_conn (next) == 1) { - ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lock); -- for (i = 0; i < h->group->conns.size; i++) -+ for (i = 0; i < h->group->conns.len; i++) - h->group->conns.ptr[i]->dirty = 0; - h->group->dirty = 0; - } -diff --git a/plugins/cc/cc.c b/plugins/cc/cc.c -index 3251f312..c8c3c86b 100644 ---- a/plugins/cc/cc.c -+++ b/plugins/cc/cc.c -@@ -292,12 +292,12 @@ cc_config_complete (void) - if (subplugin.load) - subplugin.load (); - if (subplugin.config) { -- for (i = 0; i < params.size; ++i) { -+ for (i = 0; i < params.len; ++i) { - if (subplugin.config (params.ptr[i].key, params.ptr[i].value) == -1) - return -1; - } - } -- else if (params.size > 0) { -+ else if (params.len > 0) { - /* Just print the first one in the error message. */ - nbdkit_error ("unknown parameter: %s", params.ptr[0].key); - return -1; -diff --git a/plugins/data/data.c b/plugins/data/data.c -index 03bcc8a5..960cf97d 100644 ---- a/plugins/data/data.c -+++ b/plugins/data/data.c -@@ -158,7 +158,7 @@ get_extra_param (const char *name) - { - size_t i; - -- for (i = 0; i < params.size; ++i) { -+ for (i = 0; i < params.len; ++i) { - if (strcmp (params.ptr[i].key, name) == 0) - return params.ptr[i].value; - } -@@ -176,7 +176,7 @@ data_config_complete (void) - return -1; - } - -- if (data_seen != DATA && params.size != 0) { -+ if (data_seen != DATA && params.len != 0) { - nbdkit_error ("extra parameters passed and not using data='...'"); - return -1; - } -diff --git a/plugins/data/format.c b/plugins/data/format.c -index d351f79a..986a0f6e 100644 ---- a/plugins/data/format.c -+++ b/plugins/data/format.c -@@ -83,7 +83,7 @@ substring (string s, size_t offset, size_t len) - string r = empty_vector; - - for (i = 0; i < len; ++i) { -- assert (offset+i < s.size); -+ assert (offset+i < s.len); - if (string_append (&r, s.ptr[offset+i]) == -1) { - nbdkit_error ("realloc: %m"); - exit (EXIT_FAILURE); -@@ -167,7 +167,7 @@ static expr_list expr_table; - static node_id - new_node (const expr_t e) - { -- if (expr_table.size == 0) { -+ if (expr_table.len == 0) { - static const expr_t enull = { .t = EXPR_NULL }; - if (expr_list_append (&expr_table, enull) == -1) - goto out_of_memory; -@@ -179,14 +179,14 @@ new_node (const expr_t e) - nbdkit_error ("realloc"); - exit (EXIT_FAILURE); - } -- return expr_table.size-1; -+ return expr_table.len-1; - } - - /* Get an expression by node_id. */ - static expr_t - get_node (node_id id) - { -- assert (id < expr_table.size); -+ assert (id < expr_table.len); - return expr_table.ptr[id]; - } - -@@ -196,7 +196,7 @@ free_expr_table (void) - size_t i; - expr_t e; - -- for (i = 0; i < expr_table.size; ++i) { -+ for (i = 0; i < expr_table.len; ++i) { - e = get_node (i); - switch (e.t) { - case EXPR_LIST: free (e.list.ptr); break; -@@ -344,7 +344,7 @@ debug_expr (node_id id, int level) - break; - case EXPR_LIST: - nbdkit_debug ("%s(", debug_indent (level)); -- for (i = 0; i < e.list.size; ++i) -+ for (i = 0; i < e.list.len; ++i) - debug_expr (e.list.ptr[i], level+1); - nbdkit_debug ("%s)", debug_indent (level)); - break; -@@ -370,7 +370,7 @@ debug_expr (node_id id, int level) - CLEANUP_FREE_STRING string s = empty_vector; - static const char hex[] = "0123456789abcdef"; - -- for (i = 0; i < e.string.size; ++i) { -+ for (i = 0; i < e.string.len; ++i) { - char c = e.string.ptr[i]; - if (ascii_isprint ((char) c)) - string_append (&s, e.string.ptr[i]); -@@ -445,7 +445,7 @@ read_data_format (const char *value, struct allocator *a, uint64_t *size_rtn) - uint64_t offset = 0; - int r = -1; - -- assert (expr_table.size == 0); -+ assert (expr_table.len == 0); - - /* Run the parser across the entire string, returning the top level - * expression. -@@ -600,11 +600,11 @@ parser (int level, const char *value, size_t *start, size_t len, - - case '*': /* expr*N */ - i++; -- if (list.size == 0) { -+ if (list.len == 0) { - nbdkit_error ("*N must follow an expression"); - return -1; - } -- if (! is_data_expr (get_node (list.ptr[list.size-1]))) { -+ if (! is_data_expr (get_node (list.ptr[list.len-1]))) { - nbdkit_error ("*N cannot be applied to this type of expression"); - return -1; - } -@@ -619,18 +619,18 @@ parser (int level, const char *value, size_t *start, size_t len, - nbdkit_error ("*N not numeric"); - return -1; - } -- id = list.ptr[list.size-1]; -- list.size--; -+ id = list.ptr[list.len-1]; -+ list.len--; - APPEND_EXPR (new_node (expr (EXPR_REPEAT, id, (uint64_t) i64))); - break; - - case '[': /* expr[k:m] */ - i++; -- if (list.size == 0) { -+ if (list.len == 0) { - nbdkit_error ("[N:M] must follow an expression"); - return -1; - } -- if (! is_data_expr (get_node (list.ptr[list.size-1]))) { -+ if (! is_data_expr (get_node (list.ptr[list.len-1]))) { - nbdkit_error ("[N:M] cannot be applied to this type of expression"); - return -1; - } -@@ -647,8 +647,8 @@ parser (int level, const char *value, size_t *start, size_t len, - nbdkit_error ("enclosed pattern (...)[N:M] not numeric"); - return -1; - } -- id = list.ptr[list.size-1]; -- list.size--; -+ id = list.ptr[list.len-1]; -+ list.len--; - APPEND_EXPR (new_node (expr (EXPR_SLICE, id, i64, m))); - break; - -@@ -720,11 +720,11 @@ parser (int level, const char *value, size_t *start, size_t len, - i++; - if (value[i] != '>') goto parse_error; - i++; -- if (list.size == 0) { -+ if (list.len == 0) { - nbdkit_error ("-> must follow an expression"); - return -1; - } -- if (! is_data_expr (get_node (list.ptr[list.size-1]))) { -+ if (! is_data_expr (get_node (list.ptr[list.len-1]))) { - nbdkit_error ("-> cannot be applied to this type of expression"); - return -1; - } -@@ -735,9 +735,9 @@ parser (int level, const char *value, size_t *start, size_t len, - nbdkit_error ("strndup: %m"); - return -1; - } -- id = list.ptr[list.size-1]; -+ id = list.ptr[list.len-1]; - i += flen; -- list.size--; -+ list.len--; - APPEND_EXPR (new_node (expr (EXPR_ASSIGN, name, id))); - break; - } -@@ -1023,7 +1023,7 @@ parse_word (const char *value, size_t *start, size_t len, string *rtn) - } - memcpy (copy.ptr, &value[*start], n); - copy.ptr[n] = '\0'; -- copy.size = n + 1; -+ copy.len = n + 1; - *start = i; - - /* Reserve enough space in the return buffer for the longest -@@ -1036,22 +1036,22 @@ parse_word (const char *value, size_t *start, size_t len, string *rtn) - - /* Parse the rest of {le|be}{16|32|64}: */ - if (strncmp (copy.ptr, "le16:", 5) == 0) { -- endian = little; rtn->size = 2; -+ endian = little; rtn->len = 2; - } - else if (strncmp (copy.ptr, "le32:", 5) == 0) { -- endian = little; rtn->size = 4; -+ endian = little; rtn->len = 4; - } - else if (strncmp (copy.ptr, "le64:", 5) == 0) { -- endian = little; rtn->size = 8; -+ endian = little; rtn->len = 8; - } - else if (strncmp (copy.ptr, "be16:", 5) == 0) { -- endian = big; rtn->size = 2; -+ endian = big; rtn->len = 2; - } - else if (strncmp (copy.ptr, "be32:", 5) == 0) { -- endian = big; rtn->size = 4; -+ endian = big; rtn->len = 4; - } - else if (strncmp (copy.ptr, "be64:", 5) == 0) { -- endian = big; rtn->size = 8; -+ endian = big; rtn->len = 8; - } - else { - nbdkit_error ("data parameter: expected \"le16/32/64:\" " -@@ -1060,7 +1060,7 @@ parse_word (const char *value, size_t *start, size_t len, string *rtn) - } - - /* Parse the word field into a host-order unsigned int. */ -- switch (rtn->size) { -+ switch (rtn->len) { - case 2: - if (nbdkit_parse_uint16_t ("data", ©.ptr[5], &u16) == -1) - return -1; -@@ -1081,7 +1081,7 @@ parse_word (const char *value, size_t *start, size_t len, string *rtn) - */ - switch (endian) { - case little: -- switch (rtn->size) { -+ switch (rtn->len) { - case 2: /* le16: */ - *((uint16_t *) rtn->ptr) = htole16 (u16); - break; -@@ -1096,7 +1096,7 @@ parse_word (const char *value, size_t *start, size_t len, string *rtn) - break; - - case big: -- switch (rtn->size) { -+ switch (rtn->len) { - case 2: /* be16: */ - *((uint16_t *) rtn->ptr) = htobe16 (u16); - break; -@@ -1134,7 +1134,7 @@ optimize_ast (node_id root, node_id *root_rtn) - /* For convenience this makes a new list node. */ - - /* Optimize each element of the list. */ -- for (i = 0; i < get_node (root).list.size; ++i) { -+ for (i = 0; i < get_node (root).list.len; ++i) { - id = get_node (root).list.ptr[i]; - if (optimize_ast (id, &id) == -1) - return -1; -@@ -1148,7 +1148,7 @@ optimize_ast (node_id root, node_id *root_rtn) - * because flattening the list changes the scope. - */ - if (list_safe_to_inline (get_node (id).list)) { -- for (j = 0; j < get_node (id).list.size; ++j) { -+ for (j = 0; j < get_node (id).list.len; ++j) { - if (node_ids_append (&list, get_node (id).list.ptr[j]) == -1) - goto list_append_error; - } -@@ -1165,7 +1165,7 @@ optimize_ast (node_id root, node_id *root_rtn) - } - - /* Combine adjacent pairs of elements if possible. */ -- for (i = 1; i < list.size; ++i) { -+ for (i = 1; i < list.len; ++i) { - node_id id0, id1; - - id0 = list.ptr[i-1]; -@@ -1178,7 +1178,7 @@ optimize_ast (node_id root, node_id *root_rtn) - } - - /* List of length 0 is replaced with null. */ -- if (list.size == 0) { -+ if (list.len == 0) { - free (list.ptr); - *root_rtn = new_node (expr (EXPR_NULL)); - return 0; -@@ -1187,7 +1187,7 @@ optimize_ast (node_id root, node_id *root_rtn) - /* List of length 1 is replaced with the first element, but as - * above avoid inlining if it is not a safe expression. - */ -- if (list.size == 1 && expr_safe_to_inline (get_node (list.ptr[0]))) { -+ if (list.len == 1 && expr_safe_to_inline (get_node (list.ptr[0]))) { - id = list.ptr[0]; - free (list.ptr); - *root_rtn = id; -@@ -1242,13 +1242,13 @@ optimize_ast (node_id root, node_id *root_rtn) - */ - if (get_node (id).t == EXPR_STRING && - get_node (root).r.n <= 4 && -- get_node (id).string.size <= 512) { -+ get_node (id).string.len <= 512) { - string s = empty_vector; - size_t n = get_node (root).r.n; - const string sub = get_node (id).string; - - for (i = 0; i < n; ++i) { -- for (j = 0; j < sub.size; ++j) { -+ for (j = 0; j < sub.len; ++j) { - if (string_append (&s, sub.ptr[j]) == -1) { - nbdkit_error ("realloc: %m"); - return -1; -@@ -1307,7 +1307,7 @@ optimize_ast (node_id root, node_id *root_rtn) - } - break; - case EXPR_STRING: /* substring */ -- len = get_node (id).string.size; -+ len = get_node (id).string.len; - if (m >= 0 && n <= m && m <= len) { - if (m-n == 1) - *root_rtn = new_node (expr (EXPR_BYTE, get_node (id).string.ptr[n])); -@@ -1355,23 +1355,23 @@ optimize_ast (node_id root, node_id *root_rtn) - - case EXPR_STRING: - /* A zero length string can be replaced with null. */ -- if (get_node (root).string.size == 0) { -+ if (get_node (root).string.len == 0) { - *root_rtn = new_node (expr (EXPR_NULL)); - return 0; - } - /* Strings containing the same character can be replaced by a - * fill. These can be produced by other optimizations. - */ -- if (get_node (root).string.size > 1) { -+ if (get_node (root).string.len > 1) { - const string s = get_node (root).string; - uint8_t b = s.ptr[0]; - -- for (i = 1; i < s.size; ++i) -+ for (i = 1; i < s.len; ++i) - if (s.ptr[i] != b) - break; - -- if (i == s.size) { -- *root_rtn = new_node (expr (EXPR_FILL, b, (uint64_t) s.size)); -+ if (i == s.len) { -+ *root_rtn = new_node (expr (EXPR_FILL, b, (uint64_t) s.len)); - return 0; - } - } -@@ -1442,7 +1442,7 @@ list_safe_to_inline (const node_ids list) - { - size_t i; - -- for (i = 0; i < list.size; ++i) { -+ for (i = 0; i < list.len; ++i) { - if (!expr_safe_to_inline (get_node (list.ptr[i]))) - return false; - } -@@ -1461,11 +1461,11 @@ expr_is_single_byte (const expr_t e, uint8_t *b) - if (b) *b = e.b; - return true; - case EXPR_LIST: /* A single element list if it is single byte */ -- if (e.list.size != 1) -+ if (e.list.len != 1) - return false; - return expr_is_single_byte (get_node (e.list.ptr[0]), b); - case EXPR_STRING: /* A length-1 string. */ -- if (e.string.size != 1) -+ if (e.string.len != 1) - return false; - if (b) *b = e.string.ptr[0]; - return true; -@@ -1511,10 +1511,10 @@ exprs_can_combine (expr_t e0, expr_t e1, node_id *id_rtn) - } - return true; - case EXPR_STRING: /* byte string => string */ -- len = e1.string.size; -+ len = e1.string.len; - if (string_reserve (&s, len+1) == -1) - goto out_of_memory; -- s.size = len+1; -+ s.len = len+1; - s.ptr[0] = e0.b; - memcpy (&s.ptr[1], e1.string.ptr, len); - *id_rtn = new_node (expr (EXPR_STRING, s)); -@@ -1533,20 +1533,20 @@ exprs_can_combine (expr_t e0, expr_t e1, node_id *id_rtn) - case EXPR_STRING: - switch (e1.t) { - case EXPR_BYTE: /* string byte => string */ -- len = e0.string.size; -+ len = e0.string.len; - if (string_reserve (&s, len+1) == -1) - goto out_of_memory; -- s.size = len+1; -+ s.len = len+1; - memcpy (s.ptr, e0.string.ptr, len); - s.ptr[len] = e1.b; - *id_rtn = new_node (expr (EXPR_STRING, s)); - return true; - case EXPR_STRING: /* string string => string */ -- len = e0.string.size; -- len1 = e1.string.size; -+ len = e0.string.len; -+ len1 = e1.string.len; - if (string_reserve (&s, len+len1) == -1) - goto out_of_memory; -- s.size = len+len1; -+ s.len = len+len1; - memcpy (s.ptr, e0.string.ptr, len); - memcpy (&s.ptr[len], e1.string.ptr, len1); - *id_rtn = new_node (expr (EXPR_STRING, s)); -@@ -1618,11 +1618,11 @@ evaluate (const dict_t *dict, node_id root, - list = get_node (root).list; - } - else { -- list.size = 1; -+ list.len = 1; - list.ptr = &root; - } - -- for (i = 0; i < list.size; ++i) { -+ for (i = 0; i < list.len; ++i) { - const expr_t e = get_node (list.ptr[i]); - - switch (e.t) { -@@ -1667,9 +1667,9 @@ evaluate (const dict_t *dict, node_id root, - - case EXPR_STRING: - /* Copy the string into the allocator. */ -- if (a->f->write (a, e.string.ptr, e.string.size, *offset) == -1) -+ if (a->f->write (a, e.string.ptr, e.string.len, *offset) == -1) - return -1; -- *offset += e.string.size; -+ *offset += e.string.len; - break; - - case EXPR_FILL: -diff --git a/plugins/eval/eval.c b/plugins/eval/eval.c -index fa1c23ff..b312a59c 100644 ---- a/plugins/eval/eval.c -+++ b/plugins/eval/eval.c -@@ -114,7 +114,7 @@ insert_method_script (const char *method, char *script) - size_t i; - struct method_script new_entry = { .method = method, .script = script }; - -- for (i = 0; i < method_scripts.size; ++i) { -+ for (i = 0; i < method_scripts.len; ++i) { - r = compare_script (method, &method_scripts.ptr[i]); - /* This shouldn't happen. insert_method_script() must not be - * called if the method has already been added. Call get_script() -diff --git a/plugins/floppy/directory-lfn.c b/plugins/floppy/directory-lfn.c -index a87d376a..fe47e0b6 100644 ---- a/plugins/floppy/directory-lfn.c -+++ b/plugins/floppy/directory-lfn.c -@@ -79,8 +79,8 @@ create_directory (size_t di, const char *label, - struct virtual_floppy *floppy) - { - size_t i; -- const size_t nr_subdirs = floppy->dirs.ptr[di].subdirs.size; -- const size_t nr_files = floppy->dirs.ptr[di].fileidxs.size; -+ const size_t nr_subdirs = floppy->dirs.ptr[di].subdirs.len; -+ const size_t nr_files = floppy->dirs.ptr[di].fileidxs.len; - struct lfn *lfns, *lfn; - const char *name; - uint8_t attributes; -@@ -109,14 +109,14 @@ create_directory (size_t di, const char *label, - } - for (i = 0; i < nr_subdirs; ++i) { - const size_t sdi = floppy->dirs.ptr[di].subdirs.ptr[i]; -- assert (sdi < floppy->dirs.size); -+ assert (sdi < floppy->dirs.len); - - name = floppy->dirs.ptr[sdi].name; - lfns[i].name = name; - } - for (i = 0; i < nr_files; ++i) { - const size_t fi = floppy->dirs.ptr[di].fileidxs.ptr[i]; -- assert (fi < floppy->files.size); -+ assert (fi < floppy->files.len); - - name = floppy->files.ptr[fi].name; - lfns[nr_subdirs+i].name = name; -@@ -132,7 +132,7 @@ create_directory (size_t di, const char *label, - file_size = 0; - for (i = 0; i < nr_subdirs; ++i) { - const size_t sdi = floppy->dirs.ptr[di].subdirs.ptr[i]; -- assert (sdi < floppy->dirs.size); -+ assert (sdi < floppy->dirs.len); - - lfn = &lfns[i]; - statbuf = &floppy->dirs.ptr[sdi].statbuf; -@@ -148,7 +148,7 @@ create_directory (size_t di, const char *label, - attributes = DIR_ENTRY_ARCHIVE; /* Same as set by Linux kernel. */ - for (i = 0; i < nr_files; ++i) { - const size_t fi = floppy->dirs.ptr[di].fileidxs.ptr[i]; -- assert (fi < floppy->files.size); -+ assert (fi < floppy->files.len); - - lfn = &lfns[nr_subdirs+i]; - statbuf = &floppy->files.ptr[fi].statbuf; -@@ -532,7 +532,7 @@ append_dir_table (size_t di, const struct dir_entry *entry, - { - size_t i; - -- i = floppy->dirs.ptr[di].table.size; -+ i = floppy->dirs.ptr[di].table.len; - if (dir_entries_append (&floppy->dirs.ptr[di].table, *entry) == -1) { - nbdkit_error ("realloc: %m"); - return -1; -@@ -550,8 +550,8 @@ int - update_directory_first_cluster (size_t di, struct virtual_floppy *floppy) - { - size_t i, j, pdi; -- const size_t nr_subdirs = floppy->dirs.ptr[di].subdirs.size; -- const size_t nr_files = floppy->dirs.ptr[di].fileidxs.size; -+ const size_t nr_subdirs = floppy->dirs.ptr[di].subdirs.len; -+ const size_t nr_files = floppy->dirs.ptr[di].fileidxs.len; - uint32_t first_cluster; - struct dir_entry *entry; - -@@ -561,7 +561,7 @@ update_directory_first_cluster (size_t di, struct virtual_floppy *floppy) - * table entries. - */ - i = 0; -- for (j = 0; j < floppy->dirs.ptr[di].table.size; ++j) { -+ for (j = 0; j < floppy->dirs.ptr[di].table.len; ++j) { - entry = &floppy->dirs.ptr[di].table.ptr[j]; - - /* Skip LFN entries. */ -@@ -596,12 +596,12 @@ update_directory_first_cluster (size_t di, struct virtual_floppy *floppy) - */ - if (i < nr_subdirs) { - const size_t sdi = floppy->dirs.ptr[di].subdirs.ptr[i]; -- assert (sdi < floppy->dirs.size); -+ assert (sdi < floppy->dirs.len); - first_cluster = floppy->dirs.ptr[sdi].first_cluster; - } - else if (i < nr_subdirs + nr_files) { - const size_t fi = floppy->dirs.ptr[di].fileidxs.ptr[i-nr_subdirs]; -- assert (fi < floppy->files.size); -+ assert (fi < floppy->files.len); - first_cluster = floppy->files.ptr[fi].first_cluster; - } - else -diff --git a/plugins/floppy/floppy.c b/plugins/floppy/floppy.c -index 80f350af..938f5bec 100644 ---- a/plugins/floppy/floppy.c -+++ b/plugins/floppy/floppy.c -@@ -172,7 +172,7 @@ floppy_pread (void *handle, void *buf, uint32_t count, uint64_t offset) - switch (region->type) { - case region_file: - i = region->u.i; -- assert (i < floppy.files.size); -+ assert (i < floppy.files.len); - host_path = floppy.files.ptr[i].host_path; - fd = open (host_path, O_RDONLY|O_CLOEXEC); - if (fd == -1) { -diff --git a/plugins/floppy/virtual-floppy.c b/plugins/floppy/virtual-floppy.c -index 6eae5600..b1546bd5 100644 ---- a/plugins/floppy/virtual-floppy.c -+++ b/plugins/floppy/virtual-floppy.c -@@ -97,10 +97,10 @@ create_virtual_floppy (const char *dir, const char *label, uint64_t size, - return -1; - - nbdkit_debug ("floppy: %zu directories and %zu files", -- floppy->dirs.size, floppy->files.size); -+ floppy->dirs.len, floppy->files.len); - - /* Create the on disk directory tables. */ -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - if (create_directory (i, label, floppy) == -1) - return -1; - } -@@ -115,10 +115,10 @@ create_virtual_floppy (const char *dir, const char *label, uint64_t size, - */ - data_used_size = 0; - cluster = 2; -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - floppy->dirs.ptr[i].first_cluster = cluster; - nr_bytes = -- ROUND_UP (floppy->dirs.ptr[i].table.size * sizeof (struct dir_entry), -+ ROUND_UP (floppy->dirs.ptr[i].table.len * sizeof (struct dir_entry), - CLUSTER_SIZE); - data_used_size += nr_bytes; - nr_clusters = nr_bytes / CLUSTER_SIZE; -@@ -127,7 +127,7 @@ create_virtual_floppy (const char *dir, const char *label, uint64_t size, - floppy->dirs.ptr[i].nr_clusters = nr_clusters; - cluster += nr_clusters; - } -- for (i = 0; i < floppy->files.size; ++i) { -+ for (i = 0; i < floppy->files.len; ++i) { - floppy->files.ptr[i].first_cluster = cluster; - nr_bytes = ROUND_UP (floppy->files.ptr[i].statbuf.st_size, CLUSTER_SIZE); - data_used_size += nr_bytes; -@@ -187,7 +187,7 @@ create_virtual_floppy (const char *dir, const char *label, uint64_t size, - * directory entries (which we didn't have available during - * create_directory above). - */ -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - if (update_directory_first_cluster (i, floppy) == -1) - return -1; - } -@@ -230,13 +230,13 @@ free_virtual_floppy (struct virtual_floppy *floppy) - - free (floppy->fat); - -- for (i = 0; i < floppy->files.size; ++i) { -+ for (i = 0; i < floppy->files.len; ++i) { - free (floppy->files.ptr[i].name); - free (floppy->files.ptr[i].host_path); - } - free (floppy->files.ptr); - -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - free (floppy->dirs.ptr[i].name); - free (floppy->dirs.ptr[i].subdirs.ptr); - free (floppy->dirs.ptr[i].fileidxs.ptr); -@@ -266,7 +266,7 @@ visit (const char *dir, struct virtual_floppy *floppy) - * directory will always be at dirs[0]. - */ - memset (&null_dir, 0, sizeof null_dir); -- di = floppy->dirs.size; -+ di = floppy->dirs.len; - if (dirs_append (&floppy->dirs, null_dir) == -1) { - nbdkit_error ("realloc: %m"); - goto error0; -@@ -423,7 +423,7 @@ visit_file (const char *dir, const char *name, - } - new_file.host_path = host_path; - new_file.statbuf = *statbuf; -- fi = floppy->files.size; -+ fi = floppy->files.len; - if (files_append (&floppy->files, new_file) == -1) { - nbdkit_error ("realloc: %m"); - free (host_path); -@@ -574,11 +574,11 @@ create_fat (struct virtual_floppy *floppy) - floppy->fat[0] = htole32 (0x0ffffff8); - floppy->fat[1] = htole32 (0x0fffffff); - -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - write_fat_file (floppy->dirs.ptr[i].first_cluster, - floppy->dirs.ptr[i].nr_clusters, floppy); - } -- for (i = 0; i < floppy->files.size; ++i) { -+ for (i = 0; i < floppy->files.len; ++i) { - write_fat_file (floppy->files.ptr[i].first_cluster, - floppy->files.ptr[i].nr_clusters, floppy); - } -@@ -676,15 +676,15 @@ create_regions (struct virtual_floppy *floppy) - /* Now we're into the data region. We add all directory tables - * first. - */ -- for (i = 0; i < floppy->dirs.size; ++i) { -+ for (i = 0; i < floppy->dirs.len; ++i) { - /* Directories can never be completely empty because of the volume - * label (root) or "." and ".." entries (non-root). - */ -- assert (floppy->dirs.ptr[i].table.size > 0); -+ assert (floppy->dirs.ptr[i].table.len > 0); - - if (append_region_len (&floppy->regions, - i == 0 ? "root directory" : floppy->dirs.ptr[i].name, -- floppy->dirs.ptr[i].table.size * -+ floppy->dirs.ptr[i].table.len * - sizeof (struct dir_entry), - 0, CLUSTER_SIZE, - region_data, -@@ -693,7 +693,7 @@ create_regions (struct virtual_floppy *floppy) - } - - /* Add all files. */ -- for (i = 0; i < floppy->files.size; ++i) { -+ for (i = 0; i < floppy->files.len; ++i) { - /* It's possible for a file to have zero size, in which case it - * doesn't occupy a region or cluster. - */ -diff --git a/plugins/iso/iso.c b/plugins/iso/iso.c -index cb621f41..e232175f 100644 ---- a/plugins/iso/iso.c -+++ b/plugins/iso/iso.c -@@ -105,7 +105,7 @@ make_iso (void) - fprintf (fp, " -quiet"); - if (params) - fprintf (fp, " %s", params); -- for (i = 0; i < dirs.size; ++i) { -+ for (i = 0; i < dirs.len; ++i) { - fputc (' ', fp); - shell_quote (dirs.ptr[i], fp); - } -@@ -169,7 +169,7 @@ iso_config (const char *key, const char *value) - static int - iso_config_complete (void) - { -- if (dirs.size == 0) { -+ if (dirs.len == 0) { - nbdkit_error ("you must supply the dir= parameter " - "after the plugin name on the command line"); - return -1; -diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c -index 488eadb2..ae595ea7 100644 ---- a/plugins/nbd/nbd.c -+++ b/plugins/nbd/nbd.c -@@ -244,7 +244,7 @@ static int - nbdplug_config_complete (void) - { - int c = !!sockname + !!hostname + !!uri + -- (command.size > 0) + (socket_fd >= 0) + !!raw_cid; -+ (command.len > 0) + (socket_fd >= 0) + !!raw_cid; - - /* Check the user passed exactly one connection parameter. */ - if (c > 1) { -@@ -303,7 +303,7 @@ nbdplug_config_complete (void) - return -1; - #endif - } -- else if (command.size > 0) { -+ else if (command.len > 0) { - /* Add NULL sentinel to the command. */ - if (string_vector_append (&command, NULL) == -1) { - nbdkit_error ("realloc: %m"); -@@ -574,7 +574,7 @@ nbdplug_connect (struct nbd_handle *nbd) - #else - return nbd_connect_vsock (nbd, cid, vport); - #endif -- else if (command.size > 0) -+ else if (command.len > 0) - return nbd_connect_systemd_socket_activation (nbd, (char **) command.ptr); - else if (socket_fd >= 0) - return nbd_connect_socket (nbd, socket_fd); -diff --git a/plugins/partitioning/partition-mbr.c b/plugins/partitioning/partition-mbr.c -index 9a1a043c..1f178dcb 100644 ---- a/plugins/partitioning/partition-mbr.c -+++ b/plugins/partitioning/partition-mbr.c -@@ -62,9 +62,9 @@ create_mbr_layout (void) - primary[0x1fe] = 0x55; - primary[0x1ff] = 0xaa; - -- if (the_files.size <= 4) { -+ if (the_files.len <= 4) { - /* Basic MBR with no extended partition. */ -- for (i = 0; i < the_files.size; ++i) { -+ for (i = 0; i < the_files.len; ++i) { - const struct region *region = find_file_region (i, &j); - - create_mbr_partition_table_entry (region, i == 0, the_files.ptr[i].mbr_id, -@@ -97,7 +97,7 @@ create_mbr_layout (void) - /* The remaining files are mapped to logical partitions living in - * the fourth extended partition. - */ -- for (i = 3; i < the_files.size; ++i) { -+ for (i = 3; i < the_files.len; ++i) { - if (i == 3) - eptr = eptr0; - else -@@ -117,7 +117,7 @@ create_mbr_layout (void) - create_mbr_partition_table_entry (®ion, false, the_files.ptr[i].mbr_id, - &ebr[i-3][0x1be]); - -- if (i < the_files.size-1) { -+ if (i < the_files.len-1) { - size_t j2 = j; - const struct region *enext = find_ebr_region (i+1, &j2); - const struct region *rnext = find_file_region (i+1, &j2); -diff --git a/plugins/partitioning/partitioning.c b/plugins/partitioning/partitioning.c -index 231b2d77..2301ba4e 100644 ---- a/plugins/partitioning/partitioning.c -+++ b/plugins/partitioning/partitioning.c -@@ -104,7 +104,7 @@ partitioning_unload (void) - { - size_t i; - -- for (i = 0; i < the_files.size; ++i) -+ for (i = 0; i < the_files.len; ++i) - close (the_files.ptr[i].fd); - free (the_files.ptr); - -@@ -116,7 +116,7 @@ partitioning_unload (void) - free (primary); - free (secondary); - if (ebr) { -- for (i = 0; i < the_files.size-3; ++i) -+ for (i = 0; i < the_files.len-3; ++i) - free (ebr[i]); - free (ebr); - } -@@ -235,19 +235,19 @@ partitioning_config_complete (void) - bool needs_gpt; - - /* Not enough / too many files? */ -- if (the_files.size == 0) { -+ if (the_files.len == 0) { - nbdkit_error ("at least one file= parameter must be supplied"); - return -1; - } - - total_size = 0; -- for (i = 0; i < the_files.size; ++i) -+ for (i = 0; i < the_files.len; ++i) - total_size += the_files.ptr[i].statbuf.st_size; - needs_gpt = total_size > MAX_MBR_DISK_SIZE; - - /* Choose default parttype if not set. */ - if (parttype == PARTTYPE_UNSET) { -- if (needs_gpt || the_files.size > 4) { -+ if (needs_gpt || the_files.len > 4) { - parttype = PARTTYPE_GPT; - nbdkit_debug ("picking partition type GPT"); - } -@@ -262,7 +262,7 @@ partitioning_config_complete (void) - "but you requested %zu partition(s) " - "and a total size of %" PRIu64 " bytes (> %" PRIu64 "). " - "Try using: partition-type=gpt", -- the_files.size, total_size, (uint64_t) MAX_MBR_DISK_SIZE); -+ the_files.len, total_size, (uint64_t) MAX_MBR_DISK_SIZE); - return -1; - } - -@@ -327,7 +327,7 @@ partitioning_pread (void *handle, void *buf, uint32_t count, uint64_t offset) - switch (region->type) { - case region_file: - i = region->u.i; -- assert (i < the_files.size); -+ assert (i < the_files.len); - r = pread (the_files.ptr[i].fd, buf, len, offset - region->start); - if (r == -1) { - nbdkit_error ("pread: %s: %m", the_files.ptr[i].filename); -@@ -376,7 +376,7 @@ partitioning_pwrite (void *handle, - switch (region->type) { - case region_file: - i = region->u.i; -- assert (i < the_files.size); -+ assert (i < the_files.len); - r = pwrite (the_files.ptr[i].fd, buf, len, offset - region->start); - if (r == -1) { - nbdkit_error ("pwrite: %s: %m", the_files.ptr[i].filename); -@@ -418,7 +418,7 @@ partitioning_flush (void *handle) - { - size_t i; - -- for (i = 0; i < the_files.size; ++i) { -+ for (i = 0; i < the_files.len; ++i) { - if (fdatasync (the_files.ptr[i].fd) == -1) { - nbdkit_error ("fdatasync: %m"); - return -1; -diff --git a/plugins/partitioning/virtual-disk.c b/plugins/partitioning/virtual-disk.c -index 389a17b6..d46ca46a 100644 ---- a/plugins/partitioning/virtual-disk.c -+++ b/plugins/partitioning/virtual-disk.c -@@ -56,7 +56,7 @@ create_virtual_disk_layout (void) - size_t i; - - assert (nr_regions (&the_regions) == 0); -- assert (the_files.size > 0); -+ assert (the_files.len > 0); - assert (primary == NULL); - assert (secondary == NULL); - -@@ -68,17 +68,17 @@ create_virtual_disk_layout (void) - return -1; - } - -- if (the_files.size > 4) { -+ if (the_files.len > 4) { - /* The first 3 primary partitions will be real partitions, the - * 4th will be an extended partition, and so we need to store - * EBRs for the_files.size-3 logical partitions. - */ -- ebr = malloc (sizeof (unsigned char *) * (the_files.size-3)); -+ ebr = malloc (sizeof (unsigned char *) * (the_files.len-3)); - if (ebr == NULL) { - nbdkit_error ("malloc: %m"); - return -1; - } -- for (i = 0; i < the_files.size-3; ++i) { -+ for (i = 0; i < the_files.len-3; ++i) { - ebr[i] = calloc (1, SECTOR_SIZE); - if (ebr[i] == NULL) { - nbdkit_error ("malloc: %m"); -@@ -117,7 +117,7 @@ create_virtual_disk_layout (void) - } - - /* The partitions. */ -- for (i = 0; i < the_files.size; ++i) { -+ for (i = 0; i < the_files.len; ++i) { - uint64_t offset; - - offset = virtual_size (&the_regions); -@@ -127,7 +127,7 @@ create_virtual_disk_layout (void) - assert (IS_ALIGNED (offset, SECTOR_SIZE)); - - /* Logical partitions are preceeded by an EBR. */ -- if (parttype == PARTTYPE_MBR && the_files.size > 4 && i >= 3) { -+ if (parttype == PARTTYPE_MBR && the_files.len > 4 && i >= 3) { - if (append_region_len (&the_regions, "EBR", - SECTOR_SIZE, 0, 0, - region_data, ebr[i-3]) == -1) -diff --git a/plugins/partitioning/virtual-disk.h b/plugins/partitioning/virtual-disk.h -index 7032dfc8..d56c2b86 100644 ---- a/plugins/partitioning/virtual-disk.h -+++ b/plugins/partitioning/virtual-disk.h -@@ -55,7 +55,7 @@ - * 32 if the number of files is <= GPT_MIN_PARTITIONS, which is the - * normal case. - */ --#define GPT_PTA_SIZE ROUND_UP (the_files.size, GPT_MIN_PARTITIONS) -+#define GPT_PTA_SIZE ROUND_UP (the_files.len, GPT_MIN_PARTITIONS) - #define GPT_PTA_LBAs (GPT_PTA_SIZE * GPT_PT_ENTRY_SIZE / SECTOR_SIZE) - - /* Maximum possible and default alignment between partitions. */ -diff --git a/plugins/split/split.c b/plugins/split/split.c -index c559a0cd..4c9790a6 100644 ---- a/plugins/split/split.c -+++ b/plugins/split/split.c -@@ -121,13 +121,13 @@ split_open (int readonly) - return NULL; - } - -- h->files = malloc (filenames.size * sizeof (struct file)); -+ h->files = malloc (filenames.len * sizeof (struct file)); - if (h->files == NULL) { - nbdkit_error ("malloc: %m"); - free (h); - return NULL; - } -- for (i = 0; i < filenames.size; ++i) -+ for (i = 0; i < filenames.len; ++i) - h->files[i].fd = -1; - - /* Open the files. */ -@@ -137,7 +137,7 @@ split_open (int readonly) - else - flags |= O_RDWR; - -- for (i = 0; i < filenames.size; ++i) { -+ for (i = 0; i < filenames.len; ++i) { - h->files[i].fd = open (filenames.ptr[i], flags); - if (h->files[i].fd == -1) { - nbdkit_error ("open: %s: %m", filenames.ptr[i]); -@@ -146,7 +146,7 @@ split_open (int readonly) - } - - offset = 0; -- for (i = 0; i < filenames.size; ++i) { -+ for (i = 0; i < filenames.len; ++i) { - h->files[i].offset = offset; - - if (fstat (h->files[i].fd, &statbuf) == -1) { -@@ -179,7 +179,7 @@ split_open (int readonly) - return h; - - err: -- for (i = 0; i < filenames.size; ++i) { -+ for (i = 0; i < filenames.len; ++i) { - if (h->files[i].fd >= 0) - close (h->files[i].fd); - } -@@ -195,7 +195,7 @@ split_close (void *handle) - struct handle *h = handle; - size_t i; - -- for (i = 0; i < filenames.size; ++i) -+ for (i = 0; i < filenames.len; ++i) - close (h->files[i].fd); - free (h->files); - free (h); -@@ -242,7 +242,7 @@ static struct file * - get_file (struct handle *h, uint64_t offset) - { - return bsearch (&offset, h->files, -- filenames.size, sizeof (struct file), -+ filenames.len, sizeof (struct file), - compare_offset); - } - -diff --git a/plugins/ssh/ssh.c b/plugins/ssh/ssh.c -index 535caf1a..80623525 100644 ---- a/plugins/ssh/ssh.c -+++ b/plugins/ssh/ssh.c -@@ -397,7 +397,7 @@ ssh_open (int readonly) - * as this file is rarely present. - */ - } -- for (i = 0; i < identities.size; ++i) { -+ for (i = 0; i < identities.len; ++i) { - r = ssh_options_set (h->session, - SSH_OPTIONS_ADD_IDENTITY, identities.ptr[i]); - if (r != SSH_OK) { -diff --git a/plugins/vddk/reexec.c b/plugins/vddk/reexec.c -index 9e87025e..4eae2221 100644 ---- a/plugins/vddk/reexec.c -+++ b/plugins/vddk/reexec.c -@@ -116,20 +116,20 @@ perform_reexec (const char *env, const char *prepend) - nbdkit_error ("realloc: %m"); - exit (EXIT_FAILURE); - } -- r = read (fd, buf.ptr + buf.size, buf.cap - buf.size); -+ r = read (fd, buf.ptr + buf.len, buf.cap - buf.len); - if (r == -1) { - nbdkit_error ("read: %s: %m", cmdline_file); - exit (EXIT_FAILURE); - } - if (r == 0) - break; -- buf.size += r; -+ buf.len += r; - } - close (fd); -- nbdkit_debug ("original command line occupies %zu bytes", buf.size); -+ nbdkit_debug ("original command line occupies %zu bytes", buf.len); - - /* Split cmdline into argv, then append one more arg. */ -- for (len = 0; len < buf.size; len += strlen (buf.ptr + len) + 1) { -+ for (len = 0; len < buf.len; len += strlen (buf.ptr + len) + 1) { - char *arg = buf.ptr + len; /* Next \0-terminated argument. */ - - /* See below for why we eat password parameter(s). */ -diff --git a/plugins/vddk/stats.c b/plugins/vddk/stats.c -index 76e0c244..bb5401b1 100644 ---- a/plugins/vddk/stats.c -+++ b/plugins/vddk/stats.c -@@ -94,12 +94,12 @@ display_stats (void) - #undef STUB - #undef OPTIONAL_STUB - -- qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); -+ qsort (stats.ptr, stats.len, sizeof stats.ptr[0], stat_compare); - - nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); - nbdkit_debug ("%-24s %15s %5s %15s", - "VixDiskLib_...", "µs", "calls", "bytes"); -- for (i = 0; i < stats.size; ++i) { -+ for (i = 0; i < stats.len; ++i) { - if (stats.ptr[i].usecs) { - if (stats.ptr[i].bytes > 0) - nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, -diff --git a/plugins/vddk/worker.c b/plugins/vddk/worker.c -index 2a1d4f26..c6e2fd22 100644 ---- a/plugins/vddk/worker.c -+++ b/plugins/vddk/worker.c -@@ -82,7 +82,7 @@ send_command_and_wait (struct vddk_handle *h, struct command *cmd) - return -1; - - /* Signal the caller if it could be sleeping on an empty queue. */ -- if (h->commands.size == 1) -+ if (h->commands.len == 1) - pthread_cond_signal (&h->commands_cond); - - /* This will be used to signal command completion back to us. */ -@@ -497,7 +497,7 @@ 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.size == 0) -+ 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); -diff --git a/server/exports.c b/server/exports.c -index 7ce1eda9..12c8a879 100644 ---- a/server/exports.c -+++ b/server/exports.c -@@ -90,13 +90,13 @@ nbdkit_exports_free (struct nbdkit_exports *exps) - NBDKIT_DLL_PUBLIC size_t - nbdkit_exports_count (const struct nbdkit_exports *exps) - { -- return exps->exports.size; -+ return exps->exports.len; - } - - NBDKIT_DLL_PUBLIC const struct nbdkit_export - nbdkit_get_export (const struct nbdkit_exports *exps, size_t i) - { -- assert (i < exps->exports.size); -+ assert (i < exps->exports.len); - return exps->exports.ptr[i]; - } - -@@ -106,7 +106,7 @@ nbdkit_add_export (struct nbdkit_exports *exps, - { - struct nbdkit_export e = { NULL, NULL }; - -- if (exps->exports.size == MAX_EXPORTS) { -+ if (exps->exports.len == MAX_EXPORTS) { - nbdkit_error ("nbdkit_add_export: too many exports"); - errno = EINVAL; - return -1; -diff --git a/server/extents.c b/server/extents.c -index 8da82cf1..e180e313 100644 ---- a/server/extents.c -+++ b/server/extents.c -@@ -117,13 +117,13 @@ nbdkit_extents_free (struct nbdkit_extents *exts) - NBDKIT_DLL_PUBLIC size_t - nbdkit_extents_count (const struct nbdkit_extents *exts) - { -- return exts->extents.size; -+ return exts->extents.len; - } - - NBDKIT_DLL_PUBLIC struct nbdkit_extent - nbdkit_get_extent (const struct nbdkit_extents *exts, size_t i) - { -- assert (i < exts->extents.size); -+ assert (i < exts->extents.len); - return exts->extents.ptr[i]; - } - -@@ -160,7 +160,7 @@ nbdkit_add_extent (struct nbdkit_extents *exts, - return 0; - - /* Ignore extents beyond the end of the range, or if list is full. */ -- if (offset >= exts->end || exts->extents.size >= MAX_EXTENTS) -+ if (offset >= exts->end || exts->extents.len >= MAX_EXTENTS) - return 0; - - /* Shorten extents that overlap the end of the range. */ -@@ -169,7 +169,7 @@ nbdkit_add_extent (struct nbdkit_extents *exts, - length -= overlap; - } - -- if (exts->extents.size == 0) { -+ if (exts->extents.len == 0) { - /* If there are no existing extents, and the new extent is - * entirely before start, ignore it. - */ -@@ -196,10 +196,10 @@ nbdkit_add_extent (struct nbdkit_extents *exts, - } - - /* If we get here we are going to either add or extend. */ -- if (exts->extents.size > 0 && -- exts->extents.ptr[exts->extents.size-1].type == type) { -+ if (exts->extents.len > 0 && -+ exts->extents.ptr[exts->extents.len-1].type == type) { - /* Coalesce with the last extent. */ -- exts->extents.ptr[exts->extents.size-1].length += length; -+ exts->extents.ptr[exts->extents.len-1].length += length; - return 0; - } - else { -@@ -226,13 +226,13 @@ nbdkit_extents_aligned (struct context *next_c, - /* Perform an initial query, then scan for the first unaligned extent. */ - if (next->extents (next_c, count, offset, flags, exts, err) == -1) - return -1; -- for (i = 0; i < exts->extents.size; ++i) { -+ for (i = 0; i < exts->extents.len; ++i) { - e = &exts->extents.ptr[i]; - if (!IS_ALIGNED(e->length, align)) { - /* If the unalignment is past align, just truncate and return early */ - if (e->offset + e->length > offset + align) { - e->length = ROUND_DOWN (e->length, align); -- exts->extents.size = i + !!e->length; -+ exts->extents.len = i + !!e->length; - exts->next = e->offset + e->length; - break; - } -@@ -249,7 +249,7 @@ nbdkit_extents_aligned (struct context *next_c, - */ - assert (i == 0); - while (e->length < align) { -- if (exts->extents.size > 1) { -+ if (exts->extents.len > 1) { - e->length += exts->extents.ptr[1].length; - e->type &= exts->extents.ptr[1].type; - extents_remove (&exts->extents, 1); -@@ -284,7 +284,7 @@ nbdkit_extents_aligned (struct context *next_c, - } - } - e->length = align; -- exts->extents.size = 1; -+ exts->extents.len = 1; - exts->next = e->offset + e->length; - break; - } -diff --git a/server/main.c b/server/main.c -index 5fd8308f..225258de 100644 ---- a/server/main.c -+++ b/server/main.c -@@ -940,7 +940,7 @@ start_serving (void) - r = sockets_append (&socks, s); - assert (r == 0); - } -- debug ("using socket activation, nr_socks = %zu", socks.size); -+ debug ("using socket activation, nr_socks = %zu", socks.len); - change_user (); - write_pidfile (); - top->after_fork (top); -diff --git a/server/sockets.c b/server/sockets.c -index 18b68f0a..15a26f69 100644 ---- a/server/sockets.c -+++ b/server/sockets.c -@@ -246,14 +246,14 @@ bind_tcpip_socket (sockets *socks) - - freeaddrinfo (ai); - -- if (socks->size == 0 && addr_in_use) { -+ if (socks->len == 0 && addr_in_use) { - fprintf (stderr, "%s: unable to bind to any sockets: %s\n", - program_name, strerror (EADDRINUSE)); - exit (EXIT_FAILURE); - } - - debug ("bound to IP address %s:%s (%zu socket(s))", -- ipaddr ? ipaddr : "", port, socks->size); -+ ipaddr ? ipaddr : "", port, socks->len); - } - - void -@@ -443,7 +443,7 @@ accept_connection (int listen_sock) - static void - check_sockets_and_quit_fd (const sockets *socks) - { -- const size_t nr_socks = socks->size; -+ const size_t nr_socks = socks->len; - size_t i; - int r; - -@@ -552,7 +552,7 @@ accept_incoming_connections (const sockets *socks) - } - pthread_mutex_unlock (&count_mutex); - -- for (i = 0; i < socks->size; ++i) -+ for (i = 0; i < socks->len; ++i) - closesocket (socks->ptr[i]); - free (socks->ptr); - } -diff --git a/wrapper.c b/wrapper.c -index 3bab2074..87e5a033 100644 ---- a/wrapper.c -+++ b/wrapper.c -@@ -130,9 +130,9 @@ print_command (void) - { - size_t i; - -- if (cmd.size > 0) -+ if (cmd.len > 0) - shell_quote (cmd.ptr[0], stderr); -- for (i = 1; i < cmd.size && cmd.ptr[i] != NULL; ++i) { -+ for (i = 1; i < cmd.len && cmd.ptr[i] != NULL; ++i) { - fputc (' ', stderr); - shell_quote (cmd.ptr[i], stderr); - } --- -2.31.1 - diff --git a/0023-podwrapper.pl.in-Use-short-commit-date.patch b/0023-podwrapper.pl.in-Use-short-commit-date.patch deleted file mode 100644 index dd289ac..0000000 --- a/0023-podwrapper.pl.in-Use-short-commit-date.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2df98ef35c3b023a44983583f65379793599e57f Mon Sep 17 00:00:00 2001 -From: Nir Soffer -Date: Mon, 8 Nov 2021 19:47:57 +0200 -Subject: [PATCH] podwrapper.pl.in: Use short commit date - -We can use git short commit date format $cs. Maybe it was not available -when podwrapper.pl was created. - -Signed-off-by: Nir Soffer -(cherry picked from libnbd commit 0306fdcb08e8dc5957a9e344b54200711fca1220) -(cherry picked from commit 7a1e79c6b5ca4adcef47fc0929d25d54610fc417) ---- - podwrapper.pl.in | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/podwrapper.pl.in b/podwrapper.pl.in -index abad578d..63c1025a 100755 ---- a/podwrapper.pl.in -+++ b/podwrapper.pl.in -@@ -233,8 +233,7 @@ my $date; - my $filename = "$abs_top_srcdir/.git"; - if (!$date && -d $filename) { - local $ENV{GIT_DIR} = $filename; -- $_ = `git show -O/dev/null -s --format=%ci`; -- $date = $1 if /^(\d+-\d+-\d+)\s/; -+ $date = `git show -O/dev/null -s --format=%cs`; - } - if (!$date) { - my ($day, $month, $year) = (gmtime($ENV{SOURCE_DATE_EPOCH} || time))[3,4,5]; --- -2.31.1 - diff --git a/0024-ocaml-Replace-noalloc-with-noalloc-annotation.patch b/0024-ocaml-Replace-noalloc-with-noalloc-annotation.patch deleted file mode 100644 index 4c16d66..0000000 --- a/0024-ocaml-Replace-noalloc-with-noalloc-annotation.patch +++ /dev/null @@ -1,89 +0,0 @@ -From e9f77e9da946c963e4ec5d82dfd144305f79ebb5 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 9 Nov 2021 09:07:42 +0000 -Subject: [PATCH] ocaml: Replace "noalloc" with [@@noalloc] annotation - -This requires OCaml >= 4.03 (released April 2016). The previous -minimum version was 4.02.2. - -(cherry picked from commit d15dd73845065cc9ca04aa785e2be994f76bf832) ---- - README | 2 +- - plugins/ocaml/NBDKit.ml | 16 ++++++++-------- - plugins/ocaml/nbdkit-ocaml-plugin.pod | 5 +---- - 3 files changed, 10 insertions(+), 13 deletions(-) - -diff --git a/README b/README -index b001620c..160856b6 100644 ---- a/README -+++ b/README -@@ -155,7 +155,7 @@ For the Python plugin: - - For the OCaml plugin: - -- - OCaml >= 4.02.2 -+ - OCaml >= 4.03 - - For the Tcl plugin: - -diff --git a/plugins/ocaml/NBDKit.ml b/plugins/ocaml/NBDKit.ml -index 75823ba5..4d45cc0c 100644 ---- a/plugins/ocaml/NBDKit.ml -+++ b/plugins/ocaml/NBDKit.ml -@@ -152,11 +152,11 @@ let default_callbacks = { - export_description = None; - } - --external set_name : string -> unit = "ocaml_nbdkit_set_name" "noalloc" --external set_longname : string -> unit = "ocaml_nbdkit_set_longname" "noalloc" --external set_version : string -> unit = "ocaml_nbdkit_set_version" "noalloc" --external set_description : string -> unit = "ocaml_nbdkit_set_description" "noalloc" --external set_config_help : string -> unit = "ocaml_nbdkit_set_config_help" "noalloc" -+external set_name : string -> unit = "ocaml_nbdkit_set_name" [@@noalloc] -+external set_longname : string -> unit = "ocaml_nbdkit_set_longname" [@@noalloc] -+external set_version : string -> unit = "ocaml_nbdkit_set_version" [@@noalloc] -+external set_description : string -> unit = "ocaml_nbdkit_set_description" [@@noalloc] -+external set_config_help : string -> unit = "ocaml_nbdkit_set_config_help" [@@noalloc] - - external set_field : string -> 'a -> unit = "ocaml_nbdkit_set_field" - -@@ -220,7 +220,7 @@ let register_plugin plugin = - - (* Bindings to nbdkit server functions. *) - --external _set_error : int -> unit = "ocaml_nbdkit_set_error" "noalloc" -+external _set_error : int -> unit = "ocaml_nbdkit_set_error" [@@noalloc] - - let set_error unix_error = - (* There's an awkward triple translation going on here, because -@@ -250,9 +250,9 @@ external read_password : string -> string = "ocaml_nbdkit_read_password" - external realpath : string -> string = "ocaml_nbdkit_realpath" - external nanosleep : int -> int -> unit = "ocaml_nbdkit_nanosleep" - external export_name : unit -> string = "ocaml_nbdkit_export_name" --external shutdown : unit -> unit = "ocaml_nbdkit_shutdown" "noalloc" -+external shutdown : unit -> unit = "ocaml_nbdkit_shutdown" [@@noalloc] - --external _debug : string -> unit = "ocaml_nbdkit_debug" "noalloc" -+external _debug : string -> unit = "ocaml_nbdkit_debug" [@@noalloc] - - let debug fs = - ksprintf _debug fs -diff --git a/plugins/ocaml/nbdkit-ocaml-plugin.pod b/plugins/ocaml/nbdkit-ocaml-plugin.pod -index 2bd0af25..293f8143 100644 ---- a/plugins/ocaml/nbdkit-ocaml-plugin.pod -+++ b/plugins/ocaml/nbdkit-ocaml-plugin.pod -@@ -11,10 +11,7 @@ nbdkit-ocaml-plugin - writing nbdkit plugins in OCaml - =head1 DESCRIPTION - - This manual page describes how to write nbdkit plugins in natively --compiled OCaml code. -- --Note this requires OCaml E 4.02.2, which has support for shared --libraries. See L -+compiled OCaml code. This requires OCaml E 4.03. - - =head1 WRITING AN OCAML NBDKIT PLUGIN - --- -2.31.1 - diff --git a/0025-vddk-Drop-obsolete-documentation-related-to-thread-m.patch b/0025-vddk-Drop-obsolete-documentation-related-to-thread-m.patch deleted file mode 100644 index 1abb6bb..0000000 --- a/0025-vddk-Drop-obsolete-documentation-related-to-thread-m.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5da14da22c1e26aff24baf41fb2ae0f2832acae1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 27 Nov 2021 16:44:41 +0000 -Subject: [PATCH] vddk: Drop obsolete documentation related to thread model - -Since commit 1eecf15fc3 ("vddk: Implement parallel thread model") we -have implemented a parallel thread model in this plugin, and thread -handling is believed to be safe and in conformity with the VDDK -documentation. Remove obsolete documentation contradicting this. - -Reported-by: Ming Xie -Fixes: commit 1eecf15fc3d8ea253ccec4f5883fdbb9aa6f8c2b -(cherry picked from commit 370ecb711c23f9143c933e13468e11d688d0d651) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index ce82a734..acec0bd2 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -452,14 +452,6 @@ sector boundaries. This is because the VDDK Read and Write APIs only - take sector numbers. If your client needs finer granularity, you can - use L with the setting C. - --=head2 Threads -- --Handling threads in the VDDK API is complex and does not map well to --any of the thread models offered by nbdkit (see --L). The plugin uses the nbdkit --C model, but technically even this is not --completely safe. This is a subject of future work. -- - =head2 Out of memory errors - - In the verbose log you may see errors like: --- -2.31.1 - diff --git a/0026-Revert-podwrapper.pl.in-Use-short-commit-date.patch b/0026-Revert-podwrapper.pl.in-Use-short-commit-date.patch deleted file mode 100644 index 16add6c..0000000 --- a/0026-Revert-podwrapper.pl.in-Use-short-commit-date.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b986f25be4f013eb02cd327826fa225c8202571e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 20 Nov 2021 17:50:25 +0000 -Subject: [PATCH] Revert "podwrapper.pl.in: Use short commit date" - -This commit breaks man page output because there is an extra newline -after the date which wasn't being removed. - -This reverts commit 7a1e79c6b5ca4adcef47fc0929d25d54610fc417. - -(cherry picked from commit 750ad5972bb082d188f17f8f71ef1ec0c616c676) ---- - podwrapper.pl.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/podwrapper.pl.in b/podwrapper.pl.in -index 63c1025a..abad578d 100755 ---- a/podwrapper.pl.in -+++ b/podwrapper.pl.in -@@ -233,7 +233,8 @@ my $date; - my $filename = "$abs_top_srcdir/.git"; - if (!$date && -d $filename) { - local $ENV{GIT_DIR} = $filename; -- $date = `git show -O/dev/null -s --format=%cs`; -+ $_ = `git show -O/dev/null -s --format=%ci`; -+ $date = $1 if /^(\d+-\d+-\d+)\s/; - } - if (!$date) { - my ($day, $month, $year) = (gmtime($ENV{SOURCE_DATE_EPOCH} || time))[3,4,5]; --- -2.31.1 - diff --git a/0027-Fix-podwrapper.pl.in-Use-short-commit-date.patch b/0027-Fix-podwrapper.pl.in-Use-short-commit-date.patch deleted file mode 100644 index 1077ed4..0000000 --- a/0027-Fix-podwrapper.pl.in-Use-short-commit-date.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0c430f02eec2671155c001c8a1d2f964b42022e5 Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Tue, 30 Nov 2021 12:42:01 -0600 -Subject: [PATCH] Fix "podwrapper.pl.in: Use short commit date" - -This reverts commit 750ad5972bb082d188f17f8f71ef1ec0c616c676, then -fixes the broken newline as suggested in the thread at -https://listman.redhat.com/archives/libguestfs/2021-November/msg00275.html. - -(cherry picked from commit 80036dbb0b8f9e0aab5994d80de6321c2a55c669) ---- - podwrapper.pl.in | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/podwrapper.pl.in b/podwrapper.pl.in -index abad578d..6f256ba8 100755 ---- a/podwrapper.pl.in -+++ b/podwrapper.pl.in -@@ -233,8 +233,7 @@ my $date; - my $filename = "$abs_top_srcdir/.git"; - if (!$date && -d $filename) { - local $ENV{GIT_DIR} = $filename; -- $_ = `git show -O/dev/null -s --format=%ci`; -- $date = $1 if /^(\d+-\d+-\d+)\s/; -+ $date = `git show -O/dev/null -s --format=format:%cs`; - } - if (!$date) { - my ($day, $month, $year) = (gmtime($ENV{SOURCE_DATE_EPOCH} || time))[3,4,5]; --- -2.31.1 - diff --git a/0028-scripts-Add-simple-script-for-automating-VDDK-disk-c.patch b/0028-scripts-Add-simple-script-for-automating-VDDK-disk-c.patch deleted file mode 100644 index c0e1b09..0000000 --- a/0028-scripts-Add-simple-script-for-automating-VDDK-disk-c.patch +++ /dev/null @@ -1,154 +0,0 @@ -From e00a8f2709fdf238daa195da03d8ea2aec9b05e1 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 30 Nov 2021 17:56:02 +0000 -Subject: [PATCH] scripts: Add simple script for automating VDDK disk - connections - -It's tedious to work out how to do this by hand every time. Include a -developer script to make connecting to a guest disk easy. - -(cherry picked from commit 44ee90ee01677032a14d5b71118b7af0651db3d5) ---- - .gitignore | 1 + - Makefile.am | 2 +- - configure.ac | 2 + - scripts/vddk-open.sh.in | 89 +++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 93 insertions(+), 1 deletion(-) - create mode 100755 scripts/vddk-open.sh.in - -diff --git a/.gitignore b/.gitignore -index 847b72dd..6565600f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -89,6 +89,7 @@ plugins/*/*.3 - /plugins/S3/nbdkit-S3-plugin - /plugins/tmpdisk/default-command.c - /podwrapper.pl -+/scripts/vddk-open.sh - /server/libnbdkit.a - /server/local/nbdkit.pc - /server/nbdkit -diff --git a/Makefile.am b/Makefile.am -index 49f5d91c..6df5eba0 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -46,7 +46,7 @@ EXTRA_DIST = \ - SECURITY \ - $(NULL) - --CLEANFILES += html/*.html -+CLEANFILES += html/*.html scripts/*~ - - if !ENABLE_LIBFUZZER - # NB: This is not the real nbdkit binary. It's a wrapper that allows -diff --git a/configure.ac b/configure.ac -index 1b737fc1..08c307e9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1249,6 +1249,8 @@ dnl Produce output files. - AC_CONFIG_HEADERS([config.h]) - AC_CONFIG_FILES([podwrapper.pl], - [chmod +x,-w podwrapper.pl]) -+AC_CONFIG_FILES([scripts/vddk-open.sh], -+ [chmod +x,-w scripts/vddk-open.sh]) - AC_CONFIG_FILES([common/protocol/generate-protostrings.sh], - [chmod +x,-w common/protocol/generate-protostrings.sh]) - AC_CONFIG_FILES([Makefile -diff --git a/scripts/vddk-open.sh.in b/scripts/vddk-open.sh.in -new file mode 100755 -index 00000000..218bc93c ---- /dev/null -+++ b/scripts/vddk-open.sh.in -@@ -0,0 +1,89 @@ -+#!/bin/bash - -+# @configure_input@ -+# Copyright (C) 2013-2021 Red Hat Inc. -+# -+# 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. -+ -+# Open an nbdkit-vddk-plugin connection to the first disk of a guest -+# on a VMware ESXi server. This script automates the tedious bits of -+# getting the disk name, moref, etc. However please read the -+# nbdkit-vddk-plugin documentation as well. -+# -+# Usage: -+# scripts/vddk-open.sh SERVER GUEST -r -f -v libdir=/path/to/vmware-vix-disklib-distrib [...] -+# -+# where SERVER is the hostname or IP address of the ESXi server and -+# GUEST is the name of the guest. -+# -+# These two required parameters are followed by any extra nbdkit -+# parameters you want to use, such as VDDK libdir, flags, filters etc. -+# -+# Note that the script runs ./nbdkit (ie. the wrapper in the top build -+# directory). -+ -+nbdkit="@abs_top_builddir@/nbdkit" -+ -+server="$1" -+guest="$2" -+shift 2 -+ -+# Get the libvirt XML, filename and moref. -+echo -n "root password? " -+xml="$( virsh -c "esx://root@$server/?no_verify=1" dumpxml "$guest" )" -+echo -+ -+file="$( echo "$xml" | grep '\(.*\)<.*,\1,' )" -+ -+#echo file="$file" -+#echo moref="$moref" -+ -+# Get the thumbprint. -+thumbprint="$( openssl s_client -connect "$server:443" /dev/null | -+ openssl x509 -in /dev/stdin -fingerprint -sha1 -noout 2>/dev/null | -+ grep '^sha1 Fingerprint=' | -+ sed 's/.*Fingerprint=\([A-F0-9:]\+\)/\1/' )" -+ -+#echo thumbprint="$thumbprint" -+ -+# Construct the nbdkit command line. -+declare -a args -+ -+args[${#args[@]}]="$nbdkit" -+args[${#args[@]}]="vddk" -+args[${#args[@]}]="file=$file" -+args[${#args[@]}]="vm=moref=$moref" -+args[${#args[@]}]="server=$server" -+args[${#args[@]}]="thumbprint=$thumbprint" -+args[${#args[@]}]="user=root" -+ -+echo "${args[@]}" "$@" -+"${args[@]}" "$@" --- -2.31.1 - diff --git a/0029-file-Fix-implementation-of-cache-none-for-writes.patch b/0029-file-Fix-implementation-of-cache-none-for-writes.patch deleted file mode 100644 index be65a3f..0000000 --- a/0029-file-Fix-implementation-of-cache-none-for-writes.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 5cb4adb94a6ff4325205fea3512c037c91579263 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 7 Dec 2021 21:08:26 +0000 -Subject: [PATCH] file: Fix implementation of cache=none for writes - -When testing virt-v2v we found that cache=none had very pessimal -performance in its current implementation when writing. See: - - https://github.com/libguestfs/virt-v2v/commit/ac59d3b2310511b1537d408b675b19ec9a5d384e - -However we know of a much better implementation - the one in nbdcopy. -This commit copies that implementation (for writes only). - -A simple test is to do: - - $ ./nbdkit file out.img cache=none --run 'nbdcopy fedora-33.img $uri' - -and then check the cache usage of the output file, which should be -around 0% (using https://github.com/Feh/nocache): - - $ cachestats out.img - pages in cache: 409/1572864 (0.0%) [filesize=6291456.0K, pagesize=4K] - -For modular virt-v2v doing a local disk to local disk conversion: - - - before this change, without cache=none - virt-v2v took 93.7 seconds, 19.1% pages cached in output file - - - before this change, enabling cache=none - virt-v2v took 125.4 seconds, 0.0% pages cached in output file - ^^^ this is the bad case which caused the investigation - - - after this change, without cache=none - virt-v2v took 93.2 seconds, 19.1% pages cached in output file - - - after this change, enabling cache=none - virt-v2v took 97.9 seconds, 0.1% pages cached in output file - -I tried to adjust NR_WINDOWS to find an optimum. Increasing it made -no difference in performance but predictably caused a slight increase -in cached pages. Reducing it slowed performance slightly. So I -conclude that 8 is about right, but it probably depends on the -hardware. - -(cherry picked from commit a956e2e75d6c88eeefecd967505667c9f176e3af) ---- - plugins/file/file.c | 79 +++++++++++++++++++++++++---- - plugins/file/nbdkit-file-plugin.pod | 3 ++ - 2 files changed, 72 insertions(+), 10 deletions(-) - -diff --git a/plugins/file/file.c b/plugins/file/file.c -index 35270a24..caf24b2c 100644 ---- a/plugins/file/file.c -+++ b/plugins/file/file.c -@@ -85,6 +85,69 @@ static int fadvise_mode = - /* cache mode */ - static enum { cache_default, cache_none } cache_mode = cache_default; - -+/* Define EVICT_WRITES if we are going to evict the page cache -+ * (cache=none) after writing. This is only known to work on Linux. -+ */ -+#ifdef __linux__ -+#define EVICT_WRITES 1 -+#endif -+ -+#ifdef EVICT_WRITES -+/* Queue writes so they will be evicted from the cache. See -+ * libnbd.git copy/file-ops.c for the rationale behind this. -+ */ -+#define NR_WINDOWS 8 -+ -+struct write_window { -+ int fd; -+ uint64_t offset; -+ size_t len; -+}; -+ -+static pthread_mutex_t window_lock = PTHREAD_MUTEX_INITIALIZER; -+static struct write_window window[NR_WINDOWS]; -+ -+static void -+evict_writes (int fd, uint64_t offset, size_t len) -+{ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock); -+ -+ /* Evict the oldest window from the page cache. */ -+ if (window[0].len > 0) { -+ sync_file_range (window[0].fd, window[0].offset, window[0].len, -+ SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| -+ SYNC_FILE_RANGE_WAIT_AFTER); -+ posix_fadvise (window[0].fd, window[0].offset, window[0].len, -+ POSIX_FADV_DONTNEED); -+ } -+ -+ /* Move the Nth window to N-1. */ -+ memmove (&window[0], &window[1], sizeof window[0] * (NR_WINDOWS-1)); -+ -+ /* Set up the current window and tell Linux to start writing it out -+ * to disk (asynchronously). -+ */ -+ sync_file_range (fd, offset, len, SYNC_FILE_RANGE_WRITE); -+ window[NR_WINDOWS-1].fd = fd; -+ window[NR_WINDOWS-1].offset = offset; -+ window[NR_WINDOWS-1].len = len; -+} -+ -+/* When we close the handle we must remove any windows which are still -+ * associated. They missed the boat, oh well :-( -+ */ -+static void -+remove_fd_from_window (int fd) -+{ -+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock); -+ size_t i; -+ -+ for (i = 0; i < NR_WINDOWS; ++i) -+ if (window[i].len > 0 && window[i].fd == fd) -+ window[i].len = 0; -+} -+#endif /* EVICT_WRITES */ -+ - /* Any callbacks using lseek must be protected by this lock. */ - static pthread_mutex_t lseek_lock = PTHREAD_MUTEX_INITIALIZER; - -@@ -431,6 +494,9 @@ file_close (void *handle) - { - struct handle *h = handle; - -+#ifdef EVICT_WRITES -+ remove_fd_from_window (h->fd); -+#endif - close (h->fd); - free (h); - } -@@ -583,15 +649,9 @@ file_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, - { - struct handle *h = handle; - --#if defined (HAVE_POSIX_FADVISE) && defined (POSIX_FADV_DONTNEED) -+#if EVICT_WRITES - uint32_t orig_count = count; - uint64_t orig_offset = offset; -- -- /* If cache=none we want to force pages we have just written to the -- * file to be flushed to disk so we can immediately evict them from -- * the page cache. -- */ -- if (cache_mode == cache_none) flags |= NBDKIT_FLAG_FUA; - #endif - - while (count > 0) { -@@ -608,10 +668,9 @@ file_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset, - if ((flags & NBDKIT_FLAG_FUA) && file_flush (handle, 0) == -1) - return -1; - --#if defined (HAVE_POSIX_FADVISE) && defined (POSIX_FADV_DONTNEED) -- /* On Linux this will evict the pages we just wrote from the page cache. */ -+#if EVICT_WRITES - if (cache_mode == cache_none) -- posix_fadvise (h->fd, orig_offset, orig_count, POSIX_FADV_DONTNEED); -+ evict_writes (h->fd, orig_offset, orig_count); - #endif - - return 0; -diff --git a/plugins/file/nbdkit-file-plugin.pod b/plugins/file/nbdkit-file-plugin.pod -index 0ac0ee53..f8f0e198 100644 ---- a/plugins/file/nbdkit-file-plugin.pod -+++ b/plugins/file/nbdkit-file-plugin.pod -@@ -117,6 +117,9 @@ cache: - - nbdkit file disk.img fadvise=sequential cache=none - -+Only use fadvise=sequential if reading, and the reads are mainly -+sequential. -+ - =head2 Files on tmpfs - - If you want to expose a file that resides on a file system known to --- -2.31.1 - diff --git a/0030-tests-Add-configure-disable-libguestfs-tests-flag.patch b/0030-tests-Add-configure-disable-libguestfs-tests-flag.patch deleted file mode 100644 index 207f46f..0000000 --- a/0030-tests-Add-configure-disable-libguestfs-tests-flag.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 92773e6852719354a136d31519948436f9adf7e9 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 18 Dec 2021 20:31:10 +0000 -Subject: [PATCH] tests: Add configure --disable-libguestfs-tests flag - -This can be used to disable tests which need libguestfs*. We were -already doing that in a hackish way in the Fedora build on some -architectures. This makes it more supportable. - -Note that you can use - - ./configure --enable-libguestfs --disable-libguestfs-tests - -to enable the bindings but disable the tests. - -The difference between without and with the new flag on an otherwise -fully configured Fedora machine: - - # TOTAL: 286 - # PASS: 273 - # SKIP: 13 - - # TOTAL: 263 - # PASS: 251 - # SKIP: 12 - -* except for those which directly test for requirements using -expressions like: - - requires guestfish --version - -(cherry picked from commit c09ae98ff3b4b786565de4aa173274531a753d30) ---- - configure.ac | 17 ++++++++++++++++- - tests/Makefile.am | 2 ++ - 2 files changed, 18 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 08c307e9..96d738d9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1146,7 +1146,8 @@ AS_IF([test "$with_libzstd" != "no"],[ - ]) - AM_CONDITIONAL([HAVE_LIBZSTD],[test "x$LIBZSTD_LIBS" != "x"]) - --dnl Check for libguestfs (only for the guestfs plugin and the test suite). -+dnl Check for libguestfs (only for the guestfs plugin and parts of -+dnl the test suite). - AC_ARG_WITH([libguestfs], - [AS_HELP_STRING([--without-libguestfs], - [disable guestfs plugin and tests @<:@default=check@:>@])], -@@ -1173,6 +1174,17 @@ AS_IF([test "$with_libguestfs" != "no"],[ - ]) - AM_CONDITIONAL([HAVE_LIBGUESTFS],[test "x$LIBGUESTFS_LIBS" != "x"]) - -+dnl Disable tests which need libguestfs. -+AC_ARG_ENABLE([libguestfs-tests], -+ [AS_HELP_STRING([--disable-libguestfs-tests], -+ [disable tests which need libguestfs])], -+ [], -+ [enable_libguestfs_tests=check] -+) -+AM_CONDITIONAL([USE_LIBGUESTFS_FOR_TESTS], -+ [test "x$LIBGUESTFS_LIBS" != "x" && \ -+ test "x$enable_libguestfs_tests" != "xno"]) -+ - dnl Check for ext2fs and com_err, for the ext2 filter. - AC_ARG_WITH([ext2], - [AS_HELP_STRING([--without-ext2], -@@ -1447,6 +1459,9 @@ echo "Other optional features:" - echo - feature "allocator=zstd ......................... " \ - test "x$HAVE_LIBZSTD_TRUE" = "x" -+feature "tests using libguestfs ................. " \ -+ test "x$HAVE_LIBGUESTFS_TRUE" = "x" -a \ -+ "x$USE_LIBGUESTFS_FOR_TESTS_TRUE" = "x" - - echo - echo "If any optional component is configured ‘no’ when you expected ‘yes’" -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 2b7ae9f3..43b60943 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -1888,6 +1888,8 @@ TESTS += $(LIBNBD_TESTS) - endif HAVE_LIBNBD - - if HAVE_LIBGUESTFS -+if USE_LIBGUESTFS_FOR_TESTS - check_PROGRAMS += $(LIBGUESTFS_TESTS) - TESTS += $(LIBGUESTFS_TESTS) -+endif USE_LIBGUESTFS_FOR_TESTS - endif HAVE_LIBGUESTFS --- -2.31.1 - diff --git a/0031-vddk-Implement-VMDK-creation.patch b/0031-vddk-Implement-VMDK-creation.patch deleted file mode 100644 index ffbaa30..0000000 --- a/0031-vddk-Implement-VMDK-creation.patch +++ /dev/null @@ -1,538 +0,0 @@ -From cf58241f19ed179e48c53f4d6c71df47dd2f5931 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 18 Jan 2022 08:58:15 +0000 -Subject: [PATCH] vddk: Implement VMDK creation - -Add the create=(true|false) parameter. Setting this to true causes -the VMDK local file to be created. Currently this is done on first -connection, but we might change that in future. Various other -parameters can be used to control aspects of the VMDK file. - -(cherry picked from commit a39d5773afc3ebab7e5768118a2bccb89a654585) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 102 ++++++++++++++++++++++- - plugins/vddk/vddk-structs.h | 32 +++++++ - plugins/vddk/vddk-stubs.h | 7 ++ - plugins/vddk/vddk.c | 125 ++++++++++++++++++++++++++++ - plugins/vddk/vddk.h | 5 ++ - tests/Makefile.am | 6 +- - tests/dummy-vddk.c | 10 +++ - tests/test-vddk-real-create.sh | 70 ++++++++++++++++ - 8 files changed, 354 insertions(+), 3 deletions(-) - create mode 100755 tests/test-vddk-real-create.sh - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index acec0bd2..b96192d0 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -6,7 +6,11 @@ nbdkit-vddk-plugin - nbdkit VMware VDDK plugin - - nbdkit vddk [file=]FILENAME - [compression=none|zlib|fastlz|skipz] -- [config=FILENAME] [cookie=COOKIE] [libdir=LIBRARY] -+ [config=FILENAME] [cookie=COOKIE] -+ [create=true] [create-adapter-type=ide|scsi-buslogic|...] -+ [create-hwversion=workstation4|workstation5|...] -+ [create-size=...] [create-type=monolithic-sparse|...] -+ [libdir=LIBRARY] - [nfchostport=PORT] [single-link=true] - [password=PASSWORD | password=- | password=+FILENAME | - password=-FD] -@@ -26,7 +30,7 @@ yourself (see L below). - - =head1 EXAMPLES - --=head2 Open a local VMDK file -+=head2 Open an existing local VMDK file - - nbdkit vddk /absolute/path/to/file.vmdk - -@@ -38,6 +42,18 @@ I<-r> option): - - nbdkit -r vddk /absolute/path/to/file.vmdk - -+=head2 Create a new local VMDK file -+ -+You can use VDDK to create a VMDK file and fill it with the contents -+of a disk image. Note the C parameter is the virtual -+size of the final VMDK disk image and must be at least as large as the -+input disk: -+ -+ nbdkit -U - vddk \ -+ /absolute/path/to/output.vmdk \ -+ create=1 create-size=100M \ -+ --run 'qemu-img convert input.qcow2 $uri' -+ - =head2 Open a file on a remote VMware ESXi hypervisor - - Connect directly to a VMware ESXi hypervisor and export a particular -@@ -136,6 +152,88 @@ C which can improve performance. The - cookie can be found by connecting to a VCenter Server over HTTPS and - retrieving the C cookie. - -+=item B -+ -+(nbdkit E 1.30) -+ -+Create a new, local VMDK file. Instead of opening an existing VMDK -+file, a new VMDK file is created and opened. The filename is given by -+the C parameter (see below). The file must not exist already. -+It is not possible to create a remote file using nbdkit. -+ -+If this is used, the C parameter is required to specify -+the virtual size of the disk. Other C parameters (see -+below) can be used to control the VMDK sub-format. -+ -+=item B -+ -+=item B -+ -+=item B -+ -+(nbdkit E 1.30) -+ -+Specify the VMDK disk adapter type. The default is C. -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+(nbdkit E 1.30) -+ -+Specify the VMDK virtual hardware version. The default is -+C. -+ -+=item BSIZE -+ -+(nbdkit E 1.30) -+ -+Specify the virtual size of the created disk. The C can use -+modifiers like C<100M> etc. It must be a multiple of 512 bytes -+because VMware only supports sector sizes. -+ -+If you use C then this parameter is required. -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+=item B -+ -+(nbdkit E 1.30) -+ -+Specify the VMDK sub-format. The default is C. -+ -+Some VMDK sub-formats use multiple files, where the C parameter -+specifies the "Disk Descriptor File" and the disk contents are stored -+in adjacent files. -+ - =item [B]FILENAME - - =item [B]B<[>datastoreB<] >vmname/vmnameB<.vmdk> -diff --git a/plugins/vddk/vddk-structs.h b/plugins/vddk/vddk-structs.h -index e97f017c..799c4aec 100644 ---- a/plugins/vddk/vddk-structs.h -+++ b/plugins/vddk/vddk-structs.h -@@ -43,6 +43,7 @@ - - typedef uint64_t VixError; - #define VIX_OK 0 -+#define VIX_E_NOT_SUPPORTED 6 - #define VIX_ASYNC 25000 - - #define VIXDISKLIB_FLAG_OPEN_UNBUFFERED 1 -@@ -54,6 +55,28 @@ typedef uint64_t VixError; - - #define VIXDISKLIB_SECTOR_SIZE 512 - -+enum VixDiskLibDiskType { -+ VIXDISKLIB_DISK_MONOLITHIC_SPARSE = 1, -+ VIXDISKLIB_DISK_MONOLITHIC_FLAT = 2, -+ VIXDISKLIB_DISK_SPLIT_SPARSE = 3, -+ VIXDISKLIB_DISK_SPLIT_FLAT = 4, -+ VIXDISKLIB_DISK_VMFS_FLAT = 5, -+ VIXDISKLIB_DISK_STREAM_OPTIMIZED = 6, -+ VIXDISKLIB_DISK_VMFS_THIN = 7, -+ VIXDISKLIB_DISK_VMFS_SPARSE = 8 -+}; -+ -+#define VIXDISKLIB_HWVERSION_WORKSTATION_4 3 -+#define VIXDISKLIB_HWVERSION_WORKSTATION_5 4 -+#define VIXDISKLIB_HWVERSION_WORKSTATION_6 6 -+#define VIXDISKLIB_HWVERSION_ESX30 4 -+#define VIXDISKLIB_HWVERSION_ESX4X 7 -+#define VIXDISKLIB_HWVERSION_ESX50 8 -+#define VIXDISKLIB_HWVERSION_ESX51 9 -+#define VIXDISKLIB_HWVERSION_ESX55 10 -+#define VIXDISKLIB_HWVERSION_ESX60 11 -+#define VIXDISKLIB_HWVERSION_ESX65 13 -+ - #define VIXDISKLIB_MIN_CHUNK_SIZE 128 - #define VIXDISKLIB_MAX_CHUNK_NUMBER (512*1024) - -@@ -148,4 +171,13 @@ typedef struct { - VixDiskLibBlock blocks[1]; - } VixDiskLibBlockList; - -+typedef struct { -+ enum VixDiskLibDiskType diskType; -+ enum VixDiskLibAdapterType adapterType; -+ uint16_t hwVersion; -+ uint64_t capacity; -+ uint32_t logicalSectorSize; -+ uint32_t physicalSectorSize; -+} VixDiskLibCreateParams; -+ - #endif /* NBDKIT_VDDK_STRUCTS_H */ -diff --git a/plugins/vddk/vddk-stubs.h b/plugins/vddk/vddk-stubs.h -index 7d8644c3..d5affa10 100644 ---- a/plugins/vddk/vddk-stubs.h -+++ b/plugins/vddk/vddk-stubs.h -@@ -99,6 +99,13 @@ STUB (VixDiskLib_Write, - (VixDiskLibHandle handle, - uint64_t start_sector, uint64_t nr_sectors, - const unsigned char *buf)); -+STUB (VixDiskLib_Create, -+ VixError, -+ (const VixDiskLibConnection connection, -+ const char *path, -+ const VixDiskLibCreateParams *create_params, -+ void *progress_function_unused, -+ void *progress_data_unused)); - - /* Added in VDDK 6.0. */ - STUB (VixDiskLib_Flush, -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 31e5e23b..5ebf9a2c 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -81,6 +81,14 @@ bool is_remote; /* true if remote connection */ - enum compression_type compression; /* compression */ - char *config; /* config */ - const char *cookie; /* cookie */ -+bool create; /* create */ -+enum VixDiskLibAdapterType create_adapter_type = -+ VIXDISKLIB_ADAPTER_SCSI_BUSLOGIC; /* create-adapter-type */ -+uint16_t create_hwversion = -+ VIXDISKLIB_HWVERSION_WORKSTATION_5; /* create-hwversion */ -+uint64_t create_size; /* create-size */ -+enum VixDiskLibDiskType create_type = -+ VIXDISKLIB_DISK_MONOLITHIC_SPARSE; /* create-type */ - const char *filename; /* file */ - char *libdir; /* libdir */ - uint16_t nfc_host_port; /* nfchostport */ -@@ -119,6 +127,7 @@ static int - vddk_config (const char *key, const char *value) - { - int r; -+ int64_t r64; - - if (strcmp (key, "compression") == 0) { - if (strcmp (value, "zlib") == 0) -@@ -144,6 +153,82 @@ vddk_config (const char *key, const char *value) - else if (strcmp (key, "cookie") == 0) { - cookie = value; - } -+ else if (strcmp (key, "create") == 0) { -+ r = nbdkit_parse_bool (value); -+ if (r == -1) -+ return -1; -+ create = r; -+ } -+ else if (strcmp (key, "create-adapter-type") == 0) { -+ if (strcmp (value, "ide") == 0) -+ create_adapter_type = VIXDISKLIB_ADAPTER_IDE; -+ else if (strcmp (value, "scsi-buslogic") == 0) -+ create_adapter_type = VIXDISKLIB_ADAPTER_SCSI_BUSLOGIC; -+ else if (strcmp (value, "scsi-lsilogic") == 0) -+ create_adapter_type = VIXDISKLIB_ADAPTER_SCSI_LSILOGIC; -+ else { -+ nbdkit_error ("unknown create-adapter-type: %s", value); -+ return -1; -+ } -+ } -+ else if (strcmp (key, "create-hwversion") == 0) { -+ if (strcmp (value, "workstation4") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_WORKSTATION_4; -+ else if (strcmp (value, "workstation5") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_WORKSTATION_5; -+ else if (strcmp (value, "workstation6") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_WORKSTATION_6; -+ else if (strcmp (value, "esx30") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX30; -+ else if (strcmp (value, "esx4x") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX4X; -+ else if (strcmp (value, "esx50") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX50; -+ else if (strcmp (value, "esx51") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX51; -+ else if (strcmp (value, "esx55") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX55; -+ else if (strcmp (value, "esx60") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX60; -+ else if (strcmp (value, "esx65") == 0) -+ create_hwversion = VIXDISKLIB_HWVERSION_ESX65; -+ else { -+ nbdkit_error ("unknown create-hwversion: %s", value); -+ return -1; -+ } -+ } -+ else if (strcmp (key, "create-size") == 0) { -+ r64 = nbdkit_parse_size (value); -+ if (r64 == -1) -+ return -1; -+ if (r64 <= 0 || (r64 & 511) != 0) { -+ nbdkit_error ("create-size must be greater than zero and a multiple of 512"); -+ return -1; -+ } -+ create_size = r64; -+ } -+ else if (strcmp (key, "create-type") == 0) { -+ if (strcmp (value, "monolithic-sparse") == 0) -+ create_type = VIXDISKLIB_DISK_MONOLITHIC_SPARSE; -+ else if (strcmp (value, "monolithic-flat") == 0) -+ create_type = VIXDISKLIB_DISK_MONOLITHIC_FLAT; -+ else if (strcmp (value, "split-sparse") == 0) -+ create_type = VIXDISKLIB_DISK_SPLIT_SPARSE; -+ else if (strcmp (value, "split-flat") == 0) -+ create_type = VIXDISKLIB_DISK_SPLIT_FLAT; -+ else if (strcmp (value, "vmfs-flat") == 0) -+ create_type = VIXDISKLIB_DISK_VMFS_FLAT; -+ else if (strcmp (value, "stream-optimized") == 0) -+ create_type = VIXDISKLIB_DISK_STREAM_OPTIMIZED; -+ else if (strcmp (value, "vmfs-thin") == 0) -+ create_type = VIXDISKLIB_DISK_VMFS_THIN; -+ else if (strcmp (value, "vmfs-sparse") == 0) -+ create_type = VIXDISKLIB_DISK_VMFS_SPARSE; -+ else { -+ nbdkit_error ("unknown create-type: %s", value); -+ return -1; -+ } -+ } - else if (strcmp (key, "file") == 0) { - /* NB: Don't convert this to an absolute path, because in the - * remote case this can be a path located on the VMware server. -@@ -266,6 +351,18 @@ vddk_config_complete (void) - #undef missing - } - -+ if (create) { -+ if (is_remote) { -+ nbdkit_error ("create=true can only be used to create local VMDK files"); -+ return -1; -+ } -+ -+ if (create_size == 0) { -+ nbdkit_error ("if using create=true you must specify the size using the create-size parameter"); -+ return -1; -+ } -+ } -+ - /* Restore original LD_LIBRARY_PATH after reexec. */ - if (restore_ld_library_path () == -1) - return -1; -@@ -618,6 +715,34 @@ vddk_open (int readonly) - goto err1; - } - -+ /* Creating a disk? The first time the connection is opened we will -+ * create it here (we need h->connection). Then set create=false so -+ * we don't create it again. This is all serialized through -+ * open_close_lock so it is safe. -+ */ -+ if (create) { -+ VixDiskLibCreateParams cparams = { -+ .diskType = create_type, -+ .adapterType = create_adapter_type, -+ .hwVersion = create_hwversion, -+ .capacity = create_size / VIXDISKLIB_SECTOR_SIZE, -+ .logicalSectorSize = 0, -+ .physicalSectorSize = 0 -+ }; -+ -+ VDDK_CALL_START (VixDiskLib_Create, -+ "h->connection, %s, &cparams, NULL, NULL", -+ filename) -+ err = VixDiskLib_Create (h->connection, filename, &cparams, NULL, NULL); -+ VDDK_CALL_END (VixDiskLib_Create, 0); -+ if (err != VIX_OK) { -+ VDDK_ERROR (err, "VixDiskLib_Create: %s", filename); -+ goto err2; -+ } -+ -+ create = false; /* Don't create it again. */ -+ } -+ - flags = 0; - if (readonly) - flags |= VIXDISKLIB_FLAG_OPEN_READ_ONLY; -diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h -index d99b6f4b..3a808013 100644 ---- a/plugins/vddk/vddk.h -+++ b/plugins/vddk/vddk.h -@@ -56,6 +56,11 @@ extern bool is_remote; - extern enum compression_type compression; - extern char *config; - extern const char *cookie; -+extern bool create; -+extern enum VixDiskLibAdapterType create_adapter_type; -+extern uint16_t create_hwversion; -+extern uint64_t create_size; -+extern enum VixDiskLibDiskType create_type; - extern const char *filename; - extern char *libdir; - extern uint16_t nfc_host_port; -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 43b60943..ad2d43b9 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -171,7 +171,9 @@ if HAVE_VDDK - # - # make check-vddk vddkdir=vmware-vix-disklib-distrib - check-vddk: -- $(MAKE) check TESTS="test-vddk-real.sh test-vddk-real-dump-plugin.sh" -+ $(MAKE) check TESTS="test-vddk-real.sh -+ test-vddk-real-dump-plugin.sh -+ test-vddk-real-create.sh" - endif HAVE_VDDK - - #---------------------------------------------------------------------- -@@ -1033,6 +1035,7 @@ TESTS += \ - test-vddk-dump-plugin.sh \ - test-vddk-password-fd.sh \ - test-vddk-password-interactive.sh \ -+ test-vddk-real-create.sh \ - test-vddk-real-dump-plugin.sh \ - test-vddk-real.sh \ - test-vddk-reexec.sh \ -@@ -1063,6 +1066,7 @@ EXTRA_DIST += \ - test-vddk-dump-plugin.sh \ - test-vddk-password-fd.sh \ - test-vddk-password-interactive.sh \ -+ test-vddk-real-create.sh \ - test-vddk-real-dump-plugin.sh \ - test-vddk-real.sh \ - test-vddk-reexec.sh \ -diff --git a/tests/dummy-vddk.c b/tests/dummy-vddk.c -index b6f12042..0c5e505f 100644 ---- a/tests/dummy-vddk.c -+++ b/tests/dummy-vddk.c -@@ -236,3 +236,13 @@ VixDiskLib_Wait (VixDiskLibHandle handle) - { - return VIX_OK; - } -+ -+NBDKIT_DLL_PUBLIC VixError -+VixDiskLib_Create (const VixDiskLibConnection connection, -+ const char *path, -+ const VixDiskLibCreateParams *create_params, -+ void *progress_function_unused, -+ void *progress_data_unused) -+{ -+ return VIX_E_NOT_SUPPORTED; -+} -diff --git a/tests/test-vddk-real-create.sh b/tests/test-vddk-real-create.sh -new file mode 100755 -index 00000000..8f39a4c9 ---- /dev/null -+++ b/tests/test-vddk-real-create.sh -@@ -0,0 +1,70 @@ -+#!/usr/bin/env bash -+# nbdkit -+# Copyright (C) 2018-2022 Red Hat Inc. -+# -+# 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. -+ -+source ./functions.sh -+set -e -+set -x -+ -+requires test "x$vddkdir" != "x" -+requires test -d "$vddkdir" -+requires test -f "$vddkdir/lib64/libvixDiskLib.so" -+requires test -f disk -+requires nbdcopy --version -+requires stat --version -+ -+# Testing $LD_LIBRARY_PATH stuff breaks valgrind, so skip the rest of -+# this test if valgrinding. -+if [ "x$NBDKIT_VALGRIND" = "x1" ]; then -+ echo "$0: skipped LD_LIBRARY_PATH test when doing valgrind" -+ exit 77 -+fi -+ -+# VDDK > 5.1.1 only supports x86_64. -+if [ `uname -m` != "x86_64" ]; then -+ echo "$0: unsupported architecture" -+ exit 77 -+fi -+ -+vmdk=$PWD/test-vddk-real-create.vmdk ;# note must be an absolute path -+files="$vmdk" -+rm -f $files -+cleanup_fn rm -f $files -+ -+size="$(stat -c %s disk)" -+ -+nbdkit -fv -U - vddk libdir="$vddkdir" $vmdk \ -+ create=true create-size=$size \ -+ --run 'nbdcopy disk $uri' -+ -+# Check the VMDK file was created and looks reasonable. -+test -f $vmdk -+file $vmdk | grep 'VMware' --- -2.31.1 - diff --git a/0032-vddk-Fix-documentation-of-new-create-flag.patch b/0032-vddk-Fix-documentation-of-new-create-flag.patch deleted file mode 100644 index 2af8153..0000000 --- a/0032-vddk-Fix-documentation-of-new-create-flag.patch +++ /dev/null @@ -1,29 +0,0 @@ -From eb5d5a628968c7fd5401cf7e73a6cff6c43994aa Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 18 Jan 2022 13:14:01 +0000 -Subject: [PATCH] vddk: Fix documentation of new create flag - -create=1 works, but for consistency use create=true - -Fixes: commit a39d5773afc3ebab7e5768118a2bccb89a654585 -(cherry picked from commit 0b21897b64a6a1d97a8a7361e8f781ae743dedca) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index b96192d0..6c7ae989 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -51,7 +51,7 @@ input disk: - - nbdkit -U - vddk \ - /absolute/path/to/output.vmdk \ -- create=1 create-size=100M \ -+ create=true create-size=100M \ - --run 'qemu-img convert input.qcow2 $uri' - - =head2 Open a file on a remote VMware ESXi hypervisor --- -2.31.1 - diff --git a/0033-vddk-Allow-create-hwversion-to-be-specified-as-a-num.patch b/0033-vddk-Allow-create-hwversion-to-be-specified-as-a-num.patch deleted file mode 100644 index 1a7416b..0000000 --- a/0033-vddk-Allow-create-hwversion-to-be-specified-as-a-num.patch +++ /dev/null @@ -1,55 +0,0 @@ -From c8cdce47bc38d2f59ecc4b75d6db7f032b63d527 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 18 Jan 2022 20:49:21 +0000 -Subject: [PATCH] vddk: Allow create-hwversion to be specified as a number - -This gives us a bit of future-proofing so we don't always need to add -new hardware versions immediately. Another reason for this is that -VDDK allows you to specify seemingly any number here without -complaint. - -Updates: commit a39d5773afc3ebab7e5768118a2bccb89a654585 -(cherry picked from commit 071e32927237c2c00d78684c8a0f2e5fbca9963e) ---- - plugins/vddk/nbdkit-vddk-plugin.pod | 8 ++++++-- - plugins/vddk/vddk.c | 3 ++- - 2 files changed, 8 insertions(+), 3 deletions(-) - -diff --git a/plugins/vddk/nbdkit-vddk-plugin.pod b/plugins/vddk/nbdkit-vddk-plugin.pod -index 6c7ae989..e6972900 100644 ---- a/plugins/vddk/nbdkit-vddk-plugin.pod -+++ b/plugins/vddk/nbdkit-vddk-plugin.pod -@@ -195,10 +195,14 @@ Specify the VMDK disk adapter type. The default is C. - - =item B - -+=item BN -+ - (nbdkit E 1.30) - --Specify the VMDK virtual hardware version. The default is --C. -+Specify the VMDK virtual hardware version. You can give either the -+named version or the equivalent 16 bit number. -+ -+The default is C (N = 4). - - =item BSIZE - -diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c -index 5ebf9a2c..bab8de6f 100644 ---- a/plugins/vddk/vddk.c -+++ b/plugins/vddk/vddk.c -@@ -192,7 +192,8 @@ vddk_config (const char *key, const char *value) - create_hwversion = VIXDISKLIB_HWVERSION_ESX60; - else if (strcmp (value, "esx65") == 0) - create_hwversion = VIXDISKLIB_HWVERSION_ESX65; -- else { -+ else if (nbdkit_parse_uint16_t ("create-hwversion", value, -+ &create_hwversion) == -1) { - nbdkit_error ("unknown create-hwversion: %s", value); - return -1; - } --- -2.31.1 - diff --git a/0034-tests-Fix-VDDK-tests.patch b/0034-tests-Fix-VDDK-tests.patch deleted file mode 100644 index 231d59d..0000000 --- a/0034-tests-Fix-VDDK-tests.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 84c5bc4664607fdf1f051e9e52ac6d0e4f0be049 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 18 Jan 2022 21:02:32 +0000 -Subject: [PATCH] tests: Fix VDDK tests - -We need to use quoting for the subcommand split across lines. - -Fixes: commit a39d5773afc3ebab7e5768118a2bccb89a654585 -(cherry picked from commit 4df525566b38202ed8a7485ac8e7f06edd5ee49a) ---- - tests/Makefile.am | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/Makefile.am b/tests/Makefile.am -index ad2d43b9..62a6f05b 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -171,8 +171,8 @@ if HAVE_VDDK - # - # make check-vddk vddkdir=vmware-vix-disklib-distrib - check-vddk: -- $(MAKE) check TESTS="test-vddk-real.sh -- test-vddk-real-dump-plugin.sh -+ $(MAKE) check TESTS="test-vddk-real.sh \ -+ test-vddk-real-dump-plugin.sh \ - test-vddk-real-create.sh" - endif HAVE_VDDK - --- -2.31.1 - diff --git a/0035-server-sockets-get-rid-of-AI_ADDRCONFIG.patch b/0035-server-sockets-get-rid-of-AI_ADDRCONFIG.patch deleted file mode 100644 index ad374bf..0000000 --- a/0035-server-sockets-get-rid-of-AI_ADDRCONFIG.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 222bce6b83421db1afdad24cf4e8ab7b1aa7b273 Mon Sep 17 00:00:00 2001 -From: Laszlo Ersek -Date: Tue, 18 Jan 2022 14:48:33 +0100 -Subject: [PATCH] server/sockets: get rid of AI_ADDRCONFIG - -The AI_ADDRCONFIG hint of getaddrinfo() is supposed to restrict the name -resolution to such address families (IPv4 vs. IPv6) for which the -resolving host has publicly routable addresses assigned. - -The main problem with AI_ADDRCONFIG can be shown with the following -command line: - -$ nbdkit -f -p 32776 -P pidfile -i ::1 --exit-with-parent null - -On a host where ::1 is the only IPv6 address assigned (namely to the -loopback interface), the command fails with - -> nbdkit: getaddrinfo: ::1: 32776: Address family for hostname not -> supported - -due to the "publicly routable" requirement. - -Remove AI_ADDRCONFIG from the getaddrinfo() hints, and as a replacement, -introduce the "-4" and "-6" options, similarly to netcat and ssh. - -(1) This makes options of the form: - - -i 127.0.0.1 - -i ::1 - - work regardless of "public" IPv6 / IPv4 connectivity; - -(2) options of the form - - -i localhost - -i FQDN - - will bind both IPv4 and IPv6 addresses of the desired interface(s); - -(3) omitting the option "-i" will bind both IPv4 and IPv6 wildcard - addresses (0.0.0.0 and ::); - -(4) the configurations in (2) and (3) can be restricted to IPv4 or IPv6 - addresses by adding the "-4" or "-6" option, respectively. - -Importantly, this change allows the "connect-tcp6" test case of libnbd to -pass on such hosts that have no IPv6 connectivity (i.e., where the only -assigned IPv6 address is ::1, namely on the loopback interface). - -Ref: https://listman.redhat.com/archives/libguestfs/2022-January/msg00110.html -Signed-off-by: Laszlo Ersek -Message-Id: <20220118134833.13246-3-lersek@redhat.com> -[lersek@redhat.com: fix typo in "--exit-with-parent" (Eric)] -Acked-by: Eric Blake -(cherry picked from commit 9eec2335d630ae8ef947a927c1922d725d482f4a) ---- - common/utils/windows-compat.h | 7 ------- - docs/nbdkit.pod | 20 +++++++++++++++++++- - docs/synopsis.txt | 3 ++- - server/internal.h | 1 + - server/main.c | 9 +++++++++ - server/options.h | 4 +++- - server/sockets.c | 3 ++- - 7 files changed, 36 insertions(+), 11 deletions(-) - -diff --git a/common/utils/windows-compat.h b/common/utils/windows-compat.h -index 7695bf7e..658c1d8b 100644 ---- a/common/utils/windows-compat.h -+++ b/common/utils/windows-compat.h -@@ -75,13 +75,6 @@ struct sockaddr_un - #define O_NOCTTY 0 - #endif - --/* AI_ADDRCONFIG is not available on Windows. It enables a rather -- * obscure feature of getaddrinfo to do with IPv6. -- */ --#ifndef AI_ADDRCONFIG --#define AI_ADDRCONFIG 0 --#endif -- - /* Windows lacks certain errnos, so replace them here as - * best we can. - */ -diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod -index 99cfb362..042607fb 100644 ---- a/docs/nbdkit.pod -+++ b/docs/nbdkit.pod -@@ -173,6 +173,24 @@ Display information about nbdkit or a specific plugin: - - Display brief command line usage information and exit. - -+=item B<-4> -+ -+=item B<--ipv4-only> -+ -+=item B<-6> -+ -+=item B<--ipv6-only> -+ -+When a non-numeric argument is passed to the I<-i> option (such as a -+Fully Qualified Domain Name, or a host name from C), -+restrict the name resolution to IPv4 or IPv6 addresses. -+ -+When the I<-i> option is omitted, listen on only the IPv4 or IPv6 -+address of all interfaces (C<0.0.0.0> or C<::>, respectively). -+ -+When both I<-4> and I<-6> options are present on the command line, the -+last one takes effect. -+ - =item B<-D> PLUGIN.FLAG=N - - =item B<-D> FILTER.FLAG=N -@@ -265,7 +283,7 @@ See also I<-u>. - =item B<--ipaddr> IPADDR - - Listen on the specified interface. The default is to listen on all --interfaces. See also I<-p>. -+interfaces. See also I<-4>, I<-6>, and I<-p>. - - =item B<--log=stderr> - -diff --git a/docs/synopsis.txt b/docs/synopsis.txt -index 07b9dcff..6154bb2e 100644 ---- a/docs/synopsis.txt -+++ b/docs/synopsis.txt -@@ -1,4 +1,5 @@ --nbdkit [-D|--debug PLUGIN|FILTER|nbdkit.FLAG=N] -+nbdkit [-4|--ipv4-only] [-6|--ipv6-only] -+ [-D|--debug PLUGIN|FILTER|nbdkit.FLAG=N] - [-e|--exportname EXPORTNAME] [--exit-with-parent] - [--filter FILTER ...] [-f|--foreground] - [-g|--group GROUP] [-i|--ipaddr IPADDR] -diff --git a/server/internal.h b/server/internal.h -index bc81b786..46fcdd46 100644 ---- a/server/internal.h -+++ b/server/internal.h -@@ -113,6 +113,7 @@ enum log_to { - LOG_TO_NULL, /* --log=null forced on the command line */ - }; - -+extern int tcpip_sock_af; - extern struct debug_flag *debug_flags; - extern const char *export_name; - extern bool foreground; -diff --git a/server/main.c b/server/main.c -index 225258de..8e7ac149 100644 ---- a/server/main.c -+++ b/server/main.c -@@ -86,6 +86,7 @@ static void error_if_stdio_closed (void); - static void switch_stdio (void); - static void winsock_init (void); - -+int tcpip_sock_af = AF_UNSPEC; /* -4, -6 */ - struct debug_flag *debug_flags; /* -D */ - bool exit_with_parent; /* --exit-with-parent */ - const char *export_name; /* -e */ -@@ -367,6 +368,14 @@ main (int argc, char *argv[]) - exit (EXIT_FAILURE); - #endif - -+ case '4': -+ tcpip_sock_af = AF_INET; -+ break; -+ -+ case '6': -+ tcpip_sock_af = AF_INET6; -+ break; -+ - case 'D': - add_debug_flag (optarg); - break; -diff --git a/server/options.h b/server/options.h -index e59ef17f..39299b9d 100644 ---- a/server/options.h -+++ b/server/options.h -@@ -59,8 +59,10 @@ enum { - VSOCK_OPTION, - }; - --static const char *short_options = "D:e:fg:i:nop:P:rst:u:U:vV"; -+static const char *short_options = "46D:e:fg:i:nop:P:rst:u:U:vV"; - static const struct option long_options[] = { -+ { "ipv4-only", no_argument, NULL, '4' }, -+ { "ipv6-only", no_argument, NULL, '6' }, - { "debug", required_argument, NULL, 'D' }, - { "dump-config", no_argument, NULL, DUMP_CONFIG_OPTION }, - { "dump-plugin", no_argument, NULL, DUMP_PLUGIN_OPTION }, -diff --git a/server/sockets.c b/server/sockets.c -index 15a26f69..4e4ccbc4 100644 ---- a/server/sockets.c -+++ b/server/sockets.c -@@ -179,7 +179,8 @@ bind_tcpip_socket (sockets *socks) - port = "10809"; - - memset (&hints, 0, sizeof hints); -- hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; -+ hints.ai_flags = AI_PASSIVE; -+ hints.ai_family = tcpip_sock_af; - hints.ai_socktype = SOCK_STREAM; - - err = getaddrinfo (ipaddr, port, &hints, &ai); --- -2.31.1 - diff --git a/copy-patches.sh b/copy-patches.sh index 2aaf42c..10fca0f 100755 --- a/copy-patches.sh +++ b/copy-patches.sh @@ -6,7 +6,7 @@ set -e # directory. Use it like this: # ./copy-patches.sh -rhel_version=9.0 +rhel_version=9.1 # Check we're in the right directory. if [ ! -f nbdkit.spec ]; then diff --git a/nbdkit-find-provides b/nbdkit-find-provides new file mode 100755 index 0000000..7013ccd --- /dev/null +++ b/nbdkit-find-provides @@ -0,0 +1,23 @@ +#!/bin/bash - + +# Generate RPM provides automatically for nbdkit packages and filters. +# Copyright (C) 2009-2022 Red Hat Inc. + +# To test: +# find /usr/lib64/nbdkit/plugins | ./nbdkit-find-provides VER REL +# find /usr/lib64/nbdkit/filters | ./nbdkit-find-provides VER REL + +ver="$1" +rel="$2" + +function process_file +{ + if [[ $1 =~ /plugins/nbdkit-.*-plugin ]] || + [[ $1 =~ /filters/nbdkit-.*-filter ]]; then + echo "Provides:" "$(basename $1 .so)" "=" "$ver-$rel" + fi +} + +while read line; do + process_file "$line" +done diff --git a/nbdkit.attr b/nbdkit.attr new file mode 100644 index 0000000..2757679 --- /dev/null +++ b/nbdkit.attr @@ -0,0 +1,3 @@ +%__nbdkit_provides %{_rpmconfigdir}/nbdkit-find-provides %{version} %{release} +%__nbdkit_path %{_libdir}/nbdkit/(plugins|filters)/nbdkit-.*-(plugin|filter)(\.so)?$ +%__nbdkit_flags exeonly diff --git a/nbdkit.spec b/nbdkit.spec index 8089073..98518d7 100644 --- a/nbdkit.spec +++ b/nbdkit.spec @@ -1,6 +1,9 @@ +%undefine _package_note_flags %global _hardened_build 1 %ifarch %{kernel_arches} +# ppc64le broken in rawhide: +# https://bugzilla.redhat.com/show_bug.cgi?id=2006709 # riscv64 tests fail with # qemu-system-riscv64: invalid accelerator kvm # qemu-system-riscv64: falling back to tcg @@ -8,7 +11,7 @@ # This seems to require changes in libguestfs and/or qemu to support # -cpu max or -cpu virt. # s390x builders can't run libguestfs -%ifnarch riscv64 s390 s390x +%ifnarch %{power64} riscv64 s390 s390x %global have_libguestfs 1 %endif %endif @@ -29,8 +32,6 @@ # If the test suite is broken on a particular architecture, document # it as a bug and add it to this list. -# -# armv7, aarch64: https://bugzilla.redhat.com/show_bug.cgi?id=1893892 %global broken_test_arches NONE %if 0%{?rhel} == 7 @@ -45,14 +46,14 @@ ExclusiveArch: x86_64 %global verify_tarball_signature 1 # If there are patches which touch autotools files, set this to 1. -%global patches_touch_autotools 1 +%global patches_touch_autotools %{nil} # The source directory. -%global source_directory 1.28-stable +%global source_directory 1.30-stable Name: nbdkit -Version: 1.28.5 -Release: 1%{?dist} +Version: 1.30.0 +Release: 3%{?dist} Summary: NBD server License: BSD @@ -74,44 +75,14 @@ Source2: libguestfs.keyring Source3: copy-patches.sh # Patches come from the upstream repository: -# https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-9.0/ +# https://gitlab.com/nbdkit/nbdkit/-/commits/rhel-9.1/ # Patches. -Patch0001: 0001-vddk-Refactor-how-D-vddk.stats-1-is-collected.patch -Patch0002: 0002-vddk-Extend-D-vddk.stats-1-to-show-number-of-calls-a.patch -Patch0003: 0003-vddk-Simplify-and-consolidate-VDDK_CALL_START-END-ma.patch -Patch0004: 0004-vddk-Document-troubleshooting-performance-problems.patch -Patch0005: 0005-vddk-Include-VDDK-major-library-version-in-dump-plug.patch -Patch0006: 0006-vddk-Add-logical-and-physical-sector-size-to-D-vddk..patch -Patch0007: 0007-vddk-Fix-typo-in-debug-message.patch -Patch0008: 0008-vddk-Only-print-vddk_library_version-when-we-managed.patch -Patch0009: 0009-vddk-Print-one-line-in-dump-plugin-output-for-each-V.patch -Patch0010: 0010-vddk-Move-minimum-version-to-VDDK-6.5.patch -Patch0011: 0011-vddk-Add-read-write-and-wait-asynchronous-functions.patch -Patch0012: 0012-vddk-Start-to-split-VDDK-over-several-files.patch -Patch0013: 0013-vddk-Refactor-D-vddk.stats-1-into-a-new-file.patch -Patch0014: 0014-vddk-Implement-parallel-thread-model.patch -Patch0015: 0015-vddk-Assume-that-VixDiskLib_Flush-is-available.patch -Patch0016: 0016-vddk-Simplify-detection-of-VDDK-symbols-and-baseline.patch -Patch0017: 0017-vddk-Remove-some-whitespace-from-a-couple-of-functio.patch -Patch0018: 0018-vddk-Move-config-debug-error-and-utility-functions-a.patch -Patch0019: 0019-common-utils-test-vector.c-Add-vector-benchmarks.patch -Patch0020: 0020-common-urils-vector.c-Optimize-vector-append.patch -Patch0021: 0021-common-utils-vector-Rename-alloc-to-cap.patch -Patch0022: 0022-common-utils-vector-Rename-size-to-len.patch -Patch0023: 0023-podwrapper.pl.in-Use-short-commit-date.patch -Patch0024: 0024-ocaml-Replace-noalloc-with-noalloc-annotation.patch -Patch0025: 0025-vddk-Drop-obsolete-documentation-related-to-thread-m.patch -Patch0026: 0026-Revert-podwrapper.pl.in-Use-short-commit-date.patch -Patch0027: 0027-Fix-podwrapper.pl.in-Use-short-commit-date.patch -Patch0028: 0028-scripts-Add-simple-script-for-automating-VDDK-disk-c.patch -Patch0029: 0029-file-Fix-implementation-of-cache-none-for-writes.patch -Patch0030: 0030-tests-Add-configure-disable-libguestfs-tests-flag.patch -Patch0031: 0031-vddk-Implement-VMDK-creation.patch -Patch0032: 0032-vddk-Fix-documentation-of-new-create-flag.patch -Patch0033: 0033-vddk-Allow-create-hwversion-to-be-specified-as-a-num.patch -Patch0034: 0034-tests-Fix-VDDK-tests.patch -Patch0035: 0035-server-sockets-get-rid-of-AI_ADDRCONFIG.patch + +# For automatic RPM Provides generation. +# See: https://rpm-software-management.github.io/rpm/manual/dependency_generators.html +Source4: nbdkit.attr +Source5: nbdkit-find-provides BuildRequires: make %if 0%{patches_touch_autotools} @@ -150,9 +121,7 @@ BuildRequires: python3-boto3 %endif %if !0%{?rhel} %if 0%{?have_ocaml} -# Requires OCaml 4.02.2 which contains fix for -# http://caml.inria.fr/mantis/view.php?id=6693 -BuildRequires: ocaml >= 4.02.2 +BuildRequires: ocaml >= 4.03 BuildRequires: ocaml-ocamldoc %endif BuildRequires: ruby-devel @@ -185,6 +154,11 @@ BuildRequires: %{_sbindir}/ss BuildRequires: %{_bindir}/stat BuildRequires: %{_bindir}/ssh-keygen +# This package has RPM rules that create the automatic Provides: for +# nbdkit plugins and filters. This means nbdkit build depends on +# itself, but it's a simple noarch package so easy to install. +#BuildRequires: nbdkit-srpm-macros >= 1.30.0 + # nbdkit is a metapackage pulling the server and a useful subset # of the plugins and filters. Requires: nbdkit-server%{?_isa} = %{version}-%{release} @@ -226,7 +200,6 @@ reading the nbdkit(1) and nbdkit-plugin(3) manual pages. %package server Summary: The %{name} server License: BSD -Provides: %{name}-null-plugin = %{version}-%{release} %description server This package contains the %{name} server with only the null plugin @@ -239,21 +212,6 @@ the metapackage "nbdkit". Summary: Basic plugins for %{name} License: BSD Requires: %{name}-server%{?_isa} = %{version}-%{release} -Provides: %{name}-data-plugin = %{version}-%{release} -Provides: %{name}-eval-plugin = %{version}-%{release} -Provides: %{name}-file-plugin = %{version}-%{release} -Provides: %{name}-floppy-plugin = %{version}-%{release} -Provides: %{name}-full-plugin = %{version}-%{release} -Provides: %{name}-info-plugin = %{version}-%{release} -Provides: %{name}-memory-plugin = %{version}-%{release} -Provides: %{name}-ondemand-plugin = %{version}-%{release} -Provides: %{name}-pattern-plugin = %{version}-%{release} -Provides: %{name}-partitioning-plugin = %{version}-%{release} -Provides: %{name}-random-plugin = %{version}-%{release} -Provides: %{name}-sh-plugin = %{version}-%{release} -Provides: %{name}-sparse-random-plugin = %{version}-%{release} -Provides: %{name}-split-plugin = %{version}-%{release} -Provides: %{name}-zero-plugin = %{version}-%{release} %description basic-plugins @@ -549,38 +507,6 @@ VMware VDDK for accessing VMware disks and servers. Summary: Basic filters for %{name} License: BSD Requires: %{name}-server%{?_isa} = %{version}-%{release} -Provides: %{name}-blocksize-filter = %{version}-%{release} -Provides: %{name}-cache-filter = %{version}-%{release} -Provides: %{name}-cacheextents-filter = %{version}-%{release} -Provides: %{name}-checkwrite-filter = %{version}-%{release} -Provides: %{name}-cow-filter = %{version}-%{release} -Provides: %{name}-ddrescue-filter = %{version}-%{release} -Provides: %{name}-delay-filter = %{version}-%{release} -Provides: %{name}-error-filter = %{version}-%{release} -Provides: %{name}-exitlast-filter = %{version}-%{release} -Provides: %{name}-exitwhen-filter = %{version}-%{release} -Provides: %{name}-exportname-filter = %{version}-%{release} -Provides: %{name}-extentlist-filter = %{version}-%{release} -Provides: %{name}-fua-filter = %{version}-%{release} -Provides: %{name}-ip-filter = %{version}-%{release} -Provides: %{name}-limit-filter = %{version}-%{release} -Provides: %{name}-log-filter = %{version}-%{release} -Provides: %{name}-multi-conn-filter = %{version}-%{release} -Provides: %{name}-nocache-filter = %{version}-%{release} -Provides: %{name}-noextents-filter = %{version}-%{release} -Provides: %{name}-nofilter-filter = %{version}-%{release} -Provides: %{name}-noparallel-filter = %{version}-%{release} -Provides: %{name}-nozero-filter = %{version}-%{release} -Provides: %{name}-offset-filter = %{version}-%{release} -Provides: %{name}-partition-filter = %{version}-%{release} -Provides: %{name}-pause-filter = %{version}-%{release} -Provides: %{name}-rate-filter = %{version}-%{release} -Provides: %{name}-readahead-filter = %{version}-%{release} -Provides: %{name}-retry-filter = %{version}-%{release} -Provides: %{name}-stats-filter = %{version}-%{release} -Provides: %{name}-swab-filter = %{version}-%{release} -Provides: %{name}-tls-fallback-filter = %{version}-%{release} -Provides: %{name}-truncate-filter = %{version}-%{release} %description basic-filters This package contains filters for %{name} which only depend on simple @@ -589,6 +515,8 @@ complex dependencies are packaged separately. nbdkit-blocksize-filter Adjust block size of requests sent to plugins. +nbdkit-blocksize-policy-filter Set block size constraints and policy. + nbdkit-cache-filter Server-side cache. nbdkit-cacheextents-filter Cache extents. @@ -637,12 +565,16 @@ nbdkit-partition-filter Serve a single partition. nbdkit-pause-filter Pause NBD requests. +nbdkit-protect-filter Write-protect parts of a plugin. + nbdkit-rate-filter Limit bandwidth by connection or server. nbdkit-readahead-filter Prefetch data when reading sequentially. nbdkit-retry-filter Reopen connection on error. +nbdkit-retry-request-filter Retry single requests on error. + nbdkit-stats-filter Display statistics about operations. nbdkit-swab-filter Filter for swapping byte order. @@ -705,8 +637,19 @@ for %{name}. Install this package if you want to develop plugins for %{name}. +%package srpm-macros +Summary: RPM Provides rules for %{name} plugins and filters +License: BSD +BuildArch: noarch + +%description srpm-macros +This package contains RPM rules that create the automatic Provides: +for %{name} plugins and filters found in the plugins directory. + + %package bash-completion Summary: Bash tab-completion for %{name} +License: BSD BuildArch: noarch Requires: bash-completion >= 2.0 Requires: %{name}-server = %{version}-%{release} @@ -779,10 +722,6 @@ find $RPM_BUILD_ROOT -name '*.la' -delete # rust plugin is built. Delete it if this happens. rm -f $RPM_BUILD_ROOT%{_mandir}/man3/nbdkit-rust-plugin.3* -# Remove the streaming plugin (deprecated upstream). -rm $RPM_BUILD_ROOT%{_libdir}/%{name}/plugins/nbdkit-streaming-plugin.so -rm $RPM_BUILD_ROOT%{_mandir}/man1/nbdkit-streaming-plugin.1* - %if 0%{?rhel} # In RHEL, remove some plugins we cannot --disable. for f in cc cdi torrent; do @@ -793,6 +732,11 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/%{name}/plugins/nbdkit-S3-plugin rm -f $RPM_BUILD_ROOT%{_mandir}/man1/nbdkit-S3-plugin.1* %endif +# Install RPM dependency generator. +mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/fileattrs/ +install -m 0644 %{SOURCE4} $RPM_BUILD_ROOT%{_rpmconfigdir}/fileattrs/ +install -m 0755 %{SOURCE5} $RPM_BUILD_ROOT%{_rpmconfigdir}/ + %check %ifnarch %{broken_test_arches} @@ -1085,6 +1029,7 @@ export LIBGUESTFS_TRACE=1 %doc README %license LICENSE %{_libdir}/%{name}/filters/nbdkit-blocksize-filter.so +%{_libdir}/%{name}/filters/nbdkit-blocksize-policy-filter.so %{_libdir}/%{name}/filters/nbdkit-cache-filter.so %{_libdir}/%{name}/filters/nbdkit-cacheextents-filter.so %{_libdir}/%{name}/filters/nbdkit-checkwrite-filter.so @@ -1109,14 +1054,17 @@ export LIBGUESTFS_TRACE=1 %{_libdir}/%{name}/filters/nbdkit-offset-filter.so %{_libdir}/%{name}/filters/nbdkit-partition-filter.so %{_libdir}/%{name}/filters/nbdkit-pause-filter.so +%{_libdir}/%{name}/filters/nbdkit-protect-filter.so %{_libdir}/%{name}/filters/nbdkit-rate-filter.so %{_libdir}/%{name}/filters/nbdkit-readahead-filter.so %{_libdir}/%{name}/filters/nbdkit-retry-filter.so +%{_libdir}/%{name}/filters/nbdkit-retry-request-filter.so %{_libdir}/%{name}/filters/nbdkit-stats-filter.so %{_libdir}/%{name}/filters/nbdkit-swab-filter.so %{_libdir}/%{name}/filters/nbdkit-tls-fallback-filter.so %{_libdir}/%{name}/filters/nbdkit-truncate-filter.so %{_mandir}/man1/nbdkit-blocksize-filter.1* +%{_mandir}/man1/nbdkit-blocksize-policy-filter.1* %{_mandir}/man1/nbdkit-cache-filter.1* %{_mandir}/man1/nbdkit-cacheextents-filter.1* %{_mandir}/man1/nbdkit-checkwrite-filter.1* @@ -1141,9 +1089,11 @@ export LIBGUESTFS_TRACE=1 %{_mandir}/man1/nbdkit-offset-filter.1* %{_mandir}/man1/nbdkit-partition-filter.1* %{_mandir}/man1/nbdkit-pause-filter.1* +%{_mandir}/man1/nbdkit-protect-filter.1* %{_mandir}/man1/nbdkit-rate-filter.1* %{_mandir}/man1/nbdkit-readahead-filter.1* %{_mandir}/man1/nbdkit-retry-filter.1* +%{_mandir}/man1/nbdkit-retry-request-filter.1* %{_mandir}/man1/nbdkit-stats-filter.1* %{_mandir}/man1/nbdkit-swab-filter.1* %{_mandir}/man1/nbdkit-tls-fallback-filter.1* @@ -1214,6 +1164,12 @@ export LIBGUESTFS_TRACE=1 %{_libdir}/pkgconfig/nbdkit.pc +%files srpm-macros +%license LICENSE +%{_rpmconfigdir}/fileattrs/nbdkit.attr +%{_rpmconfigdir}/nbdkit-find-provides + + %files bash-completion %license LICENSE %dir %{_datadir}/bash-completion/completions @@ -1221,6 +1177,14 @@ export LIBGUESTFS_TRACE=1 %changelog +* Fri Mar 04 2022 Richard W.M. Jones - 1.30.0-1 +- Rebase to new stable branch version 1.30.0 + resolves: rhbz#2059289 +- Add automatic provides generator and subpackage nbdkit-srpm-macros + resolves: rhbz#2059291 [bootstrap stage] +- New filters: blocksize-policy, protect, retry-request +- Fix license of bash-completion subpackage + * Mon Jan 24 2022 Richard W.M. Jones - 1.28.5-1 - Rebase to new stable branch version 1.28.5 resolves: rhbz#2011709 diff --git a/sources b/sources index 9793b35..61f30e8 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (nbdkit-1.28.5.tar.gz) = 0ea7bf1c4e1d4e5e1f2077aed7c65e62c5b09af8a54868ef8dfdd4b8eee3a8783a2e4a5f3488ccfad6776a15cec8cfd808979f84c2523d4033bf0fc572975f32 -SHA512 (nbdkit-1.28.5.tar.gz.sig) = e84575b4f0ee344d4cfb90bf0b285a6df2b5e7ffc46bb6e4e23ff47e85759494472c923b29fae367f97c7f140e649cc486a472397dbd375202ee44d8dfe0817b +SHA512 (nbdkit-1.30.0.tar.gz) = bdd9065c4faca312e103946a84901316443d8186e5b23658b721cd58e8d5e284ab6ef74996165edbf22c19bc1561068ac8c2eb368e21eaa227c43950d692e423 +SHA512 (nbdkit-1.30.0.tar.gz.sig) = bf4caf8eca8997f5033665f208454383967bc3f4f1c51925574698f3828efdf0b9004ac243bccd74a751b4edf48a53e956b1befe4e8bf29aa5a78647d5874e52