[Libguestfs] [nbdkit PATCH 1/4] server: Normalize plugin can_* values

Eric Blake eblake at redhat.com
Tue Mar 17 03:36:14 UTC 2020


The documentation for .can_write and friends mentioned merely that the
callback must return a boolean value, or -1 on failure.  Historically,
we have treated any non-zero value other than -1 as true, and some
plugins have sloppily relied on this behavior, including the
standalone nbd plugin prior to the use of libnbd in v1.14.  But in
1.15.1, we added an assert in our backend code if an enabled feature
bit is not exactly 1.  To avoid tripping the assertion, we have to
normalize the plugin values before storing our internal value.

Fixes: c306fa93ab
Signed-off-by: Eric Blake <eblake at redhat.com>
---
 server/plugins.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/server/plugins.c b/server/plugins.c
index 78ed6723..4a4fcdee 100644
--- a/server/plugins.c
+++ b/server/plugins.c
@@ -1,5 +1,5 @@
 /* nbdkit
- * Copyright (C) 2013-2019 Red Hat Inc.
+ * Copyright (C) 2013-2020 Red Hat Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -308,13 +308,21 @@ plugin_get_size (struct backend *b, void *handle)
   return p->plugin.get_size (handle);
 }

+static int normalize_bool (int value)
+{
+  if (value == -1 || value == 0)
+    return value;
+  /* Normalize all other non-zero values to true */
+  return 1;
+}
+
 static int
 plugin_can_write (struct backend *b, void *handle)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.can_write)
-    return p->plugin.can_write (handle);
+    return normalize_bool (p->plugin.can_write (handle));
   else
     return p->plugin.pwrite || p->plugin._pwrite_v1;
 }
@@ -325,7 +333,7 @@ plugin_can_flush (struct backend *b, void *handle)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.can_flush)
-    return p->plugin.can_flush (handle);
+    return normalize_bool (p->plugin.can_flush (handle));
   else
     return p->plugin.flush || p->plugin._flush_v1;
 }
@@ -336,7 +344,7 @@ plugin_is_rotational (struct backend *b, void *handle)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.is_rotational)
-    return p->plugin.is_rotational (handle);
+    return normalize_bool (p->plugin.is_rotational (handle));
   else
     return 0; /* assume false */
 }
@@ -347,7 +355,7 @@ plugin_can_trim (struct backend *b, void *handle)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.can_trim)
-    return p->plugin.can_trim (handle);
+    return normalize_bool (p->plugin.can_trim (handle));
   else
     return p->plugin.trim || p->plugin._trim_v1;
 }
@@ -380,7 +388,7 @@ plugin_can_fast_zero (struct backend *b, void *handle)
   int r;

   if (p->plugin.can_fast_zero)
-    return p->plugin.can_fast_zero (handle);
+    return normalize_bool (p->plugin.can_fast_zero (handle));
   /* Advertise support for fast zeroes if no .zero or .can_zero is
    * false: in those cases, we fail fast instead of using .pwrite.
    * This also works when v1 plugin has only ._zero_v1.
@@ -399,7 +407,7 @@ plugin_can_extents (struct backend *b, void *handle)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.can_extents)
-    return p->plugin.can_extents (handle);
+    return normalize_bool (p->plugin.can_extents (handle));
   else
     return p->plugin.extents != NULL;
 }
@@ -430,7 +438,7 @@ plugin_can_multi_conn (struct backend *b, void *handle)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

   if (p->plugin.can_multi_conn)
-    return p->plugin.can_multi_conn (handle);
+    return normalize_bool (p->plugin.can_multi_conn (handle));
   else
     return 0; /* assume false */
 }
-- 
2.25.1




More information about the Libguestfs mailing list