Howto Undo a YUM update under BTRFS in Oracle Linux

Version 14
Visibility: Open to anyone

     

    About

     

    A yum update of the OS is often complex and cannot simply be undone by uninstalling individual software packages.

    If the root filesystem is BTRFS, however, snapshot technology can roll-back the installation in seconds. This tutorial
    demonstrates how to undo a YUM update, including how to rebuild the root and /var/lib/machine subvolumes
    without relying on rsync or copying the root filesystem.

     

    Please note that this document is not an introduction to BTRFS. Plenty of other documentation exists already exists
    and is freely available on the Internet. Thus this tutorial assumes you have some BTRFS and system administration

    experience.

     

    The following was tested under Oracle Linux 7.6. The configuration of BTRFS root file system was done by the OS

    installer and choosing a custom target configuration.

     

     

     

    Example

     

    Installing Yum-plugin-fs-snapshot

     

    Install the yum-plugin-fs-snapshot package to automate the creation BTRFS snapshots when yum makes changes

    to the filesystem.

     

    [root@localhost /]# yum -y install yum-utils

    [root@localhost /]# yum-config-manager --enable ol7_optional_latest

    [root@localhost /]# yum -y install yum-plugin-fs-snapshot

     

     

    Tip:

    The yum-fs-snapshot plug-in creates a snapshot of all BTRFS filesystems, by default. If you wish to exclude a BTRFS filesystem, modify the configuration file. For example:

     

    [root@localhost /]# cat /etc/yum/pluginconf.d/fs-snapshot.conf

    [main]

    enabled = 1

    create_snapshots_in_post = 0

    exclude = /u01 /u02

     

     

    Complete Roll-back of a YUM Update


    YUM snapshots are named "yum_<date>" in the root directory. For example:

     

    [root@localhost /]# yum -y update

    ...

    Transaction test succeeded

    Running transaction

    fs-snapshot: snapshotting /: /yum_20190309020958

      Updating   : 1:grub2-common-2.02-0.76.0.3.el7.1.noarch          1/104

    etc ...

     

    [root@localhost /]# ls

    bin   etc   lib64  opt   run   sys  var  yum_20190309020958

    boot  home  media  proc  sbin  tmp  yum_20190309015329

    dev   lib   mnt    root  srv   usr  yum_20190309015421

     

    [root@localhost /]# shutdown -r now

     

     

    Determine the appropriate subvolume ID of the BTRFS snapshot.

     

    [root@localhost ~]# btrfs subvol list /

    ID 257 gen 1989 top level 5 path root

    ID 259 gen 1987 top level 257 path var/lib/machines

    ID 261 gen 48 top level 257 path yum_20190309015329

    ID 262 gen 51 top level 257 path yum_20190309015421

    ID 263 gen 1974 top level 257 path yum_20190309020958

     

     

    Remove the subvolume "root" in the GRUB bootloader configuration to let the system mount the default subvolume.

     

    [root@localhost /]# btrfs subvol set-default 263 /

    [root@localhost ~]# a=$(grubby --default-kernel)

    [root@localhost ~]# grubby --remove-args="rootflags=subvol=root" --update-kernel $a


    [root@localhost /]# shutdown -r now

     

     

    Relocating the Root Subvolume

     

    [root@localhost /]# btrfs subvol list /

    ID 257 gen 2035 top level 5 path root                      <- original root volume!

    ID 259 gen 1987 top level 257 path root/var/lib/machines

    ID 261 gen 48 top level 257 path root/yum_20190309015329

    ID 262 gen 51 top level 257 path root/yum_20190309015421

    ID 263 gen 2037 top level 257 path root/yum_20190309020958  <- current root volume!

     

     

    Mount the actual root level of the BTRFS subvolume, known as ID 0.

     

    [root@localhost /]# mkdir /mnt/btrfs

    [root@localhost /]# a=$(mount|grep ' / '|cut -d' ' -f1)

    [root@localhost /]# mount -o subvolid=0 $a /mnt/btrfs


    [root@localhost /]# ls /mnt/btrfs/root

    bin   etc   lib64  opt   run   sys  var                 yum_20190309020958

    boot  home  media  proc  sbin  tmp  yum_20190309015329

    dev   lib   mnt    root  srv   usr  yum_20190309015421

     

     

    Exchange the previous "root" subvolume with the current root volume (yum_20190309020958) and set

    the GRUB kernel command back to what it was prior to the yum roll-back.

     

    [root@localhost ~]# mv /mnt/btrfs/root/yum_20190309020958 /mnt/btrfs/newroot

    [root@localhost ~]# mv /mnt/btrfs/root /mnt/btrfs/oldroot

    [root@localhost ~]# mv /mnt/btrfs/newroot /mnt/btrfs/root

    [root@localhost ~]# umount /mnt/btrfs

     

    [root@localhost ~]# a=$(grubby --default-kernel)

    [root@localhost ~]# grubby --args="rootflags=subvol=root" --update-kernel $a

     

     

    Reconstructing the /var/lib/machine Subvolume

     

    Remove the now empty /var/lib/machine directory to let systemd create a new BTRFS subvolume for nspawn

    containers at /var/lib/machines during the next system restart.

     

    [root@localhost /]# rm -rf /var/lib/machines

     

    [root@localhost /]# shutdown -r now

     

    [root@localhost ~]# btrfs subvol list /

    ID 257 gen 2052 top level 5 path oldroot

    ID 259 gen 1987 top level 257 path oldroot/var/lib/machines

    ID 261 gen 48 top level 257 path oldroot/yum_20190309015329

    ID 262 gen 51 top level 257 path oldroot/yum_20190309015421

    ID 263 gen 2061 top level 5 path root

    ID 265 gen 2061 top level 263 path var/lib/machines

     

     

    Mount the BTRFS subvolume ID 0 to relocate previous content of the /var/lib/machine subvolume.

     

    [root@localhost ~]# a=$(mount|grep ' / '|cut -d' ' -f1)

    [root@localhost ~]# mount -o subvolid=0 $a /mnt/btrfs


    [root@localhost ~]# cd /mnt/btrfs/oldroot/var/lib/machines/

    [root@localhost machines]# mv -n * /mnt/btrfs/root/var/lib/machines/

    [root@localhost machines]# mv -n .* /mnt/btrfs/root/var/lib/machines/

    [root@localhost machines]# cd /


    [root@localhost /]# du -s /var/lib/machines/

    305796    /var/lib/machines/

     

     

    Relocating Remaining Snapshots

     

    [root@localhost /]# cd /mnt/btrfs/oldroot

    [root@localhost oldroot]# for i in yum_*

    > do mv -f /mnt/btrfs/oldroot/$i /mnt/btrfs/root/

    > done


    [root@localhost oldroot]# btrfs subvol list /

    ID 257 gen 2075 top level 5 path oldroot

    ID 259 gen 2070 top level 257 path oldroot/var/lib/machines

    ID 261 gen 48 top level 263 path yum_20190309015329

    ID 262 gen 51 top level 263 path yum_20190309015421

    ID 263 gen 2075 top level 5 path root

    ID 265 gen 2070 top level 263 path var/lib/machines

     

    Final Cleanup

     

    [root@localhost oldroot]# cd /

    [root@localhost /]# btrfs subvol delete -c /mnt/btrfs/oldroot/var/lib/machines

    Delete subvolume (commit): '/mnt/btrfs/oldroot/var/lib/machines'

     

    [root@localhost ~]# btrfs subvol delete -c /mnt/btrfs/oldroot

    Delete subvolume (commit): '/mnt/btrfs/oldroot'

     

    [root@localhost ~]# umount /mnt/btrfs

     

    [root@localhost ~]# btrfs subvol list /

    ID 261 gen 48 top level 263 path yum_20190309015329

    ID 262 gen 51 top level 263 path yum_20190309015421

    ID 263 gen 2075 top level 5 path root

    ID 265 gen 2070 top level 263 path var/lib/machines

     

    [root@localhost ~]# shutdown -r now

     

     

    If you do not plan to perform any other roll-back to a previous YUM snapshot, you can simply delete them.

     

    [root@localhost ~]# btrfs subvol list /

    ID 261 gen 48 top level 263 path yum_20190309015329

    ID 262 gen 51 top level 263 path yum_20190309015421

    ID 263 gen 2105 top level 5 path root

    ID 265 gen 2103 top level 263 path var/lib/machines

     

    [root@localhost ~]# btrfs subvol delete -c /yum_20190309015329

    Delete subvolume (commit): '//yum_20190309015329'

    [root@localhost ~]# btrfs subvol delete -c /yum_20190309015421

    Delete subvolume (commit): '//yum_20190309015421'

     

    [root@localhost ~]# btrfs subvol list /

    ID 263 gen 2109 top level 5 path root

    ID 265 gen 2103 top level 263 path var/lib/machines

     

     

     

     

    All information and instructions have been researched and tested thoroughly, but are no substitute for
    information and support provided by Oracle. Please use at your own risk.

     

    This document is distributed in the hope to help members of the Oracle community and provided under
    the terms and conditions at http://www.oracle.com/us/legal/terms/index.html.

     

    Copyright (C) 2019 Dude! @ Oracle Community. Please do not plagiarize.

     

    Comments

     

    For comments, please see Howto Undo a YUM update under BTRFS in Oracle Linux