Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-24710

logrotate stops compressing other files when a file vanished between rotation and compression

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • rhel-8.9.0, rhel-9.3.0
    • logrotate
    • None
    • None
    • Important
    • rhel-sst-cs-plumbers
    • ssg_core_services
    • 5
    • False
    • Hide

      None

      Show
      None
    • None
    • Red Hat Enterprise Linux
    • None
    • None
    • None
    • All
    • None

      What were you trying to do that didn't work?

      When a set of files have a shared script and are being rotated then compressed, it appears that logrotate will stop compressing files as soon as an error pops up, e.g. because a rotated file vanished:

      error: unable to open /tmp/foo/dir/b.log.1 for compression
      

      Specifying missingok in the configuration doesn't help, because the rotateLogSet() code is always failing:

      1960 static int rotateLogSet(struct logInfo *log, int force)
      1961 {
       :
      2165         for (i = j;
      2166              ((log->flags & LOG_FLAG_SHAREDSCRIPTS) && i < log->numFiles)
      2167              || (!(log->flags & LOG_FLAG_SHAREDSCRIPTS) && i == j); i++) {
      2168             if (! ( (logHasErrors[i] && !(log->flags & LOG_FLAG_SHAREDSCRIPTS))
      2169                    || (hasErrors && (log->flags & LOG_FLAG_SHAREDSCRIPTS)) ) ) {
      2170                 logHasErrors[i] |=
      2171                     postrotateSingleLog(log, i, state[i], rotNames[i]);
      2172                 hasErrors |= logHasErrors[i];
      2173             }
      2174         }
       :
      

      More generally, an issue with similar root cause will happen when the set contains directories being symlinks to other directories in the set, e.g.:

      /data/logs/dir/*.log
      /data/logs/symlink/*.log
      

      with "symlink" being a symlink to "dir".

      This causes the following error to occur and logs to not be compressed afterwards:

      error: error opening /tmp/foo/symlink/a.log: No such file or directory
      

      The root cause for this is not making sure the files matching the set are really unique.

      Please provide the package NVR for which bug is seen:

      logrotate-3.14.0-6.el8.x86_64
      logrotate-3.18.0-8.el9.x86_64

      How reproducible:

      Always

      Steps to reproduce "error: error opening /tmp/foo/symlink/a.log: No such file or directory"

      1. Create a logrotate.test snippet
        /tmp/foo/*/*.log
        {
            rotate 2
            missingok
            compress
            sharedscripts
            postrotate
                true
            endscript
        }
      1. Create a tree having a symlink
        # rm -fr /tmp/foo || true
         # mkdir -p /tmp/foo/dir; for f in a b c d; do f=/tmp/foo/dir/$f.log; truncate -s 10K $f; touch -d "2024-02-05 16:21:42" $f; done
         # ln -s /tmp/foo/dir /tmp/foo/symlink
      1. Execute logrotate
        # logrotate -f ./logrotate.test

      Expected results

      All files being rotated AND compressed.

      Actual results

      All files being rotated but some not compressed (the ones coming after the error).

      Steps to reproduce "error: unable to open /tmp/foo/dir/b.log.1 for compression"

      1. Create a logrotate.test snippet
        /tmp/foo/*/*.log
        {
            rotate 2
            missingok
            compress
            sharedscripts
            postrotate
                true
            endscript
        }
      1. Create a tree
        # rm -fr /tmp/foo || true
         # mkdir -p /tmp/foo/dir; for f in a b c d; do f=/tmp/foo/dir/$f.log; truncate -s 10K $f; touch -d "2024-02-05 16:21:42" $f; done
        # Install systemtap and stop the execution when log renaming will happen
         {code:java}# yum -y install systemtap yum-utils gdb
        # stap-prep
        # debuginfo-install -y logrotate glibc libacl pcre2 libattr libselinux
        # stap -v -g -e 'probe syscall.rename { if (oldpath_unquoted != "/tmp/foo/dir/b.log") next; printf("Stopping %ld\n", pid()); raise(%{SIGSTOP%}); mdelay(5000); }'
      1. Execute logrotate
        # logrotate -f ./logrotate.test
      1. logrotate will stop, stap will print the PID, connect to logrotate using gdb
         # gdb /usr/sbin/logrotate <PID>
        [...]
        (gdb)
      1. Delete the file from inside gdb after rename executed
        (gdb) next
        (gdb) next
        (gdb) 
        rotateSingleLog (rotNames=0x55c25ae8fd60, state=0x55c25ae94e50, logNum=1, log=0x55c25ae8e870) at ../logrotate.c:1831
        1831		    if (!log->rotateCount) {
        (gdb) !ls /tmp/foo/dir/
        a.log.1  b.log.1  c.log  d.log
        (gdb) !rm /tmp/foo/dir/b.log.1 
        (gdb) continue
        ...
        error: unable to open /tmp/foo/dir/b.log.1 for compression

      Expected results

      All files being rotated AND compressed.

      Actual results

      All files being rotated but some not compressed (the ones coming after the error):

      # ls /tmp/foo/dir/
      a.log.1.gz  c.log.1  d.log.1
      

              jamacku@redhat.com Jan Macku
              rhn-support-rmetrich Renaud Métrich
              Jan Macku Jan Macku
              RHEL CS Plumbers QE Bot RHEL CS Plumbers QE Bot
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated: