Install awscli2 on FreeBSD 14.1-p3

Whilst I often use the awscli on Linux or mac for which there are binary installers, I also tend to work on personal projects on FreeBSD. Unfortunately this OS is not supported by AWS. Some would recommend to use the Linuxulator but surely running a native version would be better. So here is a quick step-through of how I got it running on FreeBSD 14.1-p3 with python311 thanks mostly to this github issue and also this one. Although this is done with python311 and py311-pip, you can probably use the same method for older version of python down to python39.

First we need to clone awscli2 from https://github.com/aws/aws-cli. Be careful to select the v2 branch.

git clone https://github.com/aws/aws-cli.git
cd aws-cli
git checkout v2

Then, I ran into a problem with pyOpenSSL. After installing it, executing awscli returned the following error message: ERR_UNABLE_TO_GET_ISSUER_CERT = _lib.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT. Thanks to this other issue, it seems like a quick solution was to downgrade the version of pyOpenSSL (but this step might not be necessary to you, future reader blessed with a fix):

sudo pip install pyOpenSSL==23.1.0

Then it’s a matter of installing the requirements and building/installing the command line tool (note that it needs gcc tho, in my case gcc13-13.3.0):

sudo pip install -r requirements.txt
sudo CC=/usr/local/bin/gcc pip install -e .

And tada!

» aws --version
aws-cli/2.17.49 Python/3.11.9 FreeBSD/14.1-RELEASE-p3 source/amd64

Port configure fails on ARM64

On FreeBSD, if you are trying to build a port but it fails at the configure step with a message similar to this:

checking build system type... Invalid configuration `arm64-portbld-freebsd13.2': machine `arm64-portbld' not recognized
configure: error: /bin/sh ./build-aux/config.sub arm64-portbld-freebsd13.2 failed

Here’s a quick-fix that might work for you:

export CONFIGURE_TARGET=arm64-unknown-freebsd13.2
make install

This is similar to passing --host arm64-unknown-freebsd13.2 to the configure script instead of trying to guess it.

Devd doesn’t trigger LINK_UP

On FreeBSD, you can use devd to trigger scripts that react to device state changes. For instance, you plug/remove a device, or you connect/disconnect an Ethernet cable.

I had to use this kind of rule to restart a service when an interface is reconnected. However the rule would not trigger when the cable was reconnected.

The reason was that default rules in /etc/devd.conf were failing, hence stopping the execution of the next rules. In particular service dhclient quietstart $subsystem".

The solution was either to comment these lines in devd.conf or give my custom devd configuration a higher priority.

Override rc order in FreeBSD

In FreeBSD as in most other Operating Systems, the boot process consist of starting a set of scripts/services/daemons/processes. Each of those has constraints like depending-on or starting before other scripts for instance.

On a default FreeBSD install, this order would be determined by the packages you install, each of them installing a script in /usr/local/etc/rc.d that specifies its constraints requirements.

What, however, if you wanted to change the order of the boot process? For instance, you have a script that by default starts just after the network is ready, but in your case, it specifically has to start after another script for everything to work properly.

Well, I was confronted to that particular problem, and the answer is cross-dependency-scripts or whatever you want to call them.
Suppose that you have the following scripts in your boot process: A, B, C, D. By default, B, C and D start just after A. But you want to change that so B starts after D and C starts after B.

If you changed the order dependency in script B and C directly, that change would be overwritten on the next package update. Instead we add two empty scripts __B and __C that will just enforce the dependence. That is, __B starts after D and before B, __C starts after B and before C.

Looking at the code, at the beginning of the original scripts you would find:

-- rc.d/A
#!/bin/sh

# PROVIDE: A
-- rc.d/B
#!/bin/sh

# PROVIDE: B
# REQUIRE: A
-- rc.d/C
#!/bin/sh

# PROVIDE: C
# REQUIRE: A
-- rc.d/D
#!/bin/sh

# PROVIDE: D
# REQUIRE: A

Thus you would add two scripts __B and __D that contains:

-- rc.d/__B
#!/bin/sh

# PROVIDE: __B
# REQUIRE: D
# BEFORE: B
-- rc.d/__C
#!/bin/sh

# PROVIDE: __C
# REQUIRE: B
# BEFORE: C

FreeBSD on NanoPi R2S

The NanoPi R2S is a nice little ARM board that can serve nicely as a home router or firewall. It is comparable in power to a RaspberrryPi 3 with a 4 cores ARM Cortex-A53 SoC, namely the Rockchip RK3328. It has no video or sound output, only a handful GPIOs compared to a RPi, but it has one great advantage. It has 2 Ethernet ports, one of them is a true Gigabit internal card and the second is also a Gigabit connected through the internal USB3, so it’s a bit slower. On the RPi3, if you want 2 Gigabit Ethernet ports, you need an external card and both ports would run on the USB3, drastically limiting the bandwidth.

They generally come with a heatsink and a fan integrated as the board is quite small compared to a RPi and heats up more easily. People generally use this board with OpenWrt or Ubuntu. In the past, I also used it with Armbian as my home network gateway. People also managed to run it on OpenBSD. But this post focuses on FreeBSD.

ARM64 has been a tier-1 architecture on FreeBSD for more than a year now, which I discussed in this post. I managed to run the RPi 2B+, 3 and 4 easily, but my attempts with the Nanopi R2S proved rather unsuccessful and had their fair share of kernel panics.

Fast forward one year, and we are now at FreeBSD 13.1-p1. So I recently gave it another try, and not only is the whole experience much more stable, the installing process is also much easier and straightforward.

Installation

To install FreeBSD, I used the image provided at PersonalBSD. It’s a custom image based on a patched version of FreeBSD 13. It’s quite customized in fact, and point to its own repo by default. It starts sshd by default, and run both interfaces on DHCP. It has pubkey root login enabled and also has another admin user installed.

The rc.conf has growfs enabled, so the first boot will grow the ROOT UFS partition to the size of your SD card. It’s all GPT. There is a 256MB swap partition, but you can add a file based swap if you want. For instance in /etc/fstab:

md99 none swap sw,file=/.swap,late 0 0

The root partition has the following options enabled:

tunefs: POSIX.1e ACLs: (-a)                                disabled
tunefs: NFSv4 ACLs: (-N)                                   disabled
tunefs: MAC multilabel: (-l)                               disabled
tunefs: soft updates: (-n)                                 disabled
tunefs: soft update journaling: (-j)                       disabled
tunefs: gjournal: (-J)                                     disabled
tunefs: trim: (-t)                                         disabled
tunefs: maximum blocks per file in a cylinder group: (-e)  4096
tunefs: average file size: (-f)                            16384
tunefs: average number of files in a directory: (-s)       64
tunefs: minimum percentage of free space: (-m)             8%
tunefs: space to hold for metadata blocks: (-k)            2768
tunefs: optimization preference: (-o)                      space

It has soft updates disabled, which means that if the board has a hard reboot, you are in for some fsck nightmare. You can enable softupdates offline when the card is connected to your computer (running FreeBSD) for instance:

tunefs -n /dev/da0p2

I highly recommend to enable soft updates to save you much hassle.

Playing around

By default there is no EEPROM for the MAC addresses so they are randomly generated on each boot. Keep this in mind if you want to use IPv6 and SLAAC. There is also three status LEDs on the board. You can control them from the command line with echo 0|1 > /dev/led/nanopi-r2s:*. The custom image comes with a daemon and rc.local shell lines to setup a default state for the LEDs, but you can easily disable it.

The two interfaces are dwc0 for the Rockchip internal card, and ue0 for the card connected through USB3. Here is a quick test with iperf3 using UDP on both interfaces. Results are given in Mbits/sec.

TX RX
dwc0 765 946
ue0 784 370

 

Running it

But does it fit an use for a full fledged Internet gateway? I ran the Nanopi R2S for some time now as a home network gateway, and while it worked very well most of the time, the R2S would from time to time become completely inaccessible. Although it did not seem to panic as scripts where still running behind the scene. I could not identify what the problem was, but I know that the problem happened when either the Ethernet cable on the LAN interface was disconnected, or when too much traffic arrived on the Ethernet port.

AMD Renoir GPU on FreeBSD 13 (bis)

In a previous post, I explained that I backported the 5.5-stable branch of drm-kmod and got it running on FreeBSD 13.0-RELEASE although some bugs persisted.

Since then I’ve received several requests if it was possible to access the code or if a port was available. However the answer was always that it was a quick and dirty patch, panic do occur and that it wasn’t published on purpose (but a tarball was available).

But I’ve been at it again. I first tried to backport the 5.7-stable branch to FreeBSD 13. It did compile and display worked. But there were several bugs that I was unable to fix.

So I restarted the patch over 5.5-stable but this time dedicated more than 10 minutes for the task. The thing works and even fixed a bug in the process. Also it does now compile on a fresh FreeBSD 13.0-RELEASE ✌️

This new version is available on my github as 5.5-fbsd13release branch. Feel free to clone and try. Intel i915 is still not supported but could be if someone is interested and willing to try it.

Still no port tho, as I’m not confident at all in my understanding of drm-kmod and ability to contribute.

Find oldest file on UNIX/BSD

If you wish to find the oldest file in a directory tree on a UNIX system, you might have found the following solution:

find . -type f -printf '%T+ %p\n' | sort | head -n 1

This is all good and nice, but it only works with the GNU version of findutils. Indeed other versions of find do not support the -printf option. A more compatible option goes something like that (it’s at the same time more generic (doesn’t use -printf) and more BSD specific (stat syntax) but you might adapt it to Linux easily):

find . -type f | xargs stat -f "%m %N" | sort | head -n 1

AMD Renoir GPU on FreeBSD 13

UPDATE: github branch available (2022-03-12)

You if have a laptop running one of the latest AMD Ryzen 5 (such as the ThinkPad T14 AMD) with integrated Radeon graphic on FreeBSD 13, you probably struggled to get the GPU running and finally gave up to use the generic scfb frame buffer device instead. It is non accelerated, you cannot access any external port nor adjust the brightness, but it’s usable.

Now I’ve some good news for you! After randomly searching the FreeBSD forums I found a post that was referring to a work-in-progress branch of drm-kmod that should support the latest AMD Renoir GPU. This branch is now named 5.5-stable. After some modifications I was able to compile it on FreeBSD 13.0-RELEASE-p3 and got it to run on the GENERIC kernel.

Acceleration and the external ports work well. I even managed to get a 3 screen setup working through one of those USB-C docking station.

Only one cable connected to the laptop that carries the power supply, audio, external mouse, two screens, external HDD, floppy drive and more. Now, this is what I call “Universal Serial Bus”.

Patching the drm-kmod 5.5-stable branch to compile on 13.0-RELEASE was pretty straightforward too. A missing function here, a different signature there, some missing constants. A lot easier than other things I’ve been trying to port from 12 to 13.

Since I’ve also been able to install a modern TeX Live environment (the 2015 version from the port tree is getting rather outdated), I can now again use FreeBSD as my main working Operating System. Yahoo!

FreeBSD on RaspberryPi

RaspberryYou may have heard that ARM64 is now a tier-1 platform on FreeBSD 13. This basically means that this platform is now fully supported by the various FreeBSD teams. Seeing ARM supported as a tier 1 is really cool, since we can now play around with those ARM boards (RaspberryPi, BeagleBone, …) that were so far reserved to a selected set of Linux distributions. Being able to use an entirely different OS is refreshing.

In the last few weeks, I’ve devoted some of the very little free time that I have to try just that. I’ve installed FreeBSD on some RPi3 boards in the hope of replacing whatever they were doing before on Raspbian. If you insist you can use the video, but it’s very slow and totally unusable as a Kodi media-center. The reason being (as far as I understand) that the VideoCore drivers are a pain in the ass to port even from RPi Linux flavor to another, let alone on FreeBSD. So I wouldn’t expect improvement on that front for some time.

However as a network appliance or audio-only media-center, it works nicely. It’s just a matter of downloading the appropriate SD card image for your specific board (here and there), dd it to the SD card, boot with HDMI and USB keyboard, then configure your installation from there. Beware though, you should avoid editing the UFS partition of the image until it has been resized by growfs_enable=YES. In my case that triggered some naughty kernel panics (which I had no time to investigate thoroughly, oops).

I’ve also tried some unsupported platform such as the NanoPi R2S with mitigated success. I managed to boot on the serial interface and install some packages. But USB devices are not (or not always) showing, the driver for the second Ethernet interface is missing, and random kernel panics do happen. So I gave up for now and tried an RPi3 board instead.

I also tried running it on a RaspberryPi 1 B+ v1.2. The reason I’m trying that is to replace my media-center setup, especially the audio part. The RPi1 should consume less power, is perfectly capable for the task at hand and I’ve got a lot of them lying around. Since the device will be always on, it should be a perfect replacement for the RPi3 I used so far. For this I had to use the RPi-B image. Contrary to the RPi3 which runs ARMv8 64-bit, RPi1 B+ is still an ARMv6 32-bit architecture and a tier-2 platform on FreeBSD.

One of the problem with the RaspberryPi is that there are a lot of different version nowadays and they all share similar names. For instance if you say RPi B+, is it RPi3 B+ from 2018, RPi1 B+ from 2014, a confusion with the RPi2 B v1.2 from 2016 or the RPi2 B? All these run on different SoC with different flavor of ARM from ARMv6 to ARMv8. You must pay attention to choose the correct image for your board. Use the Wikipedia’s RaspberryPi page to tell them apart, it’s very complete, especially the Specifications and Connectors sections.