Wire up .thread_model to the sh plugin, with a change to test-eflags
to demonstrate the effect of a script that requests the tighter
SERIALIZE_CONNECTIONS. While at it, fix two swapped tests messed up
in afbcd070.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
plugins/sh/nbdkit-sh-plugin.pod | 15 ++++++++++
plugins/sh/sh.c | 51 +++++++++++++++++++++++++++++++--
tests/test-eflags.sh | 49 ++++++++++++++++++++-----------
3 files changed, 97 insertions(+), 18 deletions(-)
diff --git a/plugins/sh/nbdkit-sh-plugin.pod b/plugins/sh/nbdkit-sh-plugin.pod
index a5285ed..7ba8830 100644
--- a/plugins/sh/nbdkit-sh-plugin.pod
+++ b/plugins/sh/nbdkit-sh-plugin.pod
@@ -180,6 +180,21 @@ ignored.
/path/to/script config_complete
+=item C<thread_model>
+
+ /path/to/script thread_model
+
+On success this should print the desired thread model of the script,
+one of C<"serialize_connections">,
C<"serialize_all_requests">,
+C<"serialize_requests">, or C<"parallel">.
+
+This method is I<not> required; if omitted, then the plugin will be
+executed under the default sh thread model (currently
+C<"serialize_all_requests">, which implies this callback only makes a
+difference with an output of C<"serialize_connections">). If an error
+occurs, the script should output an error message and exit with status
+C<1>; unrecognized output is ignored.
+
=item C<open>
/path/to/script open <readonly>
diff --git a/plugins/sh/sh.c b/plugins/sh/sh.c
index 862be21..aeb0191 100644
--- a/plugins/sh/sh.c
+++ b/plugins/sh/sh.c
@@ -257,6 +257,54 @@ sh_config_complete (void)
}
}
+#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
+
+static int
+sh_thread_model (void)
+{
+ const char *args[] = { script, "thread_model", NULL };
+ CLEANUP_FREE char *s = NULL;
+ size_t slen;
+ int r;
+
+ switch (call_read (&s, &slen, args)) {
+ case OK:
+ if (slen > 0 && s[slen-1] == '\n')
+ s[slen-1] = '\0';
+ if (strcasecmp (s, "parallel") == 0)
+ r = NBDKIT_THREAD_MODEL_PARALLEL;
+ else if (strcasecmp (s, "serialize_requests") == 0 ||
+ strcasecmp (s, "serialize-requests") == 0)
+ r = NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS;
+ else if (strcasecmp (s, "serialize_all_requests") == 0 ||
+ strcasecmp (s, "serialize-all-requests") == 0)
+ r = NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS;
+ else if (strcasecmp (s, "serialize_connections") == 0 ||
+ strcasecmp (s, "serialize-connections") == 0)
+ r = NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS;
+ else {
+ nbdkit_debug ("%s: ignoring unrecognized thread model: %s",
+ script, s);
+ r = THREAD_MODEL;
+ }
+ return r;
+
+ case MISSING:
+ return THREAD_MODEL;
+
+ case ERROR:
+ return -1;
+
+ case RET_FALSE:
+ nbdkit_error ("%s: %s method returned unexpected code (3/false)",
+ script, "thread_model");
+ errno = EIO;
+ return -1;
+
+ default: abort ();
+ }
+}
+
static void *
sh_open (int readonly)
{
@@ -865,8 +913,6 @@ sh_cache (void *handle, uint32_t count, uint64_t offset, uint32_t
flags)
"script=<FILENAME> (required) The shell script to run.\n" \
"[other arguments may be used by the plugin that you load]"
-#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
-
static struct nbdkit_plugin plugin = {
.name = "sh",
.version = PACKAGE_VERSION,
@@ -878,6 +924,7 @@ static struct nbdkit_plugin plugin = {
.config = sh_config,
.config_complete = sh_config_complete,
.config_help = sh_config_help,
+ .thread_model = sh_thread_model,
.open = sh_open,
.close = sh_close,
diff --git a/tests/test-eflags.sh b/tests/test-eflags.sh
index 8158f75..80816ff 100755
--- a/tests/test-eflags.sh
+++ b/tests/test-eflags.sh
@@ -277,22 +277,6 @@ EOF
# -r
# can_multi_conn=true
-late_args="serialize=connections" do_nbdkit -r --filter=noparallel
<<'EOF'
-case "$1" in
- get_size) echo 1M ;;
- can_multi_conn) exit 0 ;;
- *) exit 2 ;;
-esac
-EOF
-
-[ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
- fail "expected HAS_FLAGS|READ_ONLY|SEND_DF"
-
-#----------------------------------------------------------------------
-# -r
-# --filter=noparallel serialize=connections
-# can_multi_conn=true
-
do_nbdkit -r <<'EOF'
case "$1" in
get_size) echo 1M ;;
@@ -304,6 +288,39 @@ EOF
[ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN )) ] ||
fail "expected HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN"
+#----------------------------------------------------------------------
+# -r
+# --filter=noparallel serialize=connections
+# can_multi_conn=true
+
+late_args="serialize=connections" do_nbdkit -r --filter=noparallel
<<'EOF'
+case "$1" in
+ get_size) echo 1M ;;
+ can_multi_conn) exit 0 ;;
+ *) exit 2 ;;
+esac
+EOF
+
+[ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
+ fail "expected HAS_FLAGS|READ_ONLY|SEND_DF"
+
+#----------------------------------------------------------------------
+# -r
+# thread_model=serialize_connections
+# can_multi_conn=true
+
+do_nbdkit -r <<'EOF'
+case "$1" in
+ get_size) echo 1M ;;
+ can_multi_conn) exit 0 ;;
+ thread_model) echo "serialize_connections" ;;
+ *) exit 2 ;;
+esac
+EOF
+
+[ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
+ fail "expected HAS_FLAGS|READ_ONLY|SEND_DF"
+
#----------------------------------------------------------------------
# -r
# can_cache=native
--
2.20.1