From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33049) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1etWta-0001E9-RU for guix-patches@gnu.org; Wed, 07 Mar 2018 06:06:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1etWtZ-0000hI-G5 for guix-patches@gnu.org; Wed, 07 Mar 2018 06:06:06 -0500 Received: from debbugs.gnu.org ([208.118.235.43]:40583) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1etWtZ-0000hB-DB for guix-patches@gnu.org; Wed, 07 Mar 2018 06:06:05 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1etWtZ-0004Vh-67 for guix-patches@gnu.org; Wed, 07 Mar 2018 06:06:05 -0500 Subject: [bug#30498] [PATCH 3/3] Use syslog for logging when running as root. Resent-Message-ID: From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Wed, 7 Mar 2018 12:04:54 +0100 Message-Id: <20180307110454.17110-4-ludo@gnu.org> In-Reply-To: <20180307110454.17110-1-ludo@gnu.org> References: <87371ea2jj.fsf@gnu.org> <20180307110454.17110-1-ludo@gnu.org> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: 30498@debbugs.gnu.org * 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