From 83c72d9bf9d6a9ccf6939b4ebd0028b62673a78a Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 12 Dec 2019 10:57:52 +0000 Subject: [PATCH 03/19] server: Add -D nbdkit.backend.controlpath and -D nbdkit.backend.datapath. These can be used to suppress verbose debugging messages from the backend. BugLink: https://bugzilla.redhat.com/1782868 Cherry picked from commit 231717e8cd5f27d76631be6651062d5a5ccf7fdc. Remove use of nofilter from the test. --- docs/nbdkit.pod | 35 ++++++++++++- server/backend.c | 83 ++++++++++++++++++------------ tests/Makefile.am | 4 ++ tests/test-nbdkit-backend-debug.sh | 70 +++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 34 deletions(-) create mode 100755 tests/test-nbdkit-backend-debug.sh diff --git a/docs/nbdkit.pod b/docs/nbdkit.pod index 346d8332..38e6bfca 100644 --- a/docs/nbdkit.pod +++ b/docs/nbdkit.pod @@ -182,7 +182,7 @@ value C. See L. =item B<--debug> nbdkit.FLAG=N Set the nbdkit server Debug Flag called C to the integer value -C. +C. See L below. =item B<--dump-config> @@ -527,6 +527,39 @@ languages. The file should be executable. For example: (see L for a full example). +=head1 SERVER DEBUG FLAGS + +As well as enabling or disabling debugging in the server using +I<--verbose> you can control extra debugging in the server using the +C<-D nbdkit.*> flags listed in this section. Note these flags are an +internal implementation detail of the server and may be changed or +removed at any time in the future. + +=over 4 + +=item B<-D nbdkit.backend.controlpath=0> + +=item B<-D nbdkit.backend.controlpath=1> + +=item B<-D nbdkit.backend.datapath=0> + +=item B<-D nbdkit.backend.datapath=1> + +These flags control the verbosity of nbdkit backend debugging messages +(the ones which show every request processed by the server). The +default for both settings is C<1> (normal debugging) but you can set +them to C<0> to suppress these messages. + +C<-D nbdkit.backend.datapath=0> is the more useful setting which lets you +suppress messages about pread, pwrite, zero, trim, etc. commands. +When transferring large amounts of data these messages are numerous +and not usually very interesting. + +C<-D nbdkit.backend.controlpath=0> suppresses the non-datapath +commands (config, open, close, can_write, etc.) + +=back + =head1 SIGNALS nbdkit responds to the following signals: diff --git a/server/backend.c b/server/backend.c index b9fe2a21..208c07b1 100644 --- a/server/backend.c +++ b/server/backend.c @@ -46,6 +46,22 @@ /* Helpers for registering a new backend. */ +/* Use: + * -D nbdkit.backend.controlpath=0 to suppress control path debugging. + * -D nbdkit.backend.datapath=0 to suppress data path debugging. + */ +int nbdkit_debug_backend_controlpath = 1; +int nbdkit_debug_backend_datapath = 1; + +#define controlpath_debug(fs, ...) \ + do { \ + if (nbdkit_debug_backend_controlpath) debug ((fs), ##__VA_ARGS__); \ + } while (0) +#define datapath_debug(fs, ...) \ + do { \ + if (nbdkit_debug_backend_datapath) debug ((fs), ##__VA_ARGS__); \ + } while (0) + void backend_init (struct backend *b, struct backend *next, size_t index, const char *filename, void *dl, const char *type) @@ -108,7 +124,7 @@ backend_load (struct backend *b, const char *name, void (*load) (void)) apply_debug_flags (b->dl, name); /* Call the on-load callback if it exists. */ - debug ("%s: load", name); + controlpath_debug ("%s: load", name); if (load) load (); } @@ -121,7 +137,7 @@ backend_unload (struct backend *b, void (*unload) (void)) */ lock_unload (); - debug ("%s: unload %s", b->name, b->type); + controlpath_debug ("%s: unload %s", b->name, b->type); if (unload) unload (); @@ -139,7 +155,7 @@ backend_open (struct backend *b, struct connection *conn, int readonly) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: open readonly=%d", b->name, readonly); + controlpath_debug ("%s: open readonly=%d", b->name, readonly); assert (h->handle == NULL); assert ((h->state & HANDLE_OPEN) == 0); @@ -151,7 +167,7 @@ backend_open (struct backend *b, struct connection *conn, int readonly) * inner-to-outer ordering. */ h->handle = b->open (b, conn, readonly); - debug ("%s: open returned handle %p", b->name, h->handle); + controlpath_debug ("%s: open returned handle %p", b->name, h->handle); if (h->handle == NULL) { if (b->i) /* Do not strand backend if this layer failed */ @@ -179,7 +195,7 @@ backend_prepare (struct backend *b, struct connection *conn) if (b->i && backend_prepare (b->next, conn) == -1) return -1; - debug ("%s: prepare readonly=%d", b->name, h->can_write == 0); + controlpath_debug ("%s: prepare readonly=%d", b->name, h->can_write == 0); if (b->prepare (b, conn, h->handle, h->can_write == 0) == -1) return -1; @@ -196,7 +212,7 @@ backend_finalize (struct backend *b, struct connection *conn) * filter furthest away from the plugin, and matching .close order. */ - debug ("%s: finalize", b->name); + controlpath_debug ("%s: finalize", b->name); /* Once finalize fails, we can do nothing further on this connection */ if (h->state & HANDLE_FAILED) @@ -223,7 +239,7 @@ backend_close (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; /* outer-to-inner order, opposite .open */ - debug ("%s: close", b->name); + controlpath_debug ("%s: close", b->name); if (h->handle) { assert (h->state & HANDLE_OPEN); @@ -252,7 +268,7 @@ backend_valid_range (struct backend *b, struct connection *conn, int backend_reopen (struct backend *b, struct connection *conn, int readonly) { - debug ("%s: reopen readonly=%d", b->name, readonly); + controlpath_debug ("%s: reopen readonly=%d", b->name, readonly); if (backend_finalize (b, conn) == -1) return -1; @@ -274,7 +290,7 @@ backend_get_size (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: get_size", b->name); + controlpath_debug ("%s: get_size", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->exportsize == -1) @@ -287,7 +303,7 @@ backend_can_write (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: can_write", b->name); + controlpath_debug ("%s: can_write", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_write == -1) @@ -300,7 +316,7 @@ backend_can_flush (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: can_flush", b->name); + controlpath_debug ("%s: can_flush", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_flush == -1) @@ -313,7 +329,7 @@ backend_is_rotational (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: is_rotational", b->name); + controlpath_debug ("%s: is_rotational", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->is_rotational == -1) @@ -327,7 +343,7 @@ backend_can_trim (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; int r; - debug ("%s: can_trim", b->name); + controlpath_debug ("%s: can_trim", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_trim == -1) { @@ -347,7 +363,7 @@ backend_can_zero (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; int r; - debug ("%s: can_zero", b->name); + controlpath_debug ("%s: can_zero", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_zero == -1) { @@ -367,7 +383,7 @@ backend_can_fast_zero (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; int r; - debug ("%s: can_fast_zero", b->name); + controlpath_debug ("%s: can_fast_zero", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_fast_zero == -1) { @@ -386,7 +402,7 @@ backend_can_extents (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: can_extents", b->name); + controlpath_debug ("%s: can_extents", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_extents == -1) @@ -400,7 +416,7 @@ backend_can_fua (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; int r; - debug ("%s: can_fua", b->name); + controlpath_debug ("%s: can_fua", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_fua == -1) { @@ -420,7 +436,7 @@ backend_can_multi_conn (struct backend *b, struct connection *conn) struct b_conn_handle *h = &conn->handles[b->i]; assert (h->handle && (h->state & HANDLE_CONNECTED)); - debug ("%s: can_multi_conn", b->name); + controlpath_debug ("%s: can_multi_conn", b->name); if (h->can_multi_conn == -1) h->can_multi_conn = b->can_multi_conn (b, conn, h->handle); @@ -432,7 +448,7 @@ backend_can_cache (struct backend *b, struct connection *conn) { struct b_conn_handle *h = &conn->handles[b->i]; - debug ("%s: can_cache", b->name); + controlpath_debug ("%s: can_cache", b->name); assert (h->handle && (h->state & HANDLE_CONNECTED)); if (h->can_cache == -1) @@ -451,8 +467,8 @@ backend_pread (struct backend *b, struct connection *conn, assert (h->handle && (h->state & HANDLE_CONNECTED)); assert (backend_valid_range (b, conn, offset, count)); assert (flags == 0); - debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64, - b->name, count, offset); + datapath_debug ("%s: pread count=%" PRIu32 " offset=%" PRIu64, + b->name, count, offset); r = b->pread (b, conn, h->handle, buf, count, offset, flags, err); if (r == -1) @@ -475,8 +491,8 @@ backend_pwrite (struct backend *b, struct connection *conn, assert (!(flags & ~NBDKIT_FLAG_FUA)); if (fua) assert (h->can_fua > NBDKIT_FUA_NONE); - debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d", - b->name, count, offset, fua); + datapath_debug ("%s: pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d", + b->name, count, offset, fua); r = b->pwrite (b, conn, h->handle, buf, count, offset, flags, err); if (r == -1) @@ -494,7 +510,7 @@ backend_flush (struct backend *b, struct connection *conn, assert (h->handle && (h->state & HANDLE_CONNECTED)); assert (h->can_flush == 1); assert (flags == 0); - debug ("%s: flush", b->name); + datapath_debug ("%s: flush", b->name); r = b->flush (b, conn, h->handle, flags, err); if (r == -1) @@ -518,8 +534,8 @@ backend_trim (struct backend *b, struct connection *conn, assert (!(flags & ~NBDKIT_FLAG_FUA)); if (fua) assert (h->can_fua > NBDKIT_FUA_NONE); - debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d", - b->name, count, offset, fua); + datapath_debug ("%s: trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d", + b->name, count, offset, fua); r = b->trim (b, conn, h->handle, count, offset, flags, err); if (r == -1) @@ -547,9 +563,10 @@ backend_zero (struct backend *b, struct connection *conn, assert (h->can_fua > NBDKIT_FUA_NONE); if (fast) assert (h->can_fast_zero == 1); - debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64 - " may_trim=%d fua=%d fast=%d", - b->name, count, offset, !!(flags & NBDKIT_FLAG_MAY_TRIM), fua, fast); + datapath_debug ("%s: zero count=%" PRIu32 " offset=%" PRIu64 + " may_trim=%d fua=%d fast=%d", + b->name, count, offset, + !!(flags & NBDKIT_FLAG_MAY_TRIM), fua, fast); r = b->zero (b, conn, h->handle, count, offset, flags, err); if (r == -1) { @@ -572,8 +589,8 @@ backend_extents (struct backend *b, struct connection *conn, assert (h->can_extents >= 0); assert (backend_valid_range (b, conn, offset, count)); assert (!(flags & ~NBDKIT_FLAG_REQ_ONE)); - debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " req_one=%d", - b->name, count, offset, !!(flags & NBDKIT_FLAG_REQ_ONE)); + datapath_debug ("%s: extents count=%" PRIu32 " offset=%" PRIu64 " req_one=%d", + b->name, count, offset, !!(flags & NBDKIT_FLAG_REQ_ONE)); if (h->can_extents == 0) { /* By default it is safe assume that everything in the range is @@ -602,8 +619,8 @@ backend_cache (struct backend *b, struct connection *conn, assert (h->can_cache > NBDKIT_CACHE_NONE); assert (backend_valid_range (b, conn, offset, count)); assert (flags == 0); - debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64, - b->name, count, offset); + datapath_debug ("%s: cache count=%" PRIu32 " offset=%" PRIu64, + b->name, count, offset); if (h->can_cache == NBDKIT_CACHE_EMULATE) { static char buf[MAX_REQUEST_SIZE]; /* data sink, never read */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 01341973..d225cc63 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -135,6 +135,7 @@ EXTRA_DIST = \ test-nbd-extents.sh \ test-nbd-tls.sh \ test-nbd-tls-psk.sh \ + test-nbdkit-backend-debug.sh \ test-nozero.sh \ test-null-extents.sh \ test_ocaml_plugin.ml \ @@ -746,6 +747,9 @@ endif HAVE_VDDK # zero plugin test. TESTS += test-zero.sh +# -D nbdkit.backend.* settings. +TESTS += test-nbdkit-backend-debug.sh + #---------------------------------------------------------------------- # Tests of language plugins. diff --git a/tests/test-nbdkit-backend-debug.sh b/tests/test-nbdkit-backend-debug.sh new file mode 100755 index 00000000..69a69a7c --- /dev/null +++ b/tests/test-nbdkit-backend-debug.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright (C) 2019 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. + +source ./functions.sh +set -x +set -e + +requires qemu-img --version + +out="test-nbdkit-backend-debug.out" +debug="test-nbdkit-backend-debug.debug" +files="$out $debug" +rm -f $files +cleanup_fn rm -f $files + +nbdkit -U - \ + -v \ + memory 10M \ + --run "qemu-img convert \$nbd $out" |& tee $debug + +# Should contain all debugging messages. +grep '^nbdkit:.*debug: memory: open' $debug +grep '^nbdkit:.*debug: memory: pread' $debug + +nbdkit -U - \ + -v -D nbdkit.backend.controlpath=0 \ + memory 10M \ + --run "qemu-img convert \$nbd $out" |& tee $debug + +# Should contain only datapath messages. +grep -v '^nbdkit:.*debug: memory: open' $debug +grep '^nbdkit:.*debug: memory: pread' $debug + +nbdkit -U - \ + -v -D nbdkit.backend.datapath=0 \ + memory 10M \ + --run "qemu-img convert \$nbd $out" |& tee $debug + +# Should contain only controlpath messages. +grep '^nbdkit:.*debug: memory: open' $debug +grep -v '^nbdkit:.*debug: memory: pread' $debug -- 2.18.2