+++ This bug was initially created as a clone of Bug #185168 +++ Description of problem: If there is a log file for which the owning userid does not exist (eg. it was created by a NIS userid and the network is down), then logrotate exits and processes no more log files, even ones with valid owning userids. For example, in the bug from which this bug was cloned, the 'mysqld' configuration file precedes the 'syslog' configuration file in /etc/logrotate.d ; somehow, the 'mysql' user id (27) was deleted, and from that point on logrotate failed to rotate the system log file (/var/log/messages) - logrotate exits and stops processing any further /etc/logrotate.d/* files if there is an error on any single /etc/logrotate.d/* file - this seems wrong to me. logrotate should not process the log files for the single /etc/logrotate.d/* file for which there is an error, but should then proceed on to process other /etc/logrotate.d/* files for which there are no errors. EG: Here's an strace from logrotate where the 'mysql' user does not exist, causing logrotate to exit with an error: 10372 lstat64("/var/log/mysqld.log", {st_dev=makedev(253, 0), st_ino=951360, st_mode=S_IFREG|0640, st_nlink=1, st_uid=0, st_gid=27, st_blksize=4096, st_blocks=8, st_size=0, st_atime=2006/03/05-13:49:24, st_mtime=2006/03/ 05-13:49:24, st_ctime=2006/03/05-13:49:24}) = 0 ... ( so the /var/log/mysqld.log file exists, with gid 27 (which should be ... the mysql uid/gid ) ... 10372 write(2, "error: ", 7) = 7 10372 write(2, "mysqld:3 unknown user \'mysql\'\n", 30) = 30 ... 10372 exit_group(1) = ?
I can't reproduce it. $ cat Rot create daily rotate 5 #no owner /tmp/tempoRot { } #owner peter /tmp/peterRot { } $ sudo /usr/sbin/logrotate -vf Rot Password: reading config file Rot reading config info for /tmp/tempoRot reading config info for /tmp/peterRot Handling 2 logs rotating pattern: /tmp/tempoRot forced from command line (5 rotations) empty log files are rotated, old logs are removed considering log /tmp/tempoRot log needs rotating rotating log /tmp/tempoRot, log->rotateCount is 5 renaming /tmp/tempoRot.5 to /tmp/tempoRot.6 (rotatecount 5, logstart 1, i 5), old log /tmp/tempoRot.5 does not exist renaming /tmp/tempoRot.4 to /tmp/tempoRot.5 (rotatecount 5, logstart 1, i 4), old log /tmp/tempoRot.4 does not exist renaming /tmp/tempoRot.3 to /tmp/tempoRot.4 (rotatecount 5, logstart 1, i 3), old log /tmp/tempoRot.3 does not exist renaming /tmp/tempoRot.2 to /tmp/tempoRot.3 (rotatecount 5, logstart 1, i 2), old log /tmp/tempoRot.2 does not exist renaming /tmp/tempoRot.1 to /tmp/tempoRot.2 (rotatecount 5, logstart 1, i 1), old log /tmp/tempoRot.1 does not exist renaming /tmp/tempoRot.0 to /tmp/tempoRot.1 (rotatecount 5, logstart 1, i 0), old log /tmp/tempoRot.0 does not exist log /tmp/tempoRot.6 doesn't exist -- won't try to dispose of it renaming /tmp/tempoRot to /tmp/tempoRot.1 creating new log mode = 0664 uid = 509 gid = 509 rotating pattern: /tmp/peterRot forced from command line (5 rotations) empty log files are rotated, old logs are removed considering log /tmp/peterRot log needs rotating rotating log /tmp/peterRot, log->rotateCount is 5 renaming /tmp/peterRot.5 to /tmp/peterRot.6 (rotatecount 5, logstart 1, i 5), old log /tmp/peterRot.5 does not exist renaming /tmp/peterRot.4 to /tmp/peterRot.5 (rotatecount 5, logstart 1, i 4), old log /tmp/peterRot.4 does not exist renaming /tmp/peterRot.3 to /tmp/peterRot.4 (rotatecount 5, logstart 1, i 3), old log /tmp/peterRot.3 does not exist renaming /tmp/peterRot.2 to /tmp/peterRot.3 (rotatecount 5, logstart 1, i 2), old log /tmp/peterRot.2 does not exist renaming /tmp/peterRot.1 to /tmp/peterRot.2 (rotatecount 5, logstart 1, i 1), old log /tmp/peterRot.1 does not exist renaming /tmp/peterRot.0 to /tmp/peterRot.1 (rotatecount 5, logstart 1, i 0), old log /tmp/peterRot.0 does not exist log /tmp/peterRot.6 doesn't exist -- won't try to dispose of it renaming /tmp/peterRot to /tmp/peterRot.1 creating new log mode = 0664 uid = 501 gid = 501 $ ll /tmp/tempoRot* -rw-rw-r-- 1 509 509 0 Mar 16 13:28 /tmp/tempoRot -rw-rw-r-- 1 509 509 28 Mar 16 13:12 /tmp/tempoRot.1 $ ll /tmp/peterRot* -rw-rw-r-- 1 pvrabec pvrabec 0 Mar 16 13:28 /tmp/peterRot -rw-rw-r-- 1 pvrabec pvrabec 36 Mar 16 13:13 /tmp/peterRot.1 # getenforce Enforcing # rpm -q logrotate logrotate-3.7.3-2.2.1.i386
Peter, perhaps it is only reproducible in the situation encountered in: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=185540#c2 You may only be able to repeat this result after backing up and manually deleting the user entry from passwd (but leaving in shadow) ? I guess this shouldn't occur in normal circumstances because a user would be deleted from both passwd and shadow ?
The problem will occur whenever getpwnam fails . In config.c, function readConfigPath, @line 265: for (i = 0; i < files_count; ++i) { assert(namelist[i] != NULL); if (readConfigFile(namelist[i], defConfig, logsPtr, numLogsPtr)) { fchdir(here); close(here); free_2d_array(namelist, files_count); return 1; } So if readConfigFile fails for ANY /etc/logrotate.d/* file, then no subsequent /etc/logrotate.d/* file is processed. The actual problem occurred in readConfigFile, config.c, @ line 563: pw = getpwnam(createOwner); if (!pw) { message(MESS_ERROR, "%s:%d unknown user '%s'\n", configFile, lineNum, createOwner); return 1; } I think that if there is a problem for a single /etc/logrotate.d/* file, then logrotate should complain about and skip over that file, but should then go on to process the remaining /etc/logrotate.d files for which there may be no error.
Fixed, see #166510.