Hi,
Here is a patch for a new one-shot mode for the debuginfod server. In this
mode the first scanning pass of the server will also output the found
executables' paths and buildids to the given file descriptor. This can (and
soon will be used in systemtap) as an easy way to scan archive files and
quickly/easily extract information concerning the executables they contain.
The patch passes all of the tests across the try-buildbots (branch
users/rgoldber/try-one-shot)
Thanks,
Ryan (rgoldber)
From a4e5d1bbd39d2448e5ae208a114e3a68d9f2c28a Mon Sep 17 00:00:00 2001
From: Ryan Goldberg
Date: Mon, 8 Aug 2022 13:30:08 -0400
Subject: [PATCH] One-shot mode for server
When in one-shot mode, for the first
scan all of the found executables' paths
and buildids will be written to the provided
file descriptor in the given format.
Signed-off-by: Ryan Goldberg
---
configure.ac | 5 ++
debuginfod/ChangeLog | 9 +++
debuginfod/Makefile.am | 2 +-
debuginfod/debuginfod.cxx| 52 ++-
debuginfod/debuginfod.h.in | 9 +++
doc/ChangeLog| 4 ++
doc/debuginfod.8 | 16 +
tests/ChangeLog | 7 ++-
tests/Makefile.am| 5 +-
tests/run-debuginfod-one-shot.sh | 105 +++
10 files changed, 209 insertions(+), 5 deletions(-)
create mode 100755 tests/run-debuginfod-one-shot.sh
diff --git a/configure.ac b/configure.ac
index 03b67a9d..aadff4ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -600,6 +600,11 @@ case "$ac_cv_search__obstack_free" in
esac
AC_SUBST([obstack_LIBS])
+AC_CHECK_LIB(json-c, json_tokener_parse, [
+ AC_DEFINE([ENABLE_ONE_SHOT], [1], [Define if the one-shot feature is enabled])
+ AC_SUBST(jsonc_LIBS, '-ljson-c')
+])
+
dnl The directories with content.
dnl Documentation.
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index a8b5d7f4..b6fac996 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,12 @@
+2022-08-09 Ryan Goldberg
+
+ * debuginfod.cxx (archive_classify): New global (one_shot_mtx).
+ (archive_classify, thread_main_fts_source_paths) In one-shot mode
+ for the first scan, output found buildids/paths to given file descriptor.
+ (parse_opt): Add "--one-shot" flag.
+ * debuginfod.h.in: Added in debuginfod_oneshot_header struct,
+ debuginfod_oneshot_header_magic
+
2022-08-02 Josef Cejka
* debuginfod.cxx (groom): Don't evaluate regex unless needed.
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 435cb8a6..03cdeed0 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -70,7 +70,7 @@ bin_PROGRAMS += debuginfod-find
endif
debuginfod_SOURCES = debuginfod.cxx
-debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
+debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) $(jsonc_LIBS) -lpthread -ldl
debuginfod_find_SOURCES = debuginfod-find.c
debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS)
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index a089d0bd..04c5f635 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -54,10 +54,12 @@ extern "C" {
#include
#include
#include
-#include
#include
#include
+#ifdef ENABLE_ONE_SHOT
+#include
+#endif
/* If fts.h is included before config.h, its indirect inclusions may not
give us the right LFS aliases of these functions, so map them manually. */
@@ -387,6 +389,8 @@ static const struct argp_option options[] =
{ "passive", ARGP_KEY_PASSIVE, NULL, 0, "Do not scan or groom, read-only database.", 0 },
#define ARGP_KEY_DISABLE_SOURCE_SCAN 0x1009
{ "disable-source-scan", ARGP_KEY_DISABLE_SOURCE_SCAN, NULL, 0, "Do not scan dwarf source info.", 0 },
+#define ARGP_KEY_ONE_SHOT 0x100a
+ { "one-shot", ARGP_KEY_ONE_SHOT, "NUM", 0, "For the first scan, output found buildids/paths to given file descriptor", 0 },
{ NULL, 0, NULL, 0, NULL, 0 },
};
@@ -439,6 +443,8 @@ static unsigned forwarded_ttl_limit = 8;
static bool scan_source_info = true;
static string tmpdir;
static bool passive_p = false;
+static int one_shot_fd = -1;
+static mutex one_shot_mtx;
static void set_metric(const string& key, double value);
// static void inc_metric(const string& key);
@@ -639,6 +645,16 @@ parse_opt (int key, char *arg,
// other conflicting options tricky to check
argp_failure(state, 1, EINVAL, "inconsistent options with passive mode");
break;
+case ARGP_KEY_ONE_SHOT:
+ one_shot_fd = atol(arg);
+ #ifdef ENABLE_ONE_SHOT
+if (one_shot_fd < 0)
+ argp_failure(state, 1, EINVAL, "one-shot fd");
+ #else
+argp_failure(state, 1, EINVAL, "Debuginfod in one-shot mode r