When we added .thread_model to plugins, we forgot to expose has_thread_model in the --dump-plugin output. What's more, it is useful to determine if the plugin itself is aware of tighter restrictions imposed by dynamic choices, by outputting both 'max_thread_model' (what the plugin was compiled as) and 'thread_model' (the resulting model based on runtime knowledge).
Note that this means that a plugin's .thread_model can be called prior to .config, so the sh plugin must be prepared for a missing script. In fact, exposing additional information during --dump-plugin will make it easier for a future patch to make sh default to PARALLEL, and still have introspection on which model will actually be used. Fixes: 9911a9d3 Signed-off-by: Eric Blake <[email protected]> --- docs/nbdkit-plugin.pod | 11 +++++--- plugins/sh/nbdkit-sh-plugin.pod | 3 +- plugins/sh/sh.c | 3 ++ server/plugins.c | 49 ++++++++++++++++++++------------- tests/test-dump-plugin.sh | 31 ++++++++++++++++++++- 5 files changed, 72 insertions(+), 25 deletions(-) diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod index 8ce702da..fe9ada87 100644 --- a/docs/nbdkit-plugin.pod +++ b/docs/nbdkit-plugin.pod @@ -128,16 +128,19 @@ is called once just after the plugin is loaded into memory. C<.config> is called zero or more times during command line parsing. C<.config_complete> is called once after all configuration information -has been passed to the plugin. +has been passed to the plugin (but not during C<nbdkit --dump-plugin>). Both are called after loading the plugin but before any connections are accepted. =item C<.thread_model> -C<.thread_model> is called once after all configuration information -has been passed to the plugin, and before any connections are -accepted. +In normal operation, C<.thread_model> is called once after +C<.config_complete> has validated all configuration information, and +before any connections are accepted. However, during C<nbdkit +--dump-plugin>, it is called after any C<.config> calls but without +C<.config_complete> (so a plugin which determines the results from a +script must be prepared for a missing script). =item C<.open> diff --git a/plugins/sh/nbdkit-sh-plugin.pod b/plugins/sh/nbdkit-sh-plugin.pod index dfa086b5..41b9e7c7 100644 --- a/plugins/sh/nbdkit-sh-plugin.pod +++ b/plugins/sh/nbdkit-sh-plugin.pod @@ -191,7 +191,8 @@ 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 +difference with an output of C<"serialize_connections">; look for +'max_thread_model' in C<nbdkit --dump-plugin sh>). If an error occurs, the script should output an error message and exit with status C<1>; unrecognized output is ignored. diff --git a/plugins/sh/sh.c b/plugins/sh/sh.c index e3d3c2f1..5869d9a4 100644 --- a/plugins/sh/sh.c +++ b/plugins/sh/sh.c @@ -273,6 +273,9 @@ sh_thread_model (void) size_t slen; int r; + if (!script) + return THREAD_MODEL; + switch (call_read (&s, &slen, args)) { case OK: if (slen > 0 && s[slen-1] == '\n') diff --git a/server/plugins.c b/server/plugins.c index 9da0361b..3bb20c93 100644 --- a/server/plugins.c +++ b/server/plugins.c @@ -140,6 +140,33 @@ plugin_version (struct backend *b) return p->plugin.version; } +/* Map thread model to a string */ +static void +plugin_dump_thread_model (const char *prefix, int model) +{ + flockfile (stdout); + printf ("%s=", prefix); + switch (model) { + case NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS: + printf ("serialize_connections"); + break; + case NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS: + printf ("serialize_all_requests"); + break; + case NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS: + printf ("serialize_requests"); + break; + case NBDKIT_THREAD_MODEL_PARALLEL: + printf ("parallel"); + break; + default: + printf ("%d # unknown thread model!", model); + break; + } + printf ("\n"); + funlockfile (stdout); +} + /* This implements the --dump-plugin option. */ static void plugin_dump_fields (struct backend *b) @@ -157,25 +184,8 @@ plugin_dump_fields (struct backend *b) printf ("api_version=%d\n", p->plugin._api_version); printf ("struct_size=%" PRIu64 "\n", p->plugin._struct_size); - printf ("thread_model="); - switch (p->plugin._thread_model) { - case NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS: - printf ("serialize_connections"); - break; - case NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS: - printf ("serialize_all_requests"); - break; - case NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS: - printf ("serialize_requests"); - break; - case NBDKIT_THREAD_MODEL_PARALLEL: - printf ("parallel"); - break; - default: - printf ("%d # unknown thread model!", p->plugin._thread_model); - break; - } - printf ("\n"); + plugin_dump_thread_model ("max_thread_model", p->plugin._thread_model); + plugin_dump_thread_model ("thread_model", backend->thread_model (backend)); printf ("errno_is_preserved=%d\n", !!p->plugin.errno_is_preserved); if (p->plugin.magic_config_key) printf ("magic_config_key=%s\n", p->plugin.magic_config_key); @@ -213,6 +223,7 @@ plugin_dump_fields (struct backend *b) HAS (extents); HAS (can_cache); HAS (cache); + HAS (thread_model); #undef HAS /* Custom fields. */ diff --git a/tests/test-dump-plugin.sh b/tests/test-dump-plugin.sh index 1d58a3a3..982d5062 100755 --- a/tests/test-dump-plugin.sh +++ b/tests/test-dump-plugin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # nbdkit -# Copyright (C) 2014 Red Hat Inc. +# Copyright (C) 2014-2019 Red Hat Inc. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -68,3 +68,32 @@ do_test () esac } foreach_plugin do_test + +# Test that --dump-plugin can be used to introspect a resulting dynamic +# thread model. +out=$({ + # sh does not yet support parallel + nbdkit --dump-plugin sh + # Here, the script further reduces things + nbdkit --dump-plugin sh - <<\EOF +case $1 in + get_size) echo 1M ;; + thread_model) echo serialize_connections ;; + *) exit 2 ;; +esac +EOF + # Here, the filter further reduces things + nbdkit --dump-plugin --filter=noparallel sh serialize=connections +} | grep thread_model) +exp="max_thread_model=serialize_all_requests +thread_model=serialize_all_requests +has_thread_model=1 +max_thread_model=serialize_all_requests +thread_model=serialize_connections +has_thread_model=1 +max_thread_model=serialize_all_requests +thread_model=serialize_connections +has_thread_model=1" +if [ "$out" != "$exp" ]; then + echo "thread_model mismatch"; exit 1 +fi -- 2.20.1 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
