13

I use Virtual Box a lot for distro / applications testing purposes.

One of the features I simply love about it is virtual machines snapshots, its saves a state of a virtual machine and is able to restore it to its former glory if something you did went wrong without any problems and without consuming your all hard disk space.

On my live systems I know how to create a 1:1 image of the file system but all the solutions I'v known will create a new image of the complete file system.

Are there any programs / file systems that are capable of taking a snapshot of a current file system, save it on another location but instead of making a complete new image it creates incremental backups?

To easy describe what I want, it should be as dd images of a file system, but instead of only a full backup it would also create incremental.


I am not looking for clonezilla, etc. It should run within the system itself with no (or almost none) intervention from the user, but contain all the data of the file systems. I am also not looking for a duplicity backup your all system excluding some folders script + dd to save your mbr. I can do that myself, looking for extra finesse.

I'm looking for something I can do before doing massive changes to a system and then if something when wrong or I burned my hard disk after spilling coffee on it I can just boot from a liveCD and restore a working snapshot to a hard disk.

It does not need to be daily, it doesn't even need a schedule. Just run once in a while and let it its job and preferably RAW based not file copy based.


6
  • So, you are looking for an application that can create installable images? If not, why don't you prefer Deja Dup? If you are asking an application can create installable images I want to know that answer also. Adding favorites. Nov 14, 2011 at 0:40
  • just posted an answer to the question as titled... but I see you are looking for more of a potential way to restore your system bare metal instead of on a file level.
    – cprofitt
    Nov 14, 2011 at 0:49
  • 1
    It sounds like you want a block level, not file system, based incremental backup. Beyond using a file system that supports snapshots I am not sure if what you are asking is possible. LVM, BTRFS may be a possibility.
    – cprofitt
    Nov 14, 2011 at 17:42
  • @cprofitt thx for fixing the title, it is more correct. Nov 16, 2011 at 12:36
  • @Bruno -- making good titles helps make this useful for people coming later to find the answer.
    – cprofitt
    Nov 16, 2011 at 14:34

6 Answers 6

14

To explain cprofitt's answer (as his answer is incremental, as I will explain)...

First you need to know about hard links.

Hard links point to the data that is actually on the disk (the physical location) and you can access the data using the hard link. Each file and directory is a hard link to the location of the data on the physical disk. Therefore if there are two files (hard links) pointing to the same location then the data is only stored once.


The process given by cprofitt involves:

  1. Rotate the backups to create a spot for a new one. ("Today's backup" from yesterday becomes "Yesterday's backup", "Yesterday's Backup" from two days ago becomes "Two Days ago's backup" and so on)

    • The list keeps growing as long as you want it, however in the script it only has 4 snapshots. (It does the whole process again for the next level (e.g. a week - "This week's backup") and rotates those, so that is why it has only 4).
    • The moving is done in reverse to prevent overwriting
  2. Copy the latest snapshot you have done (e.g. "Yesterday's backup") to the spot for the new one (e.g. "Today's backup"), making new hard links to the existing files without copying the file. So all the files in the new snapshot are pointing to the same location as the previous one.


An illustrated example

In the picture below, files of the same colour that have the same file name are hard links to the same file on disk. Here we are just dealing with two snapshots and a few files, but the example scales. (Except for the fact I am moving snapshots the opposite way to scripts in cproffit's answer)

enter image description here

The process is this:

  1. There is a snapshot of the system.

  2. The snapshot is copies (creating hard links to the existing files)

  3. Rsync is run to update the snapshot. When files are changed, it stores the new file as a new copy on the hard disk (so the older snapshot is not changed). In this example, File B has been changed. Note: we now have only 1 copy of File A and File C and two copies of File B stored on the hard disk

  4. Rotate the snapshots (in this case snapshot 0 'falls off' and is deleted and I rename snapshot 1 to snapshot 0)

  5. Copy the snapshot agin (repeat of step 2)

  6. Rsync again. (Repeat of step 3). Now we have 1 copy of File A and 2 copies of both File B and File C


A simplified version of the [first] script (not to be run, just as a stepping stone) is this:

#!/bin/bash

# Delete the snapshot we don't want (has 'fallen off')
rm -rf /root/snapshot/home/hourly.3 ;

# Rotate the snapshots by shuffling them back
mv /root/snapshot/home/hourly.2 /root/snapshot/home/hourly.3 ;
mv /root/snapshot/home/hourly.1 /root/snapshot/home/hourly.2 ;

# Copy the snapshot (creating hard links to the existing files)
cp -al /root/snapshot/home/hourly.0 /root/snapshot/home/hourly.1 ;

# Do the rsync ...
# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first.  If it were not so, this would copy over the other
# snapshot(s) too!
rsync -va --delete /home/ /root/snapshot/home/hourly.0 ;

Now the full script(s) has the full explanation here (as cprofitt linked to) and it is more thorough but it is basically as above. The other script is for grouping snapshots and the other part of cprofitt's answer talks about making the process automatic (using cron) and verifying that the backup was sucessful.

You can change the names, so instead of the directories being called "hourly..." they are called something else and the script is run manually.


To restore the whole lot, copy the latest snapshot (or a previous one) back to the directory you were taking the backups of.

To restore a single file that is still in a snapshot, go the snapshot and copy it back to where it belongs.

The backup media can be a external hard drive (must be ext2/ext3/ext4). If you were backing up / (mainly /boot, /home, /etc /root and /usr) then, say...

  1. You mount the external drive, perform the backup and create the latest snapshot.

  2. Unmount the drive.

  3. Remember you deleted a file (even from the trash) that you wanted.

  4. Connect the external drive and retrieve the file.

  5. Do a backup (just to be sure)

  6. Disconnect the drive and go travelling...

  7. Realise that a laptop and lava do not mix.

  8. With your new laptop running a live cd, format the internal drive, mount you external drive and then cp -a /media/external/snapshot-0/* /media/internal-drive (assuming snapshot-0 is the latest snapshot)

  9. Install grub to the MBR (yes it has to be seperate) - or use dd to backup the mbr, like cprofitt has said at the bottom of his answer.

  10. Reboot.

The script needs to be refined (to only get the stuff you want) and the procedure aove assumes that you don't have a /home partition. If you do (or had) create a new one on the disk and mount it in place with mount /dev/sdxy /media/external/home before copying.

8
  • 100 dd snapshots will cost 100 x <average size of snapshot> worth of disk space. 100 of these will cost <size of snapshot> + <size of changed files>. I have used this to put several snapshots of /home (~400GB) onto a 500GB disk. Nov 14, 2011 at 15:02
  • You can mount the virtual disk image on your filesystem, then take backups of that. See superuser.com/questions/158908/… and links Nov 14, 2011 at 15:13
  • Like said, this is for my running computers, not a virtual box, the vbox was just an example. Nov 14, 2011 at 15:20
  • Updated question (at the end instead of adding a comment). Nov 14, 2011 at 15:49
  • @Portablejim: You are writing that the cp is "preserving the hard links". I think this phrase is confusing. cp -al is making hardlinks to the source files instead of copying the source files. Your figures should also reflect that, e.g. by showing that the A files in figure 2 are the same file. Nov 16, 2011 at 6:18
7

You could use rsync.

Listing one: make_snapshot.sh

#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility
# ----------------------------------------------------------------------
# this needs to be a lot more general, but the basic idea is it makes
# rotating backup-snapshots of /home whenever called
# ----------------------------------------------------------------------

unset PATH  # suggestion from H. Milz: avoid accidental use of $PATH

# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;
TOUCH=/bin/touch;

RSYNC=/usr/bin/rsync;


# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;
EXCLUDES=/usr/local/etc/backup_exclude;


# ------------- the script itself --------------------------------------

# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root.  Exiting..."; exit; } fi

# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
    exit;
}
fi;


# rotating snapshots of /home (fixme: this should be more general)

# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then         \
$RM -rf $SNAPSHOT_RW/home/hourly.3 ;                \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/hourly.2 ] ; then         \
$MV $SNAPSHOT_RW/home/hourly.2 $SNAPSHOT_RW/home/hourly.3 ; \
fi;
if [ -d $SNAPSHOT_RW/home/hourly.1 ] ; then         \
$MV $SNAPSHOT_RW/home/hourly.1 $SNAPSHOT_RW/home/hourly.2 ; \
fi;

# step 3: make a hard-link-only (except for dirs) copy of the latest snapshot,
# if that exists
if [ -d $SNAPSHOT_RW/home/hourly.0 ] ; then         \
$CP -al $SNAPSHOT_RW/home/hourly.0 $SNAPSHOT_RW/home/hourly.1 ; \
fi;

# step 4: rsync from the system into the latest snapshot (notice that
# rsync behaves like cp --remove-destination by default, so the destination
# is unlinked first.  If it were not so, this would copy over the other
# snapshot(s) too!
$RSYNC                              \
    -va --delete --delete-excluded              \
    --exclude-from="$EXCLUDES"              \
    /home/ $SNAPSHOT_RW/home/hourly.0 ;

# step 5: update the mtime of hourly.0 to reflect the snapshot time
$TOUCH $SNAPSHOT_RW/home/hourly.0 ;

# and thats it for home.

# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
    exit;
} fi;

and the second:

Listing two: daily_snapshot_rotate.sh

#!/bin/bash
# ----------------------------------------------------------------------
# mikes handy rotating-filesystem-snapshot utility: daily snapshots
# ----------------------------------------------------------------------
# intended to be run daily as a cron job when hourly.3 contains the
# midnight (or whenever you want) snapshot; say, 13:00 for 4-hour snapshots.
# ----------------------------------------------------------------------

unset PATH

# ------------- system commands used by this script --------------------
ID=/usr/bin/id;
ECHO=/bin/echo;

MOUNT=/bin/mount;
RM=/bin/rm;
MV=/bin/mv;
CP=/bin/cp;

# ------------- file locations -----------------------------------------

MOUNT_DEVICE=/dev/hdb1;
SNAPSHOT_RW=/root/snapshot;

# ------------- the script itself --------------------------------------

# make sure we're running as root
if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root.  Exiting..."; exit; } fi

# attempt to remount the RW mount point as RW; else abort
$MOUNT -o remount,rw $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readwrite";
    exit;
}
fi;


# step 1: delete the oldest snapshot, if it exists:
if [ -d $SNAPSHOT_RW/home/daily.2 ] ; then          \
$RM -rf $SNAPSHOT_RW/home/daily.2 ;             \
fi ;

# step 2: shift the middle snapshots(s) back by one, if they exist
if [ -d $SNAPSHOT_RW/home/daily.1 ] ; then          \
$MV $SNAPSHOT_RW/home/daily.1 $SNAPSHOT_RW/home/daily.2 ;   \
fi;
if [ -d $SNAPSHOT_RW/home/daily.0 ] ; then          \
$MV $SNAPSHOT_RW/home/daily.0 $SNAPSHOT_RW/home/daily.1;    \
fi;

# step 3: make a hard-link-only (except for dirs) copy of
# hourly.3, assuming that exists, into daily.0
if [ -d $SNAPSHOT_RW/home/hourly.3 ] ; then         \
$CP -al $SNAPSHOT_RW/home/hourly.3 $SNAPSHOT_RW/home/daily.0 ;  \
fi;

# note: do *not* update the mtime of daily.0; it will reflect
# when hourly.3 was made, which should be correct.

# now remount the RW snapshot mountpoint as readonly

$MOUNT -o remount,ro $MOUNT_DEVICE $SNAPSHOT_RW ;
if (( $? )); then
{
    $ECHO "snapshot: could not remount $SNAPSHOT_RW readonly";
    exit;
} fi;

After creating the script to your needs add it to cron jobs.

crontab -e

add the following:

0 */4 * * * /usr/local/bin/make_snapshot.sh

0 13 * * * /usr/local/bin/daily_snapshot_rotate.sh

They cause make_snapshot.sh to be run every four hours on the hour and daily_snapshot_rotate.sh to be run every day at 13:00 (that is, 1:00 PM).

source: http://www.mikerubel.org/computers/rsync_snapshots/

* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

If you want it to run hourly you would add a cron job for each hour.

Another possible option is using rsnapshot

  1. Install rsnapshot (available in software center)

  2. Configure rsnapshot and Specify Backup Source Directory

Open the /etc/rsnapshot.conf and uncomment the following lines.

# nano /etc/rsnapshot.conf

cmd_cp          /bin/cp
cmd_ssh /usr/bin/ssh
cmd_du          /usr/bin/du
cmd_rsnapshot_diff      /usr/local/bin/rsnapshot-diff
logfile /var/log/rsnapshot
  1. Define your destination backup directories in /etc/rsnapshot.conf as shown below. In this example,

    /home – source directory that should be backed-up localhost/ – destination directory where the backup will be stored. Please note that this directory will be created under /.snapshots/{internal.n}/ directory as shown in the last step.

    nano /etc/rsnapshot.conf

    backup /home/ localhost/

  2. Test rsnapshot Configuration

Perform configuration test to make sure rsnapshot is setup properly and ready to perform linux rsync backup.

# rsnapshot configtest
Syntax OK
  1. Verify rsnapshot Hourly Backup Configuration

You can backup linux directories or files at various intervals. By default, the hourly and daily backups are configured.

Verify the hourly backup configuration.

# rsnapshot -t hourly
echo 6490 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /home \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded /etc \
/.snapshots/hourly.0/localhost/
mkdir -m 0755 -p /.snapshots/hourly.0/
/usr/bin/rsync -a --delete --numeric-ids --relative --delete-excluded \
/usr/local /.snapshots/hourly.0/localhost/
touch /.snapshots/hourly.0/
  1. Verify rsnapshot Daily Backup Configuration

Verify the daily rsnapshot cwrsync backup process is configured properly.

# rsnapshot -t daily
echo 6493 > /var/run/rsnapshot.pid
mkdir -m 0700 -p /.snapshots/
/.snapshots/hourly.5 not present (yet), nothing to copy
  1. Add Crontab Entry for rsnapshot

Once you’ve verified that the rsync hourly and daily backup configurations are setup properly in the rsnapshot cwrsync utility, it is time to set this puppy up in the crontab as shown below.

# crontab -e
0 */4 * * * /usr/local/bin/rsnapshot hourly
30 23 * * * /usr/local/bin/rsnapshot daily

source: http://www.thegeekstuff.com/2009/08/tutorial-backup-linux-using-rsnapshot-rsync-utility/

---- Bare Metal Recovery

I would use dd and tar to do baremetal recovery.

Backup important metadata:

# dd if-/dev/hda of=/backups/mbr bs=512 count=1

Backup the operating system:

# mkdir /backups
# mount nfsserver:/backups/<servername> /backups


# cd /
# tar cfz /backups/system.tar.gz --exclude /mnt --exclude /proc --exclude /backups

I personally would tend to take my system off-line if I wanted to make a baremetal restore file.

2
  • 2
    All your answer looks very good, no problems and all but its not what I am asking, any of the methods will not restore MBR and dd is not incremental. None of this is what I am asking. The last 10% might be interesting to look for but all the rest of information dump is really not. Nov 14, 2011 at 6:24
  • The details above deal with the file system (as a file system) and I added the dd process to deal with the MBR.
    – cprofitt
    Nov 14, 2011 at 17:39
3

There are 2 ways to do block based incremental backup

  • Filesystem based snapshots
  • Program based snapshots

Filesystem based snapshots

Both ZFS and BTRFS provide block based incremental snapshots (BTRFS, ZFS (page 25)). You could have a drive that you rsync to that is either ZFS or BTRFS and snapshot.

There is also LVM snapshots (mentioned by cprofitt) that provide the same block based incremental snapshots.

Program based snapshots

There a several backup programs, however a few stick out for the purpose:

I know you specifically mentioned that you are not looking for something like duplicity, however I thought I might mention some features.

However these programs require you to install them to restore. The beauty of something like rsync is that almost every linux installation has rsync (e.g. tiny core (a 10MB distribution) is missing it) by default.

Duplicity

It just stores the diff (block level) and then compresses and encrypts them. This leads to even less storage than the rsync method, however (at least the way I see it) the filesystem will need to be reconstructed, which will take time (if you are using incremental backups with it, and it depends on the time since last full backup)

The man page explains how it works.

Rdiff-backup

A client-server program that creates, like duplicity, block level diffs, however it stores changes from the lastest restore point, so the latest snapshot is the fastest to restore. Going back in time (not the lastest snapshot) requires more diffs to be analyzed and so it is slower.

Some people compare rdiff-backup to rsnapshot (seems like an more automatic way of the rsync mentod). Almost all the how-tos focus on using rdiff over the network, however I found one which mentions how to do it on localhost.

2
  • ok i like this, care to describe how to make that work with partition restoring? ie, if i break a disk how would i restore my complete system out from a snapshot with out having to make the partitions myself, etc. does not to be very detailed or include scripts, just some command names and what they would do. Nov 16, 2011 at 11:26
  • I have not had experience with these systems, I only found these from doing some research using Google (hence why they are only links). e.g. I learnt what duplicity actually is. Nov 16, 2011 at 12:20
3

You should take a look at ddar (homepage).

It is incremental in the sense of not transferring the identical parts of the snapshot. It is not incremental in the classical meaning of the word, since it is dealing with snapshots.

Note: I have not tried this myself (but I trust the author). It might not do what you'd like to achieve out-of-the-box, but still there are more similar solutions on the page (eg. ZFS), so as a starting point, it could possibly prove useful.

2
  • 1
    I am the author of ddar (thanks for the mention!). If I understand the question correctly, handing ddar a series of LVM snapshots would do exactly as requested. As you say, it deals with snapshots rather than incrementals but snapshots will have the same effect with the advantage that old snapshots can be removed at will without affecting newer ones. Nov 14, 2011 at 20:59
  • @robie i would be trilled to see how that would work, can you make a very small guide for me or any user that might be looking for this kind of solution? Nov 16, 2011 at 11:20
1

I think you can do this with LVM its only theorical, and it will waste a largue amount of hard disk. My theory is tha you can get your root system living on a logical volume, then if you want to make a test you can create an snapshot and restart the machine using the new volume.

LVM snapshots need the original volume to work. This is because the new volume holds the difference between the snapshot and the real filesystem.

If you leave the system in this state you'll start to waste disk space as the new filesystem changes. I don't know if there's a way to consolidate the snapshoted and the definitive filesytem. Surely you can dd to another logical volume, but for this you'll need twice the space of your filesystem plus the difference between your "point of recovery" and the current state.

And all of this requires reboots and is far from being automatic.

Its also supposed that several modern filesystems goes this way, like zfs on solaris systems or the experimental btrfs.

1

This one is a bit over my head, but it sounds like part of what you want to do is make partial backups of binary files (like partition image files). There's a package designed to do that (I've just read about it - not tried it.)

Take a look at bup.

https://github.com/apenwarr/bup

It might give you some ideas.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .