Richard W.M. Jones
2020-Aug-05 10:29 UTC
[Libguestfs] [PATCH nbdkit 1/2] server: Call .get_ready before redirecting stdin/stdout to /dev/null.
VDDK plugin + --run was broken because of the following sequence of
events:
(1) After .config_complete, server redirects stdin/stdout to /dev/null.
(2) Server then calls vddk_get_ready which reexecs.
(3) We restart the server from the top, but with stdin/stdout
redirected to /dev/null. So saved_stdin/saved_stdout save
/dev/null.
(4) run_command is called which "restores" /dev/null as stdin/stdout.
(5) The output of the --run option is sent to /dev/null.
In addition to fixing this problem with VDDK, it also makes general
sense not to redirect stdin/stdout before calling .get_ready since
this callback is supposed to be the last chance before the server
daemonizes, and redirecting stdin/stdout is part of daemonization.
Before this commit:
$ ./nbdkit vddk libdir=tests/.libs /dev/null --run 'qemu-img info
$nbd'
[no output]
After this commit:
$ ./nbdkit vddk libdir=tests/.libs /dev/null --run 'qemu-img info
$nbd'
image: nbd://localhost:10809
file format: raw
virtual size: 512 KiB (524288 bytes)
disk size: unavailable
One test (test-stdio.sh) made the assumption that stdin/stdout had
already been redirected to /dev/null in .get_ready. I adjusted this
test so it checks for redirection in .after_fork instead.
---
server/main.c | 10 +++++-----
tests/test-stdio-plugin.c | 9 +++++++++
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/server/main.c b/server/main.c
index 2f0aaf07..11c1614b 100644
--- a/server/main.c
+++ b/server/main.c
@@ -693,6 +693,11 @@ main (int argc, char *argv[])
/* Select the correct thread model based on config. */
lock_init_thread_model ();
+ /* Tell the plugin that we are about to start serving. This must be
+ * called before we change user, fork, or open any sockets.
+ */
+ top->get_ready (top);
+
/* Sanitize stdin/stdout to /dev/null, after saving the originals
* when needed. We are still single-threaded at this point, and
* already checked that stdin/out were open, so we don't have to
@@ -726,12 +731,7 @@ main (int argc, char *argv[])
perror ("open");
exit (EXIT_FAILURE);
}
-
- /* Tell the plugin that we are about to start serving. This must be
- * called before we change user, fork, or open any sockets.
- */
configured = true;
- top->get_ready (top);
start_serving ();
diff --git a/tests/test-stdio-plugin.c b/tests/test-stdio-plugin.c
index 618eae83..86447278 100644
--- a/tests/test-stdio-plugin.c
+++ b/tests/test-stdio-plugin.c
@@ -122,6 +122,14 @@ stdio_config_complete (void)
static int
stdio_get_ready (void)
+{
+ bool check = stdio_check ();
+ assert (check == false);
+ return 0;
+}
+
+static int
+stdio_after_fork (void)
{
bool check = stdio_check ();
assert (check == true);
@@ -163,6 +171,7 @@ static struct nbdkit_plugin plugin = {
.config = stdio_config,
.config_complete = stdio_config_complete,
.get_ready = stdio_get_ready,
+ .after_fork = stdio_after_fork,
.open = stdio_open,
.get_size = stdio_get_size,
.pread = stdio_pread,
--
2.27.0
Richard W.M. Jones
2020-Aug-05 10:29 UTC
[Libguestfs] [PATCH nbdkit 2/2] tests: Add a test of VDDK + --run.
--- tests/Makefile.am | 8 +++--- tests/test-vddk-run.sh | 56 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 676e7e68..79be5639 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -913,12 +913,13 @@ if HAVE_VDDK noinst_LTLIBRARIES += libvixDiskLib.la LIBGUESTFS_TESTS += test-vddk TESTS += \ - test-vddk-reexec.sh \ test-vddk-dump-plugin.sh \ test-vddk-password-fd.sh \ test-vddk-password-interactive.sh \ - test-vddk-real.sh \ test-vddk-real-dump-plugin.sh \ + test-vddk-real.sh \ + test-vddk-reexec.sh \ + test-vddk-run.sh \ $(NULL) test_vddk_SOURCES = test-vddk.c test.h @@ -944,9 +945,10 @@ EXTRA_DIST += \ test-vddk-dump-plugin.sh \ test-vddk-password-fd.sh \ test-vddk-password-interactive.sh \ - test-vddk-real.sh \ test-vddk-real-dump-plugin.sh \ + test-vddk-real.sh \ test-vddk-reexec.sh \ + test-vddk-run.sh \ $(NULL) # zero plugin test. diff --git a/tests/test-vddk-run.sh b/tests/test-vddk-run.sh new file mode 100755 index 00000000..19055245 --- /dev/null +++ b/tests/test-vddk-run.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright (C) 2018-2020 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# 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. + +# Test VDDK + --run parameter. + +source ./functions.sh +set -e +set -x + +# Testing $LD_LIBRARY_PATH stuff breaks valgrind, so skip the rest of +# this test if valgrinding. +if [ "x$NBDKIT_VALGRIND" = "x1" ]; then + echo "$0: skipped LD_LIBRARY_PATH test when doing valgrind" + exit 77 +fi + +requires qemu-img --version + +out=test-vddk-run.out +rm -f $out +cleanup_fn rm -f $out + +nbdkit -U - vddk libdir=.libs /dev/null --run 'qemu-img info $nbd' > $out +cat $out + +grep 'file format: raw' $out +grep 'virtual size:.*524288 bytes' $out -- 2.27.0
Eric Blake
2020-Aug-05 13:08 UTC
Re: [Libguestfs] [PATCH nbdkit 1/2] server: Call .get_ready before redirecting stdin/stdout to /dev/null.
On 8/5/20 5:29 AM, Richard W.M. Jones wrote:> VDDK plugin + --run was broken because of the following sequence of > events: > > (1) After .config_complete, server redirects stdin/stdout to /dev/null. > > (2) Server then calls vddk_get_ready which reexecs. > > (3) We restart the server from the top, but with stdin/stdout > redirected to /dev/null. So saved_stdin/saved_stdout save > /dev/null. > > (4) run_command is called which "restores" /dev/null as stdin/stdout. > > (5) The output of the --run option is sent to /dev/null. > > In addition to fixing this problem with VDDK, it also makes general > sense not to redirect stdin/stdout before calling .get_ready since > this callback is supposed to be the last chance before the server > daemonizes, and redirecting stdin/stdout is part of daemonization.It's been an interesting game of sequencing, but as we add more tests, we're certainly going to be more robust against future breakage ;) Series looks good. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Reasonably Related Threads
- [nbdkit PATCH v2 3/3] server: More tests of stdin/out handling
- [PATCH nbdkit 1/2] server: Add .after_fork callback, mainly for plugins to create threads.
- [PATCH nbdkit 0/5] server: Add .get_ready callback.
- [nbdkit PATCH v2 0/3] more consistent stdin/out handling
- Re: [PATCH nbdkit 2/2] tar: Rewrite the tar plugin (again), this time in C.