Difference between revisions of "Btrfs Tips and tricks"

From ArchWiki
Jump to: navigation, search
(Snapshot script)
(fix double redirect)
(Tag: wiki-scripts)
 
(11 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[Category:File systems]]
+
#REDIRECT [[Btrfs#Tips and tricks]]
Go back to [[Btrfs]].
 
 
 
= Btrfs Tips and tricks =
 
 
 
== Snapshot tricks ==
 
 
 
=== Automatic snapshots on each boot ===
 
 
 
It is possible to automatically save the then current state of a btrfs subvolume during system boot. Two files are needed to accomplish this, a script which snapshots btrfs subvolumes and a [[systemd]] unit file to run the script during the boot process.
 
 
 
==== Requirements ====
 
 
 
The root filesystem must have been installed into its own dedicated btrfs subvolume and the btrfs-root where all subvolumes reside has to be accessible.
 
 
 
* Example fstab {{ic|/etc/fstab}}:
 
<pre><nowiki>
 
# ...
 
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /              btrfs subvol=__current/ROOT,defaults 0 0
 
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /run/btrfs-root btrfs compress=lzo,defaults 0 0
 
UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /opt            btrfs subvol=__current/opt,defaults 0 0
 
# ...
 
</nowiki></pre>
 
 
 
==== Snapshot script ====
 
 
 
An example script to snapshot the btrfs subvolumes mounted under '/'. The script will automatically detect the names of all subvolumes mounted under '/'.
 
 
 
What the script does, is to delete all snapshots from the state, the system was in at last boot, make new snapshots and alter the /etc/fstab file of the snapshotted root subvolume to allow it to be booted without manual configuration.
 
 
 
The script requires 3 parameters:
 
# The path of the btrfs filesystem root. e. g. '/run/btrfs-root',
 
# The name of the btrfs root volume as specified in /etc/fstab. E. g. '__current/ROOT',
 
# The path where the newly created snapshots will reside without its 1st parameter portion. E. g. '__snapshot/__state_at_last_successful_boot' (if the actual path is '/run/btrfs-root/__snapshot/__state_at_last_successful_boot')
 
 
 
 
 
<span style="color:red">CAUTION: This script will delete all snapshots of the same name as the regular subvolume names in the path its third parameter is pointing to.</span> Be careful that the 3rd parameter is <span style="color:red">NOT</span> pointing at the place where your subvolumes reside in --- In this example, '/run/btrfs-root' as a <span style="color:red">3rd</span> parameter would be incorrect and possibly lead to data loss.
 
 
 
 
 
* Example file {{ic|/usr/local/bin/snapshot_current_system_state.sh}}:
 
<pre><nowiki>
 
#!/bin/sh
 
 
 
# example call: /usr/local/bin/snapshot_current_system_state.sh '/run/btrfs-root' '__current/ROOT' '__snapshot/__state_at_last_successful_boot'
 
 
 
if [ $# -ne 3 ]
 
then
 
  /usr/bin/echo -e "This script requires three parameters:\n1st parameter: The path of the btrfs filesystem root. e. g. /run/btrfs-root\n2nd parameter: The name of the btrfs root volume as specified in /etc/fstab. E. g. __current/ROOT\n3rd parameter: The path where the newly created snapshots will reside without its 1st parameter portion. E. g. __snapshot/__state_at_last_successful_boot\nCAUTION: This script will delete all snapshots of the same name as the regular volume names in the path parameter 3 is pointing to."
 
  exit 0
 
fi
 
 
 
btrfs_root="${1}" # example: '/run/btrfs-root'
 
path_to_root_volume="${2}" # example: '__current/ROOT'
 
path_to_snapshots="${3}" # example: '__snapshot/__state_at_last_successful_boot'
 
 
 
# take no snapshots when booted into a snapshot
 
if [ -e '/SNAPSHOT-TIMESTAMP' ]
 
then
 
  exit 0
 
fi
 
 
 
# anti recursive snapshots
 
for subvolume in $(/usr/bin/btrfs subvolume list '/' | /usr/bin/awk '{print $NF}')
 
do
 
  path_to_snapshot="${btrfs_root}/${path_to_snapshots}/${subvolume}"
 
 
 
  if [ -d "${path_to_snapshot}" ]
 
  then
 
    /usr/bin/btrfs subvolume delete "${path_to_snapshot}"
 
  fi 
 
done
 
 
 
subvolumes="$(/usr/bin/btrfs subvolume list '/' | /usr/bin/awk '{print $NF}')"
 
for subvolume in $subvolumes
 
do
 
  snapshot_directory="${btrfs_root}/${path_to_snapshots}/$(/usr/bin/dirname ${subvolume})"
 
 
 
  if [ ! -d "${snapshot_directory}" ]
 
  then
 
    /usr/bin/mkdir -p "${snapshot_directory}"
 
  fi 
 
 
 
  /usr/bin/btrfs subvolume snapshot "${btrfs_root}/${subvolume}" "${btrfs_root}/${path_to_snapshots}/${subvolume}"
 
 
 
  if [ "${subvolume}" = "${path_to_root_volume}" ]
 
  then
 
    timestamp="$(/usr/bin/date +%d.%m.%Y-%H:%M:%S)"
 
 
 
    /usr/bin/echo -e "Arch Linux --- state at last successful boot (nonpersistent) [${timestamp}]\n" > "${btrfs_root}/${path_to_snapshots}/${path_to_root_volume}/etc/issue"
 
 
 
    /usr/bin/echo "${timestamp}" > "${btrfs_root}/${path_to_snapshots}/${path_to_root_volume}/SNAPSHOT-TIMESTAMP"
 
 
 
    sed_path_to_snapshots="$(/usr/bin/echo ${path_to_snapshots} | /usr/bin/sed --posix --regexp-extended 's/\//\\\//g')"
 
 
 
    for subvolumeX in $(echo $subvolumes | /usr/bin/sed --posix --regexp-extended 's/\//\\\//g')
 
    do
 
      /usr/bin/sed --posix --regexp-extended "s/subvol=${subvolumeX}/subvol=${sed_path_to_snapshots}\/${subvolumeX}/g" --in-place "${btrfs_root}/${path_to_snapshots}/${path_to_root_volume}/etc/fstab"
 
    done
 
  fi
 
done
 
 
 
/usr/bin/sync
 
</nowiki></pre>
 
 
 
==== [[systemd]] unit file ====
 
 
 
Following [[systemd]] unit file will run the script every time the system manages to successfully boot into multi-user.target:
 
* Example file {{ic|/etc/systemd/system/snapshot_current_system_state_upon_boot.service}}:
 
<pre><nowiki>
 
[Unit]
 
Description=Takes a snapshot of each btrfs-subvolume mounted under / after multi-user-target has been reached.
 
After=multi-user.target
 
 
 
[Service]
 
Type=oneshot
 
ExecStart=/bin/sh /usr/local/bin/snapshot_current_system_state.sh '/run/btrfs-root' '__current/ROOT' '__snapshot/__state_at_last_successful_boot'
 
 
 
[Install]
 
WantedBy=multi-user.target
 
</nowiki></pre>
 
 
 
The unit file has to be symlinked by systemd:
 
 
 
{{bc|systemctl enable snapshot_current_system_state_upon_boot.service}}
 
=== Booting into snapshots ===
 
 
 
=== Boot manager entry ===
 

Latest revision as of 19:24, 21 July 2016