aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse_log.c
diff options
context:
space:
mode:
authorBernd Schubert <bschubert@ddn.com>2024-07-10 23:04:46 +0200
committerBernd Schubert <bernd.schubert@fastmail.fm>2024-07-14 14:28:44 +0200
commitdae1184302834b52cff438fbf5322cd1c9c79c06 (patch)
tree3c71a7f60f442d460f5968e239ab0ed2a0defe27 /lib/fuse_log.c
parent67ce439e2d73e73426b68695288729c6ffd63e5b (diff)
downloadlibfuse-dae1184302834b52cff438fbf5322cd1c9c79c06.tar.gz
Add syslog and fatal signal handler feature
I see random ENOTCONN failures in xfstest generic/013 and generic/014 in my branch, but earliest on the 2nd run - takes ~12hours to get the issue, but then there are no further information logged. ENOTCONN points to a daemon crash - I need backtraces and a core dump. This adds optional handling of fatal signals to print a core dump and optional syslog logging with these new public functions: fuse_set_fail_signal_handlers() In addition to the existing fuse_set_signal_handlers(). This is not enabled together with fuse_set_signal_handlers(), as it is change in behavior and file systems might already have their own fatal handlers. fuse_log_enable_syslog Print logs to syslog instead of stderr fuse_log_close_syslog Close syslog (for now just does closelog()) Code in fuse_signals.c is also updated, to be an array of signals, and setting signal handlers is now down with a for-loop instead of one hand coded set_one_signal_handler() per signal.
Diffstat (limited to 'lib/fuse_log.c')
-rw-r--r--lib/fuse_log.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/lib/fuse_log.c b/lib/fuse_log.c
index 0d268ab..95d6379 100644
--- a/lib/fuse_log.c
+++ b/lib/fuse_log.c
@@ -12,12 +12,56 @@
#include <stdarg.h>
#include <stdio.h>
+#include <stdbool.h>
+#include <syslog.h>
-static void default_log_func(
- __attribute__(( unused )) enum fuse_log_level level,
- const char *fmt, va_list ap)
+#define MAX_SYSLOG_LINE_LEN 512
+
+static bool to_syslog = false;
+
+static void default_log_func(__attribute__((unused)) enum fuse_log_level level,
+ const char *fmt, va_list ap)
{
- vfprintf(stderr, fmt, ap);
+ if (to_syslog) {
+ int sys_log_level;
+
+ /*
+ * with glibc fuse_log_level has identical values as
+ * syslog levels, but we also support BSD - better we convert to
+ * be sure.
+ */
+ switch (level) {
+ case FUSE_LOG_DEBUG:
+ sys_log_level = LOG_DEBUG;
+ break;
+ case FUSE_LOG_INFO:
+ sys_log_level = LOG_INFO;
+ break;
+ case FUSE_LOG_NOTICE:
+ sys_log_level = LOG_NOTICE;
+ break;
+ case FUSE_LOG_WARNING:
+ sys_log_level = LOG_WARNING;
+ break;
+ case FUSE_LOG_ERR:
+ sys_log_level = LOG_ERR;
+ break;
+ case FUSE_LOG_CRIT:
+ sys_log_level = LOG_CRIT;
+ break;
+ case FUSE_LOG_ALERT:
+ sys_log_level = LOG_ALERT;
+ break;
+ case FUSE_LOG_EMERG:
+ sys_log_level = LOG_EMERG;
+ }
+
+ char log[MAX_SYSLOG_LINE_LEN];
+ vsnprintf(log, MAX_SYSLOG_LINE_LEN, fmt, ap);
+ syslog(sys_log_level, "%s", log);
+ } else {
+ vfprintf(stderr, fmt, ap);
+ }
}
static fuse_log_func_t log_func = default_log_func;
@@ -38,3 +82,15 @@ void fuse_log(enum fuse_log_level level, const char *fmt, ...)
log_func(level, fmt, ap);
va_end(ap);
}
+
+void fuse_log_enable_syslog(const char *ident, int option, int facility)
+{
+ to_syslog = true;
+
+ openlog(ident, option, facility);
+}
+
+void fuse_log_close_syslog(void)
+{
+ closelog();
+} \ No newline at end of file