Updating Gentoo

Gentoo is a rolling-release distribution meaning that you don't have to wait for major releases (e.g. Red Hat 6, 7, 8, or 6.1, 7.1, 7.9, etc.) to get the current version of KDE, Gnome, PHP, etc. There is a trade off between monolithic releases and rolling-updates. Upgrading monolithic releases can be a annoying, time consuming, and may require several reboots. Using Fedora for example, a new core is released about every 6 months and is only supported for roughly a year. Although the process is not difficult, it isn’t something that I look forward to. There is also the risk of losing your data when upgrading these types of distributions as well. Granted there some tools that help with this and you may need the stability of having packages locked to a certain version, such as when running a server.

With Gentoo and other rolling release distributions, there is no need to take time out of your day to prepare for a major version upgrade. By doing little updates you essentially get to a new "major version" over time. For binary rolling release distributions, not staying on top of updates won't set you back much time or effort. With Gentoo, if you wait too long between updates you may run into conflicts and have to backtrack, which could lead to significantly longer compile times. Regardless, you should always keep your system up to date.

Prerequisites

This blog will demonstrate a "best case" scenario of how I update my system while including as much as I can, such as portage updates or news items.

app-portage/eix and app-portage/gentoolkit are helpful for searching for packages based on specific criteria and providing additional information that you may need when troubleshooting. The sys-kernel/genkernel is a tool that makes building new kernels easier.


emerge app-portage/eix app-portage/gentoolkit sys-apps/mlocate sys-kernel/genkernel

Pre-Update

Here we're going to synchronize repositories, update the search index, and read any news items.


emaint -a sync && eix-update && updatedb && eselect news list

eselect news list can be substituted with eselect news read to see all new items.

If there is an update to portage, you will see a message telling you to run the following command:


emerge -1 sys-apps/portage

Update

Once all repositories are synchronized, update the system by running the command:


emerge --update --deep --newuse --ask --verbose --keep-going @world

The short version of the above is emerge -auvND --keep-going @world. Below is a key explaining what the letters mean that are displayed to the left of the package that will be merged.

N new (not yet installed)
S new SLOT installation (side-by-side versions)
U updating (to another version)
D downgrading (best version seems lower)
r reinstall (forced for some reason, possibly due to slot or sub-slot)
R replacing (remerging same version)
F fetch restricted (must be manually downloaded)
f fetch restricted (already downloaded)
i interactive (requires user input)
B blocked by another package (unresolved conflict)
b blocked by another package (automatically resolved conflict)

Post-Update

When all the packages are updated you may see a message saying that you need to rebuild some dependencies. Most of the time running the following command will work. Other times you may need to use the equery command to figure out what packages need to be built again.


emerge @preserved-rebuild

We want to select the new kernel if there was one in the update.


eselect kernel list

Available kernel symlink targets:
  [1]   linux-5.4.80-gentoo-r1
  [2]   linux-5.4.92-gentoo
  [3]   linux-5.4.97-gentoo
  [4]   linux-5.10.27-gentoo
  [5]   linux-5.10.49-gentoo-r1
  [6]   linux-5.10.52-gentoo *
  [7]   linux-5.10.61-gentoo
  [8]   linux-5.10.76-gentoo-r1
  [9]   linux-5.15.11-gentoo
  [10]  linux-5.15.16-gentoo
  [11]  linux-5.15.23-gentoo 

eselect kernel set 11

Next we need to pull over the existing kernel configuration into the new source tree. There are several places you can get the configuration of the running kernel.


# From procfs, if **CONFIG_IKCONFIG_PROC** was set.
zcat /proc/config.gz > /usr/src/linux/.config

# The old kernel source tree, if CONFIG_IKCONFIG was set.
/usr/src/linux/scripts/extract-ikconfig /path/to/old/kernel > /usr/src/linux/.config

# /boot partition, if it was installed there.
cp /boot/config-($uname -r) /usr/src/linux/.config

# If using genkernel, and  `SAVE_CONFIG="yes"`  is set, then configurations are stored in /etc/kernels
cp /etc/kernels/kernel-config-$(uname -r) /usr/src/linux/.config

# The most reliable is in the source tree of the currently-running kernel.
cp /usr/src/linux-$(uname -r)/.config /usr/src/linux

Building the Kernel

There are two ways to build a new kernel. The first is the manual way, and the second is using genkernel. The second way is the one I use, and makes things a lot easier. The genkernel program comes with a lot of options, and it also comes with a configuration file located at /etc/genkernel.conf. Editing the configuration file to suit your needs will enable you to reduce the command down to this:


genkernel all

In my **/etc/genkernel.conf** file, I have the following options set, your may be different depending on what you have which equates to genkernel --no-mrproper --menuconfig --oldconfig --lvm --mdadm --luks --bootloader=grub2


# Run 'make oldconfig' before compiling this kernel
OLDCONFIG="yes"

# Run 'make mrproper' before compiling this kernel
MRPROPER="no"

# Mount BOOTDIR automatically if it isn't mounted
MOUNTBOOT="yes"

# Save the new configuration in /etc/kernels upon
# successful compilation
SAVE_CONFIG="yes"

# Enable color output in genkernel
NOCOLOR="false"

# Genkernel uses an independent configuration for MAKEOPTS, and does not source
# /etc/portage/make.conf . You can override the default setting by uncommenting
# and tweaking the following line. Default setting is set up by
# ${GK_SHARE}/${ARCH_OVERRIDE}/config.sh . The recommended value for -j
# argument is: *+1
MAKEOPTS="$(portageq envvar MAKEOPTS)"

# Add LVM support
LVM="yes"

# Add LUKS support
LUKS="yes"

# Add MDRAID support
MDADM="yes"

# Specify a custom mdadm.conf.
# By default the initramfs will be built *without* an mdadm.conf and will auto-detect
# arrays during bootup.  Usually, this should not be needed.
MDADM_CONFIG="/etc/mdadm.conf"

# Add new kernel to grub
# Possible values: empty/"no", "grub", "grub2"
BOOTLOADER="grub2"

# Run "emerge @module-rebuild" automatically when possible and necessary
# after kernel and modules have been compiled
MODULEREBUILD="yes"

Clean Up

If everything goes fine, you should be able to move on to the next step and clean up any unneeded packages.


emerge --depclean --pretend --verbose 

[...snip...]
>>> These are the packages that would be unmerged:

 dev-lang/spidermonkey
    selected: 78.15.0 
   protected: none 
     omitted: 91.11.0 

 sys-devel/clang-runtime
    selected: 13.0.0 
   protected: none 
     omitted: 14.0.6 

 media-libs/libopenaptx
    selected: 0.2.0 
   protected: none 
     omitted: none 

 sys-libs/db
    selected: 5.3.28-r8 
   protected: none 
     omitted: none 

 dev-python/python-slip
    selected: 0.6.5-r1 
   protected: none 
     omitted: none 

 dev-python/py
    selected: 1.10.0 
   protected: none 
     omitted: none 

Finally, rebuild dependency, update configuration files, update the file index for mlocate, clean up downloaded sources so the DISTDIR and PKGDIR, and look for any packages that are still hanging around when they shouldn't be.


revdep-rebuild -i && dispatach-conf && updatedb && eclean-dist --deep && eix-test-obsolete

Installed packages with a version not in the database (or masked):
[U] app-doc/xmltoman (0.4-r1@03/18/2021 -> 0.4-r2): Simple scripts for converting xml to groff or html
[U] app-portage/recover-broken-vdb (0.0.9@11/20/2021 -> 1.0.0-r1): Check Portage's VDB for internal inconsistency on ELF metadata
[?] dev-lang/vala (0.50.10(0.50)@01/30/2022 0.56.3(0.56)@09/22/2022 -> 0.56.3(0.56)^t): Compiler for the GObject type system
[?] dev-python/pyproject2setuppy (22-r1@02/11/2022 -> ??): Cheap setup.py hack to install flit & poetry-based projects
[?] gui-libs/libhandy (0.0.13(0.0/0)@12/30/2020 1.6.3(1)@08/08/2022 -> 1.6.3(1)^t): Building blocks for modern adaptive GNOME apps
[U] sys-apps/man-pages-posix (2017a@01/25/2021 -> 2017a-r1^b): POSIX man-pages (0p, 1p, 3p)
[U] sys-apps/xdg-desktop-portal-gtk (1.8.0@06/04/2021 -> 1.14.0): Backend implementation for xdg-desktop-portal using GTK+
[?] sys-kernel/gentoo-sources (5.4.80-r1(5.4.80-r1)@12/17/2020 5.4.92(5.4.92)@01/28/2021 5.4.97(5.4.97)@02/14/2021 5.10.27(5.10.27)@04/02/2021 5.10.49-r1(5.10.49-r1)@07/16/2021 5.10.52(5.10.52)@07/31/2021 5.10.61(5.10.61)@09/09/2021 5.10.76-r1(5.10.76-r1)@11/14/2021 5.15.11(5.15.11)@01/02/2022 5.15.16(5.15.16)@01/30/2022 5.15.23(5.15.23)@02/11/2022 5.15.26(5.15.26)@03/09/2022 5.15.41(5.15.41)@05/24/2022 5.15.52(5.15.52)@07/09/2022 5.15.59(5.15.59)@08/07/2022 5.15.69(5.15.69)@09/22/2022 -> 4.9.329(4.9.329)^bs 4.14.294(4.14.294)^bs 4.19.259(4.19.259)^bs 5.4.214(5.4.214)^bs 5.10.144(5.10.144)^bs 5.15.69(5.15.69)^bs): Full sources including the Gentoo patchset for the 5.19 kernel tree

Troubleshooting

Conflicts

As in life, there will be conflicts from time to time and each conflict is different. The following conflict says that I can't install dev-libs/icu-71.1-r1 (overlay, use flags, etc) because dev-libs/icu-70.1 is required by dev-lang/php-7.3.33.


(dev-libs/icu-71.1-r1:0/71.1::gentoo, ebuild scheduled for merge) USE="-debug -doc -examples -static-libs -test -verify-sig" ABI_X86="(64) -32 (-x32)" conflicts with
    dev-libs/icu:0/70.1= required by (dev-lang/php-7.3.33:7.3/7.3::gentoo, installed) USE="acl bcmath bzip2 cli ctype curl exif fileinfo filter flatfile fpm ftp gd gdbm hash iconv imap inifile intl ipv6 jit json mhash mssql mysql mysqli nls oci8-instant-client odbc opcache pcntl pdo phar posix postgres readline session simplexml spell sqlite ssl systemd tokenizer truetype unicode xml xmlreader xmlrpc xmlwriter zip zlib -apache2 -argon2 -berkdb -calendar -cdb -cgi -cjk -coverage -debug -embed -enchant -firebird -gmp -iodbc -kerberos -ldap -ldap-sasl -libedit -lmdb -phpdbg -qdbm -recode (-selinux) -session-mm -sharedmem -snmp -soap -sockets -sodium -sysvipc -test -threads -tidy -tokyocabinet -wddx -webp -xpm -xslt -zip-encryption" ABI_X86="(64)"
                ^^^^^^^^

In this case, because php-7.3.33 is no longer supported, to fix this, I would remove php-7.3.33 and try the update again.


emerge --depclean --verbose --ask dev-lang/php:7.3

preserved-rebuild

After a successful merge, you may see the following message. This is typically fixed by running emerge @preserved-rebuild.


!!! existing preserved libs:
>>> package: dev-libs/icu-71.1-r1
 *  - /usr/lib64/libicudata.so.70
 *  - /usr/lib64/libicudata.so.70.1
 *      used by /usr/lib64/libqalculate.so.22.15.0 (sci-libs/libqalculate-3.22.0)
 *  - /usr/lib64/libicui18n.so.70
 *  - /usr/lib64/libicui18n.so.70.1
 *      used by /usr/bin/js78 (dev-lang/spidermonkey-78.15.0)
 *      used by /usr/lib64/libmozjs-78.so.0.0.0 (dev-lang/spidermonkey-78.15.0)
 *      used by /usr/lib64/postgresql-13/bin/postgres (dev-db/postgresql-13.5-r1)
 *      used by /usr/sbin/xfs_scrub (sys-fs/xfsprogs-5.14.2)
 *  - /usr/lib64/libicuuc.so.70
 *  - /usr/lib64/libicuuc.so.70.1
 *      used by /usr/bin/js78 (dev-lang/spidermonkey-78.15.0)
 *      used by /usr/lib64/libmozjs-78.so.0.0.0 (dev-lang/spidermonkey-78.15.0)
 *      used by /usr/lib64/libqalculate.so.22.15.0 (sci-libs/libqalculate-3.22.0)
 *      used by /usr/lib64/postgresql-13/bin/postgres (dev-db/postgresql-13.5-r1)
 *      used by /usr/sbin/xfs_scrub (sys-fs/xfsprogs-5.14.2)
>>> package: dev-libs/libffi-3.4.2-r2
 *  - /usr/lib64/libffi.so.7
 *  - /usr/lib64/libffi.so.7.1.0
 *      used by /usr/lib/llvm/12/lib64/libLLVM-12.so (sys-devel/llvm-12.0.1)
 *      used by /usr/lib/llvm/13/lib64/libLLVM-13.so (sys-devel/llvm-13.0.1)
 *      used by /usr/lib/python3.7/lib-dynload/_ctypes.cpython-37m-x86_64-linux-gnu.so (dev-lang/python-3.7.10_p3)
 *      used by /usr/lib64/jffi-1.2/libjffi-1.3.so (dev-java/jffi-1.3.6)
 *      used by /usr/lib64/python2.7/lib-dynload/_ctypes.so (dev-lang/python-2.7.18_p13)
 *      used by /usr/lib64/ruby/gems/2.6.0/extensions/x86_64-linux/2.6.0/ffi-1.15.5/ffi_c.so (dev-ruby/ffi-1.15.5)
 *      used by /usr/lib64/ruby/gems/2.6.0/gems/ffi-1.15.5/lib/ffi_c.so (dev-ruby/ffi-1.15.5)
 *      used by /usr/lib64/ruby/gems/2.7.0/extensions/x86_64-linux/2.7.0/ffi-1.15.5/ffi_c.so (dev-ruby/ffi-1.15.5)
 *      used by /usr/lib64/ruby/gems/2.7.0/gems/ffi-1.15.5/lib/ffi_c.so (dev-ruby/ffi-1.15.5)
Use emerge @preserved-rebuild to rebuild packages using these libraries
emerge @preserved-rebuild

If running the emerge @preserved-rebuild doesn't do anything or there are still packages there, go through each package that is using the library and run emerge --depclean -av and get rid of the old out of date version. In this case dev-lang/python:2.7, sys-devel/llvm:12, dev-db/postgres-13.5-r1 and spidermonkey-78.15.0 were old versions that were no longer needed.

 

Some of the packages may have other dependencies but those packages aren't required by anything else so it's safe to remove them as well. Other times, there are packages that you simply don't need. Like in my case, I didn't need sys-fs/xfsprogs because I don't have kernel support for it and will never use that file system.

Emerge ALL the things!!!


emerge -eav @world

Error sync'ing repositories

There have been a handful of times where I had an issue with sync'ing a repository due to the head not pointing to a branch.


>>>
>>> Timestamps on the server and in the local repository are the same.
>>> Cancelling all further sync action. You are already up to date.
>>>
>>> In order to force sync, remove '/var/db/repos/gentoo/metadata/timestamp.chk'.
>>>

 * Manifest timestamp: 2022-09-25 05:09:59 UTC
 * Valid OpenPGP signature found:
 * - primary key: DCD05B71EAB94199527F44ACDB6B8C1F96D8BF6D
 * - subkey: E1D6ABB63BFCFB4BA02FDF1CEC590EEAC9189250
 * - timestamp: 2022-09-25 05:09:59 UTC
=== Sync completed for gentoo
>>> Syncing repository 'librewolf' into '/var/db/repos/librewolf'...
/var/db/repos/librewolf
/usr/bin/git fetch origin
Already up to date.
=== Sync completed for librewolf
>>> Syncing repository 'steam-overlay' into '/var/db/repos/steam-overlay'...
/var/db/repos/steam-overlay
/usr/bin/git fetch origin
Already up to date.
=== Sync completed for steam-overlay
>>> Syncing repository 'pf4public' into '/var/db/repos/pf4public'...
/var/db/repos/pf4public
fatal: HEAD does not point to a branch
!!! git rev-parse error in /var/db/repos/pf4public
>>> Syncing repository 'pentoo' into '/var/db/repos/pentoo'...
/var/db/repos/pentoo
/usr/bin/git fetch origin
Already up to date.
=== Sync completed for pentoo

 * IMPORTANT: config file '/etc/sudoers' needs updating.
 * See the CONFIGURATION FILES and CONFIGURATION FILES UPDATE TOOLS
 * sections of the emerge man page to learn how to update config files.

Action: sync for repo: gentoo, returned code = 0
Action: sync for repo: librewolf, returned code = 0
Action: sync for repo: steam-overlay, returned code = 0
Action: sync for repo: pf4public, returned code = 128
Action: sync for repo: pentoo, returned code = 0

eselect repository remove [ID]
eselect repository enable [ID]
emaint -a sync

TL;DR


emaint -a sync && eix-update && updatedb && eselect news list
emerge -1 sys-apps/portage
emerge --update --deep --newuse --ask --verbose --keep-going @world
emerge @preserved-rebuild
eselect kernel list [NUM]
zcat /proc/config.gz > /usr/src/linux/.config
genkernel all
emerge --depclean --ask --verbose
revdep-rebuild -i && dispatach-conf && updatedb && eclean-dist --deep && eix-test-obsolete