Install FreeBSD 13.3 on Thinkpad x250

 01.06.2024 -  [mss]_Cyclist -  ~5 Minutes

Installation of FreeBSD with Wayland on Thinkpad x250

When my SSD died in my Thinkpad x250 it was time to replace it. All backups in place. Should be no problem. Wrong. Installation with ZFS on root went without problems. These came when I wanted to get i3 on xorg running. All drivers installed as documented in the handbook   Yes, I wanted i3, but ended up with sway.

Step 1: Installation on ZFS

This step is straight forward. I do not think it is necessary to go into much details here. Just follow the installation instructions.

  • Download FreeBSD 13.3 (I just did not want to upgrade to 14.0 right now).
  • I went with the memstick because I did not have wired network. So I needed all components to be available offline.
  • Follow the instructions of the installer.
  • Upgrade FreeBSD
root@freebsd:~ # freebsd-update fetch install
....
root@freebsd:~ # reboot

Step 2: Wireless network

First identify the network cards:

root@freebsd:~ # pciconf -lv | grep -A1 -B3 network

em0@pci0:0:25:0:	class=0x020000 rev=0x03 hdr=0x00 vendor=0x8086 device=0x15a2 subvendor=0x17aa subdevice=0x2226
    vendor     = 'Intel Corporation'
    device     = 'Ethernet Connection (3) I218-LM'
    class      = network
    subclass   = ethernet
--
iwm0@pci0:3:0:0:	class=0x028000 rev=0x59 hdr=0x00 vendor=0x8086 device=0x095a subvendor=0x8086 subdevice=0x5010
    vendor     = 'Intel Corporation'
    device     = 'Wireless 7265'
    class      = network

The wireless card is iwm0.

So let’s configure this:

root@freebsd:~ # ifconfig wlan0 create wlandev iwm0
root@freebsd:~ # sysrc wlans_iwm0="wlan0"
root@freebsd:~ # sysrc ifconfig_wlan0="WPA SYNCDHCP"

Add your wireless credentials. Edit /etc/wpa_supplicant.conf

network={
  ssid="FreeBSD"
  psk="PresharedKey"
}

In order to get it working

root@freebsd:~ # service netif restart

Step 3: Getting ports tree

We will use git to get the ports. First install git

root@freebsd:~ # pkg install git

Then clone the ports tree

root@freebsd:~ # git clone https://git.FreeBSD.org/ports.git /usr/ports

This will take a while to complete.

Step 4: Install video card drivers

First identify your graphic card

root@freebsd:~ # pciconf -lv|grep -B4 VGA
vgapci0@pci0:0:2:0:	class=0x030000 rev=0x09 hdr=0x00 vendor=0x8086 device=0x1616 subvendor=0x17aa subdevice=0x2226
    vendor     = 'Intel Corporation'
    device     = 'HD Graphics 5500'
    class      = display
    subclass   = VGA

So we need to install the Intel HD Graphics 5500 driver. Install

root@freebsd:~ # cd /usr/ports/graphics/drm-kmod
root@freebsd:~ # make install
root@freebsd:~ # sysrc kld_list+=i915kms

Now it is time to reboot and check if the driver is loaded.

Step 5: Install xorg

Install xorg and add your non-root user to the video group

root@freebsd:~ # pkg install xorg xinit
root@freebsd:~ # pw groupmod -m video mss-cyclist

Step 6: Install i3

Installation of i3 is simple.

root@freebsd:~ # pkg install i3 i3lock-color i3status

Create a ~/.xinitrc in your home directory

exec i3

Step 7: Try to start i3

This should not be too hard, should it? Until now everything went smooth. And now Murphy’s law kicks in trying to start xorg.

mss-cyclist@freebsd:~ % startx

Murphy around the corner

And now? A black screen shows up. A blank cursor in the uppper left corner. The fan of my Thinkpad goes wild. Nothing happens. The laptop is completely frozen. No luck in trying to kill xorg. No reaction to the keyboard. Only way to get around is to power it off the hard way.

I tried this several times without any success.

What is wrong?

Could be my trusted x250 died on me? Are these the wrong drivers? Nothing I tried seems to be working. Several hard resets further without any luck. Everything is working as expected - except xorg.

Ubuntu live cd

Just to make sure my Thinkpad is ok I downloaded Ubuntu and tried to start it as a live image. If Ubuntu will not run, then FreeBSD will certainly not run. To my relief Ubuntu started without any problems. Shortly after I was rewarded with a GUI. Some tests. Nothing wrong with my hardware.

GhostBSD

So when Linux is capable of running on my laptop, how can I get my beloved FreeBSD to get running? Next idea is to try a FreeBSD live cd. So I downloaded GhostBSD and run the live image. To my relief GhostBSD showed me the Mate desktop. So apparantly FreeBSD is capable to run on my x250 with GUI!

Back to the installation

Some fiddling around did not give any results. Screen still frozen, no way to start xorg. Several hard resets more leave me with the bitter thought to abandon FreeBSD (not really an option) or to buy a newer Thinkpad. Not the best prospects ahead.

Step 8: Wayland to the rescue

So there was still one option left which I did not consider. Give Wayland a try.

Installation of Wayland

root@freebsd:~ # pkg install wayland seatd
root@freebsd:~ # sysrc seatd_enable="YES"
root@freebsd:~ # service seatd start

The wayland compositor needs a runtime directory

root@freebsd:~ # mkdir -p /var/run/user
root@freebsd:~ # chown root:video /var/run/user

The runtime directory needs to be known in the XDG_RUNTIME_DIR environment variable. We will persist this later.

mss-cyclist@freebsd:~ % export XDG_RUNTIME_DIR=/var/run/user/`id -u`

Installation of Sway

Luckily Wayland has Sway as a drop-in replacement for i3. So it should be familiar to use.

# pkg install sway swayidle swaylock-effects alacritty dmenu-wayland dmenu alacritty
mss-cyclist@freebsd:~ % mkdir ~/.config/sway
mss-cyclist@freebsd:~ % cp /usr/local/etc/sway/config ~/.config/sway

Following the FreeBSD handbook there are some important changes to be made ~/.config/sway/config

...
input * xkb_rules evdev
set $term alacritty
...

Step 9: Starting Sway

Now let’s try if this works:

mss-cyclist@freebsd:~ % sway

And to my surprise: sway is working. I am greeted with the sway GUI. Lucky me: I do not need to ban neither FreeBSD nor my x250.

Step 10: Persist XDG_RUNTIME_DIR

Last but not least: let’s not to forget to persist XDG_RUNTIME_DIR. Edit ~/.cshrc and add

setenv XDG_RUNTIME_DIR=/var/run/user/`id -u`

FreeBSD user disappeared during update

 23.04.2020 -  ~2 Minutes

When trying to install a package it can happen that it fails because the user to be created ‘disappeared’.

User disappeared during update

This happened when I tried to install openntpd.

root@freebsd:~ # pkg install openntpd
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked): 

New packages to be INSTALLED:
     openntpd: 6.2p3_4,2                                                               

Number of packages to be installed: 1

The process will require 1 MiB more space.

Proceed with this action? [y/N]: y

===> Creating groups.

===> Creating users
Creating user '_ntp' with uid '233'.
pw: user '_ntp' disappeared during update
pkg: PRE-INSTALL script failed

Solution

First call vipw

root@freebsd:~ # vipw

Do not change anything. Just type:

:wq

And press <Enter>. This will sync your user database.

vipw: password list updated

Now you can try again to install the package.

root@freebsd:~ # pkg install openntpd
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
     openntpd: 6.2p3_4,2

Number of packages to be installed: 1

The process will require 1 MiB more space.

Proceed with this action? [y/N]: y
[1/1] Installing openntpd-6.2p3_4,2...
===> Creating groups.                        
Using existing group '_ntp'.
===> Creating users                          
Using existing user '_ntp'.
[1/1] Extracting openntpd-6.2p3_4,2: 100%

Finally the package is successfully installed.

Default sound volume in FreeBSD

 18.04.2020 -  ~1 Minute

The default sound volume of FreeBSD can be altered with sysctl.

Current default volume

In order to see the current default volume you need to query the value with sysctl.

root@freebsd:~ # sysctl hw.snd.vpc_0db
hw.snd.vpc_0db: 45

Change default volume

If you want to increase the volume lower the number. For a lower default volume increase it. The changes will have immediately effect.

Increase default volume

root@freebsd:~ # sysctl hw.snd.vpc_0db=35
hw.snd.vpc_0db: 45 -> 35

Decrease default volume

root@freebsd:~ # sysctl hw.snd.vpc_0db=55
hw.snd.vpc_0db: 35 -> 55

Make changes permanent

The changes made to the default volume will not be permanent. After a reboot the default value will be restored. To keep the desired value after a reboot you need to edit /etc/sysctl.conf

# Default sound volume
hw.snd.vpc_0db="35"

PostgreSQL in FreeBSD Jail

 16.04.2020 -  ~5 Minutes

For some use cases it can be interesting to put services into a jail. Putting PostgreSQL into its own jail has an advantage if you are using pkg to install your software. It can happen that the package you want to install is compiled with a different version of PostgreSQL. In that case you cannot install the new package without touching your production database. By separating the database you will not have to worry about any incompatibilities anymore.

This page will go through the necessary steps in order te run PostgreSQL in a FreeBSD jail.

Step 1: Jail creation

Create a new jail with ezjail.

root@pgjail:~ # ezjail-admin create pgjail 'lo1|127.0.1.1,bge0|192.168.1.10'

Modify jail for PostgreSQL

Before you proceed edit the jail config.

Edit /usr/local/etc/ezjail/pgjail

# To specify the start up order of your ezjails, use these lines to
# create a Jail dependency tree. See rcorder(8) for more details.
#
# PROVIDE: standard_ezjail
# REQUIRE: 
# BEFORE:
#
export jail_pgjail_hostname="pgjail"
export jail_pgjail_ip="lo1|127.0.1.1,bge0|192.168.1.10"
export jail_pgjail_rootdir="/usr/jails/pgjail"
export jail_pgjail_exec_start="/bin/sh /etc/rc"
export jail_pgjail_exec_stop=""
export jail_pgjail_mount_enable="YES"
export jail_pgjail_devfs_enable="YES"
export jail_pgjail_devfs_ruleset="devfsrules_jail"
export jail_pgjail_procfs_enable="YES"
export jail_pgjail_fdescfs_enable="YES"
export jail_pgjail_image=""
export jail_pgjail_imagetype=""
export jail_pgjail_attachparams=""
export jail_pgjail_attachblocking=""
export jail_pgjail_forceblocking=""
export jail_pgjail_zfs_datasets=""
export jail_pgjail_cpuset=""
export jail_pgjail_fib=""
export jail_pgjail_parentzfs=""
export jail_pgjail_parameters="sysvmsg=new sysvsem=new sysvshm=new"
export jail_pgjail_post_start_script=""
export jail_pgjail_retention_policy=""

The important part is export jail_pgjail_parameters="sysvmsg=new sysvsem=new sysvshm=new"

From the man page JAIL(8):

sysvmsg
Allow access to SYSV IPC message primitives. If set to “inherit”, all IPC objects on the system are visible to this jail, whether they were created by the jail itself, the base system, or other jails. If set to “new”, the jail will have its own key namespace, and can only see the objects that it has created; the system (or parent jail) has access to the jail’s objects, but not to its keys. If set to “disable”, the jail cannot perform any sysvmsg-related system calls.

sysvsem, sysvshm
Allow access to SYSV IPC semaphore and shared memory primitives, in the same manner as sysvmsg.

Step 2: Start jail

Start the jail and connect to the console.

root@pgjail:~ # ezjail-admin start pgjail
root@pgjail:~ # ezjail-admin console pgjail

Step 3: Jail configuration

Configuration inside jail

Before the jail can access the internet for installation you need to configure a nameserver. Herefore you need to edit /etc/resolv.conf

nameserver 192.168.1.1

Step 4: Installation of PostgreSQL

Install PostgreSQL server.

Now you are ready to install PostgreSQL server in the jail.

root@pgjail:~ # pkg install postgresql12-server
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 7 package(s) will be affected (of 0 checked):

    New packages to be INSTALLED:
    gettext-runtime: 0.20.1
    icu: 66.1,1
    indexinfo: 0.3.1
    perl5: 5.30.2
    postgresql12-client: 12.2
    postgresql12-server: 12.2_1
    readline: 8.0.4

    Number of packages to be installed: 7

    The process will require 142 MiB more space.
    32 MiB to be downloaded.

    Proceed with this action? [y/N]:

Add PostgreSQL to /etc/rc.conf to enable it on start of the jail.

postgresql_enable="YES"

PostgreSQL needs to be initialized before it can be started.

 root@pgjail:~ # /usr/local/etc/rc.d/postgresql initdb

Error initialization

If you did not adjust the jail as described earlier you will not be able to initialize the database. You will get an error:

root@pgjail:~ # /usr/local/etc/rc.d/postgresql initdb                                                                                                  
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /var/db/postgres/data12 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 20
selecting default shared_buffers ... 400kB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... 2020-04-17 04:23:22.188 UTC [34146] FATAL:  could not create shared memory segment: Function not implemented
2020-04-17 04:23:22.188 UTC [34146] DETAIL:  Failed system call was shmget(key=5432001, size=48, 03600).
child process exited with exit code 1
initdb: removing data directory "/var/db/postgres/data12"

PostgreSQL successfully initialized

If you enabled sysvmsg then everything should work and you can initialize the db.

root@pgjail:~ # /usr/local/etc/rc.d/postgresql initdb
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /var/db/postgres/data12 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /usr/local/bin/pg_ctl -D /var/db/postgres/data12 -l logfile start

root@pgjail:~ # 

Post initialization

Now you can start PostgreSQL server.

root@pgjail:~ # service postgresql start
2020-04-17 04:31:43.949 UTC [39302] LOG:  starting PostgreSQL 12.2 on amd64-portbld-freebsd11.3, compiled by FreeBSD clang version 8.0.0 (tags/RELEASE_800/final 356365) (based on LLVM 8.0.0), 64-bit
2020-04-17 04:31:43.950 UTC [39302] LOG:  could not create IPv6 socket for address "::1": Protocol not supported
2020-04-17 04:31:43.950 UTC [39302] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2020-04-17 04:31:43.973 UTC [39302] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2020-04-17 04:31:44.009 UTC [39302] LOG:  ending log output to stderr
2020-04-17 04:31:44.009 UTC [39302] HINT:  Future log output will go to log destination "syslog".
root@pgjail:~ #

Post installation

Finally you are able to connect to the PostgreSQL server and start with your database administration.

root@pgjail:~ # psql -U postgres
psql (12.2)
Type "help" for help.

postgres=#