[PATCH] v2v: parse_libvirt_xml: number disks from 0 (RHBZ#1615885)
by Pino Toscano
When parsing the libvirt XML, make sure to assign the IDs for disks
(s_disk_id) from 0 instead of 1, just like all the other input modes not
based on libvirt XML.
---
v2v/parse_libvirt_xml.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
index 78a6e71c0..dac99511c 100644
--- a/v2v/parse_libvirt_xml.ml
+++ b/v2v/parse_libvirt_xml.ml
@@ -246,7 +246,7 @@ let parse_libvirt_xml ?conn xml =
(* Non-removable disk devices. *)
let disks =
let get_disks, add_disk =
- let disks = ref [] and i = ref 0 in
+ let disks = ref [] and i = ref (-1) in
let get_disks () = List.rev !disks in
let add_disk qemu_uri format controller p_source =
incr i;
--
2.17.1
6 years, 4 months
[PATCH] v2v: Verify that ’source.s_disks.s_disk_id‘s are all unique.
by Richard W.M. Jones
---
v2v/v2v.ml | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 09bc4f37d..1775200d3 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -31,6 +31,7 @@ open Utils
open Cmdline
module G = Guestfs
+module IntSet = Set.Make(struct let compare = compare type t = int end)
(* Conversion mode, either normal (copying) or [--in-place]. *)
type conversion_mode =
@@ -234,10 +235,15 @@ and open_source cmdline input =
if source.s_disks = [] then
error (f_"source has no hard disks!");
- List.iter (
- fun disk ->
- assert (disk.s_qemu_uri <> "");
- ) source.s_disks;
+ let () =
+ let ids = ref IntSet.empty in
+ List.iter (
+ fun { s_qemu_uri; s_disk_id } ->
+ assert (s_qemu_uri <> "");
+ (* Check s_disk_id are all unique. *)
+ assert (not (IntSet.mem s_disk_id !ids));
+ ids := IntSet.add s_disk_id !ids
+ ) source.s_disks in
source
--
2.18.0
6 years, 4 months
[PATCH] v2v: -o rhv-upload: Fix error message disk numbering (RHBZ#1615885).
by Richard W.M. Jones
Thanks: Xiaodai Wang
---
v2v/output_rhv_upload.ml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
index 6260eaac5..df91a117f 100644
--- a/v2v/output_rhv_upload.ml
+++ b/v2v/output_rhv_upload.ml
@@ -361,13 +361,13 @@ If the messages above are not sufficient to diagnose the problem then add the
*)
let nr_disks = List.length targets in
let image_uuids =
- List.map (
- fun t ->
+ List.mapi (
+ fun i t ->
let id = t.target_overlay.ov_source.s_disk_id in
let diskid_file = diskid_file_of_id id in
if not (wait_for_file diskid_file finalization_timeout) then
error (f_"transfer of disk %d/%d failed, see earlier error messages")
- (id+1) nr_disks;
+ (i+1) nr_disks;
let diskid = read_whole_file diskid_file in
diskid
) targets in
--
2.18.0
6 years, 4 months
[PATCH nbdkit 00/10] FreeBSD support.
by Richard W.M. Jones
With these patches, a majority of tests pass. The notable
things which are still broken:
- Because FreeBSD links /home -> /usr/home, $(pwd) gives a different
result from realpath(2). Therefore some tests which implicitly
rely on (eg) a plugin which calls nbdkit_realpath internally and
then checking that path against $(pwd) fail.
- Shebangs (#!) don't seem to work the same way under FreeBSD as
they do under the Linux kernel. In any case ‘#!/usr/sbin/nbdkit perl’
runs the script under the shell. I didn't investigate why so far.
- You have to use GNU make (gmake). BSD make gets very confused by
automake Makefiles. I don't know if it's something we're doing
wrong or if it's just not supposed to work.
Rich.
6 years, 4 months
[PATCH nbdkit] vddk: Document issue with out of memory errors
by Richard W.M. Jones
Note this fix is incomplete / not ready for upstream:
(1) We haven't definitively proven this is the issue. Mor is
still investigating and producing the proof.
(2) We will need to make a similar change to virt-v2v documentation.
Rich.
6 years, 4 months
[PATCH] Change wording from "twice" to "more than once" in error messages
by Pino Toscano
When erroring out about duplicated parameters, say "more than once"
instead of "twice", since there can be more than two repeated
parameters.
Thanks to: Xiaodai Wang
---
generator/fish.ml | 2 +-
generator/perl.ml | 2 +-
resize/resize.ml | 4 ++--
tools/virt-tar | 4 ++--
v2v/input_libvirt_vddk.ml | 2 +-
v2v/output_rhv_upload.ml | 4 ++--
v2v/output_vdsm.ml | 4 ++--
7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/generator/fish.ml b/generator/fish.ml
index 33da789bd..708c1b3a9 100644
--- a/generator/fish.ml
+++ b/generator/fish.ml
@@ -367,7 +367,7 @@ let generate_fish_run_cmds actions () =
pr " }\n";
pr "\n";
pr " if (optargs_s.bitmask & this_mask) {\n";
- pr " fprintf (stderr, _(\"%%s: optional argument \\\"%%s\\\" given twice\\n\"),\n";
+ pr " fprintf (stderr, _(\"%%s: optional argument \\\"%%s\\\" given more than once\\n\"),\n";
pr " cmd, this_arg);\n";
pr " goto out;\n";
pr " }\n";
diff --git a/generator/perl.ml b/generator/perl.ml
index 5fa00a92d..cd0595640 100644
--- a/generator/perl.ml
+++ b/generator/perl.ml
@@ -496,7 +496,7 @@ PREINIT:
) optargs;
pr "croak (\"unknown optional argument '%%s'\", this_arg);\n";
pr " if (optargs_s.bitmask & this_mask)\n";
- pr " croak (\"optional argument '%%s' given twice\",\n";
+ pr " croak (\"optional argument '%%s' given more than once\",\n";
pr " this_arg);\n";
pr " optargs_s.bitmask |= this_mask;\n";
pr " }\n";
diff --git a/resize/resize.ml b/resize/resize.ml
index 8e4bb1b16..174f1c699 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -170,7 +170,7 @@ let main () =
let expand = ref "" in
let set_expand s =
if s = "" then error (f_"empty --expand option")
- else if !expand <> "" then error (f_"--expand option given twice")
+ else if !expand <> "" then error (f_"--expand option given more than once")
else expand := s
in
let expand_content = ref true in
@@ -186,7 +186,7 @@ let main () =
let shrink = ref "" in
let set_shrink s =
if s = "" then error (f_"empty --shrink option")
- else if !shrink <> "" then error (f_"--shrink option given twice")
+ else if !shrink <> "" then error (f_"--shrink option given more than once")
else shrink := s
in
let sparse = ref true in
diff --git a/tools/virt-tar b/tools/virt-tar
index 2d5c8b0b7..57e6b2602 100755
--- a/tools/virt-tar
+++ b/tools/virt-tar
@@ -187,14 +187,14 @@ Specify that the input or output tarball is gzip-compressed.
sub set_mode_x
{
- die __"virt-tar: extract/upload mode specified twice on the command line\n"
+ die __"virt-tar: extract/upload mode specified more than once on the command line\n"
if $mode;
$mode = "x";
}
sub set_mode_u
{
- die __"virt-tar: extract/upload mode specified twice on the command line\n"
+ die __"virt-tar: extract/upload mode specified more than once on the command line\n"
if $mode;
$mode = "u";
}
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
index 630a07e26..c868b997c 100644
--- a/v2v/input_libvirt_vddk.ml
+++ b/v2v/input_libvirt_vddk.ml
@@ -87,7 +87,7 @@ let parse_input_options options =
(key, value)
) options in
- (* Check no option appears twice. *)
+ (* Check no option appears more than once. *)
let keys = List.map fst options in
if List.length keys <> List.length (List.sort_uniq keys) then
error (f_"-it vddk: duplicate -io options on the command line");
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
index 6260eaac5..2bff35029 100644
--- a/v2v/output_rhv_upload.ml
+++ b/v2v/output_rhv_upload.ml
@@ -53,11 +53,11 @@ let parse_output_options options =
function
| "rhv-cafile", v ->
if !rhv_cafile <> None then
- error (f_"-o rhv-upload: -oo rhv-cafile set twice");
+ error (f_"-o rhv-upload: -oo rhv-cafile set more than once");
rhv_cafile := Some v
| "rhv-cluster", v ->
if !rhv_cluster <> None then
- error (f_"-o rhv-upload: -oo rhv-cluster set twice");
+ error (f_"-o rhv-upload: -oo rhv-cluster set more than once");
rhv_cluster := Some v
| "rhv-direct", "" -> rhv_direct := true
| "rhv-direct", v -> rhv_direct := bool_of_string v
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
index 95eb1eaf7..dc107cf2f 100644
--- a/v2v/output_vdsm.ml
+++ b/v2v/output_vdsm.ml
@@ -69,11 +69,11 @@ let parse_output_options options =
error (f_"-o vdsm: unknown vdsm-compat level ‘%s’") v
| "vdsm-vm-uuid", v ->
if !vm_uuid <> None then
- error (f_"-o vdsm: -oo vdsm-vm-uuid set twice");
+ error (f_"-o vdsm: -oo vdsm-vm-uuid set more than once");
vm_uuid := Some v;
| "vdsm-ovf-output", v ->
if !ovf_output <> None then
- error (f_"-o vdsm: -oo vdsm-ovf-output set twice");
+ error (f_"-o vdsm: -oo vdsm-ovf-output set more than once");
ovf_output := Some v;
| "vdsm-ovf-flavour", v ->
ovf_flavour := Create_ovf.ovf_flavour_of_string v
--
2.17.1
6 years, 4 months
[PATCH] v2v: parse_libvirt_xml: handle srN CDROM devices (RHBZ#1612785)
by Pino Toscano
This device naming is mostly written by virt-p2v, so get the slot from
it directly without using the drive_index "decoding" function.
---
v2v/parse_libvirt_xml.ml | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
index 36d2f66dd..55432f537 100644
--- a/v2v/parse_libvirt_xml.ml
+++ b/v2v/parse_libvirt_xml.ml
@@ -396,7 +396,15 @@ let parse_libvirt_xml ?conn xml =
else
loop rest
in
- loop ["hd"; "sd"; "vd"; "xvd"; "fd"] in
+ if String.is_prefix dev "sr" then (
+ let name = String.sub dev 2 (String.length dev - 2) in
+ try Some (int_of_string name)
+ with Failure _ ->
+ warning (f_"could not parse device name ‘%s’ from the source libvirt XML") dev;
+ None
+ )
+ else
+ loop ["hd"; "sd"; "vd"; "xvd"; "fd"] in
let typ =
match xpath_string "@device" with
--
2.17.1
6 years, 4 months
Using SPDK as QEMU's rootfs disk && A patch for libguestfs to support SPDK
by Bob Chen
Hi guys,
During the last few weeks, I've been looking at how to use SPDK as QEMU's
bootable rootfs disk.
I managed to boot up a SPDK rootfs disk by using OVMF UEFI boot-loader. And
in order to deploy the guest OS before start-up(which has a unrecognizable
filesystem to the host), I have written a small patch for the libguestfs.
It was based on Redhat's CentOS libguestfs-1.36.10 RPM, hopefully somebody
could add this SPDK support into the mainline code.
What I'm asking here is a new problem I encountered yesterday. When I
increased the guest memory to more than 8GB, the guest kernel would crash
at boot-up (see attached screen-shot). This issue would not be reproduced
if I only use SPDK as the data disk.
Maybe there is something wrong with the boot-loader?
Thanks, Bob
<0083-Add-SPDK-drive-support.patch>
------------------------------------------------------
>From 7927b0fa080db923989cef7181531dfaa09ccf6c Mon Sep 17 00:00:00 2001
From: Bob Chen <a175818323(a)gmail.com>
Date: Fri, 27 Jul 2018 12:55:28 +0800
Subject: [PATCH 1/1] Add SPDK drive support
---
lib/drives.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
lib/guestfs-internal.h | 2 ++
lib/launch-direct.c | 20 ++++++++++++++++++--
lib/launch-libvirt.c | 3 +++
lib/qemu.c | 3 +++
5 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/lib/drives.c b/lib/drives.c
index d3887c1..780b1b2 100644
--- a/lib/drives.c
+++ b/lib/drives.c
@@ -396,6 +396,45 @@ create_drive_iscsi (guestfs_h *g,
}
#endif /* DISABLED IN RHEL 7 */
+static struct drive *
+create_drive_spdk (guestfs_h *g,
+ const struct drive_create_data *data)
+{
+ if (data->username != NULL) {
+ error (g, _("spdk: you cannot specify a username with this protocol"));
+ return NULL;
+ }
+ if (data->secret != NULL) {
+ error (g, _("spdk: you cannot specify a secret with this protocol"));
+ return NULL;
+ }
+
+ if (data->nr_servers != 1) {
+ error (g, _("spdk: you must specify exactly one server"));
+ return NULL;
+ }
+
+ if (data->servers[0].transport != drive_transport_unix) {
+ error (g, _("spdk: only unix transport is supported"));
+ return NULL;
+ }
+
+ return create_drive_non_file (g, data);
+}
+
+bool
+guestfs_int_has_spdk_drive (guestfs_h *g)
+{
+ size_t i;
+ struct drive *drv;
+ ITER_DRIVES(g, i, drv) {
+ if (drv->src.protocol == drive_protocol_spdk) {
+ return true;
+ }
+ }
+ return false;
+}
+
/**
* Create the special F</dev/null> drive.
*
@@ -494,6 +533,7 @@ guestfs_int_drive_protocol_to_string (enum
drive_protocol protocol)
case drive_protocol_sheepdog: return "sheepdog";
case drive_protocol_ssh: return "ssh";
case drive_protocol_tftp: return "tftp";
+ case drive_protocol_spdk: return "spdk";
}
abort ();
}
@@ -878,6 +918,11 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char
*filename,
drv = create_drive_curl (g, &data);
}
#endif /* DISABLED IN RHEL 7 */
+ else if (STREQ (protocol, "spdk")) {
+ data.protocol = drive_protocol_spdk;
+ data.iface = safe_strdup(g, "vhost-user-scsi-pci");
+ drv = create_drive_spdk(g, &data);
+ }
else {
error (g, _("unknown protocol '%s'"), protocol);
drv = NULL; /*FALLTHROUGH*/
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 3bae02b..a0e5573 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -199,6 +199,7 @@ enum drive_protocol {
drive_protocol_sheepdog,
drive_protocol_ssh,
drive_protocol_tftp,
+ drive_protocol_spdk,
};
enum drive_transport {
@@ -829,6 +830,7 @@ extern void guestfs_int_rollback_drives (guestfs_h *g,
size_t);
extern void guestfs_int_add_dummy_appliance_drive (guestfs_h *g);
extern void guestfs_int_free_drives (guestfs_h *g);
extern const char *guestfs_int_drive_protocol_to_string (enum
drive_protocol protocol);
+extern bool guestfs_int_has_spdk_drive (guestfs_h *g);
/* appliance.c */
extern int guestfs_int_build_appliance (guestfs_h *g, char **kernel, char
**initrd, char **appliance);
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
index 3d6e72e..f157324 100644
--- a/lib/launch-direct.c
+++ b/lib/launch-direct.c
@@ -409,8 +409,17 @@ launch_direct (guestfs_h *g, void *datav, const char
*arg)
ADD_CMDLINE_PRINTF ("%d", g->smp);
}
- ADD_CMDLINE ("-m");
- ADD_CMDLINE_PRINTF ("%d", g->memsize);
+ if (guestfs_int_has_spdk_drive(g)) {
+ ADD_CMDLINE ("-m");
+ ADD_CMDLINE ("1G");
+ ADD_CMDLINE ("-object");
+ ADD_CMDLINE
("memory-backend-file,id=mem0,size=1G,mem-path=/dev/hugepages,share=on");
+ ADD_CMDLINE ("-numa");
+ ADD_CMDLINE ("node,memdev=mem0");
+ } else {
+ ADD_CMDLINE ("-m");
+ ADD_CMDLINE_PRINTF ("%d", g->memsize);
+ }
/* Force exit instead of reboot on panic */
ADD_CMDLINE ("-no-reboot");
@@ -567,6 +576,13 @@ launch_direct (guestfs_h *g, void *datav, const char
*arg)
goto cleanup0;
}
#endif
+ else if (drv->iface && STREQ(drv->iface, "vhost-user-scsi-pci")) {
+ /* SPDK */
+ ADD_CMDLINE ("-chardev");
+ ADD_CMDLINE_PRINTF ("socket,id=vhost,path=%s", escaped_file);
+ ADD_CMDLINE ("-device");
+ ADD_CMDLINE ("vhost-user-scsi-pci,chardev=vhost");
+ }
else if (drv->iface) {
ADD_CMDLINE ("-drive");
ADD_CMDLINE_PRINTF ("%s,if=%s", param, drv->iface);
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index 05c398b..468ece9 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -1548,6 +1548,9 @@ construct_libvirt_xml_disk (guestfs_h *g,
case drive_protocol_tftp:
error (g, _("libvirt does not support the qemu curl driver
protocols (ftp, http, etc.); try setting LIBGUESTFS_BACKEND=direct"));
return -1;
+ case drive_protocol_spdk:
+ error (g, _("libvirt does not support SPDK driver protocol yet;
try setting LIBGUESTFS_BACKEND=direct"));
+ return -1;
}
if (construct_libvirt_xml_disk_target (g, xo, drv_index) == -1)
diff --git a/lib/qemu.c b/lib/qemu.c
index 887e31b..a77ea87 100644
--- a/lib/qemu.c
+++ b/lib/qemu.c
@@ -942,6 +942,8 @@ guestfs_int_drive_source_qemu_param (guestfs_h *g,
case drive_protocol_tftp:
return make_uri (g, "tftp", src->username, src->secret,
&src->servers[0], src->u.exportname);
+ case drive_protocol_spdk:
+ return safe_strdup(g, src->servers[0].u.socket);
}
abort ();
@@ -1016,6 +1018,7 @@ guestfs_int_discard_possible (guestfs_h *g, struct
drive *drv,
case drive_protocol_https:
case drive_protocol_ssh:
case drive_protocol_tftp:
+ case drive_protocol_spdk:
NOT_SUPPORTED (g, -1,
_("discard cannot be enabled on this drive: "
"protocol '%s' does not support discard"),
--
1.8.3.1
6 years, 4 months
[PATCH nbdkit] python: Try harder to print the full traceback on error.
by Richard W.M. Jones
The tracebacks are compressed into a single line because we're using
PyObject_Str, but they are just about usable if not very readable.
For example you would see an error like this:
nbdkit: error: ./python-exception.py: config_complete: error: ['Traceback (most recent call last):\n', ' File "./python-exception.py", line 54, in config_complete\n raise_error1()\n', ' File "./python-exception.py", line 48, in raise_error1\n raise_error2()\n', ' File "./python-exception.py", line 45, in raise_error2\n raise RuntimeError("this is the test string")\n', 'RuntimeError: this is the test string\n']
which can be read by manually unfolding the exception in an editor as:
nbdkit: error: ./python-exception.py: config_complete: error:
Traceback (most recent call last):
File "./python-exception.py", line 54, in config_complete
raise_error1()
File "./python-exception.py", line 48, in raise_error1
raise_error2()
File "./python-exception.py", line 45, in raise_error2
raise RuntimeError("this is the test string")
RuntimeError: this is the test string
This also fixes the Python exception test which, it turned out, was
not testing anything. It now tests both simple exceptions and
tracebacks.
Tested with Python 2.7.15 & 3.6.6.
---
plugins/python/python.c | 92 ++++++++++++++++++++++++++++------
tests/python-exception.py | 20 +++++++-
tests/test-python-exception.sh | 13 ++++-
3 files changed, 109 insertions(+), 16 deletions(-)
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 7eb91d7..3450b9b 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -129,27 +129,91 @@ python_to_string (PyObject *str)
return NULL;
}
+/* This is the fallback in case we cannot get the full traceback. */
+static void
+print_python_error (const char *callback, PyObject *error)
+{
+ PyObject *error_str;
+ char *error_cstr = NULL;
+
+ error_str = PyObject_Str (error);
+ error_cstr = python_to_string (error_str);
+ nbdkit_error ("%s: %s: error: %s",
+ script, callback,
+ error_cstr ? error_cstr : "<unknown>");
+ Py_DECREF (error_str);
+ free (error_cstr);
+}
+
+/* Convert the Python traceback to a string and call nbdkit_error.
+ * https://stackoverflow.com/a/15907460/7126113
+ */
+static int
+print_python_traceback (const char *callback,
+ PyObject *type, PyObject *error, PyObject *traceback)
+{
+ PyObject *module_name, *traceback_module, *format_exception_fn, *rv,
+ *traceback_str;
+ char *traceback_cstr;
+
+#ifdef HAVE_PYSTRING_FROMSTRING
+ module_name = PyString_FromString ("traceback");
+#else
+ module_name = PyUnicode_FromString ("traceback");
+#endif
+ traceback_module = PyImport_Import (module_name);
+ Py_DECREF (module_name);
+
+ /* couldn't 'import traceback' */
+ if (traceback_module == NULL)
+ return -1;
+
+ format_exception_fn = PyObject_GetAttrString (traceback_module,
+ "format_exception");
+ if (format_exception_fn == NULL)
+ return -1;
+ if (!PyCallable_Check (format_exception_fn))
+ return -1;
+
+ rv = PyObject_CallFunctionObjArgs (format_exception_fn,
+ type, error, traceback, NULL);
+ traceback_str = PyObject_Str (rv);
+ traceback_cstr = python_to_string (traceback_str);
+ if (traceback_cstr == NULL) {
+ Py_DECREF (rv);
+ return -1;
+ }
+
+ nbdkit_error ("%s: %s: error: %s",
+ script, callback,
+ traceback_cstr);
+ Py_DECREF (rv);
+ free (traceback_cstr);
+
+ /* This means we succeeded in calling nbdkit_error. */
+ return 0;
+}
+
static int
check_python_failure (const char *callback)
{
if (PyErr_Occurred ()) {
- PyObject *type, *error, *traceback, *error_str;
- char *error_cstr;
+ PyObject *type, *error, *traceback;
- /* Convert the Python exception to a string.
- * https://stackoverflow.com/a/1418703
- * But forget about the traceback, it's very hard to print.
- * https://stackoverflow.com/q/1796510
- */
PyErr_Fetch (&type, &error, &traceback);
PyErr_NormalizeException (&type, &error, &traceback);
- error_str = PyObject_Str (error);
- error_cstr = python_to_string (error_str);
- nbdkit_error ("%s: %s: error: %s",
- script, callback,
- error_cstr ? error_cstr : "<unknown>");
- Py_DECREF (error_str);
- free (error_cstr);
+
+ /* Try to print the full traceback. */
+ if (print_python_traceback (callback, type, error, traceback) == -1) {
+ /* Couldn't do that, so fall back to converting the Python error
+ * to a string.
+ */
+ print_python_error (callback, error);
+ }
+
+ /* In all cases this returns -1 to indicate that a Python error
+ * occurred.
+ */
return -1;
}
return 0;
diff --git a/tests/python-exception.py b/tests/python-exception.py
index 1debf51..739057f 100644
--- a/tests/python-exception.py
+++ b/tests/python-exception.py
@@ -32,10 +32,28 @@
# A dummy python plugin which just raises an exception in config_complete.
+test = "simple"
-def config_complete():
+def config(k, v):
+ global test
+ if k == "test":
+ test = v
+ else:
+ raise RuntimeError("unknown config parameter")
+
+def raise_error2():
raise RuntimeError("this is the test string")
+def raise_error1():
+ raise_error2()
+
+def config_complete():
+ if test == "simple":
+ raise RuntimeError("this is the test string")
+ elif test == "traceback":
+ raise_error1()
+ else:
+ raise RuntimeError("unknown test")
def open(readonly):
return 1
diff --git a/tests/test-python-exception.sh b/tests/test-python-exception.sh
index 83999af..7120132 100755
--- a/tests/test-python-exception.sh
+++ b/tests/test-python-exception.sh
@@ -31,12 +31,23 @@
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
+set -e
+set -x
+
output=test-python-exception.out
rm -f $output
-nbdkit -f -v python ./python-exception.py > $output 2>&1 ||:
+nbdkit -f -v python ./python-exception.py test=simple > $output 2>&1 ||:
+cat $output
grep 'this is the test string' $output
+nbdkit -f -v python ./python-exception.py test=traceback > $output 2>&1 ||:
+cat $output
+
+grep 'raise_error1' $output
+grep 'raise_error2' $output
+grep 'this is the test string' $output
+
rm $output
--
2.18.0
6 years, 4 months