Creating differential backups with hard links and rsync

You can use a hard link in Linux to create two file names that both point to the same physical location on a hard disk. For instance, if I type:

> echo xxxx > a
> cp -l a b
> cat a
xxxx
> cat b
xxxx

I create a file named “a” that contains the string “xxxx”. Then I create a hard link “b” that also points to the same spot on the disk. Now if I write to the file “a” whatever I write also appears in file “b” and vice versa:

> echo yyyy > b
> cat b
yyyy
> cat a
yyyy
> echo zzzz > a
> cat a
zzzz
> cat b
zzzz

Copying to a hard link updates the data on the disk that each hard link points to:

> rm a b c
> echo xxxx > a
> echo yyyy > c
> cp -l a b
> cat a b c
xxxx
xxxx
yyyy

“a” and “b” point to the same file on disk, “c” is a separate file. If I copy a file “c” to “b” that also updates “a”:

> cp c b 
> cat a b c
yyyy
yyyy
yyyy
> echo zzzz > c
> cat a b c
yyyy
yyyy
zzzz 

What most people don’t know is that rsync is an exception to this rule. If you use rsync to sync two files, and it sees that the target file is a hard link, it will create a new target file but only if the contents of the two files are not the same:

> rm a
> rm b
> echo xxxx > a
> cp -l a b
> cat a
xxxx
> cat b
xxxx
> echo yyyy > c
> cat c
yyyy
> rsync -av c b
sending incremental file list
c
sent 87 bytes  received 31 bytes  236.00 bytes/sec
total size is 5  speedup is 0.04
> cat b
yyyy
> cat c
yyyy
> cat a
xxxx

File “b” is no longer a hard link of “a”, it’s a new file. If I update “a” it no longer updates “b”:

> echo zzzz > a
> cat a b c
zzzz
yyyy
yyyy

However, if the file that I’m rsync-ing is the same as “b”, then rsync does NOT break the hard link, it leaves the file alone:

> rm a
> rm b
> rm c
> echo xxxx > a
> cp -al a b
> cp -p a c
> cat a b c
xxxx
xxxx
xxxx

At this point “a” and “b” both point to the same file on the disk, which contains the string “xxxx”. “c” is a separate file that also contains the string “xxxx” and has the same permissions and timestamp as “a”.

> rsync -av c b
sending incremental file list
sent 39 bytes  received 12 bytes  102.00 bytes/sec
total size is 5  speedup is 0.10
> cat a b c
xxxx
xxxx
xxxx

At this point I’ve rsynced file “c” to “b”, but since c has the same contents and timestamp as “a” and “b” rsync does nothing at all. It doesn’t break the hard link. If I change “b” it still updates “a”:

> echo yyyy > b
> cat a b c
yyyy
yyyy
xxxx

This is how many modern file system backup programs work. On day 1 you make an rsync copy of your entire file system:

backup@backup_server> DAY1=`date +%Y%m%d%H%M%S`
backup@backup_server> rsync -av -e ssh earl@192.168.1.20:/home/earl/ /var/backups/$DAY1/

On day 2 you make a hard link copy of the backup, then a fresh rsync:

backup@backup_server> DAY2=`date +%Y%m%d%H%M%S`
backup@backup_server> cp -al /var/backups/$DAY1 /var/backups/$DAY2
backup@backup_server> rsync -av -e ssh --delete earl@192.168.1.20:/home/earl/ /var/backups/$DAY2/

“cp -al” makes a hard link copy of the entire /home/earl/ directory structure from the previous day, then rsync runs against the copy of the tree. If a file remains unchanged then rsync does nothing — the file remains a hard link. However, if the file’s contents changed, then rsync will create a new copy of the file in the target directory. If a file was deleted from /home/earl then rsync deletes the hard link from that day’s copy.

In this way, the $DAY1 directory has a snapshot of the /home/earl tree as it existed on day 1, and the $DAY2 directory has a snapshot of the /home/earl tree as it existed on day 2, but only the files that changed take up additional disk space. If you need to find a file as it existed at some point in time you can look at that day’s tree. If you need to restore yesterday’s backup you can rsync the tree from yesterday, but you don’t have to store a copy of all of the data from each day, you only use additional disk space for files that changed or were added.

I use this technique to keep 90 daily backups of a 500GB file system on a 1TB drive.

One caveat: The hard links do use up inodes. If you’re using a file system such as ext3, which has a set number of inodes, you should allocate extra inodes on the backup volume when you create it. If you’re using a file system that can dynamically add inodes, such as ext4, zfs or btrfs, then you don’t need to worry about this.

Workaround to fix the problem of KDE “forgetting” your multi-monitor setup

I originally reported this KDE4 bug as https://bugs.kde.org/show_bug.cgi?id=312190. It’s also reported as bugs #311641, #309356, and #307589.

In my case I have 3 monitors on one video card. The card and all three monitors are detected correctly, but after I reboot the “Position” settings have all reverted to what they were when I first installed KDE.

I can change the position settings back to the correct settings, click “Save as Default”, log  out, log in, and the position settings have once again reverted to what they were when I first installed KDE.

After trying several things I still haven’t fixed the problem (I suspect a timing issue in the KDE startup) but I did figure out a work-around that anyone can use to “fix” their system so their monitors come up correctly. I posted the work-around on bugs.kde.org and I’m also posting it here.

Here’s how you do it:

Get your monitors set up the way you want them using Configure Desktop > Display and Monitor and click “Save as Default.” This updates the file ~/.kde4/share/config/krandrrc.

Open ~/.kde4/share/config/krandrrc, copy everything on the line after “StartupCommands=”. In my case the line looks like this:

xrandr --output DVI-I-1 --pos 1680x0 --mode 1680x1050 --refresh 60\nxrandr --output DP-0 
  --pos 3360x0 --mode 1680x1050 --refresh 60\nxrandr --output DVI-D-0 --pos 0x0 --mode 1680x1050
  --refresh 60\nxrandr --output DVI-I-1 --primary

Create a new script called ~/bin/workaround-for-kde-bug-312190.sh:

mkdir -p ~/bin
vim ~/bin/workaround-for-kde-bug-312190.sh

(If you don’t like vim, use whatever editor you like.)

Paste the line into the script file.

Change the “\n” characters into actual newlines so you end up with each “xrandr” command on a separate line. In my case I ended up with:

xrandr --output DVI-I-1 --pos 1680x0 --mode 1680x1050 --refresh 60
xrandr --output DP-0 --pos 3360x0 --mode 1680x1050 --refresh 60
xrandr --output DVI-D-0 --pos 0x0 --mode 1680x1050 --refresh 60
xrandr --output DVI-I-1 --primary

These are the settings for MY desktop. Yours will look different!

Make it executable:

chmod +x ~/bin/workaround-for-kde-bug-312190.sh

Run the script ~/bin/workaround-for-kde-bug-312190.sh. Your monitors should still be set up correctly. If they’re messed up, you probably didn’t cut and paste the line correctly. Repeat the above steps again.

Pick Autostart from the KDE menu. (Use the Search function if you can’t figure out where it’s buried.)

Click “Add Script” and paste the line “~/bin/workaround-for-kde-bug-312190.sh” into the “Shell script path” text box.

Click OK, click OK.

The next time you restart KDE it will still start up with the wrong configuration, then Autostart will execute ~/bin/workaround-for-kde-bug-312190.sh and fix the problem.

Getting rid of self-resizing windows in Ubuntu Linux 12.04

I’ve been using a pre-release “daily build” installation of Ubuntu 12.04 “Precise Pangolin” and noticed that current default for Gnome is for windows to resize themselves when you get close to the edge of the screen. I have two 22″ widescreen monitors and if I moved a window near the top edge it would maximize and fill the screen. If I moved a window to any edge Gnome would decide for me that what I “really” wanted was to enlarge the window to fill half the screen or do something else equally annoying. This might work well on a 10″ netbook screen, but on dual 22″ monitors it’s annoying as hell.

I tracked the problem down to a setting in Compiz, the screen compositing tool used by many Linux desktop environments, so if you’re using KDE or Unity with Compiz and you’re finding self-resizing windows irritating this fix should work for you as well.

To fix the problem you need to install the CompizConfig Settings Manager, so fire up Synaptic Package Manager and search for “compizconfig-settings-manager” and install it.

Once installed, if you’re using Gnome go to Applications > System Tools > Preferences and click “CompizConfig Settings Manager” to start the tool.

Scroll down to “Window Management.”

Uncheck “Place Windows”.

Leave “Grid” checked, but click the word “Grid” to get the Grid settings, then go to the Edges tab and change all Resize Actions to “None”.

Click Back.

Now your desktop will do what you tell it to do, rather than second-guessing you and doing something that you do not want.

One thing that you can now do (that you probably really don’t want) is to have the title bar (and it’s controls) move off-screen, which means you can’t move or resize the window unless you Alt-right-click on it. To fix that issue:

Check the “Put” plugin.

Click the word “Put” to bring up more options, go to the “Misc Options” tab, check “Avoid Offscreen”, click Back, then Close Window.

Hope you find this useful.

Work-around for a locked-up Gnome 3 screen saver in Ubuntu 11.10

Gnome 3 has a screen saver (or more accurately a screen blanker — there are no pretty pictures) which is turned on by default and which password-protects (locks) your desktop by default when it activates. Unfortunately it’s been known to be buggy since it was released as part of Gnome 2, often refusing to unlock your screen and forcing you to reboot your system.

Users of the Gnome 3 desktop shell are reporting that for some video card and monitor combinations the Gnome 3 screen saver, after getting a key press / mouse movement that should prompt you for your password to unlock the screen:

  • Won’t unlock the screen at all.
  • Will display a mouse pointer but no password prompt.
  • Will display your original screen and all open documents (without prompting for a password) but will not allow you to click on anything, basically appearing as a locked-up desktop.

My setup reliably produces situation #3.

To unlock a locked-up desktop:

  • Ctrl-Alt-F1 will give you a text-based terminal login.
  • Log in with your user name and password.
  • Type: “killall gnome-screensaver”
  • Ctrl-Alt-F7 to get back to the (now unlocked) Gnome 3 desktop.

To replace the Gnome 3 screen saver with something less buggy:

  • Activities > Applications > Other > Synaptic Package Manager
  • Quick filter: xscreensaver
  • Right click ‘xscreensaver’ and select ‘Mark for Installation’
  • Click ‘Apply’ to install
  • Activities > Applications > System Tools  > System Settings > Screen
  • Set “Turn off after” to ‘Never’ and “Lock” to ‘OFF’. This disables gnome-screensaver.
  • Activities > Applications > All > Screensaver
  • Follow the prompts to activate xscreensaver

If you try to uninstall gnome-screensaver Synaptic Package Manager will also want to uninstall gnome and gnome-core, which is a bad idea if you want to run Gnome. Gnome will always start gnome-screensaver even if you have it disabled, and xscreensaver won’t run if gnome-screensaver is running. So you basically need to kill gnome-screensaver after Gnome has started and then start xscreensaver. You can do this by adding a startup program:

  • Activities > Applications > Other > Startup Programs > Add
  • Name: “Screen Saver”
  • Command: “sleep 30; killall gnome-screensaver; sleep 5; xscreensaver”
  • Comment: “Kill gnome-screensaver, start xscreensaver”
  • Click “Add”

Hope you find this useful.

Adding a task bar to Gnome 3 on Ubuntu 11.10

To install Gnome 3 on Ubuntu 11.10 start up a terminal and type:

sudo apt-get install gnome-shell

To use Gnome 3 instead of Unity: when you log in, click the “gear” above your password. Select “Gnome”, log in.

After you get tired of “click Activities, find the window you want, click the window” every time you want to switch from one window to another, and you decide you really need a taskbar again to maintain your sanity, start up a terminal and type:

sudo apt-get install tint2
tint2 &

You now have a taskbar again. To get it to appear every time you start Gnome 3 go to Activities > Applications > Other > Startup Applications, then click “Add”, Name: “tint2 task bar”, Command: “tint2”, click “Save”.

Done.

Hope you find this useful.