diff --git a/0001-ocaml-Call-caml_shutdown-when-unloading-the-plugin.patch b/0001-ocaml-Call-caml_shutdown-when-unloading-the-plugin.patch new file mode 100644 index 0000000..ea629d1 --- /dev/null +++ b/0001-ocaml-Call-caml_shutdown-when-unloading-the-plugin.patch @@ -0,0 +1,76 @@ +From 5a23c7cf3c5eccac6e6de775722bc1136a66be83 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 5 Jul 2021 17:54:45 +0100 +Subject: [PATCH 1/7] ocaml: Call caml_shutdown when unloading the plugin + +This has several useful effects (taken from the OCaml documentation): + +* Running the functions that were registered with "Stdlib.at_exit". + +* Triggering finalization of allocated custom blocks. For example, + "Stdlib.in_channel" and "Stdlib.out_channel" are represented by + custom blocks that enclose file descriptors, which are to be + released. + +* Unloading the dependent shared libraries that were loaded by the runtime, + including "dynlink" plugins. + +* Freeing the memory blocks that were allocated by the runtime with + "malloc". + +If the function is not present (for OCaml < 4.05) then we just skip +this step. + +(cherry picked from commit 99140272a0675b3d123d2c42cb0a5ab73b09fba2) +--- + configure.ac | 18 ++++++++++++++++++ + plugins/ocaml/plugin.c | 4 ++++ + 2 files changed, 22 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 9b171b7e..a7c4c8d3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -857,6 +857,24 @@ EOF + rm -f conftest.c conftest.o + ]) + ++dnl Check if OCaml has caml_shutdown (added 2014). ++AS_IF([test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && \ ++ test "x$enable_ocaml" = "xyes"],[ ++ AC_MSG_CHECKING([for caml_shutdown]) ++ cat >conftest.c <<'EOF' ++#include ++int main () { char *p = (void *) caml_shutdown; return 0; } ++EOF ++ AS_IF([$OCAMLC conftest.c >&AS_MESSAGE_LOG_FD 2>&1],[ ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE([HAVE_CAML_SHUTDOWN],[1], ++ [caml_shutdown found at compile time.]) ++ ],[ ++ AC_MSG_RESULT([no]) ++ ]) ++ rm -f conftest.c conftest.o ++]) ++ + dnl For developing plugins in Rust, optional. + AC_CHECK_PROG([CARGO],[cargo],[cargo],[no]) + AC_ARG_ENABLE([rust], +diff --git a/plugins/ocaml/plugin.c b/plugins/ocaml/plugin.c +index 00959cb6..9d7d72ad 100644 +--- a/plugins/ocaml/plugin.c ++++ b/plugins/ocaml/plugin.c +@@ -131,6 +131,10 @@ unload_wrapper (void) + free ((char *) plugin.config_help); + + remove_roots (); ++ ++#ifdef HAVE_CAML_SHUTDOWN ++ caml_shutdown (); ++#endif + } + + static void +-- +2.32.0 + diff --git a/0002-ocaml-Fix-valgrinding-by-only-ignoring-caml_stat_all.patch b/0002-ocaml-Fix-valgrinding-by-only-ignoring-caml_stat_all.patch new file mode 100644 index 0000000..aefbb25 --- /dev/null +++ b/0002-ocaml-Fix-valgrinding-by-only-ignoring-caml_stat_all.patch @@ -0,0 +1,39 @@ +From 397b7b245aee178b2683de8a34847843f658b43d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Mon, 5 Jul 2021 18:00:28 +0100 +Subject: [PATCH 2/7] ocaml: Fix valgrinding by only ignoring caml_stat_alloc* + functions + +These are meant to be "static" so are not freed by design. Other +allocations should all be freed, especially now that we are calling +caml_shutdown. + +(cherry picked from commit 875a5056758dca754225f49516a0f4c8e788ac94) +--- + valgrind/ocaml.suppressions | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/valgrind/ocaml.suppressions b/valgrind/ocaml.suppressions +index f74b0943..a2b7fc60 100644 +--- a/valgrind/ocaml.suppressions ++++ b/valgrind/ocaml.suppressions +@@ -29,11 +29,12 @@ + # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + # SUCH DAMAGE. + +-# OCaml, by design, doesn't bother to free the major heap before +-# calling exit. Ignore that leak. ++# OCaml caml_stat_* allocations are meant to be "static" so OCaml will ++# never free them by design. See the OCaml manual, chapter ++# "Interfacing C with OCaml". + { +- ocaml_heap_leak ++ ocaml_stat_allocations + Memcheck:Leak + ... +- fun:caml_alloc_for_heap ++ fun:caml_stat_alloc* + } +-- +2.32.0 + diff --git a/0003-ocaml-tests-Actually-call-.get_ready-method-in-test-.patch b/0003-ocaml-tests-Actually-call-.get_ready-method-in-test-.patch new file mode 100644 index 0000000..f3c88e6 --- /dev/null +++ b/0003-ocaml-tests-Actually-call-.get_ready-method-in-test-.patch @@ -0,0 +1,29 @@ +From 4efeffd80a5e85abf5603f20631910b2ef180317 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 13 Jul 2021 16:50:16 +0100 +Subject: [PATCH 3/7] ocaml: tests: Actually call .get_ready method in test + plugin + +It was added in a previous commit, but never called. + +Fixes: commit d52d0adf3d395f98f0fb4cd06044cc6dc7aeaef0 +(cherry picked from commit 156aa8337e5d1886c296a94de631b01c10f1bc78) +--- + tests/test_ocaml_plugin.ml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/test_ocaml_plugin.ml b/tests/test_ocaml_plugin.ml +index 2bbaa218..fee8528e 100644 +--- a/tests/test_ocaml_plugin.ml ++++ b/tests/test_ocaml_plugin.ml +@@ -99,6 +99,7 @@ let plugin = { + version = NBDKit.version (); + + load = Some load; ++ get_ready = Some get_ready; + unload = Some unload; + config = Some config; + config_complete = Some config_complete; +-- +2.32.0 + diff --git a/0004-ocaml-Rearrange-the-callbacks.patch b/0004-ocaml-Rearrange-the-callbacks.patch new file mode 100644 index 0000000..24a311f --- /dev/null +++ b/0004-ocaml-Rearrange-the-callbacks.patch @@ -0,0 +1,315 @@ +From 1610c0865534819eccefec55fd2d751843bb6d64 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 13 Jul 2021 16:15:45 +0100 +Subject: [PATCH 4/7] ocaml: Rearrange the callbacks + +Just refactoring. + +(cherry picked from commit e54e16e81c51dcbb16d70d83c5b0403babdf5f99) +--- + plugins/ocaml/NBDKit.mli | 31 +++++++++-------- + plugins/ocaml/callbacks.h | 34 +++++++++---------- + plugins/ocaml/NBDKit.ml | 68 ++++++++++++++++++-------------------- + tests/test_ocaml_plugin.ml | 9 ++--- + 4 files changed, 72 insertions(+), 70 deletions(-) + +diff --git a/plugins/ocaml/NBDKit.mli b/plugins/ocaml/NBDKit.mli +index ac4b0cbc..cda09f44 100644 +--- a/plugins/ocaml/NBDKit.mli ++++ b/plugins/ocaml/NBDKit.mli +@@ -69,33 +69,31 @@ type thread_model = + The ['a] parameter is the handle type returned by your + [open_connection] method and passed back to all connected calls. *) + type 'a plugin = { +- name : string; (* required *) ++ (* Plugin description. *) ++ name : string; (** required field *) + longname : string; + version : string; + description : string; + ++ (* Plugin lifecycle. *) + load : (unit -> unit) option; ++ get_ready : (unit -> unit) option; ++ after_fork : (unit -> unit) option; + unload : (unit -> unit) option; + +- dump_plugin : (unit -> unit) option; +- ++ (* Plugin configuration. *) + config : (string -> string -> unit) option; + config_complete : (unit -> unit) option; + config_help : string; + thread_model : (unit -> thread_model) option; + +- get_ready : (unit -> unit) option; +- after_fork : (unit -> unit) option; +- ++ (* Connection lifecycle. *) + preconnect : (bool -> unit) option; +- list_exports : (bool -> bool -> export list) option; +- default_export : (bool -> bool -> string) option; +- open_connection : (bool -> 'a) option; (* required *) ++ open_connection : (bool -> 'a) option; (** required field *) + close : ('a -> unit) option; + +- get_size : ('a -> int64) option; (* required *) +- export_description : ('a -> string) option; +- ++ (* NBD negotiation. *) ++ get_size : ('a -> int64) option; (** required field *) + can_cache : ('a -> cache_flag) option; + can_extents : ('a -> bool) option; + can_fast_zero : ('a -> bool) option; +@@ -107,13 +105,20 @@ type 'a plugin = { + can_zero : ('a -> bool) option; + is_rotational : ('a -> bool) option; + +- pread : ('a -> int32 -> int64 -> flags -> string) option; (* required *) ++ (* Serving data. *) ++ pread : ('a -> int32 -> int64 -> flags -> string) option; (* required field *) + pwrite : ('a -> string -> int64 -> flags -> unit) option; + flush : ('a -> flags -> unit) option; + trim : ('a -> int32 -> int64 -> flags -> unit) option; + zero : ('a -> int32 -> int64 -> flags -> unit) option; + extents : ('a -> int32 -> int64 -> flags -> extent list) option; + cache : ('a -> int32 -> int64 -> flags -> unit) option; ++ ++ (* Miscellaneous. *) ++ dump_plugin : (unit -> unit) option; ++ list_exports : (bool -> bool -> export list) option; ++ default_export : (bool -> bool -> string) option; ++ export_description : ('a -> string) option; + } + + (** The plugin with all fields set to [None], so you can write +diff --git a/plugins/ocaml/callbacks.h b/plugins/ocaml/callbacks.h +index 7171ef21..4d29fb73 100644 +--- a/plugins/ocaml/callbacks.h ++++ b/plugins/ocaml/callbacks.h +@@ -33,21 +33,8 @@ + /* This is not a header file. It is included at various places in + * plugin.c as a convenient way to define per-callback things. + */ +-CB(load) +-CB(unload) +-CB(dump_plugin) +-CB(config) +-CB(config_complete) +-CB(thread_model) +-CB(get_ready) + CB(after_fork) +-CB(preconnect) +-CB(list_exports) +-CB(default_export) +-CB(open) +-CB(close) +-CB(get_size) +-CB(export_description) ++CB(cache) + CB(can_cache) + CB(can_extents) + CB(can_fast_zero) +@@ -57,11 +44,24 @@ CB(can_multi_conn) + CB(can_trim) + CB(can_write) + CB(can_zero) ++CB(close) ++CB(config) ++CB(config_complete) ++CB(default_export) ++CB(dump_plugin) ++CB(export_description) ++CB(extents) ++CB(flush) ++CB(get_ready) ++CB(get_size) + CB(is_rotational) ++CB(list_exports) ++CB(load) ++CB(open) + CB(pread) ++CB(preconnect) + CB(pwrite) +-CB(flush) ++CB(thread_model) + CB(trim) ++CB(unload) + CB(zero) +-CB(extents) +-CB(cache) +diff --git a/plugins/ocaml/NBDKit.ml b/plugins/ocaml/NBDKit.ml +index cdc3bc58..529618d2 100644 +--- a/plugins/ocaml/NBDKit.ml ++++ b/plugins/ocaml/NBDKit.ml +@@ -65,27 +65,20 @@ type 'a plugin = { + description : string; + + load : (unit -> unit) option; ++ get_ready : (unit -> unit) option; ++ after_fork : (unit -> unit) option; + unload : (unit -> unit) option; + +- dump_plugin : (unit -> unit) option; +- + config : (string -> string -> unit) option; + config_complete : (unit -> unit) option; + config_help : string; + thread_model : (unit -> thread_model) option; + +- get_ready : (unit -> unit) option; +- after_fork : (unit -> unit) option; +- + preconnect : (bool -> unit) option; +- list_exports : (bool -> bool -> export list) option; +- default_export : (bool -> bool -> string) option; + open_connection : (bool -> 'a) option; + close : ('a -> unit) option; + + get_size : ('a -> int64) option; +- export_description : ('a -> string) option; +- + can_cache : ('a -> cache_flag) option; + can_extents : ('a -> bool) option; + can_fast_zero : ('a -> bool) option; +@@ -104,6 +97,11 @@ type 'a plugin = { + zero : ('a -> int32 -> int64 -> flags -> unit) option; + extents : ('a -> int32 -> int64 -> flags -> extent list) option; + cache : ('a -> int32 -> int64 -> flags -> unit) option; ++ ++ dump_plugin : (unit -> unit) option; ++ list_exports : (bool -> bool -> export list) option; ++ default_export : (bool -> bool -> string) option; ++ export_description : ('a -> string) option; + } + + let default_callbacks = { +@@ -113,27 +111,20 @@ let default_callbacks = { + description = ""; + + load = None; ++ get_ready = None; ++ after_fork = None; + unload = None; + +- dump_plugin = None; +- + config = None; + config_complete = None; + config_help = ""; + thread_model = None; + +- get_ready = None; +- after_fork = None; +- + preconnect = None; +- list_exports = None; +- default_export = None; + open_connection = None; + close = None; + + get_size = None; +- export_description = None; +- + can_cache = None; + can_extents = None; + can_fast_zero = None; +@@ -152,6 +143,11 @@ let default_callbacks = { + zero = None; + extents = None; + cache = None; ++ ++ dump_plugin = None; ++ list_exports = None; ++ default_export = None; ++ export_description = None; + } + + external set_name : string -> unit = "ocaml_nbdkit_set_name" "noalloc" +@@ -186,21 +182,8 @@ let register_plugin plugin = + if plugin.config_help <> "" then set_config_help plugin.config_help; + + let may f = function None -> () | Some a -> f a in +- may (set_field "load") plugin.load; +- may (set_field "unload") plugin.unload; +- may (set_field "dump_plugin") plugin.dump_plugin; +- may (set_field "config") plugin.config; +- may (set_field "config_complete") plugin.config_complete; +- may (set_field "thread_model") plugin.thread_model; +- may (set_field "get_ready") plugin.get_ready; + may (set_field "after_fork") plugin.after_fork; +- may (set_field "preconnect") plugin.preconnect; +- may (set_field "list_exports") plugin.list_exports; +- may (set_field "default_export") plugin.default_export; +- may (set_field "open") plugin.open_connection; +- may (set_field "close") plugin.close; +- may (set_field "get_size") plugin.get_size; +- may (set_field "export_description") plugin.export_description; ++ may (set_field "cache") plugin.cache; + may (set_field "can_cache") plugin.can_cache; + may (set_field "can_extents") plugin.can_extents; + may (set_field "can_fast_zero") plugin.can_fast_zero; +@@ -210,14 +193,27 @@ let register_plugin plugin = + may (set_field "can_trim") plugin.can_trim; + may (set_field "can_write") plugin.can_write; + may (set_field "can_zero") plugin.can_zero; ++ may (set_field "close") plugin.close; ++ may (set_field "config") plugin.config; ++ may (set_field "config_complete") plugin.config_complete; ++ may (set_field "default_export") plugin.default_export; ++ may (set_field "dump_plugin") plugin.dump_plugin; ++ may (set_field "export_description") plugin.export_description; ++ may (set_field "extents") plugin.extents; ++ may (set_field "flush") plugin.flush; ++ may (set_field "get_ready") plugin.get_ready; ++ may (set_field "get_size") plugin.get_size; + may (set_field "is_rotational") plugin.is_rotational; ++ may (set_field "list_exports") plugin.list_exports; ++ may (set_field "load") plugin.load; ++ may (set_field "open") plugin.open_connection; + may (set_field "pread") plugin.pread; ++ may (set_field "preconnect") plugin.preconnect; + may (set_field "pwrite") plugin.pwrite; +- may (set_field "flush") plugin.flush; ++ may (set_field "thread_model") plugin.thread_model; + may (set_field "trim") plugin.trim; +- may (set_field "zero") plugin.zero; +- may (set_field "extents") plugin.extents; +- may (set_field "cache") plugin.cache ++ may (set_field "unload") plugin.unload; ++ may (set_field "zero") plugin.zero + + (* Bindings to nbdkit server functions. *) + +diff --git a/tests/test_ocaml_plugin.ml b/tests/test_ocaml_plugin.ml +index fee8528e..00a65a75 100644 +--- a/tests/test_ocaml_plugin.ml ++++ b/tests/test_ocaml_plugin.ml +@@ -101,19 +101,20 @@ let plugin = { + load = Some load; + get_ready = Some get_ready; + unload = Some unload; ++ + config = Some config; + config_complete = Some config_complete; ++ thread_model = Some thread_model; + + open_connection = Some open_connection; + close = Some close; +- list_exports = Some list_exports; +- default_export = Some default_export; + get_size = Some get_size; + pread = Some pread; + pwrite = Some pwrite; +- + extents = Some extents; +- thread_model = Some thread_model; ++ ++ list_exports = Some list_exports; ++ default_export = Some default_export; + } + + let () = NBDKit.register_plugin plugin +-- +2.32.0 + diff --git a/0005-ocaml-Fix-comment-on-plugin-.pread-field.patch b/0005-ocaml-Fix-comment-on-plugin-.pread-field.patch new file mode 100644 index 0000000..9a2e20c --- /dev/null +++ b/0005-ocaml-Fix-comment-on-plugin-.pread-field.patch @@ -0,0 +1,29 @@ +From 229f106d65e2a54aa21afde9182b0e110a83b0df Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 15 Jul 2021 20:41:03 +0100 +Subject: [PATCH 5/7] ocaml: Fix comment on plugin .pread field + +Incorrectly updated in earlier commit. + +Fixes: commit e54e16e81c51dcbb16d70d83c5b0403babdf5f99 +(cherry picked from commit b42144fc3eb6869d3a3424036877f206c6c5f2b9) +--- + plugins/ocaml/NBDKit.mli | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/ocaml/NBDKit.mli b/plugins/ocaml/NBDKit.mli +index cda09f44..0f7b87e9 100644 +--- a/plugins/ocaml/NBDKit.mli ++++ b/plugins/ocaml/NBDKit.mli +@@ -106,7 +106,7 @@ type 'a plugin = { + is_rotational : ('a -> bool) option; + + (* Serving data. *) +- pread : ('a -> int32 -> int64 -> flags -> string) option; (* required field *) ++ pread : ('a -> int32 -> int64 -> flags -> string) option;(** required field *) + pwrite : ('a -> string -> int64 -> flags -> unit) option; + flush : ('a -> flags -> unit) option; + trim : ('a -> int32 -> int64 -> flags -> unit) option; +-- +2.32.0 + diff --git a/0006-docs-Correct-selinux-label-example.patch b/0006-docs-Correct-selinux-label-example.patch new file mode 100644 index 0000000..a6c398c --- /dev/null +++ b/0006-docs-Correct-selinux-label-example.patch @@ -0,0 +1,40 @@ +From 8c86f8bbc326ff1578989a03b3c98b06634f62c1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 22 Jul 2021 16:31:34 +0100 +Subject: [PATCH 6/7] docs: Correct --selinux-label example + +The actual label you should use for the internal socket is +system_u:object_r:svirt_socket_t:s0 (not svirt_t). + +The filesystem label is different and was not documented before, so +this is added. + +See also: +https://bugzilla.redhat.com/show_bug.cgi?id=1984938 + +(cherry picked from commit 835762d1c68e30f650032bc8d8280e6140d8e46f) +--- + docs/nbdkit.pod | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod +index 68399eca..5b679895 100644 +--- a/docs/nbdkit.pod ++++ b/docs/nbdkit.pod +@@ -377,9 +377,11 @@ socket. + + The common — perhaps only — use of this option is to allow libvirt + guests which are using SELinux and sVirt confinement to access nbdkit +-Unix domain sockets: ++Unix domain sockets. The example below shows how to do this. Note ++that the socket and filesystem labels are different. + +- nbdkit --selinux-label system_u:object_r:svirt_t:s0 ... ++ nbdkit -U /tmp/sock --selinux-label=system_u:object_r:svirt_socket_t:s0 ... ++ chcon system_u:object_r:svirt_image_t:s0 /tmp/sock + + =item B<--swap> + +-- +2.32.0 + diff --git a/0007-cow-Fix-assert-failure-in-cow_extents.patch b/0007-cow-Fix-assert-failure-in-cow_extents.patch new file mode 100644 index 0000000..637d9bf --- /dev/null +++ b/0007-cow-Fix-assert-failure-in-cow_extents.patch @@ -0,0 +1,148 @@ +From c0c0728f40466cf4a8ab4868002e331df6d85b1e Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 24 Jul 2021 13:30:55 +0100 +Subject: [PATCH 7/7] cow: Fix assert failure in cow_extents + +$ nbdkit sparse-random 4G --filter=cow --run 'nbdinfo --map $uri' +nbdkit: cow.c:591: cow_extents: Assertion `count > 0' failed. + +nbdinfo calls us with count = 0xfffffe00 [1] stored in a 32 bit +quantity. This was rounded up to the next block boundary and so +overflows (count becomes 0, hence the assertion). + +Use a 64 bit variable for count to allow rounding up. This requires +further changes as a further 32 bit variable must not be allowed to +overflow. + +This also adds a regression test. + +[1] UINT32_MAX - 512 + 1 from: +https://gitlab.com/nbdkit/libnbd/-/blob/c55c5d9960809efd27cd044d007a33ea1636f4b0/info/map.c#L64 + +(cherry picked from commit 4d66ab72b29fc56190c7a6368eff3a6ba94c0f9f) +--- + tests/Makefile.am | 2 ++ + filters/cow/cow.c | 16 +++++++++--- + tests/test-cow-extents-large.sh | 46 +++++++++++++++++++++++++++++++++ + 3 files changed, 61 insertions(+), 3 deletions(-) + create mode 100755 tests/test-cow-extents-large.sh + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index e0b31ba9..9630205d 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1402,6 +1402,7 @@ TESTS += \ + test-cow.sh \ + test-cow-extents1.sh \ + test-cow-extents2.sh \ ++ test-cow-extents-large.sh \ + test-cow-unaligned.sh \ + $(NULL) + endif +@@ -1410,6 +1411,7 @@ EXTRA_DIST += \ + test-cow.sh \ + test-cow-extents1.sh \ + test-cow-extents2.sh \ ++ test-cow-extents-large.sh \ + test-cow-null.sh \ + test-cow-unaligned.sh \ + $(NULL) +diff --git a/filters/cow/cow.c b/filters/cow/cow.c +index 83844845..3bd09399 100644 +--- a/filters/cow/cow.c ++++ b/filters/cow/cow.c +@@ -571,19 +571,23 @@ cow_cache (nbdkit_next *next, + /* Extents. */ + static int + cow_extents (nbdkit_next *next, +- void *handle, uint32_t count, uint64_t offset, uint32_t flags, ++ void *handle, uint32_t count32, uint64_t offset, uint32_t flags, + struct nbdkit_extents *extents, int *err) + { + const bool can_extents = next->can_extents (next); + const bool req_one = flags & NBDKIT_FLAG_REQ_ONE; ++ uint64_t count = count32; + uint64_t end; + uint64_t blknum; + +- /* To make this easier, align the requested extents to whole blocks. */ ++ /* To make this easier, align the requested extents to whole blocks. ++ * Note that count is a 64 bit variable containing at most a 32 bit ++ * value so rounding up is safe here. ++ */ + end = offset + count; + offset = ROUND_DOWN (offset, BLKSIZE); + end = ROUND_UP (end, BLKSIZE); +- count = end - offset; ++ count = end - offset; + blknum = offset / BLKSIZE; + + assert (IS_ALIGNED (offset, BLKSIZE)); +@@ -628,6 +632,12 @@ cow_extents (nbdkit_next *next, + * as we can. + */ + for (;;) { ++ /* nbdkit_extents_full cannot read more than a 32 bit range ++ * (range_count), but count is a 64 bit quantity, so don't ++ * overflow range_count here. ++ */ ++ if (range_count >= UINT32_MAX - BLKSIZE + 1) break; ++ + blknum++; + offset += BLKSIZE; + count -= BLKSIZE; +diff --git a/tests/test-cow-extents-large.sh b/tests/test-cow-extents-large.sh +new file mode 100755 +index 00000000..ea981dcb +--- /dev/null ++++ b/tests/test-cow-extents-large.sh +@@ -0,0 +1,46 @@ ++#!/usr/bin/env bash ++# nbdkit ++# Copyright (C) 2018-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. ++ ++# Regression test of an earlier overflow in cow_extents. ++# https://listman.redhat.com/archives/libguestfs/2021-July/msg00037.html ++ ++source ./functions.sh ++set -e ++set -x ++ ++requires_filter cow ++requires_plugin sparse-random ++requires nbdinfo --version ++ ++for size in 0 3G 4G 5G 8G; do ++ nbdkit -U - sparse-random $size --filter=cow --run 'nbdinfo --map $uri' ++done +-- +2.32.0 + diff --git a/nbdkit.spec b/nbdkit.spec index ad6d82d..1b6062d 100644 --- a/nbdkit.spec +++ b/nbdkit.spec @@ -51,7 +51,7 @@ ExclusiveArch: x86_64 Name: nbdkit Version: 1.26.2 -Release: 1%{?dist} +Release: 1%{?dist}.1 Summary: NBD server License: BSD @@ -72,6 +72,15 @@ Source2: libguestfs.keyring # Maintainer script which helps with handling patches. Source3: copy-patches.sh +# Patches in upstream stable-1.26 branch. +Patch0001: 0001-ocaml-Call-caml_shutdown-when-unloading-the-plugin.patch +Patch0002: 0002-ocaml-Fix-valgrinding-by-only-ignoring-caml_stat_all.patch +Patch0003: 0003-ocaml-tests-Actually-call-.get_ready-method-in-test-.patch +Patch0004: 0004-ocaml-Rearrange-the-callbacks.patch +Patch0005: 0005-ocaml-Fix-comment-on-plugin-.pread-field.patch +Patch0006: 0006-docs-Correct-selinux-label-example.patch +Patch0007: 0007-cow-Fix-assert-failure-in-cow_extents.patch + BuildRequires: make %if 0%{patches_touch_autotools} BuildRequires: autoconf, automake, libtool @@ -1241,6 +1250,9 @@ export LIBGUESTFS_TRACE=1 %changelog +* Mon Jul 26 2021 Richard W.M. Jones - 1.26.2-1.1 +- Add patches from upstream stable-1.26 branch, fixing a virt-v2v crash + * Mon Jul 05 2021 Richard W.M. Jones - 1.26.2-1 - New upstream stable version 1.26.2.