Package: guix-patches;
Reported by: Danny Milosavljevic <dannym <at> scratchpost.org>
Date: Sat, 17 Feb 2018 12:21:02 UTC
Severity: normal
Tags: patch
Done: ludo <at> gnu.org (Ludovic Courtès)
Bug is archived. No further changes may be made.
Message #53 received at 30498 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: 30498 <at> debbugs.gnu.org Cc: Danny Milosavljevic <dannym <at> scratchpost.org>, Ludovic Courtès <ludo <at> gnu.org> Subject: [PATCH 3/3] Use syslog for logging when running as root. Date: Wed, 7 Mar 2018 12:04:54 +0100
* modules/shepherd/comm.scm (call-with-syslog-port, syslog-output-port): New procedures. * modules/shepherd.scm (main): Set 'log-output-port' to (syslog-output-port) when running as root. * doc/shepherd.texi (Invoking shepherd): Adjust accordingly. --- doc/shepherd.texi | 18 ++++++++++--- modules/shepherd.scm | 2 +- modules/shepherd/comm.scm | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/doc/shepherd.texi b/doc/shepherd.texi index 01d8050..7946f8b 100644 --- a/doc/shepherd.texi +++ b/doc/shepherd.texi @@ -406,13 +406,23 @@ permissions are not as expected. @cindex log file Log output into @var{file}. -The default behavior is to write to @file{/dev/kmsg} when running as -superuser. This special device is GNU/Linux-specific; when it does not -exist, write to @file{/var/log/shepherd.log} instead. - For unprivileged users, the default log file is @file{$XDG_CONFIG_HOME/shepherd/shepherd.log}. +@cindex syslog +When running as root, the default behavior is to connect to +@file{/dev/log}, the @dfn{syslog} socket (@pxref{Overview of Syslog,,, +libc, The GNU C Library Reference Manual}). A syslog daemon, +@command{syslogd}, is expected to read messages from there +(@pxref{syslogd invocation, syslogd,, libc, GNU Inetutils}). + +When @file{/dev/log} is unavailable, for instance because +@command{syslogd} is not running, as is the case during system startup +and shutdown, @command{shepherd} falls back to the Linux kernel +@dfn{ring buffer}, @file{/dev/kmsg}. If @file{/dev/kmsg} is missing, as +is the case on other operating systems, it falls back to +@file{/dev/console}. + @item --pid[=@var{file}] When @command{shepherd} is ready to accept connections, write its PID to @var{file} or to the standard output if @var{file} is omitted. diff --git a/modules/shepherd.scm b/modules/shepherd.scm index 39fbe14..fede338 100644 --- a/modules/shepherd.scm +++ b/modules/shepherd.scm @@ -168,7 +168,7 @@ (cond (logfile (open-file logfile "al")) ((zero? (getuid)) - (open-file "/dev/kmsg" "wl")) + (syslog-output-port)) (else (open-file (user-default-log-file) "al")))) (%current-logfile-date-format diff --git a/modules/shepherd/comm.scm b/modules/shepherd/comm.scm index e686bfa..cbd8686 100644 --- a/modules/shepherd/comm.scm +++ b/modules/shepherd/comm.scm @@ -50,6 +50,7 @@ report-command-error log-output-port + syslog-output-port start-logging stop-logging make-shepherd-output-port @@ -216,6 +217,71 @@ on service '~a':") ;; 'strftime' format strings for entries in the log file. (make-parameter default-logfile-date-format)) +(define call-with-syslog-port + (let ((port #f)) ;connection to /dev/log + (lambda (proc) + "Call PROC with an open output port. The output port corresponds to +/dev/log (aka. syslog) or, if that is unavailable, a degraded logging +mechanism." + (define (call/syslog) + (catch 'system-error + (lambda () + (proc port)) + (lambda args + (if (memv (system-error-errno args) + (list ENOTCONN ECONNREFUSED EPIPE)) + (begin + (set! port #f) + (call-with-syslog-port proc)) + (apply throw args))))) + + (or (and port (not (port-closed? port)) (call/syslog)) + (let ((sock (socket AF_UNIX SOCK_DGRAM 0))) + (catch 'system-error + (lambda () + (connect sock AF_UNIX "/dev/log") + (setvbuf sock _IOLBF) + (set! port sock) + (call/syslog)) + (lambda args + (close-port sock) + (if (memv (system-error-errno args) + (list ENOENT ECONNREFUSED)) + (catch 'system-error + (lambda () + (call-with-output-file "/dev/kmsg" + (lambda (port) + (setvbuf port _IOFBF) + (proc port)))) + (lambda args + (if (memv (system-error-errno args) + (list ENOENT EACCES EPERM)) + (call-with-output-file "/dev/console" + (lambda (port) + (setvbuf port _IONBF) + (proc port))) + (apply throw args)))) + (apply throw args))))))))) + +(define (syslog-output-port) + "Return the output port to write to syslog or /dev/kmsg, whichever is +available." + (make-soft-port + (vector + (lambda (char) ;write char + (call-with-syslog-port + (lambda (port) + (write-char char port)))) + (lambda (str) ;write string + (call-with-syslog-port + (lambda (port) + (display str port)))) + (const #t) ;flush + #f ;get char + (lambda () ;close + (call-with-syslog-port close-port))) + "w")) ;output port + (define %not-newline (char-set-complement (char-set #\newline))) -- 2.16.2
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.