Home Using Gentoo emerge upgrade in BTRFS snapshot
Post
Cancel

Using Gentoo emerge upgrade in BTRFS snapshot

The issue

I’m a Gentoo use since a long time now and one of the biggest constrain I see while using this distribution is the long upgrade time.

Here I want to say that the issue is not the time by itself but the time under which the running OS is in a possibly instable state. The major issue being that while we are building the packages there is for some moments issues while the next packages have not yet been built and installed.

The major issue being when we are under the non stables versions for which we can be stucked in the middle of the upgrade with needs to search solutions with a system which will possibly not boot again if we reboot before fixing them.

The snapshot approach

With the BTRFS I see a possible improvement by using the snapshot feature not killing my system before getting all the packages built and installed.

The idea

The idea is basically to perform the update following the given steps :

  1. Perform emerge --sync to get the new package tree.
  2. Make a snapthot in read/write mode for the / filesystem.
  3. Chroot in the new snashot directory
  4. Build the new packages and generate the related binary packages.
  5. Once done, install the binary packages in the running system.

The good point in theses steps is that we can stop, pause any time in the build process without having a broken running system.

Scripts

I detail in the following the content of the operations to perform.

But I provide here a set of script in an archive doing everything and to extract in your / (or anywhere else but with some fixes to apply in paths).

2024-05-17-gentoo-btrfs-slash-scripts.tar.bz2

It contains:

  • ./backup/create_build_dir.sh
  • ./backup/create_snapshot.sh
  • ./backup/delete_snapshot.sh
  • mount.sh
  • umount.sh
  • chroot.sh
  • update.sh

It currently store all the common files in /home/gentoo.

To be done once

In order to each the chrooting I prepare some scripts in my / directory. It also help in case of boot issues if I need to make some fixes from a libusb in last ressort.

So I create two scripts in / :

  1. A script to mount the gentoo sub filesystems (mount.sh)
  2. Chroot in (chroot.sh)

Script mount.sh :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash

# Note : to be placed in "/mount.sh"

set -e
set -u
set -x

#dir=/mnt/gentoo
dir=${PWD}

if [[ ${dir} == "/" ]]; then
	echo "Invalid working dir : $dir !" 1>&2
	exit 1
fi

# common OS paths
mount --types proc /proc $dir/proc
mount --rbind /sys $dir/sys
mount --make-rslave $dir/sys
mount --rbind /dev $dir/dev
mount --make-rslave $dir/dev
mount --bind /run $dir/run
mount --make-slave $dir/run

# to put the binpkg at the right place
binpkg=/var/cache/binpkgs
mount --bind $binpkg $dir/$binpkg
mount --make-slave $dir/$binpkg

# to put the sources at the right place
distdir=/var/cache/distfiles
mount --bind $distdir $dir/$distdir
mount --make-slave $dir/$distdir

# If use a tmpfir elsewhere
#mount -U 583574f3-2a25-46c8-ba2a-d82e04a11cf6 $dir/var/tmp/portage/

Script chroot.sh :

1
2
#!/bin/bash
chroot $dir /bin/bash

Practical steps

Sync

First we need to sync the packages:

1
emerge --sync

Snapshot

Then we can snashot usnig btrfs :

1
2
3
4
5
6
7
8
9
10
11
12
# create /backup dir
mkdir -p /backup
cd /backup

# create a readonly backup in case
btrfs subvolume snapshot -r / /backup/snapshot-$(date "+%Y_%m_%d")

# create the read/write one
btrfs subvolume snapshot / /backup/build-$(date "+%Y_%m_%d")

# create a symlink on last
ln -s -f build-$(date "+%Y_%m_%d") build-current

Scripts to snapthots

In practice I made myself some helper script to ease the procedure which I store in /backup dir :

Script /backup/create_build_dir.sh

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

set -e
set -x

#./create_snapshot.sh

dirname=build-$(date "+%Y_%m_%d")

btrfs subvolume snapshot / /backup/${dirname}

ln -s -f ${dirname} build-current

Script /backup/create_snapshot.sh

1
2
3
4
5
6
#!/bin/bash

set -e
set -x

btrfs subvolume snapshot -r / /backup/snapshot-$(date "+%Y_%m_%d")

Script /backup/delete_snapshot.sh

1
2
3
4
5
6
7
#!/bin/bash

set -e
set -u
set -x

btrfs subvolume delete $1

Chroot

Now we can chroot in this new root dir:

1
2
3
4
5
6
7
8
9
# jump in
cd /backup/build-current


# mount sub filesystems
./mount.sh

# chroot in
./chroot.sh

Build

Now we can build all the update taking care to build the binary packaging in the mean time (you can also use quickpkg afterward in case):

1
2
# perform the update
emerge --update --newuse --deep --with-bdeps=y --buildpkg @world -a

You can now quit the chroot to come back to the running Gentoo :

1
2
# exit chroot
exit

Install in running system

Now just perform the update in you running system forcing the use of binary packages thankgs to the emerge -K/--usepkgonly option :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# perform update from binary packages only (-K)
emerge --update --newuse --deep --with-bdeps=y --usepkgonly @world

# rebuild modules
emerge -a -1 gentoo-kernel @module-rebuild

# eventually look to update grub for new kernels
grub-mkconfig -o /boot/grub/grub.cfg

# perform the next standard steps :
dispatch-conf
emerge --depclean

# read news
eselect news list 

Delete temporary snapthot

Delete the build snapthot :

1
2
# delete snapthot
btrfs subvolume delete snapshot-2024_01_04
This post is licensed under CC BY-ND 4.0 by the author.