1

I use rsnapshot to make regular backups of my systems' filesystems to a remote server.

(For those familiar with rsync but less used to rsnapshot here is a brief introduction to its workings. A backup is a file-by-file copy of a source file-system tree, much like cp -a would produce. The "current" backup is always hourly.0, and the previous one is hourly.1. These names are rotated each time a backup begins. Under the covers rsnapshot uses rsync --link-dest to hardlink unchanged files in hourly.0 to the corresponding entries in the previous backup tree, hourly.1.)

If a backup fails, the previous backup is copied (linked) using cp -al to the current backup, so that a backup always appears to have been made.

What I would like is to avoid making a backup if there have been no changes since the previous backup. This could include a backup failure or simply that the source filesystem was not modified since the last backup. ("Making a backup" can be rephrased to "deleting an unnecessary backup" if you would prefer.)

I've considered looking in the hourly.0 tree for files that are not hard-linked elsewhere, and if there is none then simply deleting the backup tree. This does not handle a file that is validly linked elsewhere within its backup, and it also fails to consider changes to directories. I have also considered using rsync --dry-run to compare the two backup trees and looking at its output but this feels somewhat ugly.

Is there a better solution?

2

After the snapshot, you can use rsnapshot diff which calls rsnapshot-diff to note the differences between two snapshots. It just compares inode numbers so is fairly efficient.

Alternatively, before each backup create a file outside the backup tree to note the time, touch timestamp. Then before a new backup, create a new timestamp, touch timestamp.new, and test if any files or directories have a newer time than the old timestamp

find tree -newer timestamp

If not, do not do the backup. In any case, mv timestamp.new timestamp for the next time. This assumes you don't have applications that manipulate the file and directory timestamps.

0

I have also considered this as a possibility, which is more generic than the excellent proposals I've accepted from meuh.

listfiles()
{
    (
        # List attributes of file tree, discarding inode number
        cd "$1" 2>/dev/null && find . -type f -ls | sed -r 's/^ *[1-9][0-9]*//' | sort
    )
}

listfiles hourly.1 >/tmp/list1
listfiles hourly.0 >/tmp/list0
cmp -s /tmp/list1 /tmp/list0 && echo "the same" || echo "different"

This also ignores ACLs and Extended Attributes associated with a file but not listed with find -ls. However, for my purposes this would have been acceptable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.