[Libguestfs] [PATCH nbdkit 5/6] ocaml: Always unregister the global root and free the handle

Richard W.M. Jones rjones at redhat.com
Wed Jun 21 21:08:56 UTC 2023


If the OCaml code did not provide a close method, we would never call
close_wrapper, and then we ended up leaking the global root and handle.
---
 plugins/ocaml/plugin.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/plugins/ocaml/plugin.c b/plugins/ocaml/plugin.c
index fe781f9af..a4671d6ed 100644
--- a/plugins/ocaml/plugin.c
+++ b/plugins/ocaml/plugin.c
@@ -76,6 +76,7 @@ constructor (void)
  * nbdkit_plugin struct and return it from our own plugin_init
  * function.
  */
+static void close_wrapper (void *h);
 static void unload_wrapper (void);
 static void free_strings (void);
 static void remove_roots (void);
@@ -92,6 +93,10 @@ static struct nbdkit_plugin plugin = {
    */
   .name = NULL,
 
+  /* We always call these, even if the OCaml code does not provide a
+   * callback.
+   */
+  .close = close_wrapper,
   .unload = unload_wrapper,
 };
 
@@ -345,6 +350,9 @@ open_wrapper (int readonly)
   CAMLreturnT (void *, ret);
 }
 
+/* We always have a close function, since we need to unregister the
+ * global root and free the handle.
+ */
 static void
 close_wrapper (void *h)
 {
@@ -352,10 +360,12 @@ close_wrapper (void *h)
   CAMLparam0 ();
   CAMLlocal1 (rv);
 
-  rv = caml_callback_exn (close_fn, *(value *) h);
-  if (Is_exception_result (rv)) {
-    nbdkit_error ("%s", caml_format_exception (Extract_exception (rv)));
-    /*FALLTHROUGH*/
+  if (close_fn) {
+    rv = caml_callback_exn (close_fn, *(value *) h);
+    if (Is_exception_result (rv)) {
+      nbdkit_error ("%s", caml_format_exception (Extract_exception (rv)));
+      /*FALLTHROUGH*/
+    }
   }
 
   caml_remove_generational_global_root (h);
-- 
2.41.0



More information about the Libguestfs mailing list