BTRFS How to make a snapshot and rollback

I’ve mentioned earlier on how to fix the root FS filling up with snapshots generated by apt-get upgrade
Now assume I do need to rollback because of whatever went wrong.
First, if you haven’t installed yet apt-btrfs-snapshot (because of this) we do it now and then we upgrade.
apt-get install apt-btrfs-snapshot
# apt-get upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: evolution-data-server evolution-data-server-common evolution-data-server-online-accounts gir1.2-ebook-1.2 gir1.2-ebookcontacts-1.2 gir1.2-edataserver-1.2 google-chrome-beta libcamel-1.2-45 libebackend-1.2-7 libebook-1.2-14 libebook-contacts-1.2-0 libecal-1.2-16 libedata-book-1.2-20 libedata-cal-1.2-23 libedataserver-1.2-18 locales 16 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 52.4 MB of archives. After this operation, 8,133 kB of additional disk space will be used. Do you want to continue? [Y/n] y ........
Done. see the snapshots we now have
# btrfs subvolume list / ID 257 gen 8126 top level 5 path @ ID 258 gen 8126 top level 5 path @home ID 325 gen 8123 top level 5 path @apt-snapshot-2014-05-23_22:14:26 # apt-btrfs-snapshot list Available snapshots: @apt-snapshot-2014-05-23_22:14:26
Lets do a manual one cause I know I’m going to do a few silly things now.
# btrfs subvolume snapshot / /andreas_doing_silly_things Create a snapshot of '/' in '//andreas_doing_silly_things'
I can see it here.
# ls -al / total 25 drwxr-xr-x 1 root root 228 May 23 22:29 . drwxr-xr-x 1 root root 228 May 23 22:29 .. drwxr-xr-x 1 root root 176 May 23 22:29 andreas_doing_silly_things
Now we want to rollback. Identify the deice where btrfs is on and mount it
# df -h / Filesystem Size Used Avail Use% Mounted on /dev/sdb4 25G 9.4G 15G 40% / root@USB-DISK:/#
mount /dev/sdb4 /mnt
# ls -al total 16 drwxr-xr-x 1 root root 78 May 23 22:14 . drwxr-xr-x 1 root root 228 May 23 22:29 .. drwxr-xr-x 1 root root 228 May 23 22:29 @ drwxr-xr-x 1 root root 176 May 2 21:15 @apt-snapshot-2014-05-23_22:14:26 drwxr-xr-x 1 root root 14 May 2 21:13 @home # btrfs subvolume list /mnt ID 257 gen 8201 top level 5 path @ ID 258 gen 8128 top level 5 path @home ID 325 gen 8123 top level 5 path @apt-snapshot-2014-05-23_22:14:26 ID 329 gen 8201 top level 5 path @/andreas_doing_silly_things
Ideally we want to go back to before the patching cause I feel that upgrade made some mess. I first create a markr to see that this is my pre-upgrade FS
# cd /mnt root@USB-DISK:/mnt# ls -al total 16 drwxr-xr-x 1 root root 78 May 23 22:14 . drwxr-xr-x 1 root root 228 May 23 23:23 .. drwxr-xr-x 1 root root 228 May 23 23:23 @ drwxr-xr-x 1 root root 226 May 23 23:33 @apt-snapshot-2014-05-23_22:14:26 drwxr-xr-x 1 root root 14 May 2 21:13 @home
# cd @apt-snapshot-2014-05-23_22:14:26 # touch thatsbeforetheupgrade.txt # ls -al total 24 drwxr-xr-x 1 root root 226 May 23 23:33 . drwxr-xr-x 1 root root 78 May 23 22:14 .. drwxr-xr-x 1 root root 2052 May 15 21:07 bin drwxrwxr-x 1 root root 0 May 2 21:09 boot drwxrwxr-x 1 root root 0 May 2 21:12 cdrom drwxr-xr-x 1 root root 902 Apr 17 02:26 dev drwxr-xr-x 1 root root 4420 May 23 22:14 etc drwxrwxr-x 1 root root 0 May 2 21:09 home lrwxrwxrwx 1 root root 33 May 2 21:15 initrd.img -> boot/initrd.img-3.13.0-24-generic drwxr-xr-x 1 root root 760 May 5 20:18 lib drwxr-xr-x 1 root root 40 Apr 17 02:21 lib64 drwxr-xr-x 1 root root 14 May 2 21:24 media drwxr-xr-x 1 root root 6 May 12 19:51 mnt drwxr-xr-x 1 root root 34 May 3 10:06 opt drwxr-xr-x 1 root root 0 Apr 10 23:12 proc drwx------ 1 root root 100 May 9 20:30 root drwxr-xr-x 1 root root 334 Apr 17 02:27 run drwxr-xr-x 1 root root 4338 May 22 16:02 sbin drwxr-xr-x 1 root root 0 Apr 17 02:21 srv drwxr-xr-x 1 root root 0 Mar 13 01:41 sys -rw-r--r-- 1 root root 0 May 23 23:33 thatsbeforetheupgrade.txt drwxrwxrwt 1 root root 400 May 23 22:14 tmp drwxr-xr-x 1 root root 70 Apr 17 02:21 usr drwxr-xr-x 1 root root 114 Apr 17 02:29 var lrwxrwxrwx 1 root root 30 May 2 21:15 vmlinuz -> boot/vmlinuz-3.13.0-24-generic
I’m not cheating
# ls -al /thatsbeforetheupgrade.txt ls: cannot access /thatsbeforetheupgrade.txt: No such file or directory
Now we rollback before the update:
# mv /mnt/@ /mnt/@_badroot # mv /mnt/@apt-snapshot-2014-05-23_22:14:26 /mnt/@ # ls -al total 16 drwxr-xr-x 1 root root 30 May 24 00:09 . drwxr-xr-x 1 root root 228 May 23 23:23 .. drwxr-xr-x 1 root root 226 May 23 23:33 @ drwxr-xr-x 1 root root 228 May 23 23:23 @_badroot drwxr-xr-x 1 root root 14 May 2 21:13 @home # cd @ # ls bin boot cdrom dev etc home initrd.img lib lib64 media mnt opt proc root run sbin srv sys thatsbeforetheupgrade.txt tmp usr var vmlinuz
which will set the new root partition (volume) as “@apt-snapshot-2014-05-23_22:14:26” which was before we run apt-get upgrade. Reboot the box.
reboot
After the reboot check what we have done.
ls / bin boot cdrom dev etc home initrd.img lib lib64 media mnt opt proc root run sbin srv sys thatsbeforetheupgrade.txt tmp usr var vmlinuz
That looks promising.
# btrfs subvolume list / ID 257 gen 8257 top level 5 path @_badroot ID 258 gen 8260 top level 5 path @home ID 325 gen 8260 top level 5 path @ ID 329 gen 8201 top level 5 path @_badroot/andreas_doing_silly_things
And because I like to proof Einstein right I do the same again and expect it this time to work.
# apt-get upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: evolution-data-server evolution-data-server-common evolution-data-server-online-accounts gir1.2-ebook-1.2 gir1.2-ebookcontacts-1.2 gir1.2-edataserver-1.2 google-chrome-beta libcamel-1.2-45 libebackend-1.2-7 libebook-1.2-14 libebook-contacts-1.2-0 libecal-1.2-16 libedata-book-1.2-20 libedata-cal-1.2-23 libedataserver-1.2-18 locales 16 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/52.4 MB of archives. After this operation, 8,133 kB of additional disk space will be used. Do you want to continue? [Y/n]
Now closing that theory lets do some cleanup.
# mount /dev/sdb4 /mnt # btrfs subvolume list /mnt ID 257 gen 8257 top level 5 path @_badroot ID 258 gen 8266 top level 5 path @home ID 325 gen 8266 top level 5 path @ ID 329 gen 8201 top level 5 path @_badroot/andreas_doing_silly_things # btrfs subvolume delete /mnt/@_badroot/andreas_doing_silly_things Delete subvolume '/mnt/@_badroot/andreas_doing_silly_things' # btrfs subvolume delete /mnt/@_badroot Delete subvolume '/mnt/@_badroot' # btrfs subvolume list /mnt ID 257 gen 8257 top level 0 path DELETED ID 258 gen 8268 top level 5 path @home ID 325 gen 8268 top level 5 path @ ID 329 gen 8201 top level 0 path DELETED
You can do the same with the manual created snapshot “andreas_doing_silly_things”. That’s why I put it into as informational.