[Libguestfs] [PATCH nbdkit] plugins: python: Add error example

Nir Soffer nsoffer at redhat.com
Sun Jan 30 22:14:02 UTC 2022


This plugin simulates errors in pread, pwrite, and extents. This is
useful for testing error handling in NBD clients, and understanding how
plugin exceptions are reported to the NBD client.
---
 plugins/python/Makefile.am       |  1 +
 plugins/python/examples/error.py | 77 ++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 plugins/python/examples/error.py

diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am
index eecd7e89..e6e6c9e6 100644
--- a/plugins/python/Makefile.am
+++ b/plugins/python/Makefile.am
@@ -27,20 +27,21 @@
 # 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 $(top_srcdir)/common-rules.mk
 
 EXTRA_DIST = \
 	nbdkit-python-plugin.pod \
 	examples/file.py \
+	examples/error.py \
 	examples/imageio.py \
 	examples/ramdisk.py \
 	examples/url.py \
 	$(NULL)
 
 if HAVE_PYTHON
 
 plugin_LTLIBRARIES = nbdkit-python-plugin.la
 
 nbdkit_python_plugin_la_SOURCES = \
diff --git a/plugins/python/examples/error.py b/plugins/python/examples/error.py
new file mode 100644
index 00000000..0331a83e
--- /dev/null
+++ b/plugins/python/examples/error.py
@@ -0,0 +1,77 @@
+# Example Python plugin.
+#
+# This plugin simulates errors for testing NBD client error hanlding.
+# Every odd call will fail, and every even call will succeed, unless
+# there a real error accesing the specified file.
+#
+# This example can be freely used for any purpose.
+
+# Run it from the build directory like this:
+#
+#   ./nbdkit -f -v python ./plugins/python/examples/error.py file=test.img
+#
+# Or run it after installing nbdkit like this:
+#
+#   nbdkit -f -v python ./plugins/python/examples/error.py file=test.img
+#
+# The -f -v arguments are optional.  They cause the server to stay in
+# the foreground and print debugging, which is useful when testing.
+
+import os
+
+API_VERSION = 2
+
+filename = None
+calls = 0
+
+
+def config(key, value):
+    global filename
+    assert key == "file"
+    filename = value
+
+
+def open(readonly):
+    flags = os.O_RDONLY if readonly else os.O_RDWR
+    return {"fd": os.open(filename, flags)}
+
+
+def can_extents(h):
+    return True
+
+
+def get_size(h):
+    return os.stat(h["fd"]).st_size
+
+
+def extents(h, count, offset, flags):
+    global calls
+    calls += 1
+    if calls % 2:
+        raise RuntimeError(f"extents error offset={offset} count={count}")
+
+    # We don't really support extents, so we report the entire file as
+    # data.
+    return [(offset, count, 0)]
+
+
+def pread(h, buf, offset, flags):
+    global calls
+    calls += 1
+    if calls % 2:
+        raise RuntimeError(f"pread error offset={offset} count={len(buf)}")
+
+    os.lseek(h["fd"], offset, os.SEEK_SET)
+    n = os.readv(h['fd'], [buf])
+    assert n == len(buf)
+
+
+def pwrite(h, buf, offset, flags):
+    global calls
+    calls += 1
+    if calls % 2:
+        raise RuntimeError(f"pwrite error offset={offset} count={len(buf)}")
+
+    os.lseek(h["fd"], offset, os.SEEK_SET)
+    n = os.writev(h['fd'], [buf])
+    assert n == len(buf)
-- 
2.34.1




More information about the Libguestfs mailing list