Eric Blake
2019-Jul-02 22:36 UTC
[Libguestfs] [nbdkit PATCH] sh: Parse a larger number of error messages
In order to trigger a non-EIO failure, a script had to output
_exactly_ 'EINVAL ' or similar, with one trailing space and no
message, because we forgot to limit the length of the string
comparison. Fix things to tolerate an error name without a message,
as well as to be case-insensitive.
Also, parse EOVERFLOW (missed in commit 6f8c8084).
Signed-off-by: Eric Blake <eblake@redhat.com>
---
I'm also working on adding tests/test-sh-errors.h to ensure we
don't regress, I'll push that along with this once I get it working.
plugins/sh/nbdkit-sh-plugin.pod | 4 +--
plugins/sh/call.c | 45 +++++++++++++++++++++++----------
2 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/plugins/sh/nbdkit-sh-plugin.pod b/plugins/sh/nbdkit-sh-plugin.pod
index f108051f..55ee6c69 100644
--- a/plugins/sh/nbdkit-sh-plugin.pod
+++ b/plugins/sh/nbdkit-sh-plugin.pod
@@ -85,5 +85,5 @@ The method was executed successfully.
=item 1 and 8-127
-There was an error. The script may print on stderr an errno and a
-message, for example:
+There was an error. The script may print on stderr an errno name,
+optionally followed by whitespace and a message, for example:
ENOSPC Out of space
diff --git a/plugins/sh/call.c b/plugins/sh/call.c
index f69523c1..585bd32c 100644
--- a/plugins/sh/call.c
+++ b/plugins/sh/call.c
@@ -42,6 +42,7 @@
#include <poll.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <ctype.h>
#include <nbdkit-plugin.h>
@@ -267,32 +268,36 @@ static void
handle_script_error (char *ebuf, size_t len)
{
int err;
- size_t skip;
+ size_t skip = 0;
char *p;
- if (strcmp (ebuf, "EPERM ") == 0) {
+ if (strncasecmp (ebuf, "EPERM", 5) == 0) {
err = EPERM;
- skip = 6;
+ skip = 5;
}
- else if (strcmp (ebuf, "EIO ") == 0) {
+ else if (strncasecmp (ebuf, "EIO", 3) == 0) {
err = EIO;
- skip = 4;
+ skip = 3;
}
- else if (strcmp (ebuf, "ENOMEM ") == 0) {
+ else if (strncasecmp (ebuf, "ENOMEM", 6) == 0) {
err = ENOMEM;
- skip = 7;
+ skip = 6;
}
- else if (strcmp (ebuf, "EINVAL ") == 0) {
+ else if (strncasecmp (ebuf, "EINVAL", 6) == 0) {
err = EINVAL;
- skip = 7;
+ skip = 6;
}
- else if (strcmp (ebuf, "ENOSPC ") == 0) {
+ else if (strncasecmp (ebuf, "ENOSPC", 6) == 0) {
err = ENOSPC;
skip = 7;
}
- else if (strcmp (ebuf, "ESHUTDOWN ") == 0) {
+ else if (strncasecmp (ebuf, "EOVERFLOW", 9) == 0) {
+ err = EOVERFLOW;
+ skip = 9;
+ }
+ else if (strncasecmp (ebuf, "ESHUTDOWN", 9) == 0) {
err = ESHUTDOWN;
- skip = 10;
+ skip = 9;
}
else {
/* Default to EIO. */
@@ -300,6 +305,18 @@ handle_script_error (char *ebuf, size_t len)
skip = 0;
}
+ if (skip && ebuf[skip]) {
+ if (!isspace ((unsigned char) ebuf[skip])) {
+ /* Treat 'EINVALID' as EIO, not EINVAL */
+ err = EIO;
+ skip = 0;
+ }
+ else
+ do
+ skip++;
+ while (isspace ((unsigned char) ebuf[skip]));
+ }
+
while (len > 0 && ebuf[len-1] == '\n')
ebuf[--len] = '\0';
@@ -311,8 +328,8 @@ handle_script_error (char *ebuf, size_t len)
/* ... but truncate it for the error message below. */
*p = '\0';
}
- if (strlen (ebuf) >= skip)
- ebuf += skip;
+ assert (strlen (ebuf) >= skip);
+ ebuf += skip;
nbdkit_error ("%s: %s", script, ebuf);
}
else
--
2.20.1
Richard W.M. Jones
2019-Jul-04 09:50 UTC
Re: [Libguestfs] [nbdkit PATCH] sh: Parse a larger number of error messages
ACK, thanks. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top
Seemingly Similar Threads
- [PATCH nbdkit] common/include: Add locale-safe ascii_strcasecmp and ascii_strncasecmp.
- [PATCH nbdkit] sh: Don't need to cast parameter of ascii_is* to (unsigned char).
- [nbdkit PATCH 1/3] server: Add internal support for NBDKIT_FLAG_FAST_ZERO
- [nbdkit PATCH] sh: Allow pwrite to not consume all data
- [nbdkit PATCH] sh: Allow pwrite to not consume all data