From 10a6d7b4a1552862d6a68dd4a0d8a55f6938c8b5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 27 Oct 2021 12:30:41 +0100 Subject: [PATCH] vddk: Refactor -D vddk.stats=1 into a new file Acked-by: Laszlo Ersek (cherry picked from commit dcd5bc51ed7710c32d956345ea8da14ba15ef8f5) --- plugins/vddk/Makefile.am | 1 + plugins/vddk/stats.c | 118 +++++++++++++++++++++++++++++++++++++++ plugins/vddk/vddk.c | 78 +------------------------- plugins/vddk/vddk.h | 15 +++++ 4 files changed, 135 insertions(+), 77 deletions(-) create mode 100644 plugins/vddk/stats.c diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am index 232aaedd..4f470ff9 100644 --- a/plugins/vddk/Makefile.am +++ b/plugins/vddk/Makefile.am @@ -46,6 +46,7 @@ nbdkit_vddk_plugin_la_SOURCES = \ vddk.c \ vddk.h \ reexec.c \ + stats.c \ vddk-structs.h \ vddk-stubs.h \ $(top_srcdir)/include/nbdkit-plugin.h \ diff --git a/plugins/vddk/stats.c b/plugins/vddk/stats.c new file mode 100644 index 00000000..18a42714 --- /dev/null +++ b/plugins/vddk/stats.c @@ -0,0 +1,118 @@ +/* nbdkit + * Copyright (C) 2013-2021 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. + */ + +#include + +#include +#include +#include +#include + +#include + +#define NBDKIT_API_VERSION 2 +#include + +#include "vector.h" + +#include "vddk.h" + +/* Debug flags. */ +NBDKIT_DLL_PUBLIC int vddk_debug_stats; + +pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; + +/* For each VDDK API define a variable to store the time taken (used + * to implement -D vddk.stats=1). + */ +#define STUB(fn,ret,args) struct vddk_stat stats_##fn = { .name = #fn } +#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) +#include "vddk-stubs.h" +#undef STUB +#undef OPTIONAL_STUB + +DEFINE_VECTOR_TYPE(statlist, struct vddk_stat) + +static int +stat_compare (const void *vp1, const void *vp2) +{ + const struct vddk_stat *st1 = vp1; + const struct vddk_stat *st2 = vp2; + + /* Note: sorts in reverse order of time spent in each API call. */ + if (st1->usecs < st2->usecs) return 1; + else if (st1->usecs > st2->usecs) return -1; + else return 0; +} + +static const char * +api_name_without_prefix (const char *name) +{ + return strncmp (name, "VixDiskLib_", 11) == 0 ? name + 11 : name; +} + +void +display_stats (void) +{ + statlist stats = empty_vector; + size_t i; + + if (!vddk_debug_stats) return; + +#define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) +#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) +#include "vddk-stubs.h" +#undef STUB +#undef OPTIONAL_STUB + + qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); + + nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); + nbdkit_debug ("%-24s %15s %5s %15s", + "VixDiskLib_...", "µs", "calls", "bytes"); + for (i = 0; i < stats.size; ++i) { + if (stats.ptr[i].usecs) { + if (stats.ptr[i].bytes > 0) + nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, + api_name_without_prefix (stats.ptr[i].name), + stats.ptr[i].usecs, + stats.ptr[i].calls, + stats.ptr[i].bytes); + else + nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64, + api_name_without_prefix (stats.ptr[i].name), + stats.ptr[i].usecs, + stats.ptr[i].calls); + } + } + statlist_reset (&stats); +} diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c index 041bff1a..67ac775c 100644 --- a/plugins/vddk/vddk.c +++ b/plugins/vddk/vddk.c @@ -61,7 +61,6 @@ NBDKIT_DLL_PUBLIC int vddk_debug_diskinfo; NBDKIT_DLL_PUBLIC int vddk_debug_extents; NBDKIT_DLL_PUBLIC int vddk_debug_datapath = 1; -NBDKIT_DLL_PUBLIC int vddk_debug_stats; /* For each VDDK API define a global variable. These globals are * initialized when the plugin is loaded (by vddk_get_ready). @@ -99,25 +98,6 @@ bool unbuffered; /* unbuffered */ const char *username; /* user */ const char *vmx_spec; /* vm */ -/* For each VDDK API define a variable to store the time taken (used - * to implement -D vddk.stats=1). - */ -struct vddk_stat { - const char *name; /* function name */ - int64_t usecs; /* total number of usecs consumed */ - uint64_t calls; /* number of times called */ - uint64_t bytes; /* bytes transferred, datapath calls only */ -}; -static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; -static void display_stats (void); -#define STUB(fn,ret,args) \ - static struct vddk_stat stats_##fn = { .name = #fn } -#define OPTIONAL_STUB(fn,ret,args) \ - static struct vddk_stat stats_##fn = { .name = #fn } -#include "vddk-stubs.h" -#undef STUB -#undef OPTIONAL_STUB - /* Unload the plugin. */ static void vddk_unload (void) @@ -130,69 +110,13 @@ vddk_unload (void) if (dl) dlclose (dl); - if (vddk_debug_stats) - display_stats (); + display_stats (); free (config); free (libdir); free (password); } -DEFINE_VECTOR_TYPE(statlist, struct vddk_stat) - -static int -stat_compare (const void *vp1, const void *vp2) -{ - const struct vddk_stat *st1 = vp1; - const struct vddk_stat *st2 = vp2; - - /* Note: sorts in reverse order of time spent in each API call. */ - if (st1->usecs < st2->usecs) return 1; - else if (st1->usecs > st2->usecs) return -1; - else return 0; -} - -static const char * -api_name_without_prefix (const char *name) -{ - return strncmp (name, "VixDiskLib_", 11) == 0 ? name + 11 : name; -} - -static void -display_stats (void) -{ - statlist stats = empty_vector; - size_t i; - -#define STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -#define OPTIONAL_STUB(fn,ret,args) statlist_append (&stats, stats_##fn) -#include "vddk-stubs.h" -#undef STUB -#undef OPTIONAL_STUB - - qsort (stats.ptr, stats.size, sizeof stats.ptr[0], stat_compare); - - nbdkit_debug ("VDDK function stats (-D vddk.stats=1):"); - nbdkit_debug ("%-24s %15s %5s %15s", - "VixDiskLib_...", "µs", "calls", "bytes"); - for (i = 0; i < stats.size; ++i) { - if (stats.ptr[i].usecs) { - if (stats.ptr[i].bytes > 0) - nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64 " %15" PRIu64, - api_name_without_prefix (stats.ptr[i].name), - stats.ptr[i].usecs, - stats.ptr[i].calls, - stats.ptr[i].bytes); - else - nbdkit_debug (" %-22s %15" PRIi64 " %5" PRIu64, - api_name_without_prefix (stats.ptr[i].name), - stats.ptr[i].usecs, - stats.ptr[i].calls); - } - } - statlist_reset (&stats); -} - static void trim (char *str) { diff --git a/plugins/vddk/vddk.h b/plugins/vddk/vddk.h index 29775eb4..1400589d 100644 --- a/plugins/vddk/vddk.h +++ b/plugins/vddk/vddk.h @@ -126,4 +126,19 @@ extern char *reexeced; extern void reexec_if_needed (const char *prepend); extern int restore_ld_library_path (void); +/* stats.c */ +struct vddk_stat { + const char *name; /* function name */ + int64_t usecs; /* total number of usecs consumed */ + uint64_t calls; /* number of times called */ + uint64_t bytes; /* bytes transferred, datapath calls only */ +}; +extern pthread_mutex_t stats_lock; +#define STUB(fn,ret,args) extern struct vddk_stat stats_##fn; +#define OPTIONAL_STUB(fn,ret,args) STUB(fn,ret,args) +#include "vddk-stubs.h" +#undef STUB +#undef OPTIONAL_STUB +extern void display_stats (void); + #endif /* NBDKIT_VDDK_H */ -- 2.31.1