RaspberryPi5
This page has my notes on fiddling with the Raspberry Pi 5. The RaspberryPi3 wiki page has notes on the older Raspberry Pi 3.
References
General information
Download links
- Raspberry Pi Imager, used to write the Micro SD card.
Glossary
- FFC
- Flat Flexible Cable. Refers to any variety of electrical cable that is both flat and flexible, with flat solid conductors. In the context of this page, the FFC cable used is the one that connects the NVMe HAT with the Raspberry Pi 5 board.
- GPIO
- General-purpose input/output. Wikipedia link. The Raspberry Pi has a 40 pin GPIO connection where hardware extension can be plugged in.
- HAT
- Hardware Attached on Top. An expansion board format for the Raspberry Pi.
- NVM
- Non-volatile memory. This is often NAND flash memory that comes in several physical form factors, including solid-state drives (SSDs), PCIe add-in cards, and M.2 cards, the successor to mSATA cards.
- NVMe
- NVM Express. Wikipedia link. An open, logical-device interface specification for accessing a computer's non-volatile storage media usually attached via the PCI Express bus. NVM Express, as a logical-device interface, has been designed to capitalize on the low latency and internal parallelism of solid-state storage devices.[1]
- PCI
- Peripheral Component Interconnect.
- PCIe
- PCI Express. Wikipedia link. A high-speed standard used to connect hardware components inside computers. It is designed to replace older expansion bus standards such as PCI, PCI-X and AGP. PCIe is commonly used to connect graphics cards, sound cards, Wi-Fi and Ethernet adapters, and storage devices such as solid-state drives and hard disk drives. Allows devices to be added or removed while the computer is running (hot swapping). PCIe connections are made through lanes, which are pairs of conductors that send and receive data.
- Pi
- Short for Raspberry Pi.
- Raspberry Pi Imager
- Utility that is used to download an OS image and write it onto the Micro SD card so that the Raspberry Pi can boot from it. For the Raspberry Pi 3 this used to be NOOBS (New Out Of the Box Software).
- Raspberry Pi OS
- A Debian-based operating system for the Raspberry Pi. For the Raspberry Pi 3 this used to be Raspbian.
Hardware
Parts
- Raspberry Pi 5 with 16 GB memory
- digitec.ch link
- Manufacturer number = SC1113
- CPU = Cortex-A76, 4 cores, 2400 MHz
- USB-A 2.0 (2x), USB-A 3.0 (2x)
- HDMI (2x)
- Raspberry Pi 5 official power supply
- digitec.ch link
- Manufacturer number = SC1157
- 27W
- USB-C
- 1.2m cable
- Micro SD Card 64 GB
- digitec.ch link
- Manufacturer number = SC1629
- Class 10
- Waveshare fan + heat sink
- Manufacturer product title = Active Cooler (B) for Raspberry Pi 5, Active Cooling Fan, Aluminium Heatsink, With Thermal Pads
- The "(B)" part distinguishes this product from other, similar products
- digitec.ch link
- Waveshare product page
- SKU = 26412
- Part number = Pi5-Active-Cooler-B
- Input voltage = 5V DC
- Manufacturer product title = Active Cooler (B) for Raspberry Pi 5, Active Cooling Fan, Aluminium Heatsink, With Thermal Pads
- Waveshare NVMe SSD Adapter HAT
- Manufacturer product title = PCIe To 2-Ch M.2 Adapter Type B for Raspberry Pi 5, Compatible with 2280 / 2260 / 2242 / 2230 size NVMe Protocol M.2 SSD, Raspberry Pi 5 NVMe HAT
- The "(B)" part distinguishes this product from other, similar products
- digitec.ch link
- Waveshare product page
- Waveshare wiki page
- SKU = 27710
- Part number = PCIe TO 2-CH M.2 HAT+ (B)
- Supports 2 NVMe SSDs
- Supports NVMe sizes 2230, 2242, 2260, 2280
- Manufacturer product title = PCIe To 2-Ch M.2 Adapter Type B for Raspberry Pi 5, Compatible with 2280 / 2260 / 2242 / 2230 size NVMe Protocol M.2 SSD, Raspberry Pi 5 NVMe HAT
- NVMe SSD
- Manufacturer product title = Crucial P310 4TB PCIe Gen4 NVMe 2280 M.2 SSD
- digitec.ch link
- Crucial product page
- Manufacturer number = CT4000P310SSD8
- 4 TB
- No heatsink
- Format = 2280
- Case
- Manufacturer product title = Industrial Grade Metal Case (D) for Raspberry Pi 5, Larger Internal Space, Supports Installing Official Cooling Fan And Various HATs, Wall-mount and Rail-mount Support
- digitec.ch link
- The "(D)" part distinguishes this product from other, similar products
- Waveshare product page
- SKU = 26087
- Part number = PI5-CASE-D
- Supports installing a Raspberry Pi 5 with a HAT
Assembly order
- Write OS onto Micro SD card
- Remove plastic covers from NVMe HAT screw holes
- Add fan / heatsink to Pi board
- Unplug FFC cable from NVMe HAT (remember how it was plugged in), then plug it into the Pi board
- Add GPIO extender to Pi board
- Add standups to Pi board
- Add NVMe HAT to Pi board
- Plug FFC cable into NVMe HAT
- Add NVMe to NVMe HAT
- Screw NVMe HAT onto standups
- Add Micro SD card to Pi board
- Add Pi board into case
- Connect Pi to power and ethernet (unless WiFi is used)
Write OS onto Micro SD card
- Insert the Micro SD card into one of the Transcend adapters
- Plug the adapter into the MacBook => it shows up formatted as ExFat
- Download and install Raspberry Pi Imager (https://www.raspberrypi.com/software/)
- Launch Raspberry Pi Imager, select the Micro SD card disk, then walk through the setup process
- Raspberry Pi OS (64-bit) = > A variant of Debian Trixie
- The further steps are: Set a hostname, select localisation options, set up an initial user account "pi", configure the WLAN name + password, activate SSH (including selecting an SSH public key).
- The final step is setting up Raspberry Pi Connect. I declined to use this service.
- Start the write process => requires a macOS admin password
- Once the process is finished, the card can be removed and inserted into the Raspberry Pi 5.
Remove plastic covers from NVMe HAT screw holes
All 8 screw holes on the Waveshare NVMe HAT were covered with an orange plastic lid. These must be removed so that an NVMe module can be fastened onto the NVMe HAT.
I have been unable to remove the lids from the top - I'm not sure if they were slightly glued to the HAT, or what other mechanism held them in place. Lacking any more elegant methods, my solution was to tighten a screw into each screw hole from below, forcing the orange plastic lid away.
To be able to do this, the HAT must not be fastened yet to the Pi board, so that the underside of the HAT can still be accessed. I noticed the organge plastic lids only at the very end after I had already fastened the HAT to the Pi board. Being unable to remove the lids from above, I had to remove the HAT again from Pi board, which was very difficult because this included sliding the HAT off the 40 pins of the GPIO extender. This required "see-sawing" in reverse, combined with quite a bit of force, but in a very controlled way so as not to twist or bend the GPIO extender's 40 pins at the moment when the HAT comes off. I would rather not repeat this process, so the best thing is to remove the orange plastic lids right at the beginning.
Add fan / heatsink to Pi board
Thermal paste or no thermal paste?
A comment on digitec.ch said to add thermal paste because "the thermal pads are relatively thick". After searching the net a bit, I decided against using thermal paste so as not to interfere with the design of the thermal pads.
Thermal pad placement
In preparation, to be able to follow the discussion, place the Pi board so that the USB and ethernet ports point to the right.
The chips on the Pi board have different sizes and different heights. It is important to place the thermal pads onto the correct chips. The problem is: Which ones are the correct chips? Depending on the source you're looking at, there are many different opinions.
Facts
- There are three thermal pads.
- One of them is larger than the other two.
- The larger pad is noticeably thinner than the other two.
- The other two have the same size and thickness.
Ideas where to place the thermal pads
- The official Waveshare product page (link see further up on this page) has an illustration that shows that the large/thin pad is placed onto the CPU in the Pi board's center, and the two smaller/thicker pads are placed on the black chip in the top center position (someone said this is the RAM chip), and on the black chip in the top right position (the I/O controller).
- Most of the other videos I saw show the official Raspberry fan/heatsink where the 3-4 thermal pads are already glued to the underside of the heatsink in the presumably correct positions. Here the chips covered are the top-left chip (WiFi), bottom-left (Power Management Integrated Circuit) and the CPU. In one video there was a 4th thermal pad that covered the top-right chip (I/O controller).
- The very first video I saw said that the 3 black chips (bottom-left, top-center and top-right) should be covered, because they are less high, whereas the two silver chips (top-left and Pi board center) will then be in direct contact with the heatsink metal plate.
- Many comments I read say that that the RAM chip does not heat up enough to need cooling. Adding a thermal pad to it might even conduct heat from the CPU to the RAM chip which might negatively affect the chip's performance.
Conclusion: As I have no real clue about these things, after two hours of deliberation I finally decided to go with the instructions from the Waveshare product page.
Procedure
- In the top right position of the board, behind the top USB port there is a small socket providing power and control for the fan. The socket is protected with a small white/beige plastic cover. Remove that cover while it is still easily accessible.
- For each thermal pad
- Remove the plastic film from one side of the pad
- Place the pad onto the chip
- Remove the plastic film from the other side of the pad
- Place the fan / heat sink onto the Pi board so that it touches the thermal pads. The fan / heat sink orientation should be so that the cooling fins point to the left and the cable is on the right.
- Place the fan / heat sink so that it matches the two holes on the Pi board.
- Press the "spring-loaded pins" down into the holes until they click.
- Insert the cable into the socket on the Pi board. The yellow cable needs to be closest to the top edge of the Pi board.
Unplug FFC cable from NVMe HAT (remember how it was plugged in), then plug it into the Pi board
On unboxing the NVMe HAT, I found the FFC cable to be already plugged into the NVMe HAT. I left it like that, thinking to plug the cable into the Pi board later after the NVMe HAT was mounted. This was a mistake! Once the HAT is mounted, vertical access to the socket on the Pi board is mostly obstructed, making it extremely difficult to plug the cable in. I managed to do so, but only with the help of pliers and a lot of time.
Therefore: Unplug the FFC cable from the NVMe HAT and plug it into the Pi board now. The cable can then be plugged back into the NVMe HAT later once the HAT is mounted.
Important: Make sure to plug the cable in the right way. The cable must be turned so that the labels printed on it are on top. The cable also has a white arrow on both sides. At the site of the socket on the Pi board, the arrow must be on the side of the ethernet port. See also the illustration on the product page (linked further up on this wiki page).
Procedure:
- Open the lock at the socket
- Remove/insert the cable
- Close the lock at the socket
Pliers are very useful for handling the FFC cable.
Add GPIO extender to Pi board
- Make sure that the 40 pins of the GPIO extender are all straight. In my case, some of the pins were bent and I had to straighten them.
- Place the GPIO extender on top of the 40 pins of the GPIO connection on the Pi board.
- Slowly press down, first on the one side, then on the other, sliding the extender slowly down over the pins bit by bit in a kind of "see-saw" motion.
- Removing the GPIO extender again is at least very difficult. Personally I couldn't manage it, because I didn't dare pulling as hard on the extender as would have been necessary, for fear of damaging the Pi board.
Add standups to Pi board
The Pi board has 4 holes. For each hole, take a standoff that ends in a screw (from the case materials), insert the screw from the bottom into the hole, then put a regular standup (either from the case materials or the NVMe HAT materials) on it from the top. Tighten the screw until everything is fixed in place.
Why a standoff that ends in a screw, and not just a regular screw from the NVMe HAT materials? Because at the end the Pi board needs to be mounted inside the case.
Add NVMe HAT to Pi board
- Place the NVMe HAT so that the 40 pins of the GPIO extender are aligned with the corresponding 40 holes on the NVMe HAT.
- Managing to get all 40 pins aligned can be quite difficult and needs some trial and error. A well-lit workplace is very helpful.
- Once the alignment is good, slide the NVMe HAT down over the 40 pins in slow "see-saw" motions - first a bit on the left, then a bit on the right, etc. - until the HAT sits flush on the bottom of the GPIO extender.
- Removing the HAT again is possible, but a delicate operation, because it requires reverse "see-sawing" motions combined with force, but not so much force as to bend any of the GPIO extender's 40 pins.
Plug FFC cable into NVMe HAT
Now that the NVMe HAT is mounted, the FFC cable can be plugged into the HAT again. See the previous section for notes.
Add NVMe to NVMe HAT
- Plug the NVMe into the HAT at an angle (in a video I saw someone mentioned a 40° angle) until it clicks into position.
- Press the NVMe down and screw it into position.
Screw NVMe HAT onto standups
Now that the NVMe HAT is ready, it can be screwed fast onto the standups.
Add Micro SD card to Pi board
- The slot for the Micro SD card is below the Pi board.
- Insert the card into the slot, with the card pins facing upwards in the direction of the Pi board.
Add Pi board into case
- First take the plastic button cap from the case materials and place it into the appropriate holes on the case, so that the on/off button of the Pi can later be pressed from outside the case.
- Next, place the Pi board inside the case so that the 4 standoffs (see Add standups to Pi board) are located above the corresponding 4 holes in the case bottom. Screw it semi-fast.
- Close the case and screw it shut. Test that the plastic button cap activates the Pi's on/off button.
- Finally, tighten the screws at the case bottom so that the Pi board is fixed in place.
Connect Pi to power and ethernet (unless WiFi is used)
I'm using a wired network to connect the Pi to the household network, so insert the ethernet cable to achieve that. On first boot, the Pi will be also connected via WiFi, but that can be disabled later on.
Finally, connect the Pi to the power supply. The Raspberry Pi immediately boots now.
Installing the operating system
Unlike the Raspberry Pi 3, there is no separate OS installation phase where NOOBs boostraps and then installs the OS. For the Raspberry Pi 5 you write the OS (Raspberry Pi OS) directly onto the Micro SD card and then boot from that.
General Raspbian configuration
The physical console
TODO Find out how this works for the Raspberry Pi 5. Cf. the notes on the Raspberry Pi 3 page.
etckeeper
I like to install the package etckeeper to have the content of /etc versioned.
Once installed, initialize the versioning by running
sudo etckeeper init
To commit pending changes:
sudo etckeeper commit "message"
Use the "vcs" subcommand to invoke the VCS of your choice (default is git) with the given command. Examples:
# Equivalent to "git log" sudo etckeeper vcs log # Equivalent to "git status" sudo etckeeper vcs status
'Note: The etckeeper package installs a daily cron routine (/etc/cron.daily/etckeeper) that performs an auto-commit of all pending changes.
Change keyboard layout
The initial keyboard layout is set up with Raspberry Pi Imager. To later change the layout, run
sudo raspi-config
From the interactive menu select "Localisation Options" followed by "Keyboard". The tool then automatically selects the keyboard layout that matches your keyboard.
Timezone
Run
sudo raspi-config
From the interactive menu select "Localisation Options" followed by "Timezone". You can then select the correct timezone.
Root access
Raspberry Pi OS is configured to disallow root login. Instead the idea is to use sudo.
The initial user that was set up with Raspberry Pi Imager is a sudoer who is allowed to run all commands as root, even su root.
System name
The initial system name is set up with Raspberry Pi Imager. To change the system name, run
sudo raspi-config
From the interactive menu select "System Options" followed by "Hostname".
I have not tried, but assume that this change will take effect only when you reboot the system. To also change the name in the current session, run this command
sudo hostname <new name>
SSH access
The initial SSH setup is done with Raspberry Pi Imager, i.e. whether to enable or disable SSH, and whether to use an SSH key. If anything needs to be changed, consult the OpenSSH wiki page.
I have not tried this out, but apparently SSH can be enabled or disabled using
sudo raspi-config
Disable default login upon boot
As mentioned above, the Pi auto-logins both on console 1 and on the GUI console after a boot. To disable this, run
sudo raspbi-config
then select "System options" followed by "Auto Login". Here you can define the desired login options.
Disable WiFi and Bluetooth
To permanently disable WiFi and Bluetooth on the firmware level, edit the file /boot/firmware/config.txt and add the following lines somewhere near the top, before the first section ([section-name]) appears. Reboot afterwards.
dtoverlay=disable-wifi dtoverlay=disable-bt
To only temporarily disable WiFi and Bluetooth, the rfkill tool might be useful. There are also many other ways, not documented here.
The rfkill tool can be used to show whether WiFi and/or Bluetooth are active. Example with output showing that WiFi and Bluetooth are enabled and active:
$ rfkill list 0: hci0: Bluetooth Soft blocked: no Hard blocked: no 1: phy0: Wireless LAN Soft blocked: no Hard blocked: no
Note: If WiFi and/or Bluetooth are disabled on the firmware level, then the rfkill tool does not see them and the corresponding section will not appear in its output. If both are disabled on the firmware level, the rfkill output is empty.
Install the HTB
Follow instructons on the wiki page HTB to install the HTB (herzbube's toolbox).
Switch to vim
vim-tiny is already installed, but I like the benefit of directly opening .gz files with vi, so I install the Debian package
vim
Now run the following interactive command to switch the default text editor from nano to vim:
sudo update-alternatives --config editor
btrfs support
For several years I have used btrfs on the Raspberry Pi 3 on several external USB disks that were attached to the Pi. I will therefore continue to use it also on the Raspberry Pi 5. Unlike the default filesystem ext4, some things still have to be configured for btrfs.
First, load the btrfs kernel module:
sudo modprobe btrfs
Next, install the user-space utilities that allow us to create or otherwise handle a btrfs file system
btrfs-progs
Enable VNC
Info in this section taken from the official Raspberry Pi documentation.
Run
sudo raspbi-config
then select "Interface options" followed by "VNC". Choose "Yes" to enable VNC (or "No" to disable it). It may be necessary to reboot after enabling VNC, but I'm not sure.
Raspberry Pi documentation recommends to use TigerVNC as the client.
- Website
- GitHub releases for downloading the latest release (at the time of writing binaries were hosted on SourceForge, the release page on GitHub merely contained a link).
You can use both hostname and IP address to connect. Upon connecting, TigerVNC will moan about certificate issues (""Hostname does not match the server certificate" and "certificate has been signed by an unknown authority") because the Pi uses a self-signed certificate. You'll have to accept the warnings to proceed. Also note that when I tried connecting the first time after enabling VNC on the Pi, TigerVNC was unable to connect. After several retries and a reboot, it suddenly started to work, so I guess rebooting the Pi is necessary.
Note: I also tried connecting with the VNC client built into macOS (Finder > Go > Connect to server > vnc://hostname-or-ip-address), but this did not work (not even after a reboot).
Integration into household network
This is as simple as attaching the Raspberry Pi 5 to the household LAN. The Fritz!Box, which acts as the DHCP server in the network, automatically assigns an IP address to the Pi, and makes it accessible under its configured hostname, which is
raspberrypi5
Note: I prefer to integrate the Pi via wired ethernet, so any data transfers it currently performs for backup purposes do not take away resources from the wireless network. Because of that I have permanently disabled WiFi on the firmware level. See section Disable WiFi and Bluetooth.
Migrating data from Raspberry Pi 3
Attach disks to new Raspberry Pi 5
- Unmount all disks on the Raspberry Pi 3, disable Samba, then unplug the USB hub from the Raspberry Pi 3.
- Plug the USB hub into the Raspberry Pi 5, using one of the USB 3.0 ports (blue color code).
Run blkid to verify that the Raspberry Pi 5 sees the disks. Note that in the following output the NVMe SSD disk is already present because I had already created it.
pi@raspberrypi5:~ $ sudo blkid /dev/nvme0n1: UUID="d1e61ef1-51ce-4093-9a04-c20f2f8c3cd4" UUID_SUB="0a7a67cf-ac11-4dec-aabf-40fa87180e00" BLOCK_SIZE="4096" TYPE="btrfs" /dev/mmcblk0p1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="BFD4-9C30" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="41423b67-01" /dev/mmcblk0p2: LABEL="rootfs" UUID="8abab6b9-ef90-4fee-ae3d-91079bfae7c1" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="41423b67-02" /dev/sdb1: UUID="a8866988-112d-4fd4-af87-9e87db223093" UUID_SUB="c8d80b0c-f436-4225-bea9-9af1240d2566" BLOCK_SIZE="4096" TYPE="btrfs" PARTUUID="0005f107-01" /dev/loop0: LABEL="origin:rpi-swap" TYPE="swap" /dev/sdc1: UUID="1e2774a2-b255-4068-8ff8-bef397ae8fd1" UUID_SUB="444c5724-799c-43e0-bff8-030427242089" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="My Passport" PARTUUID="3482f387-2dd0-49ae-832a-218e846c0a98" /dev/sda1: UUID="ea7c7255-930a-496a-a80a-bc7282252b51" UUID_SUB="26200238-500e-4756-9b6d-d29e1c586345" BLOCK_SIZE="4096" TYPE="btrfs" PARTUUID="1d9bcdc0-01" /dev/zram0: LABEL="zram0" UUID="d36fe913-1c64-43d1-afb3-e9e1269a2821" TYPE="swap"
Take over entries from /etc/fstab on the Raspberry Pi 3. Verify that the UUIDs used match the ones printed by blkid (see previous command):
UUID=1e2774a2-b255-4068-8ff8-bef397ae8fd1 /mnt/fileserver-old btrfs defaults 0 2 UUID=ea7c7255-930a-496a-a80a-bc7282252b51 /mnt/backup-copy btrfs defaults 0 2 UUID=a8866988-112d-4fd4-af87-9e87db223093 /mnt/backup-snapshot btrfs defaults 0 2 UUID=6d936965-cfb0-4858-b001-ea104007c5c2 /mnt/encrypted-backup btrfs defaults,noauto 0 2 UUID=7f0c83bc-3c47-4734-8cc8-17cdf3a4b6c6 /mnt/backup-mirror btrfs defaults,noauto 0 2
Note: The filesystem to be mounted on /mnt/fileserver-old will eventually be deleted - or the mount point renamed - because the data on that disk will be moved to the NVMe SSD disk.
Space cache version problem
The btrfs filesystems that were created with the old Raspberry Pi 3 use the "space cache v1", which is deprecated with the newer version of btrfs that is present on the Raspberry Pi 5. The symptom is that such a filesystem cannot be mounted:
pi@raspberrypi5:~ $ sudo mount /mnt/fileserver-old
mount: /mnt/fileserver-old: wrong fs type, bad option, bad superblock on /dev/sdc1, missing codepage or helper program, or other error.
dmesg(1) may have more information after failed mount system call.
Invoking dmesg as suggested by the output reveals the actual issue:
[ 19.531558] BTRFS: device fsid 1e2774a2-b255-4068-8ff8-bef397ae8fd1 devid 1 transid 72809 /dev/sdc1 (8:33) scanned by pool-0 (821) [ 19.532499] BTRFS info (device sdc1): first mount of filesystem 1e2774a2-b255-4068-8ff8-bef397ae8fd1 [ 19.532518] BTRFS info (device sdc1): using crc32c (crc32c-lib) checksum algorithm [ 19.532529] BTRFS warning (device sdc1): space cache v1 is being deprecated and will be removed in a future release, please use -o space_cache=v2 [ 19.532533] BTRFS warning (device sdc1): v1 space cache is not supported for page size 16384 with sectorsize 4096
The properties of the unmounted filesystem can be inspected with the following command. The space cache version is probably hidden somewhere in the output, although I was unable to find it at first glance.
sudo btrfs inspect-internal dump-super /dev/sdc1
More useful is the following command, which allows you to mount the filesystem in read-only mode and without space cache, to verify that the filesystem is still operative:
sudo mount -o ro,nospace_cache /mnt/fileserver-old
The actual solution is to clear the old v1 space cache and instead mount the filesystem with the new v2 space cache:
sudo mount -o clear_cache,space_cache=v2 /mnt/fileserver-old
Once this is done, the filesystem can be unmounted and re-mounted without any options - from now on the new v2 space cache is used by default:
sudo mount /mnt/fileserver-old
Fileserver configuration
Prepare a hard disk
Instructions in this section apply whenever a new hard disk needs to be set up. This can be an external USB hard disk, or an NVMe SSD.
First connect the disk to the Pi. Check that the Pi is seeing the block device:
$ lsblk [...] nvme0n1 259:0 0 3.6T 0 disk
Next, format it for btrfs like this:
sudo mkfs.btrfs -f /dev/nvme0n1
This should output the new filesystem's UUID, but if it does not you can run blkid to find out the UUID:
$ sudo blkid [...] /dev/nvme0n1: UUID="d1e61ef1-51ce-4093-9a04-c20f2f8c3cd4" UUID_SUB="0a7a67cf-ac11-4dec-aabf-40fa87180e00" BLOCK_SIZE="4096" TYPE="btrfs"
Add an entry to /etc/fstab:
UUID=d1e61ef1-51ce-4093-9a04-c20f2f8c3cd4 /mnt/fileserver btrfs defaults 0 2
Update systemd to pick up the changed /etc/fstab:
sudo systemctl daemon-reload
Finally, create the mount point for the file system, then mount it:
sudo mkdir /mnt/fileserver sudo mount /mnt/fileserver
Prepare filesystem for "Scan to Network Folder" function
The household's current HP printer has a "Scan to Network Folder" function that allows the printer to place scanned documents into a predefined network folder. In this step we create the filesystem infrastructure that is necessary for this to work.
First, we need the actual filesystem folder that will receive the documents:
mkdir -p /mnt/fileserver/daten/Temp/scanning
Next we create a symlink to this folder that we can then use to set up a Samba network share with non-privileged access:
ln -s /mnt/fileserver/daten/Temp/scanning /mnt/fileserver/scanning
Last but not least, because several unrelated users need to have write access to this folder, we need to make it world-writable:
chmod 777 /mnt/fileserver/daten/Temp/scanning
Note: To set up the "Scan to Network Folder" function, use the printer's web interface. Also see the Printing wiki page.
Install samba
Install the package
samba
to install the Samba file server daemon. See the Samba wiki page for details on how to configure Samba.
Here are my changes to the default configuration in /etc/samba/smb.conf:
[global] # Don't sync because I want the system user "pi" to have a different # password than the Samba user "pi". The Samba user's password is much # simpler. unix password sync = no [daten] comment = Haushalt Daten path = /mnt/fileserver/daten read only = no browseable = yes create mask = 0700 directory mask = 0700 valid users = pi [alles-andere] comment = Alle anderen Daten path = /mnt/fileserver/alles-andere read only = no browseable = yes create mask = 0700 directory mask = 0700 valid users = pi # We don't want the scanner device to be able to access the entire fileserver # share - there are too many sensitive documents on it! If the printer # device is compromised in a currently unforeseen attack, then we want to # limit the attacker to a fileserver area that is as small as possible. This # is the rationale behind this separate "scanning" network share. # In order to make the limitation effective, we must of course also have a # separate user (piscanner) that the printer device can use, but which has # access only to the "scanning" network share. The regular "pi" user is # trusted, so it can have access as well. [scanning] comment = Scanning Daten path = /mnt/fileserver/scanning read only = no browseable = yes create mask = 0666 directory mask = 0777 valid users = pi, piscanner
Notes:
- Not visible above: I have commented out all other shares
Create system user for scanner device (otherwise we won't be able to create a Samba user), but prevent it from logging in on the console. The commands used here are documented slightly better on the BasicSystemConfiguration wiki page.
sudo adduser piscanner sudo passwd -l piscanner
Finally, add Samba users:
sudo smbpasswd -a pi sudo smbpasswd -a piscanner
Notes:
- The Samba service must be running or the command will fail
- Each user you create must correspond to an existing system user or the command will fail
Backup jobs
Summary
The Raspberry Pi is an integral part of my backup solution. It does the following things:
- Create an off-site copy of the hosting provider data set that is created every night on various hosting provider machines
- Create a copy of some data sets that are stored on the intranet file server
- Create snapshots of these copied data sets using a time-machine like tool
The following sections document how the system needs to be configured for this to work:
- Connect 2 external USB hard disk drives to the Pi
- Install a few Debian packages to provide the necessary software
- Configure a cron job that runs the shell scripts that perform the two jobs
Prepare 2 hard disks
Connect 2 external USB hard disks to the Pi, then proceed to make them available in the system in the same way as outlined above in the "Fileserver" section. When everything is ready the hard disks appear something like this:
pi@raspberrypi1:~$ df -h Filesystem Size Used Avail Use% Mounted on [...] /dev/sda1 1.9T 2.0G 1.9T 1% /mnt/backup-copy /dev/sdc1 1.9T 17M 1.9T 1% /mnt/backup-snapshot
Install keychain
Install the Debian package
keychain
This is necessary so that automated cron scripts can use RSA/DSA authentication for passwordless logins to remote servers. See the OpenSSH wiki page for details.
Note: Since I have abandoned my dedicated server project this is, strictly speaking, no longer necessary, because currently none of my hosting providers allows passwordless login. I keep this section, though, in case I may need it again in the future.
bup
Although Raspbian includes a Debian package for bup, at the time of writing the package is severely out of date: Version 0.25-1 which is from December 2013 vs. the most recent release 0.28.1 which is from June 2016. In the last few versions bup has made important advances that I do not want to do without, because of that a manual build of an up-to-date clone of the bup repository is necessary.
As user pi run these commands:
# Install build dependencies. An up-to-date list of packages can be found in # the README of the GitHub repository. sudo apt-get install python2.7-dev python-fuse python-pyxattr python-pylibacl linux-libc-dev acl attr python-tornado # Optional, with this present the make process will create man pages apt-get install pandoc # Optional, this is used for writing parity information so that bup # may be able to recover from some amount of repository corruption: apt-get install par2 # Get the sources mkdir ~/build cd ~/build git clone https://github.com/bup/bup.git # Build, test and install cd bup make make test sudo make install DESTDIR=/usr/local PREFIX=''
Note: Two of the tests fail, but this is not an error. The reason is that the tests erroneously try to run bup restore on a repository with an absolute instead of a relative path. Of course, the repositories which the tests expect to exist in the root directory of the system do not exist there.
cron configuration
The cron configuration snippet that runs the scripts is located here:
/etc/cron.d/backup-scripts
And this is the content:
pi@raspberrypi1:~/bin$ cat /etc/cron.d/backup-scripts # /usr/local/htb/bin is required to find HTB scripts # On Raspberry Pi 3 /usr/local/bin was required to find bup. # On Raspberry Pi 5 the system-provided bup is found in /usr/bin PATH=/usr/local/htb/sbin:/usr/local/htb/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # ---------------------------------------------------------------------- # Create copies of data sets # ---------------------------------------------------------------------- # Run at 03:00 am every Monday and Thursday. # The on-site backup job runs at 01:00 am every day, but # that's irrelevant because we don't copy the data produced # by that job. Instead we copy the data after logrotate has # run. logrotate runs at 06:25 am. This means that we are # actually copying the data from the previous night. # # Note: Currently disabled because no dedicated server is in use. #00 3 * * 1,4 pi /usr/local/htb/bin/htb-mkbackupcopy.sh -i "*.1" -i "*/" -e "*" root@pelargir.herzbube.ch:/var/backups/ /mnt/backup-copy/backupcopy.pelargir/ >>/mnt/backup-copy/backupcopy.pelargir.log 2>&1 # Run at 03:00 am every Monday and Thursday. # The backups are created by my service provider between # 22:00 and 23:00 every day. 00 3 * * 1,4 pi BACKUPCOPY_NAME=backupcopy.sftp.solnet.ch && ~/bin/backup-solnet.sh "$BACKUPCOPY_NAME" >>/mnt/backup-copy/$BACKUPCOPY_NAME.log 2>&1 # Run two hours after the previous copy job. This should # be sufficient time for the previous job to complete. # Even if it isn't, there's no harm done when the two jobs # run in parallel - all that will happen is that the two # jobs take a little longer because they both write to the # same file system. # # The data set copied here is less than 10 GB in size. 00 5 * * 1,4 pi /usr/local/htb/bin/htb-mkbackupcopy.sh /mnt/fileserver/daten/ /mnt/backup-copy/backupcopy.daten/ >>/mnt/backup-copy/backupcopy.daten.log 2>&1 # Run 5 minutes after the previous copy job. This should # be sufficient time for the previous job to complete. # # The data set copied here is less than 200 GB in size. # # When last measured, a full copy was 124 GB in size and # took 7.5 - 8 hours to complete (slightly more than # 0.25 GB per minute), and an incremental copy on those # 124 GB with zero files to copy took less than 1 minute # to complete. 05 5 * * 1,4 pi /usr/local/htb/bin/htb-mkbackupcopy.sh -e /Filme /mnt/fileserver/alles-andere/Media/ /mnt/backup-copy/backupcopy.media/ >>/mnt/backup-copy/backupcopy.media.log 2>&1 # Run 15 minutes after the previous copy job. This should # be sufficient time for the previous job to complete. # 15 minutes is sufficient to copy roughly 3-4 GB of data. # # The data set copied here is less than 100 GB in size. # # When last measured, a full copy was 50 GB in size, and # and an incremental copy on those 50 GB with zero files # to copy took less than 30 seconds to complete. 20 5 * * 1,4 pi /usr/local/htb/bin/htb-mkbackupcopy.sh /mnt/fileserver/alles-andere/Backup/Snapshots /mnt/backup-copy/backupcopy.backupsnapshots/ >>/mnt/backup-copy/backupcopy.backupsnapshots.log 2>&1 # Run 25 minutes after the previous copy job. This should # be sufficient time for the previous job to complete. # 25 minutes is sufficient to copy roughly 5-7 GB of data. # # The data set copied here is less than 10 GB in size. # # When last measured, a full copy was 2.7 GB in size and # took 10 minutes to complete, and an incremental copy # on those 2.7 GB with zero files to copy took less than # 10 seconds to complete. 45 5 * * 1,4 pi /usr/local/htb/bin/htb-mkbackupcopy.sh -i "/dedicated-server" -i "/facebook-herzbube102.zip" -i /mailman.tar.gz -i "/OldWindowsData" -i "/websites-unversioned" -i "/Work" -e "/*" /mnt/fileserver/alles-andere/Archiv/ /mnt/backup-copy/backupcopy.archiv/ >> /mnt/backup-copy/backupcopy.archiv.log 2>&1 # ---------------------------------------------------------------------- # Create snapshot of data set copies # Creating the initial snapshot may take substantial time, but once the # initial snapshot exists subsequent snapshots typically are created in # under a minute - unless, of course, the data set has seen a large # turnover of files since the last snapshot. This means that the snapshot # jobs can be timed relatively close after each other. # ---------------------------------------------------------------------- # Run at 03:00 am every Sunday. # This creates a snapshot of the off-site data that was # copied on Thursday. # # Note: Currently disabled because no dedicated server is in use. #00 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.pelargir /mnt/backup-snapshot/backupcopy.pelargir.bup >>/mnt/backup-snapshot/backupcopy.pelargir.bup.log 2>&1 00 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.sftp.solnet.ch /mnt/backup-snapshot/backupcopy.sftp.solnet.ch.bup >>/mnt/backup-snapshot/backupcopy.sftp.solnet.ch.bup.log 2>&1 10 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.daten /mnt/backup-snapshot/backupcopy.daten.bup >>/mnt/backup-snapshot/backupcopy.daten.bup.log 2>&1 20 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.media /mnt/backup-snapshot/backupcopy.media.bup >>/mnt/backup-snapshot/backupcopy.media.bup.log 2>&1 30 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.backupsnapshots /mnt/backup-snapshot/backupcopy.backupsnapshots.bup >>/mnt/backup-snapshot/backupcopy.backupsnapshots.bup.log 2>&1 40 3 * * 0 pi /usr/local/htb/bin/htb-mkbackupsnapshot.sh /mnt/backup-copy/backupcopy.archiv /mnt/backup-snapshot/backupcopy.archiv.bup >>/mnt/backup-snapshot/backupcopy.archiv.bup.log 2>&1
Notes:
- The shell scripts executed by
cronare documented on the wiki page BackupScripts. - The copying script requires that a working
keychain/ssh-agentconfiguration is in place. See the OpenSSH wiki page for details.
Manually activated cron configuration
Another cron configuration that contains script invocations that need to be manually activated is located here:
/etc/cron.d/manual-backup-scripts
The script invocations correspond exactly to the ones that are documented on the wiki page BackupSolution.
This is the content:
# /usr/local/htb/bin is required to find HTB scripts # On Raspberry Pi 3 /usr/local/bin was required to find bup. # On Raspberry Pi 5 the system-provided bup is found in /usr/bin PATH=/usr/local/htb/sbin:/usr/local/htb/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # ---------------------------------------------------------------------- # Backup scripts that need to be enabled manually # ---------------------------------------------------------------------- # # The scripts in this file perform backups that can take many hours to # run if a lot of data needs to be copied. In the case of the mirror # backup, the job ran for about two weeks. # # Adjust the time spec when to run a script, uncomment the line, then # after you're done disable the line again. # # Time specs: minutes, hours, day of month, month # ---------------------------------------------------------------------- # Encrypted Backup # ---------------------------------------------------------------------- # # Before the Encrypted Backup script can be run, the system needs to # be prepared by opening the LUKS partition on the encrypted backup # disk and mounting the filesystem inside the LUKS partition. After the # backup is complete, the filesystem needs to be unmounted and the LUKS # partition needs to be closed. See the wiki page # https://wiki.herzbube.ch/index.php/BackupSolution # for the commands to do these things. # # This is the command to clone the latest snapshot data onto the # encrypted backup disk. #25 22 01 04 * pi htb-mkbackupcopy.sh /mnt/backup-snapshot /mnt/encrypted-backup/ >>/mnt/encrypted-backup/encrypted-backup.log 2>&1 # ---------------------------------------------------------------------- # Mirror # ---------------------------------------------------------------------- # # The mirroring commands can be run at any time, no system preparation is # needed (except for plugging in the mirroring disk). Details about the # mirroring process can be found on the wiki page # https://wiki.herzbube.ch/index.php/BackupSolution # # Copy everything in the "alles-andere" folder, except the Movie Library data set # and the folders/files that are already included in the regular backup #40 23 01 04 * pi htb-mkbackupcopy.sh -e "/Media" -e "/Backup/Snapshots" -e "/Archiv/dedicated-server" -e "/Archiv/facebook-herzbube102.zip" -e "/Archiv/mailman.tar.gz" -e "/Archiv/OldWindowsData" -e "/Archiv/websites-unversioned" -e "/Archiv/Work" /mnt/fileserver/alles-andere/ /mnt/backup-mirror/fileserver/alles-andere-no-movies/ >> /mnt/backup-mirror/fileserver-alles-andere-no-movies.log 2>&1 # # Copy the Movie Library data set in a separate step, because it is located in # the /Media folder, which was excluded in the first command #35 10 02 04 * pi htb-mkbackupcopy.sh /mnt/fileserver/alles-andere/Media/Filme/ /mnt/backup-mirror/fileserver/alles-andere-movies/ >> /mnt/backup-mirror/fileserver-alles-andere-movies.log 2>&1
Troubleshooting
System reboots into emergency mode
The system probably recommends to issue the command journalctl -xb to investigate the problem. This dumps a large log into your lap from which it can be very difficult to find out the root cause. This slightly modified command lists only log messages that have some sort of error:
journalctl -xb -p3
In my case the root problem was that I had an entry in my /etc/fstab which referred to a removable USB drive which was no longer present at boot time. Commenting out the entry and then rebooting solved my problem. Other solutions (which are all not very satisfying) are
- Use the mount option "nofail". The problem here is that you don't get any errors if you really want to mount the drive but it doesn't work.
- Use the mount option "noauto". The problem here is that the drive not only is not mounted at boot time, but also if you attach it later when the system is already running.