I am trying to take snapshots of a massive folder regularly.

I have read here: http://www.mikerubel.org/computers/rsync_snapshots/#Incremental
that cp -al takes a snapshot of a folder by simply copying the hard links.

That is all great, but the problem is that in this snapshot, if I change a file, it changes in all snapshots. What I would like instead is to have the system create a new file on-change and link to that instead. That way each snapshot would not become invalid on an edit of the first file.

How can I achieve that?

p.s. I tried rsync -a --delete --link-dest=../backup.1 source_directory/ backup.0/, but it has the same problem.


That's how hardlinks work. But, there are ways around it:

A couple of options come to mind:

  • Use a filesystem with support for copy-on-write files, like btrfs. Of course, were you using btrfs, you'd just use its native snapshots... If your filesystem supports it, you can use cp --reflink=always. Unfortunately, ext4 doesn't support this.
  • Only share hardlinks across your snapshots, not with the original. That is, the first time you see a given version of a file, copy it to the snapshot. But the next time, link it to the one in the previous snapshot. (Not sure what program I used to do this—a decade ago—but searching turns up dirvish, obnam, storebackup, and rsnapshot)
  • Depending on how your files are being changed, you might be able to guarantee that a write temp/rename is used to change them, then that will break the hardlink—so the version in the snapshot will remain pristine. This is less safe, though, as bugs could corrupt your snapshot.
  • Take LVM snapshots of the entire filesystem.

Of course, there is the other option—use a proper backup system. Most all of them can manage to only backup changed files.

| improve this answer | |
  • What do you recommend as a way to back up a massive folder? – Fzs2 Mar 29 '13 at 19:37
  • I was thinking using rsync to a server which has a cronjob to do cp -al regularly for snapshots.. alongside rsync-ing onwards for even more copies. How does that sound? – Fzs2 Mar 29 '13 at 19:52
  • @HermannIngjaldsson well, it depends on how you do your backups. Personally, I'd just add it to my Bacula setup—but I wouldn't recommend that unless you have a bunch of machines to back up, or already know Bacula. So, I guess I'd suggest you try rsnapshot first. – derobert Mar 29 '13 at 20:00
  • rsnapshot is good – developerbmw Jun 20 '15 at 2:31

What you're looking for is a form of copy-on-write, where multiple files that have the same content use the same space on the disk until one of them is modified. Hard links only implement copy-on-write if the application that does the writing deletes the file and creates a new file by the same name (which is usually done by creating a new file by a different name, then moving it into place). The application you're using is evidently not doing this: it's overwriting the existing file.

Some applications can be configured to use the replacement strategy. Some applications use the replacement strategy by default, but use the overwrite strategy when they see a file with multiple hard links, precisely so as not to break the hard links. Your current snapshot technique will work if you can configure your application to replace instead of overwriting.

Fl-cow modifies programs to systematically use the replacement strategy on files with multiple hard links.

Alternatively, you may store your files on a filesystem that performs copy-on-write or deduplication, or have a snapshot feature, and not worry about hard links: Btrfs or Zfs. Depending on your partitioning scheme, using LVM snapshots may be an option.

My recommendation is to use a proper snapshot tool. Making reliable backups is surprisingly difficult. You probably want rsnapshot.

| improve this answer | |

The following is a ruby script that I wrote that wraps the "cp -al" and rsync into a nice script that can be run manually or via cron. Destination can be local or remote (via ssh):

Ghetto Timemachine

The basic answer to your question, as mentioned in a previous comment, the source needs to be kept apart from the hard links. Ex, assume a daily backup of your home directory:


  • /home/flakrat


  • /data/backup/daily
    • /monday
    • /tuesday
    • /wednesday
    • /thursday
    • ...

The hard links are created by running "cp -al" against yesterday's backup. Say it's Tuesday morning when you run it:

cd /data/backup/daily

rm -rf tuesday

cp -al monday tuesday

rsync -a --delete /home/flakrat /data/backup/daily/tuesday/

| improve this answer | |

rdiff-backup seems to do what you want, check it out.

Using rsync you must first make a full backup not using hard links. The next backup can point to the previous backup and hard link to it. That way your backups are not hard linked to your working files (the ones you are modifying). Example. If my previous backup was so folder backup.01 my backup script would first increment the folders by renaming them up by one so backup.01 becomes backup.02. Then the script creates a new empty folder called backup.01. it would then rscync the new backup into the new folder and hard link to backup.02 so that only new files will take any space in the backup. The rsync command would look something like this: rsync -rlt sourcepath backuppath/backup.01 --link-dest=backuppath/backup.02

So you can see, all the hard linking is happening on the backup path. This way you do not have to worry about copy on write when modifying files in your source path.

| improve this answer | |

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.