After re-reading my own posts, I see my tone can be interpreted as hostile. Not my intention; I may be a bit frustrated, but not hostile/angry/peeved. Once again, me fail Eglish.
To fix, I shall try to outline how LVM2-based snapshotting and backups work, from an users perspective.
LVM2 is the Linux Logical Volume Manager. (The 2 at the end is usually omitted, since the first version of LVM is ancient, and no longer used.)
It comprises of a group of userspace tools, and a library that interfaces to the Linux kernel Device Mapper, which does the actual work.
You have one or more hardware storage devices, with at least one partition on each.
If you are using software RAID, the
md (multiple device) kernel driver will use those partitions, and export the RAID devices (
/dev/mdN) as the partitions actually used.
LVM combines one or more of these partitions into one or more physical volumes. (Run
sudo pvdisplay to see current physical volumes.)
One or more physical volumes – across hardware devices – are combined into a Volume Group. You can have one or more Volume Groups. (Run
sudo vgdisplay to see these. You may need to run
sudo vgscan first, to scan all known LVM devices for Volume Groups first, especially if you just attached external media. It can take a bit of time.)
Each Volume Group contains one or more Logical Volumes. Each logical volume is seen as a partition, and contains a filesystem or swap space, is used as a raw partition for some kind of experiments, or is unused. (Run
sudo lvdisplay to see these.) Logical Volumes can be resized within a Volume Group.
Do not use all space in a Volume Group for Logical Volumes. Snapshots use up some space in the Volume Group.
When Logical Volumes are mounted, the device path (as shown in e.g.
df -h or
du -hs or
mount) will show
/dev/mapper/VolumeGroup-LogicalVolume as the device.
To take a snapshot of a Logical Volume, you create a new logical volume using
lvcreate (8):
sudo lvcreate -s VolumeGroup/LogicalVolume -L size -n NewLogicalVolume This is atomic, and takes an exact snapshot of that Logical Volume at that point, and is okay to do even when it is mounted and active. You'll want to ensure that applications are not writing to files in that Logical Volume right then, or the files will obviously be in an intermediate state. (There are tricks on how to check if any writes have occurred after the snapshot, most being heuristic in the sense that they can give false positives, but not false negatives; quite reliable.)
Then, you can either mount the new Logical Volume (
/dev/mapper/VolumeGroup-NewLogicalVolume, but with any dashes in NewLogicalVolume doubled; there is also copy-on-write
/dev/mapper/VolumeGroup-NewLogicalVolume-cow device) and copy/compress/use its contents at your leisure, or save the image.
For storing the image on an external storage device, I recommend creating a partition the exact same size as the Logical Volume. Since the partition will be a normal filesystem, it is usually auto-mounted when connected. To update the backup, you can use the volume label to find the device corresponding to the partition:
label="foo" ; user=$(id -un) ; dev=$(LANG=C LC_ALL=C mount | awk '$2 == "on" && $3 == "'"/media/$user/$label"'" { print $1 }')If current user has media with volume label
foo mounted, its corresponding device will be in shell variable
dev; otherwise the shell variable will be empty.
Then, unmount the device using
umount $devand copy the partition image over using e.g.
sudo dd if=/dev/mapper/VolumeGroup-NewLogicalVolume of="$dev" oconv=fdatasync,nocreat bs=1048576Note that the device name is inserted by the current shell to the sudo command.
Finally, remove the no longer needed Logical Volume,
sudo lvremove -y VolumeGroup/NewLogicalVolumeand the snapshot is done.
To restore an existing image, find the device corresponding to the partition (again as
$dev). Then, unmount the Logical Volume,
sudo umount /dev/mapper/VolumeGroup-LogicalVolumerestore the image,
sudo dd if="$dev" of=/dev/mapper/VolumeGroup-LogicalVolume oconv=fdatasync,nocreat bs=1048576and remount the Logical Volume,
sudo mount /dev/mapper/VolumeGroup-LogicalVolumeThat's the short version.
As you can surely see, there are many different ways of automating this. A simple udev rule and a shell script is could be used to prompt you when an external backup media is attached whether you want to back up current Logical Volumes to that media. For restoring, you'll want a command-line command (it's useful to add
status=progress to dd commands in that case), since you might be in emergency command line, and in any case you'll want to unmount the Logical Volume (making GUI use, uh, difficult – workarounds exist, of course) for the restoration.
As to why I don't think this is a workable pattern for
workstations, is that in my opinion, workstations are
volatile and modular. A monolithic backup is too rigid.
If you partition your system so that
/home is a separate Logical Volume, then image-based backups become viable. However, even then,
I believe that instead of dd'ing the image itself, we should use
tar (with or without compression, possibly niced and/or ioniced) to compress the filesystem contents to the external media. That way, the external media can contain multiple backups. With an index file (text file describing the file list inside the tar archive), one can trivially restore individual files or subdirectories, which can come in handy.
If the OS is on a separate Logical Volume or Volumes, then taking a snapshot after a clean install makes a lot of sense. When tar'ing the user files, you can also save the currently installed package list, output of
LANG=C LC_ALL=C dpkg -l | awk '$1 == "ii" { print $2, $3 }' > packages.listso you can quickly upgrade an older image to newer by installing the difference in the packages – or if you get some sort of conflicts after installing a package, and purging the package doesn't fix it, you can compare incidental changes in the packages/versions.
Let's say
packages.list contains the desired package list. Then, running
LANG=C LC_ALL=C dpkg -l | awk -v src=packages.list 'BEGIN { while (getline) { if ($1=="ii") pkg[$2] = $3 } while (getline < src) { if ($1 in pkg) { if (pkg[$1] != $2) printf "Update: %s from %s to %s\n", $1, pkg[$1], $2 } else { printf "Install: %s %s\n", $1, $2 } } }'gives you a summary of which packages need updating/downgrading and which packages need installing.
This, of course, could be automated in the backup user interface.
A simple GUI utility would make a lot of assumptions on how the system is partitioned, that this is essentially a single-human-user system, and so on. Not a problem if you write your own GUI, but a problem when considering more general use backup tool.