public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] Allow systemd activation for debuginfod
@ 2021-03-07 12:49 Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 1/6] Find and link libsystemd Victor Westerhuis
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

As a developer I have a few self-built Debian packages in a small repo
on my own laptop. I like having debuginfod running when debugging them,
but it does not have to be running all the time.

This patch series is a first try at integrating systemd socket 
activation in debuginfod. I've tried to split the series into different
ways of integration. I'm not sure if watchdog support is really useful,
since the main loop doesn't do any work. If it isn't, I can drop it.

Victor Westerhuis (6):
  Find and link libsystemd
  Allow socket activation by systemd
  Notify systemd when ready and stopping
  Use cache directory from systemd
  Report error exit reason to systemd
  Support systemd watchdog

 config/debuginfod.service |   3 +-
 configure.ac              |  12 ++
 debuginfod/Makefile.am    |   7 +
 debuginfod/debuginfod.cxx | 267 +++++++++++++++++++++++++++++---------
 4 files changed, 226 insertions(+), 63 deletions(-)

-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 1/6] Find and link libsystemd
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 2/6] Allow socket activation by systemd Victor Westerhuis
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 configure.ac           | 12 ++++++++++++
 debuginfod/Makefile.am |  7 +++++++
 2 files changed, 19 insertions(+)

diff --git a/configure.ac b/configure.ac
index aa8439e8..8d52b666 100644
--- a/configure.ac
+++ b/configure.ac
@@ -773,6 +773,17 @@ AS_IF([test "x$enable_debuginfod" != "xno"], [
     if test "x$enable_debuginfod" = "xno"; then
       AC_MSG_ERROR([dependencies not found, use --disable-debuginfod to disable.])
     fi
+
+    AC_ARG_ENABLE([systemd],AC_HELP_STRING([--enable-systemd], [Enable systemd support in debuginfod]))
+    AS_IF([test "x$enable_systemd" != "xno"], [
+        PKG_CHECK_MODULES([libsystemd],[libsystemd],[enable_systemd=yes],[
+            AS_IF([test "x$enable_systemd" = "xyes"], [
+                AC_MSG_ERROR([need libsystemd, use --disable-systemd to disable.])
+            ], [enable_systemd=no])
+        ])
+    ])
+    AS_IF([test "x$enable_systemd" = "xyes"],AC_DEFINE([ENABLE_SYSTEMD],[1],[Enable systemd support]))
+    AM_CONDITIONAL([SYSTEMD],[test "x$enable_systemd" = "xyes"])
 ])
 
 AS_IF([test "x$enable_debuginfod" != "xno"],AC_DEFINE([ENABLE_DEBUGINFOD],[1],[Build debuginfod]))
@@ -823,6 +834,7 @@ AC_MSG_NOTICE([
     Extra Valgrind annotations         : ${use_vg_annotations}
     libdebuginfod client support       : ${enable_libdebuginfod}
     Debuginfod server support          : ${enable_debuginfod}
+    Debuginfod systemd support         : ${enable_systemd}
     Default DEBUGINFOD_URLS            : ${default_debuginfod_urls}
 
   EXTRA TEST FEATURES (used with make check)
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 3adb2755..e7528c3a 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -35,6 +35,10 @@ AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
 	   $(libmicrohttpd_CFLAGS) $(libcurl_CFLAGS) $(sqlite3_CFLAGS) \
 	   $(libarchive_CFLAGS)
 
+if SYSTEMD
+AM_CPPFLAGS += $(libsystemd_CFLAGS)
+endif
+
 # Disable eu- prefixing for artifacts (binaries & man pages) in this
 # directory, since they do not conflict with binutils tools.
 program_prefix=
@@ -71,6 +75,9 @@ endif
 
 debuginfod_SOURCES = debuginfod.cxx
 debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS) $(libmicrohttpd_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
+if SYSTEMD
+debuginfod_LDADD += $(libsystemd_LIBS)
+endif
 
 debuginfod_find_SOURCES = debuginfod-find.c
 debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(argp_LDADD) $(fts_LIBS)
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 2/6] Allow socket activation by systemd
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 1/6] Find and link libsystemd Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 3/6] Notify systemd when ready and stopping Victor Westerhuis
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 debuginfod/debuginfod.cxx | 161 ++++++++++++++++++++++++++++----------
 1 file changed, 121 insertions(+), 40 deletions(-)

diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 2aecc049..caced48c 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -93,6 +93,10 @@ using namespace std;
 
 #include <microhttpd.h>
 
+#ifdef ENABLE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #if MHD_VERSION >= 0x00097002
 // libmicrohttpd 0.9.71 broke API
 #define MHD_RESULT enum MHD_Result
@@ -367,6 +371,10 @@ static const struct argp_option options[] =
    { "fdcache-prefetch", ARGP_KEY_FDCACHE_PREFETCH, "NUM", 0, "Number of archive files to prefetch into fdcache.", 0 },
 #define ARGP_KEY_FDCACHE_MINTMP 0x1004
    { "fdcache-mintmp", ARGP_KEY_FDCACHE_MINTMP, "NUM", 0, "Minimum free space% on tmpdir.", 0 },
+#ifdef ENABLE_SYSTEMD
+#define ARGP_KEY_SYSTEMD 0x1005
+   { "systemd", ARGP_KEY_SYSTEMD, NULL, 0, "Use systemd socket activation and cache directory.", 0 },
+#endif
    { NULL, 0, NULL, 0, NULL, 0 }
   };
 
@@ -412,6 +420,9 @@ static long fdcache_mbs;
 static long fdcache_prefetch;
 static long fdcache_mintmp;
 static string tmpdir;
+#ifdef ENABLE_SYSTEMD
+static bool systemd;
+#endif
 
 static void set_metric(const string& key, double value);
 // static void inc_metric(const string& key);
@@ -541,6 +552,11 @@ parse_opt (int key, char *arg,
     case ARGP_KEY_ARG:
       source_paths.insert(string(arg));
       break;
+#ifdef ENABLE_SYSTEMD
+    case ARGP_KEY_SYSTEMD:
+      systemd = true;
+      break;
+#endif
       // case 'h': argp_state_help (state, stderr, ARGP_HELP_LONG|ARGP_HELP_EXIT_OK);
     default: return ARGP_ERR_UNKNOWN;
     }
@@ -3267,6 +3283,16 @@ static void sqlite3_sharedprefix_fn (sqlite3_context* c, int argc, sqlite3_value
 }
 
 
+static void close_databases ()
+{
+  sqlite3 *database = db;
+  sqlite3 *databaseq = dbq;
+  db = dbq = 0; // for signal_handler not to freak
+  (void) sqlite3_close (databaseq);
+  (void) sqlite3_close (database);
+}
+
+
 int
 main (int argc, char *argv[])
 {
@@ -3372,46 +3398,105 @@ main (int argc, char *argv[])
              "cannot run database schema ddl: %s", sqlite3_errmsg(db));
     }
 
-  // Start httpd server threads.  Separate pool for IPv4 and IPv6, in
-  // case the host only has one protocol stack.
-  MHD_Daemon *d4 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+  vector<MHD_Daemon *> daemons;
+#ifdef ENABLE_SYSTEMD
+  if (systemd)
+    {
+      int fds = sd_listen_fds (true);
+      if (fds <= 0)
+        {
+          close_databases ();
+          error (EXIT_FAILURE, -fds, "cannot get fds from systemd");
+        }
+
+      for (int i = 0; i < fds; ++i)
+        {
+          int fd = SD_LISTEN_FDS_START + i;
+
+          rc = sd_is_socket_inet (fd, AF_UNSPEC, SOCK_STREAM, true, 0);
+          if (rc < 0)
+            {
+              close_databases ();
+              error (EXIT_FAILURE, -rc, "unable to determine fd type");
+            }
+          else if (rc == 0)
+            {
+              close_databases ();
+              error (EXIT_FAILURE, 0,
+                     "fd %d is not of the correct socket type", fd);
+            }
+
+          MHD_Daemon *d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
 #if MHD_VERSION >= 0x00095300
-                                     | MHD_USE_INTERNAL_POLLING_THREAD
+                                            | MHD_USE_INTERNAL_POLLING_THREAD
 #else
-                                     | MHD_USE_SELECT_INTERNALLY
+                                            | MHD_USE_SELECT_INTERNALLY
 #endif
-                                     | MHD_USE_DEBUG, /* report errors to stderr */
-                                     http_port,
-                                     NULL, NULL, /* default accept policy */
-                                     handler_cb, NULL, /* handler callback */
-                                     MHD_OPTION_END);
-  MHD_Daemon *d6 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+                                            | MHD_USE_DEBUG /* report errors to stderr */
+                                            | MHD_USE_ITC, /* don't close socket on shutdown */
+                                            0,
+                                            NULL, NULL, /* default accept policy */
+                                            handler_cb, NULL, /* handler callback */
+                                            MHD_OPTION_LISTEN_SOCKET,
+                                            fd,
+                                            MHD_OPTION_END);
+          if (d == NULL)
+            {
+              close_databases ();
+              error (EXIT_FAILURE, 0,
+                    "cannot start http server on fd %d", fd);
+            }
+
+          obatched(clog) << "started http server on fd " << fd << endl;
+
+          daemons.push_back (d);
+        }
+    }
+  else
+#endif
+    {
+      // Start httpd server threads.  Separate pool for IPv4 and IPv6, in
+      // case the host only has one protocol stack.
+      MHD_Daemon *d4 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
 #if MHD_VERSION >= 0x00095300
-                                     | MHD_USE_INTERNAL_POLLING_THREAD
+                                         | MHD_USE_INTERNAL_POLLING_THREAD
 #else
-                                     | MHD_USE_SELECT_INTERNALLY
+                                         | MHD_USE_SELECT_INTERNALLY
 #endif
-                                     | MHD_USE_IPv6
-                                     | MHD_USE_DEBUG, /* report errors to stderr */
-                                     http_port,
-                                     NULL, NULL, /* default accept policy */
-                                     handler_cb, NULL, /* handler callback */
-                                     MHD_OPTION_END);
-
-  if (d4 == NULL && d6 == NULL) // neither ipv4 nor ipv6? boo
-    {
-      sqlite3 *database = db;
-      sqlite3 *databaseq = dbq;
-      db = dbq = 0; // for signal_handler not to freak
-      sqlite3_close (databaseq);
-      sqlite3_close (database);
-      error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port);
-    }
+                                         | MHD_USE_DEBUG, /* report errors to stderr */
+                                         http_port,
+                                         NULL, NULL, /* default accept policy */
+                                         handler_cb, NULL, /* handler callback */
+                                         MHD_OPTION_END);
+      MHD_Daemon *d6 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
+#if MHD_VERSION >= 0x00095300
+                                         | MHD_USE_INTERNAL_POLLING_THREAD
+#else
+                                         | MHD_USE_SELECT_INTERNALLY
+#endif
+                                         | MHD_USE_IPv6
+                                         | MHD_USE_DEBUG, /* report errors to stderr */
+                                         http_port,
+                                         NULL, NULL, /* default accept policy */
+                                         handler_cb, NULL, /* handler callback */
+                                         MHD_OPTION_END);
+
+      if (d4 == NULL && d6 == NULL) // neither ipv4 nor ipv6? boo
+        {
+          close_databases ();
+          error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port);
+        }
+
+      obatched(clog) << "started http server on "
+                     << (d4 != NULL ? "IPv4 " : "")
+                     << (d6 != NULL ? "IPv6 " : "")
+                     << "port=" << http_port << endl;
 
-  obatched(clog) << "started http server on "
-                 << (d4 != NULL ? "IPv4 " : "")
-                 << (d6 != NULL ? "IPv6 " : "")
-                 << "port=" << http_port << endl;
+      if (d4)
+        daemons.push_back(d4);
+      if (d6)
+        daemons.push_back(d6);
+    }
 
   // add maxigroom sql if -G given
   if (maxigroom)
@@ -3505,8 +3590,8 @@ main (int argc, char *argv[])
     pthread_join (it, NULL);
 
   /* Stop all the web service threads. */
-  if (d4) MHD_stop_daemon (d4);
-  if (d6) MHD_stop_daemon (d6);
+  for (auto&& i : daemons)
+    MHD_stop_daemon (i);
 
   /* With all threads known dead, we can clean up the global resources. */
   rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_CLEANUP_DDL, NULL, NULL, NULL);
@@ -3520,11 +3605,7 @@ main (int argc, char *argv[])
   (void) regfree (& file_include_regex);
   (void) regfree (& file_exclude_regex);
 
-  sqlite3 *database = db;
-  sqlite3 *databaseq = dbq;
-  db = dbq = 0; // for signal_handler not to freak
-  (void) sqlite3_close (databaseq);
-  (void) sqlite3_close (database);
+  close_databases ();
 
   return 0;
 }
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 3/6] Notify systemd when ready and stopping
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 1/6] Find and link libsystemd Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 2/6] Allow socket activation by systemd Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 4/6] Use cache directory from systemd Victor Westerhuis
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 config/debuginfod.service | 1 +
 debuginfod/debuginfod.cxx | 6 ++++++
 2 files changed, 7 insertions(+)

diff --git a/config/debuginfod.service b/config/debuginfod.service
index b64d8cb9..6c434705 100644
--- a/config/debuginfod.service
+++ b/config/debuginfod.service
@@ -4,6 +4,7 @@ Documentation=http://elfutils.org/
 After=network.target
 
 [Service]
+Type=Notify
 EnvironmentFile=/etc/sysconfig/debuginfod
 User=debuginfod
 Group=debuginfod
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index caced48c..4dece371 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -3576,11 +3576,17 @@ main (int argc, char *argv[])
     }
 
   /* Trivial main loop! */
+#ifdef ENABLE_SYSTEMD
+  (void) sd_notify (false, "READY=1");
+#endif
   set_metric("ready", 1);
   while (! interrupted)
     pause ();
   scanq.nuke(); // wake up any remaining scanq-related threads, let them die
   set_metric("ready", 0);
+#ifdef ENABLE_SYSTEMD
+  (void) sd_notify (false, "STOPPING=1");
+#endif
 
   if (verbose)
     obatched(clog) << "stopping" << endl;
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 4/6] Use cache directory from systemd
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
                   ` (2 preceding siblings ...)
  2021-03-07 12:49 ` [RFC PATCH 3/6] Notify systemd when ready and stopping Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 5/6] Report error exit reason to systemd Victor Westerhuis
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 config/debuginfod.service | 2 +-
 debuginfod/debuginfod.cxx | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/config/debuginfod.service b/config/debuginfod.service
index 6c434705..c99b5406 100644
--- a/config/debuginfod.service
+++ b/config/debuginfod.service
@@ -8,7 +8,7 @@ Type=Notify
 EnvironmentFile=/etc/sysconfig/debuginfod
 User=debuginfod
 Group=debuginfod
-#CacheDirectory=debuginfod
+CacheDirectory=debuginfod
 ExecStart=/usr/bin/debuginfod -d /var/cache/debuginfod/debuginfod.sqlite -p $DEBUGINFOD_PORT $DEBUGINFOD_VERBOSE $DEBUGINFOD_PRAGMAS $DEBUGINFOD_PATHS
 # Stopping can take a long time if scanning of large archives is in progress
 TimeoutStopSec=60
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 4dece371..9542c5e2 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -3307,6 +3307,13 @@ main (int argc, char *argv[])
 
   /* Set computed default values. */
   db_path = string(getenv("HOME") ?: "/") + string("/.debuginfod.sqlite"); /* XDG? */
+#ifdef ENABLE_SYSTEMD
+  if (getenv("CACHE_DIRECTORY"))
+    {
+      db_path = string(getenv("CACHE_DIRECTORY")) + string("/debuginfod.sqlite");
+      setenv (DEBUGINFOD_CACHE_PATH_ENV_VAR, getenv("CACHE_DIRECTORY"), false);
+    }
+#endif
   int rc = regcomp (& file_include_regex, ".*", REG_EXTENDED|REG_NOSUB); // match everything
   if (rc != 0)
     error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 5/6] Report error exit reason to systemd
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
                   ` (3 preceding siblings ...)
  2021-03-07 12:49 ` [RFC PATCH 4/6] Use cache directory from systemd Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 12:49 ` [RFC PATCH 6/6] Support systemd watchdog Victor Westerhuis
  2021-03-07 14:54 ` [RFC PATCH 0/6] Allow systemd activation for debuginfod Frank Ch. Eigler
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 debuginfod/debuginfod.cxx | 74 ++++++++++++++++++++++++---------------
 1 file changed, 46 insertions(+), 28 deletions(-)

diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 9542c5e2..35b5fc18 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -120,6 +120,24 @@ using namespace std;
 #endif
 
 
+#ifdef ENABLE_SYSTEMD
+#define report_error(status, errnum, format, ...) \
+  do \
+    { \
+      int s = (status), e = (errnum); \
+      if (s != 0 && e != 0) \
+        { \
+          (void) sd_notifyf (false, "ERRNO=%d", e); \
+          (void) sd_notifyf (false, "STATUS=" format, ##__VA_ARGS__); \
+        } \
+      error (s, e, format, ##__VA_ARGS__); \
+    } \
+  while (false)
+#else
+#define report_error(...) error(__VA_ARGS__)
+#endif
+
+
 inline bool
 string_endswith(const string& haystack, const string& needle)
 {
@@ -3316,10 +3334,10 @@ main (int argc, char *argv[])
 #endif
   int rc = regcomp (& file_include_regex, ".*", REG_EXTENDED|REG_NOSUB); // match everything
   if (rc != 0)
-    error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
+    report_error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
   rc = regcomp (& file_exclude_regex, "^$", REG_EXTENDED|REG_NOSUB); // match nothing
   if (rc != 0)
-    error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
+    report_error (EXIT_FAILURE, 0, "regcomp failure: %d", rc);
 
   // default parameters for fdcache are computed from system stats
   struct statfs sfs;
@@ -3337,8 +3355,8 @@ main (int argc, char *argv[])
   argp_program_version_hook = print_version; // this works
   (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
   if (remaining != argc)
-      error (EXIT_FAILURE, 0,
-             "unexpected argument: %s", argv[remaining]);
+      report_error (EXIT_FAILURE, 0,
+                    "unexpected argument: %s", argv[remaining]);
 
   if (scan_archives.size()==0 && !scan_files && source_paths.size()>0)
     obatched(clog) << "warning: without -F -R -U -Z, ignoring PATHs" << endl;
@@ -3362,13 +3380,13 @@ main (int argc, char *argv[])
   if (rc == SQLITE_CORRUPT)
     {
       (void) unlink (db_path.c_str());
-      error (EXIT_FAILURE, 0,
-             "cannot open %s, deleted database: %s", db_path.c_str(), sqlite3_errmsg(db));
+      report_error (EXIT_FAILURE, 0,
+                    "cannot open %s, deleted database: %s", db_path.c_str(), sqlite3_errmsg(db));
     }
   else if (rc)
     {
-      error (EXIT_FAILURE, 0,
-             "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(db));
+      report_error (EXIT_FAILURE, 0,
+                    "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(db));
     }
 
   // open the readonly query variant
@@ -3381,8 +3399,8 @@ main (int argc, char *argv[])
                         NULL);
   if (rc)
     {
-      error (EXIT_FAILURE, 0,
-             "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(dbq));
+      report_error (EXIT_FAILURE, 0,
+                    "cannot open %s, consider deleting database: %s", db_path.c_str(), sqlite3_errmsg(dbq));
     }
 
 
@@ -3393,16 +3411,16 @@ main (int argc, char *argv[])
   rc = sqlite3_create_function(dbq, "sharedprefix", 2, SQLITE_UTF8, NULL,
                                & sqlite3_sharedprefix_fn, NULL, NULL);
   if (rc != SQLITE_OK)
-    error (EXIT_FAILURE, 0,
-           "cannot create sharedprefix function: %s", sqlite3_errmsg(dbq));
+    report_error (EXIT_FAILURE, 0,
+                  "cannot create sharedprefix function: %s", sqlite3_errmsg(dbq));
 
   if (verbose > 3)
     obatched(clog) << "ddl: " << DEBUGINFOD_SQLITE_DDL << endl;
   rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_DDL, NULL, NULL, NULL);
   if (rc != SQLITE_OK)
     {
-      error (EXIT_FAILURE, 0,
-             "cannot run database schema ddl: %s", sqlite3_errmsg(db));
+      report_error (EXIT_FAILURE, 0,
+                    "cannot run database schema ddl: %s", sqlite3_errmsg(db));
     }
 
   vector<MHD_Daemon *> daemons;
@@ -3413,7 +3431,7 @@ main (int argc, char *argv[])
       if (fds <= 0)
         {
           close_databases ();
-          error (EXIT_FAILURE, -fds, "cannot get fds from systemd");
+          report_error (EXIT_FAILURE, -fds, "cannot get fds from systemd");
         }
 
       for (int i = 0; i < fds; ++i)
@@ -3424,13 +3442,13 @@ main (int argc, char *argv[])
           if (rc < 0)
             {
               close_databases ();
-              error (EXIT_FAILURE, -rc, "unable to determine fd type");
+              report_error (EXIT_FAILURE, -rc, "unable to determine fd type");
             }
           else if (rc == 0)
             {
               close_databases ();
-              error (EXIT_FAILURE, 0,
-                     "fd %d is not of the correct socket type", fd);
+              report_error (EXIT_FAILURE, 0,
+                            "fd %d is not of the correct socket type", fd);
             }
 
           MHD_Daemon *d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
@@ -3450,8 +3468,8 @@ main (int argc, char *argv[])
           if (d == NULL)
             {
               close_databases ();
-              error (EXIT_FAILURE, 0,
-                    "cannot start http server on fd %d", fd);
+              report_error (EXIT_FAILURE, 0,
+                            "cannot start http server on fd %d", fd);
             }
 
           obatched(clog) << "started http server on fd " << fd << endl;
@@ -3491,7 +3509,7 @@ main (int argc, char *argv[])
       if (d4 == NULL && d6 == NULL) // neither ipv4 nor ipv6? boo
         {
           close_databases ();
-          error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port);
+          report_error (EXIT_FAILURE, 0, "cannot start http server at port %d", http_port);
         }
 
       obatched(clog) << "started http server on "
@@ -3531,8 +3549,8 @@ main (int argc, char *argv[])
         obatched(clog) << "extra ddl:\n" << i << endl;
       rc = sqlite3_exec (db, i.c_str(), NULL, NULL, NULL);
       if (rc != SQLITE_OK && rc != SQLITE_DONE && rc != SQLITE_ROW)
-        error (0, 0,
-               "warning: cannot run database extra ddl %s: %s", i.c_str(), sqlite3_errmsg(db));
+        report_error (0, 0,
+                      "warning: cannot run database extra ddl %s: %s", i.c_str(), sqlite3_errmsg(db));
     }
 
   if (maxigroom)
@@ -3563,7 +3581,7 @@ main (int argc, char *argv[])
   pthread_t pt;
   rc = pthread_create (& pt, NULL, thread_main_groom, NULL);
   if (rc)
-    error (EXIT_FAILURE, rc, "cannot spawn thread to groom database\n");
+    report_error (EXIT_FAILURE, rc, "cannot spawn thread to groom database\n");
   else
     all_threads.push_back(pt);
 
@@ -3571,13 +3589,13 @@ main (int argc, char *argv[])
     {
       rc = pthread_create (& pt, NULL, thread_main_fts_source_paths, NULL);
       if (rc)
-        error (EXIT_FAILURE, rc, "cannot spawn thread to traverse source paths\n");
+        report_error (EXIT_FAILURE, rc, "cannot spawn thread to traverse source paths\n");
       all_threads.push_back(pt);
       for (unsigned i=0; i<concurrency; i++)
         {
           rc = pthread_create (& pt, NULL, thread_main_scanner, NULL);
           if (rc)
-            error (EXIT_FAILURE, rc, "cannot spawn thread to scan source files / archives\n");
+            report_error (EXIT_FAILURE, rc, "cannot spawn thread to scan source files / archives\n");
           all_threads.push_back(pt);
         }
     }
@@ -3610,8 +3628,8 @@ main (int argc, char *argv[])
   rc = sqlite3_exec (db, DEBUGINFOD_SQLITE_CLEANUP_DDL, NULL, NULL, NULL);
   if (rc != SQLITE_OK)
     {
-      error (0, 0,
-             "warning: cannot run database cleanup ddl: %s", sqlite3_errmsg(db));
+      report_error (0, 0,
+                    "warning: cannot run database cleanup ddl: %s", sqlite3_errmsg(db));
     }
 
   // NB: no problem with unconditional free here - an earlier failed regcomp would exit program
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC PATCH 6/6] Support systemd watchdog
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
                   ` (4 preceding siblings ...)
  2021-03-07 12:49 ` [RFC PATCH 5/6] Report error exit reason to systemd Victor Westerhuis
@ 2021-03-07 12:49 ` Victor Westerhuis
  2021-03-07 14:54 ` [RFC PATCH 0/6] Allow systemd activation for debuginfod Frank Ch. Eigler
  6 siblings, 0 replies; 12+ messages in thread
From: Victor Westerhuis @ 2021-03-07 12:49 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Victor Westerhuis

Signed-off-by: Victor Westerhuis <victor@westerhu.is>
---
 debuginfod/debuginfod.cxx | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 35b5fc18..b31c77d3 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -94,6 +94,7 @@ using namespace std;
 #include <microhttpd.h>
 
 #ifdef ENABLE_SYSTEMD
+#include <time.h>
 #include <systemd/sd-daemon.h>
 #endif
 
@@ -3600,13 +3601,43 @@ main (int argc, char *argv[])
         }
     }
 
+#ifdef ENABLE_SYSTEMD
+  uint64_t timeout_usec;
+  int watchdog_enabled = sd_watchdog_enabled (true, &timeout_usec);
+  if (watchdog_enabled < 0)
+    report_error (0, -watchdog_enabled,
+                  "warning: cannot determine if watchdog is enabled");
+#endif
+
   /* Trivial main loop! */
 #ifdef ENABLE_SYSTEMD
   (void) sd_notify (false, "READY=1");
 #endif
   set_metric("ready", 1);
-  while (! interrupted)
-    pause ();
+#ifdef ENABLE_SYSTEMD
+  if (watchdog_enabled > 0)
+    {
+      timeout_usec /= 2;
+      struct timespec timeout;
+      timeout.tv_sec = timeout_usec / 1000000;
+      timeout.tv_nsec = timeout_usec % 1000000 * 1000;
+
+      rc = 0;
+      struct timespec remaining_timeout;
+      while (! interrupted)
+        {
+          if (rc == 0)
+            {
+              (void) sd_notify (false, "WATCHDOG=1");
+              remaining_timeout = timeout;
+            }
+          rc = nanosleep (&remaining_timeout, &remaining_timeout);
+        }
+    }
+  else
+#endif
+    while (! interrupted)
+      pause ();
   scanq.nuke(); // wake up any remaining scanq-related threads, let them die
   set_metric("ready", 0);
 #ifdef ENABLE_SYSTEMD
-- 
2.30.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/6] Allow systemd activation for debuginfod
  2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
                   ` (5 preceding siblings ...)
  2021-03-07 12:49 ` [RFC PATCH 6/6] Support systemd watchdog Victor Westerhuis
@ 2021-03-07 14:54 ` Frank Ch. Eigler
  2021-03-07 16:47   ` Mark Wielaard
  2021-03-07 19:01   ` Frank Ch. Eigler
  6 siblings, 2 replies; 12+ messages in thread
From: Frank Ch. Eigler @ 2021-03-07 14:54 UTC (permalink / raw)
  To: Victor Westerhuis; +Cc: elfutils-devel

Hi -

> As a developer I have a few self-built Debian packages in a small repo
> on my own laptop. I like having debuginfod running when debugging them,
> but it does not have to be running all the time.

What about the grooming/scanning cycles?

> This patch series is a first try at integrating systemd socket 
> activation in debuginfod. I've tried to split the series into different
> ways of integration. [...]

Thanks, the code is fairly readable in this breakdown.  The mhd
initialization looks rather worse, and if we decided to do this, I
might focus on simplifying that.  (Maybe I'd use the classic inetd
socket-stdin/stdout style rather than systemd-specific APIs.)

But I'm not sure a web-api-only functionality makes much sense -
unless there is also a sibling debuginfod to do the scanning/grooming,
in which case ... how does this help?

- FChE


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/6] Allow systemd activation for debuginfod
  2021-03-07 14:54 ` [RFC PATCH 0/6] Allow systemd activation for debuginfod Frank Ch. Eigler
@ 2021-03-07 16:47   ` Mark Wielaard
  2021-03-07 18:17     ` Frank Ch. Eigler
  2021-03-07 19:01   ` Frank Ch. Eigler
  1 sibling, 1 reply; 12+ messages in thread
From: Mark Wielaard @ 2021-03-07 16:47 UTC (permalink / raw)
  To: Frank Ch. Eigler, Victor Westerhuis; +Cc: elfutils-devel

Hi,

On Sun, 2021-03-07 at 09:54 -0500, Frank Ch. Eigler via Elfutils-devel
wrote:
> As a developer I have a few self-built Debian packages in a small
> > repo
> > on my own laptop. I like having debuginfod running when debugging them,
> > but it does not have to be running all the time.
> 
> What about the grooming/scanning cycles?

I was thinking the same thing. This patch series takes care of the web-
socket activation part. systemd also provides path-based activation of
units [1]. That could maybe be used for the scanning cycles. systemd
would then trigger activation when something is dropped into (or
removed from) the search directory.

Cheers,

Mark

[1] https://www.freedesktop.org/software/systemd/man/systemd.path.html

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/6] Allow systemd activation for debuginfod
  2021-03-07 16:47   ` Mark Wielaard
@ 2021-03-07 18:17     ` Frank Ch. Eigler
  2021-03-10 15:37       ` Mark Wielaard
  0 siblings, 1 reply; 12+ messages in thread
From: Frank Ch. Eigler @ 2021-03-07 18:17 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: Victor Westerhuis, elfutils-devel

Hi -

> > What about the grooming/scanning cycles?
> 
> I was thinking the same thing. This patch series takes care of the web-
> socket activation part. systemd also provides path-based activation of
> units [1]. That could maybe be used for the scanning cycles. systemd
> would then trigger activation when something is dropped into (or
> removed from) the search directory.

.... yeah but it's not recursive, not symlink-following-aware, doesn't
work for all filesystems (NFS!).


- FChE


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/6] Allow systemd activation for debuginfod
  2021-03-07 14:54 ` [RFC PATCH 0/6] Allow systemd activation for debuginfod Frank Ch. Eigler
  2021-03-07 16:47   ` Mark Wielaard
@ 2021-03-07 19:01   ` Frank Ch. Eigler
  1 sibling, 0 replies; 12+ messages in thread
From: Frank Ch. Eigler @ 2021-03-07 19:01 UTC (permalink / raw)
  To: Victor Westerhuis, elfutils-devel

Hi -

> But I'm not sure a web-api-only functionality makes much sense -
> unless there is also a sibling debuginfod to do the scanning/grooming,
> in which case ... how does this help?

Another angle to consider: metrics/monitoring.  The code goes to some
effort to let an operator know how the system running: how fast sqlite
queries are, what sort of network throughput to expect.  If instead we
have short-lived processes serving this or that purpose, we lose
monitoring capability completely.

- FChE


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/6] Allow systemd activation for debuginfod
  2021-03-07 18:17     ` Frank Ch. Eigler
@ 2021-03-10 15:37       ` Mark Wielaard
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Wielaard @ 2021-03-10 15:37 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: Victor Westerhuis, elfutils-devel

Hi Frank, Hi Victor,

On Sun, 2021-03-07 at 13:17 -0500, Frank Ch. Eigler wrote:
> > > What about the grooming/scanning cycles?
> > 
> > I was thinking the same thing. This patch series takes care of the web-
> > socket activation part. systemd also provides path-based activation of
> > units [1]. That could maybe be used for the scanning cycles. systemd
> > would then trigger activation when something is dropped into (or
> > removed from) the search directory.
> 
> .... yeah but it's not recursive, not symlink-following-aware, doesn't
> work for all filesystems (NFS!).

But is that important for this use case? A single developer box with a
local dir having some debuginfo for local packages. debuginfod could
just warn (and keep running/scanning) if it detects that dir contains
symlinks, subdirs, etc. on first scan. I don't think path-based
activation means you have to quit once done, just that you might be
reactivated if you do.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-03-10 15:37 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-07 12:49 [RFC PATCH 0/6] Allow systemd activation for debuginfod Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 1/6] Find and link libsystemd Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 2/6] Allow socket activation by systemd Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 3/6] Notify systemd when ready and stopping Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 4/6] Use cache directory from systemd Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 5/6] Report error exit reason to systemd Victor Westerhuis
2021-03-07 12:49 ` [RFC PATCH 6/6] Support systemd watchdog Victor Westerhuis
2021-03-07 14:54 ` [RFC PATCH 0/6] Allow systemd activation for debuginfod Frank Ch. Eigler
2021-03-07 16:47   ` Mark Wielaard
2021-03-07 18:17     ` Frank Ch. Eigler
2021-03-10 15:37       ` Mark Wielaard
2021-03-07 19:01   ` Frank Ch. Eigler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).