This post documents the steps I took to share the Portage instance one Gentoo machine across the other Gentoo machines I have using NFSv4. One machine syncs portage, all the other machines benefit. For purposes of this post, server will refer to the machine which holds and automatically sync portage for the local network, and client will refer to all of the other local Gentoo machines which will look to the server for Portage.

Portage Directory Settings

In order for this to work, the following settings will be made consistent across machines by setting in each Gentoo machines /etc/portage/make.conf file. Any older settings to the contrary need to be replaced or commented out. These are the directories the server will share via NFS to the other machines.

$ sudo vim /etc/portage/make.conf

# Portage Directories
PORTDIR="/var/db/repos/gentoo"
DISTDIR="/var/cache/distfiles"
PKGDIR="/var/cache/binpkgs"

Portage Server Setup

NFS will be the sharing mechanism I use to make Portage available over the network, so the first step will be to get it up and running on the server.

Enable NFS in Kernel on Server Hosting Portage

These are the kernel configuration settings I went with for the server. I am enabling NFS version 3 and $ support for both client and server. Only the server settings are needed on this machine to share Portage, but I will eventually be using this machine as an NFS client in the future, adding support to the kernel now. Settings below are for kernel 5.10.15.

Process Overview:

  1. Make kernel configuration changes needed to enable NFS server functions.
  2. Recompile kernel to apply the configuration changes.
  3. Update boot loader with new kernel.
  4. Reboot machine to load kernel.

Details on updating kernel on Gentoo can be found on the Gentoo Wiki

 File systems  --->
 [*] Network File Systems  --->
 --- Network File Systems
<M>   NFS client support
< >     NFS client support for NFS version 2
<M>     NFS client support for NFS version 3
[*]       NFS client support for the NFSv3 ACL protocol extension
<M>     NFS client support for NFS version 4
[ ]     Provide swap over NFS support
[*]   NFS client support for NFSv4.1
[*]     NFS client support for NFSv4.2
    (kernel.org) NFSv4.1 Implementation ID Domain
[ ]     NFSv4.1 client support for migration
[*]   Provide NFS client caching support
[ ]   Use the legacy NFS DNS resolver
[*]   NFS: Disable NFS UDP protocol support
[ ]   NFS: Enable support for the NFSv4.2 READ_PLUS operation
<M>   NFS server support
-*-     NFS server support for NFS version 3
[*]       NFS server support for the NFSv3 ACL protocol extension
[*]     NFS server support for NFS version 4
[*]   NFSv4.1 server support for pNFS block layouts
[*]   NFSv4.1 server support for pNFS SCSI layouts
[*]   NFSv4.1 server support for pNFS Flex File layouts
[*]   NFSv4.2 inter server to server COPY
[*]   Provide Security Label support for NFSv4 server    

The following steps should be were done after the server was rebooted using a kernel with NFS version 4 support.

Set Up Portage Export Using NFSv4

Install net-fs/nfs-utils package to make NFS client and server daemons available.

sudo emerge -a nfs-utils
...
>>> Recording net-fs/nfs-utils in "world" favorites file...
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

 * GNU info directory index is up-to-date.
 $
 

Create the directory structure to be used for exports from the server. In this cae, /export/gentoo, /export/distfiles, and /export/binpkgs is what NFS clients will mount form the server.

sudo mkdir -p /export/{gentoo,distfiles,binpkgs}

Bind actual directory I want to share to export mount point, in this case /var/db/repos/gentoo, /var/cache/distfiles, and /var/cache/binpkgs are what I will be sharing from the server.

$ sudo mount --bind /var/db/repos/gentoo /export/gentoo
$ sudo mount --bind /var/cache/distfiles /export/distfiles
$ sudo mount --bind /var/cache/binpkgs /export/binpkgs

Make the export mount happen automatically on boot by adding to existing /etc/fstab file.

$ sudo vim /etc/fstab

### NFS export bind mounts
/var/db/repos/gentoo    /export/gentoo          none    bind            0 0
/var/cache/distfiles    /export/distfiles      none    bind            0 0
/var/cache/binpkgs      /export/binpkgs         none    bind            0 0

Create or edit /etc/export to set access and other NFS options.

/export       192.168.1.0/24(rw,fsid=0,no_subtree_check,sync)
/export/portage 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

Enable and start nfs-server service using systemd.

$ sudo systemctl enable nfs-server
reated symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /lib/systemd/system/nfs-server.service.
$ sudo systemctl start nfs-server
$ sudo systemctl status nfs-server
● nfs-server.service - NFS server and services
     Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
      Active: active (exited) since Fri 2021-02-12 06:15:02 CST; 3s ago
      Process: 43672 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
      Process: 43673 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS)
     Main PID: 43673 (code=exited, status=0/SUCCESS)
         CPU: 6ms

 Feb 12 06:15:02 sparky systemd[1]: Starting NFS server and services...
 Feb 12 06:15:02 sparky exportfs[43672]: point 1
 Feb 12 06:15:02 sparky exportfs[43672]: point 2
 Feb 12 06:15:02 sparky exportfs[43672]: point 3
 Feb 12 06:15:02 sparky systemd[1]: Finished NFS server and services.

Confirm what is being exported by NFS on server is as expected before moving on to the client setup.

$ sudo showmount -e localhost
Export list for localhost:
/export/binpkgs   192.168.1.0/24
/export/distfiles 192.168.1.0/24
/export/gentoo    192.168.1.0/24
/export           192.168.1.0/24
$

Portage Client Set Up

Enable NFS in Kernel on Client

Like the server each client must have NFS support enabled in the kernel. My clients already have this enabled, but if they did not, I would add as I did above for the server, add to configuration, recompile kernel, add to boot loader and reboot. For clients only NFS client configuration settings matter, and I try to keep as much of the kernel configurations that make sense the same across machines. NFS settings are among the settings which make sense to me to keep the same across machines.

Install nfs-utils

As my clients already have NFS support, and use NFS for things other than Portage, it it no surprise that nfs-utils is already installed, but if it was not, I would install in the usual way emerge -a nfs-utils before making any changes to Portage on the machine.

Update Client fstab File to mount NFS Shares

In the below, 192.168.1.95 is the ip address of the server hosting portage and the NFS shares.

$ sudo vim /etc/fstab

# NFS mounts for shared Portage
192.168.1.95:/gentoo		/var/db/repos/gentoo    nfs4	 ro,hard 0 0
192.168.1.95:/distfiles		/var/cache/distfiles   	nfs4     rw,hard 0 0
192.168.1.95:/binpkgs		/var/cache/binpkgs     	nfs4     ro,hard 0 0

Replace Existing Portage Directories with NFS Shares

Next I backed up the existing portage directories on the client and then created new empty directories which will serve as the mount points to the Portage directories from the server.

$ sudo mv /var/db/repos/gentoo /var/db/repos/gentoo.backup
$ sudo mkdir /var/db/repos/gentoo
$ sudo mv /var/cache/distfiles /var/cache/distfiles.backup
$ sudo mkdir /var/cache/distfiles
$ sudo mv /var/cache/binpkgs /var/cache/binpkgs.backup
$ sudo mkdir /var/cache/binpkgs

Mount Portage NFS Shares from Server on Client

Below I mount each of the shares on the client manually. The changes to the fstab should handle this on reboot, but I want manual success first before I trust to automation. After mounting I list the mounts to make sure everything looks as I hoped.

$ sudo mount /var/db/repos/gentoo
$ sudo mount /var/cache/distfiles
$ sudo mount /var/cache/binpkgs

mount |grep 192.168.1.95
192.168.1.95:/gentoo on /var/db/repos/gentoo type nfs4 (ro,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.238,local_lock=none,addr=192.168.1.95)
192.168.1.95:/distfiles on /var/cache/distfiles type nfs4 (rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.238,local_lock=none,addr=192.168.1.95)
192.168.1.95:/binpkgs on /var/cache/binpkgs type nfs4 (ro,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.238,local_lock=none,addr=192.168.1.95)

Disable Portage Sync Mechanisms on Clients

For me this meant finding the cron setting which periodically synced Portage from the Internet. The server is set to update on a daily basis, so there is no longer a need for individual clients to also initiate a Portage sync.

Testing Clients

  1. Reboot client and confirm shares are mounted as expected. This worked as expected. After rebooting I again listed the mounts and found the NFS shares from the server attached as desired.
  2. Attempt to write file to each share. As root I was able to touch a file to /var/cache/distfiles but not to either /var/db/repos/gentoo or /var/cache/binpkgs. This was expected behavior as only /var/cache/distfiles is mounted as read write (rw), the other locations are mounted as read only.
  3. Update packages on client. This went well, the client fount updates that needed to be applied and did sow without errors as below.
$ sudo  emerge -DNuvta @world

 * IMPORTANT: 1 news items need reading for repository 'gentoo'.
 * Use eselect news read to view new items.


These are the packages that would be merged, in reverse order:


Calculating dependencies... done!
[ebuild  rR    ] dev-python/cryptography-3.3.2::gentoo  USE="-idna (-libressl) -test" PYTHON_TARGETS="python3_7 python3_8 -pypy3 -python3_9" 0 KiB
[ebuild  r  U  ]  dev-python/cffi-1.14.5:0/1.14.5::gentoo [1.14.4:0/1.14.4::gentoo] USE="-doc -test" PYTHON_TARGETS="python3_7 python3_8 -python3_9" 464 KiB
[ebuild     U  ] sys-apps/util-linux-2.36.2::gentoo [2.36.1-r1::gentoo] USE="cramfs logger ncurses nls pam readline (split-usr) static-libs suid systemd udev (unicode) -audit -build -caps -cryptsetup -fdformat -hardlink -kill -python (-selinux) -slang -su -test -tty-helpers" ABI_X86="(64) -32 (-x32)" PYTHON_TARGETS="python3_7 python3_8 -python3_9" 5,223 KiB

Total: 3 packages (2 upgrades, 1 reinstall), Size of downloads: 5,687 KiB

The following packages are causing rebuilds:

  (dev-python/cffi-1.14.5:0/1.14.5::gentoo, ebuild scheduled for merge) causes rebuilds for:
    (dev-python/cryptography-3.3.2:0/0::gentoo, ebuild scheduled for merge)

Would you like to merge these packages? [Yes/No] yes

>>> Verifying ebuild manifests

>>> Emerging (1 of 3) sys-apps/util-linux-2.36.2::gentoo
 * Fetching files in the background.
 * To view fetch progress, run in another terminal:
 * tail -f /var/log/emerge-fetch.log
 * util-linux-2.36.2.tar.xz BLAKE2B SHA512 size ;-) ...                                 [ ok ]
...
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

 * GNU info directory index is up-to-date.

 * IMPORTANT: 1 news items need reading for repository 'gentoo'.
 * Use eselect news read to view new items.

 * After world updates, it is important to remove obsolete packages with
 * emerge --depclean. Refer to `man emerge` for more information.
  1. Update packages on multiple clients at same time. This seems to work fine too. I updated server and two clients at the same with no issues. Everything seems in order and working properly.

Conclusion

Everything seems to have gone according to plan. Updates are working across all machines, though only the server is syncing with portage. In a few days I will go through all the clients and delete the backup directories which were created. As a side benefit of this effort, all my Gentoo boxes now have much more consistent Portage configurations regardless of when they were first built.

References: