Public bug reported:

Cronlog, when used with -S/-l or -P, fails to maintain a symlink to the
newest logfile if the previous link target is moved.

Consider a case where Apache writing out to cronolog:

CustomLog "|/usr/sbin/cronolog -S /foo/access_log
/foo/%Y/%m/%d/access_log"

Now, if no one hits that site for a day or so, and your out-of-band log
archiving processes go and compress the old log files, the symlink's
broken; cronolog will subsequently fail to re-link /foo/access_log,
though logs WILL be written to /foo/%Y/%m/%d

Ultimately, this boils down to cronolog calling stat() against the
symlink; stat() will return -1 on the broken link and skip the unlink()
code; cronolog should be calling lstat().

Here's an example:

gkuchta@ve:~/dev/cronolog$ mkdir -p 2012/06/11
gkuchta@ve:~/dev/cronolog$ echo "foo" > 2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ ln -s 2012/06/11/access_log access_log
gkuchta@ve:~/dev/cronolog$ gzip 2012/06/11/access_log 
gkuchta@ve:~/dev/cronolog$ ls -l
total 4
drwxr-xr-x 3 gkuchta gkuchta 4096 2012-06-12 13:37 2012
lrwxrwxrwx 1 gkuchta gkuchta   21 2012-06-12 13:37 access_log -> 
2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ echo "bar" | /usr/bin/cronolog -S 
/home/gkuchta/dev/cronolog/access_log 
/home/gkuchta/dev/cronolog/%Y/%m/%d/access_log
gkuchta@ve:~/dev/cronolog$ cat access_log
cat: access_log: No such file or directory
gkuchta@ve:~/dev/cronolog$ ls -l
total 4
drwxr-xr-x 3 gkuchta gkuchta 4096 2012-06-12 13:37 2012
lrwxrwxrwx 1 gkuchta gkuchta   21 2012-06-12 13:37 access_log -> 
2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ find .
.
./2012
./2012/06
./2012/06/11
./2012/06/11/access_log.gz
./2012/06/12
./2012/06/12/access_log
./access_log

If we catch the error from symlink() we see what's happening.

gkuchta@ve:~/scratch$ diff cronolog-1.6.2/src/cronoutils.c 
cronolog-1.6.2-patch/src/cronoutils.c 
214c214,217
<       symlink(pfilename, linkname);
---
>       if (symlink(pfilename, linkname) != 0)
>     {
>         perror("symlink");
>     }


gkuchta@ve:~/dev/cronolog$ mkdir -p 2012/06/11
gkuchta@ve:~/dev/cronolog$ echo "foo" > 2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ ln -s 2012/06/11/access_log 
gkuchta@ve:~/dev/cronolog$ gzip 2012/06/11/access_log 
gkuchta@ve:~/dev/cronolog$ echo "bar" | 
/home/gkuchta/scratch/cronolog/sbin/cronolog -S 
/home/gkuchta/dev/cronolog/access_log 
/home/gkuchta/dev/cronolog/%Y/%m/%d/access_log
symlink: File exists

Here's what I believe to be the appropriate behavior. While digging
around for where to submit this patch, it looks like someone else
submitted something similar about 4 years ago, but the cronolog mailing
list is dead and the maintainer seems AWOL.

gkuchta@ve:~/$ cat cronoutils.patch 
--- cronolog-1.6.2/src/cronoutils.c     2001-05-03 16:43:21.000000000 +0000
+++ cronolog-1.6.2-patch/src/cronoutils.c       2012-06-12 14:33:15.000000000 
+0000
@@ -195,11 +195,11 @@
 {
     struct stat                stat_buf;
     
-    if (stat(prevlinkname, &stat_buf) == 0)
+    if (lstat(prevlinkname, &stat_buf) == 0)
     {
        unlink(prevlinkname);
     }
-    if (stat(linkname, &stat_buf) == 0)
+    if (lstat(linkname, &stat_buf) == 0)
     {
        if (prevlinkname) {
            rename(linkname, prevlinkname);


gkuchta@ve:~/dev/cronolog$ mkdir -p 2012/06/11
gkuchta@ve:~/dev/cronolog$ echo "foo" > 2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ ln -s 2012/06/11/access_log access_log
gkuchta@ve:~/dev/cronolog$ gzip 2012/06/11/access_log 
gkuchta@ve:~/dev/cronolog$ ls -l
total 4
drwxr-xr-x 3 gkuchta gkuchta 4096 2012-06-12 15:02 2012
lrwxrwxrwx 1 gkuchta gkuchta   21 2012-06-12 15:02 access_log -> 
2012/06/11/access_log
gkuchta@ve:~/dev/cronolog$ echo "now it works" | 
/home/gkuchta/scratch/cronolog/sbin/cronolog -S 
/home/gkuchta/dev/cronolog/access_log 
/home/gkuchta/dev/cronolog/%Y/%m/%d/access_log
gkuchta@ve:~/dev/cronolog$ ls -l
total 4
drwxr-xr-x 3 gkuchta gkuchta 4096 2012-06-12 15:02 2012
lrwxrwxrwx 1 gkuchta gkuchta   48 2012-06-12 15:03 access_log -> 
/home/gkuchta/dev/cronolog/2012/06/12/access_log
gkuchta@ve:~/dev/cronolog$ cat access_log
now it works
gkuchta@ve:~/dev/cronolog$ 

Anyhow, thanks for the consideration.

Cheers,

Garrett

ProblemType: Bug
DistroRelease: Ubuntu 10.04
Package: cronolog 1.6.2-5.3ubuntu1
Uname: Linux 2.6.18-028stab099.3 x86_64
Architecture: amd64
Date: Tue Jun 12 14:48:42 2012
ProcEnviron:
 PATH=(custom, user)
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: cronolog

** Affects: cronolog (Ubuntu)
     Importance: Undecided
         Status: New


** Tags: amd64 apport-bug lucid

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1012178

Title:
  cronolog fails to keep symlink to newest log updated if previous link
  target is moved (patch included)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/cronolog/+bug/1012178/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to