Switching backups: From fakeroot to --fake-super
I’m a big fan of incremental backups, and in my opinion one of the best ways to do such backups are hardlink-backups via rsync
like snapback2
does them (even though the software has some flaws I currently run into, I’ll have to have a look at that).
However, if you do backups like this, you either need root on the backup machine or some other way to store permissions. When I first set up such backup infrastructures, I came up with the idea to use fakeroot
, which is able to store the faked permissions in a file and read them from there again. However, this solution is bad in many aspects:
- It doesn’t scale: Our
fakeroot
-savefile currently nears the 200 MB and we don’t have an easy way to clean it up, because fakeroot
saves the permissions depending on inode (which is in fact good for hard-link backups). This makes up for quite a delay when starting to backup. - It isn’t portable:
fakeroot
saves the permissions depending on inodes, and when you move to another filesystem, the permissions are lost. - It makes things complicated: We needed to write a wrapper for SSH because it didn’t like to be run within
fakeroot
. Probably other programs might complain as well.
There are probably numerous other reasons why this was a bad idea in the first place, but it seemed reasonable back then.
Now, I learned about the rsync
-option some would have known and used right from the start: --fake-super
. This option tells rsync
to not save the owner and permissions as the owner and permissions of the file, but instead to create an extended attribute (xattr) for the file (named user.rsync.%stat
by the way) which contains all the information I might otherwise need root access to store. This attribute looks like
user.rsync.%stat="104755 0,0 131750:131750"
My goal was to convert our existing backups from fakeroot
to --fake-super
. The format isn’t that complicated: The first number is octal and contains the file type and permissions, the second tuple of digits is the device number represented as major and minor device number, and the last two are the user and group id. But sadly, stat(1)
can only generate the first number as hex (with %f
) or without the file type (with %a
) but not everything in octal. Everything else isn’t a problem (%t,%T %u:%g
). But because of this first digit, I decided to write a small C program that can be run in the fakeroot and sets the correct xattr derived from the current (faked) state of the file. Maybe this would have been possible by using rsync directly, but I wasn’t able to come up with a way that didn’t involve copying everything over again. So, here’s my little program:
I don’t normally do C, so there may be a couple of design flaws I’m happy to learn about. The program would be called with find -exec set-rsync-xattr {} +
.