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

Bug in --newer option handling in tarsnap



The --newer option to make backups of all files newer (with a later ctime) than
a given date doesn't seem to work properly on tarsnap.  Here's a test I did 
with tarsnap 1.0.32 on FreeBSD-current:

ichotolot# /usr/local/bin/tarsnap --keyfile /root/tarsnap.key --print-stats --dry-run -v -v --humanize-numbers --one-file-system --checkpoint-bytes 104857600 --newer 2012-01-05 -c -f foo /mntbak/ts/bootsy
                                       Total size  Compressed size
All archives                                61 GB            50 GB
  (unique data)                            7.8 GB           6.2 GB
This archive                               1.5 kB           1.4 kB
New data                                    558 B           1.1 kB

Observe that the tarsnap command doesn't actually find any files in the
tree under /mntbak/ts/bootsy to backup, despite the fact that there are 
plenty of such files there, as can be seen with the equivalent invocation
of regular old (BSD) tar:

ichotolot# tar -c -f /dev/null -v -v --newer 2012-01-05 -c -f foo /mntbak/ts/boots
tar: Removing leading '/' from member names
a mntbak/ts/bootsy/.snap
a mntbak/ts/bootsy/boot
a mntbak/ts/bootsy/.bacula-list.bz2
a mntbak/ts/bootsy/boot/boot
a mntbak/ts/bootsy/boot/boot0
a mntbak/ts/bootsy/boot/boot0sio
a mntbak/ts/bootsy/boot/boot2
a mntbak/ts/bootsy/boot/defaults
a mntbak/ts/bootsy/boot/loader
[... rest of file listing skipped, you get the idea...]

The culprit seems to be in the write_hierarchy() routine in the following
bit of code:

                /*
                 * In -u mode, check that the file is newer than what's
                 * already in the archive; in all modes, obey --newerXXX flags.
                 */
                if (!new_enough(bsdtar, name, st))
                        continue;

Note that if this code sees that, e.g., /mntbak/ts/bootsy has ctime older
than the --newer time, it will skip processing of that tree entry altogether
even if that tree entry is a directory and thus should be checked to see if
it or any subdirectories have files which *do* meet the "new enough" criterion.
Note that the analogous code in the FreeBSD 'tar' utility's
/usr/src/contrib/libarchive/tar/write.c has an extra bit of code just to 
force descent into a new directory in that case: 

                /*
                 * In -u mode, check that the file is newer than what's
                 * already in the archive; in all modes, obey --newerXXX flags.
                 */
                if (!new_enough(bsdtar, name, st)) {
                        if (!descend)
                                continue;
                        if (bsdtar->option_interactive &&
                            !yes("add '%s'", name))
                                continue;
                        tree_descend(tree);
                        continue;
                }

It looks like some variation on that code should be added to the tarsnap 
write_hierarchy() function.

					Richard