Hello,
I'm testing how to undo a YUM update using BTRFS under Oracle Linux. The system (OL 7.6) was installed under VirtualBox, choosing BTRFS for the root volume during the initial installation. After reading various documentations available on the web and experimenting, it finally seems I succeeded, but the process overall is not very user or admin friendly. I wonder if there isn't an easier way.
I was able to boot the system using a snapshot that was automatically created by yum-plugin-fs-snapshot, doing the following:
# btrfs subvol list /
ID 257 gen 2024 top level 5 path root
ID 259 gen 2012 top level 257 path var/lib/machines
ID 261 gen 1557 top level 257 path yum_20190301201114
ID 262 gen 1557 top level 257 path yum_20190301201921
ID 263 gen 1557 top level 257 path yum_20190301202303
The snapshot I want to use is yum_20190301201114.
# btrfs subvolume set-default 261 /
The GRUB kernel command line overwrites the default and mounts subvol root - this won't work.
# grubby --remove-args="rootflags=subvol=root" --update-kernel /boot/vmlinuz-4.1.12-124.25.1.el7uek.x86_64
The file system table /etc/fstab still contains the previous data, but it doesn't seem to make a difference. I suppose it doesn't matter since specifying the root volume at the kernel command line supersedes fstab.
UUID=b5ca95eb-d671-44d1-be67-c6677c1af515 / btrfs defaults,subvol=root,_netdev,_netdev 0 0
After a reboot, it seems successful.
So far so good!
Although "roll-back" seems commonly used in this case, I would not really call it a roll-back, not from a DBA perspective, because no data is physically removed or restored, and it's "simply" using a previous version of the file system. I also think it's not really "undoing" things, as I have to use a different GRUB kernel command line.
How to complete revert to an older status of the file system, without booting into a different BTRFS subvolid? I've seen some information about moving subvolumes at the OS level, but I don't think it is possible to replace a BTRFS top volume with a snapshot.
So, I did the following, which basically mounts the previous subvolume root (ID 257) and use rsync to copy back the currently mounted root.
1. Problem:
# mount -o subvolid=257 /mnt
mount: can't find /mnt in /etc/fstab
# mount /mnt
mount: can't find /mnt in /etc/fstab
I couldn't find any help, but modifying etc/fstab seems to solve the issue: So I modifed /etc/fstab:
UUID=b5ca95eb-d671-44d1-be67-c6677c1af515 /mnt btrfs defaults,subvol=root,_netdev,_netdev 0 0
# mount -a
# df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 25G 4.5G 19G 19% /mnt
Now since I have the subvol=root mounted under /mnt... I can copy back the current root filesystem
# yum -y install rsync
# rsync --progress -aHAX \
--exclude=/proc --exclude=/dev --exclude=/sys --exclude=/mnt --exclude=/run \
/ /mnt
Then restore the previous GRUB kernel command line:
# grubby --args="rootflags=subvol=root" --update-kernel /boot/vmlinuz-4.1.12-124.25.1.el7uek.x86_64
# sync
Resetting the machine.
Apparently this worked, and I can delete all the yum snapshot volumes that I don't need anymore.
2. Problem:
# btrfs subvol delete yum_20190301201114
Delete subvolume (no-commit): '//yum_20190301201114'
ERROR: cannot delete '//yum_20190301201114': Operation not permitted
# btrfs subvol get-default /
ID 261 gen 2119 top level 257 path yum_20190301201114
# btrfs subvol set-default 257 /
# btrfs subvol delete -c yum_20190301201114
Delete subvolume (commit): '//yum_20190301201114'
ERROR: cannot delete '//yum_20190301201114': Directory not empty
I find the following confusing:
# btrfs subvol list /yum_20190301201114
ID 257 gen 2149 top level 5 path root
ID 259 gen 2120 top level 257 path root/var/lib/machines
ID 261 gen 2119 top level 257 path root/yum_20190301201114
ID 278 gen 2108 top level 261 path yum_20190307135320
# btrfs subvol list /
ID 257 gen 2153 top level 5 path root
ID 259 gen 2120 top level 257 path var/lib/machines
ID 261 gen 2119 top level 257 path yum_20190301201114
ID 278 gen 2108 top level 261 path yum_20190301201114/yum_20190307135320
But the following seemed to have worked:
# btrfs subvol delete -c /yum_20190301201114/yum_20190307135320
Delete subvolume (commit): '/yum_20190301201114/yum_20190307135320'
# btrfs subvol delete -c /yum_20190301201114
Delete subvolume (commit): '//yum_20190301201114'
Finally remove the remaining yum snapshots:
# for i in yum_*; do btrfs subvol delete -c $i; done
Delete subvolume (commit): '//yum_20190301201921'
Delete subvolume (commit): '//yum_20190302002511'
Delete subvolume (commit): '//yum_20190302003305'
Delete subvolume (commit): '//yum_20190302003948'
Delete subvolume (commit): '//yum_20190302004042'
Delete subvolume (commit): '//yum_20190305192600'
Delete subvolume (commit): '//yum_20190305223812'
Delete subvolume (commit): '//yum_20190306164409'
Delete subvolume (commit): '//yum_20190306170031'
Delete subvolume (commit): '//yum_20190306170336'
Delete subvolume (commit): '//yum_20190306170817'
Delete subvolume (commit): '//yum_20190307035113'
# ls
bin dev home lib64 mnt opt root sbin sys u01 u03 var
boot etc lib media new proc run srv tmp u02 usr
I guess it's all done. But is it the right/best procedure?
Thanks!