I have just bumped myself to the same issue. Your error message:

error: error creating output file /var/log/syslog.1.gz: File exists

indicates that the file syslog.1.gz exists. @madduck can you check that the 
file doesn't really exist?

In my case a previous logrotate command must have been interrupted while 
gzipping, creating:
syslog
syslog.1
syslog.1.gz
syslog.2.gz
etc
where syslog.1.gz was of 0 size. Apparently, the compression error causes this 
to not attempt rename and rotation.

I suggest adding some handling to logrotate so that it would check the 
destination file's existance.
In the patch attached I am modifying the 'createOutputFile' function to stat 
the destination file and either
remove it (if it's of size 0) or rename it to .garbage (otherwise).

I have given very little testing to this patch, please review&test it.

--- logrotate-3.8.7.orig/logrotate.c
+++ logrotate-3.8.7/logrotate.c
@@ -300,10 +300,34 @@ static int runScript(struct logInfo *log
 int createOutputFile(char *fileName, int flags, struct stat *sb, acl_type acl, int force_mode)
 {
     int fd;
-       struct stat sb_create;
-       int acl_set = 0;
+    struct stat sb_create;
+    int acl_set = 0;

-       fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW),
+    if (stat(fileName, &sb_create) == 0) {
+       /* this indicates that the destination file exists, while it should not */
+       if (sb_create.st_size == 0) {
+         /* the file is of zero size, so not needed */
+         if (unlink(fileName) != 0) {
+           message(MESS_ERROR, "output file %s exists and failed to remove it: %s\n",
+                  fileName, strerror(errno));
+           return -1;
+         }
+       } else {
+         int fnlength=sizeof(fileName);
+         char* garbage=malloc(fnlength+8); /* 'garbage\0' */
+         strncpy(garbage, fileName, fnlength);
+         strncpy(garbage+fnlegth, "garbage\0");
+         if (rename(filename,garbage) != 0) {
+           message(MESS_ERROR, "output file %s exists and failed to rename it to %s: %s\n",
+                  fileName, garbage, strerror(errno));
+           free(garbage);
+           return -1;
+       }
+       free(garbage);
+
+    }
+
+    fd = open(fileName, (flags | O_EXCL | O_NOFOLLOW),
                (S_IRUSR | S_IWUSR) & sb->st_mode);

     if (fd < 0) {

Reply via email to