guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[shepherd] 02/02: log-rotation: Skip non-regular files.


From: Ludovic Courtès
Subject: [shepherd] 02/02: log-rotation: Skip non-regular files.
Date: Wed, 11 Dec 2024 06:42:50 -0500 (EST)

civodul pushed a commit to branch main
in repository shepherd.

commit fb0f6fe5cef6772580d7d3f8505411342320069e
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Wed Dec 11 11:58:56 2024 +0100

    log-rotation: Skip non-regular files.
    
    Until now, /dev/console, /dev/tty12, etc. were skipped, but only because
    they were always below the size threshold.  The service could
    potentially attempt to rotate directories specified as external log
    files (reported size is usually 4 KiB), leading to an uncaught exception
    in the timer action when calling ‘truncate-file’.
    
    This change makes the non-regular-file check explicit.
    
    * modules/shepherd/service/log-rotation.scm (rotate-file): Explicitly
    skip non-regular files.
    * tests/services/log-rotation.sh: Test it.
    * NEWS: Update.
---
 NEWS                                      | 10 ++++++++++
 modules/shepherd/service/log-rotation.scm | 31 ++++++++++++++++++-------------
 tests/services/log-rotation.sh            | 10 ++++++++--
 3 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/NEWS b/NEWS
index eba97b9..6b6bb98 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,16 @@ Copyright © 2013-2014, 2016, 2018-2020, 2022-2024 Ludovic 
Courtès <ludo@gnu.or
 
 Please send Shepherd bug reports to bug-guix@gnu.org.
 
+* Changes in 1.0.1
+
+** ‘log-rotation’ service explicitly skips non-regular files
+
+Previously, the log rotation service would attempt to rotate non-regular files
+with a reported size greater than the threshold; in practice that could
+potentially happen when specifying a directory as an external log file, and
+only if the threshold is set below 4096 bytes.  Non-regular files are now
+explicitly skipped.
+
 * Changes in 1.0.0
 
 ** ‘herd status SERVICE’ shows high-level info about services
diff --git a/modules/shepherd/service/log-rotation.scm 
b/modules/shepherd/service/log-rotation.scm
index 64eb1cd..d4a1289 100644
--- a/modules/shepherd/service/log-rotation.scm
+++ b/modules/shepherd/service/log-rotation.scm
@@ -139,19 +139,24 @@ called with @var{file}."
      (local-output (l10n "Log file '~a' is inaccessible; not rotating.")
                    file))
     (stat
-     (if (> (stat:size stat) rotation-size-threshold)
-         (begin
-           ;; First rotate past logs, to free "FILE.1".
-           (rotate-past-logs file rotate)
-           ;; Then rename FILE to "FILE.1".
-           (let* ((next (string-append file ".1"))
-                  (rotated? (rotate-current file next)))
-             (when rotated?
-               (compress-file compression next)
-               (local-output (l10n "Rotated '~a'.") file))))
-         (local-output
-          (l10n "Not rotating '~a', which is below the ~a B threshold.")
-          file rotation-size-threshold)))))
+     (cond ((not (eq? 'regular (stat:type stat)))
+            ;; Do not rotate /dev/tty12, directories, or anything like that.
+            (local-output
+             (l10n "Not rotating '~a', which is not a regular file.")
+             file))
+           ((> (stat:size stat) rotation-size-threshold)
+            ;; First rotate past logs, to free "FILE.1".
+            (rotate-past-logs file rotate)
+            ;; Then rename FILE to "FILE.1".
+            (let* ((next (string-append file ".1"))
+                   (rotated? (rotate-current file next)))
+              (when rotated?
+                (compress-file compression next)
+                (local-output (l10n "Rotated '~a'.") file))))
+           (else
+            (local-output
+             (l10n "Not rotating '~a', which is below the ~a B threshold.")
+             file rotation-size-threshold))))))
 
 (define* (rotate-logs logger #:optional (rotate rename-file)
                       #:key
diff --git a/tests/services/log-rotation.sh b/tests/services/log-rotation.sh
index 854bd70..91f8748 100644
--- a/tests/services/log-rotation.sh
+++ b/tests/services/log-rotation.sh
@@ -26,11 +26,13 @@ pid="t-pid-$$"
 service_log1="$PWD/t-service-log1-$$"
 service_log2="$PWD/t-service-log2-$$"
 external_log="$PWD/t-service-extlog-$$"
+invalid_external_log="$PWD/t-service-invalid-extlog-$$"
 
 herd="herd -s $socket"
 
 trap "zcat $log* || true;
       rm -f $socket $conf $log* $service_log1* $service_log2* $external_log*;
+      rmdir $invalid_external_log;
       test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT
 
 cat > "$conf" <<EOF
@@ -65,7 +67,7 @@ cat > "$conf" <<EOF
         (log-rotation-service
           ;; Arrange so that it does not trigger automatically.
           (calendar-event #:months (list past-month))
-          #:external-log-files '("$external_log")
+          #:external-log-files '("$invalid_external_log" "$external_log")
           #:rotation-size-threshold 0)))
 
 (register-services services)
@@ -83,7 +85,7 @@ $herd start log-rotation
 
 sleep 0.5
 
-for file in "$service_log1" "$service_log2" "$external_log" "$log"
+for file in "$service_log1" "$service_log2" "$external_log" 
"$invalid_external_log" "$log"
 do
     $herd files log-rotation | grep "$file"
 done
@@ -92,6 +94,8 @@ test -f "$service_log1"
 test -f "$service_log2"
 echo "This is an external log file." > "$external_log"
 
+mkdir "$invalid_external_log"                  # not a regular file, so should 
not be rotated
+
 # First rotation.
 $herd trigger log-rotation
 
@@ -109,6 +113,8 @@ gunzip < "$external_log.1.gz" | grep "external log file"
 test -f "$external_log"
 guile -c "(exit (zero? (stat:size (stat \"$external_log\"))))"
 
+zgrep "Not rotating .*$invalid_external_log" "$log"* # not a regular file
+
 # Second rotation.
 $herd trigger log-rotation
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]