Category Archives: Linux

Remote desktop on Raspberry Pi with Vino in 3 steps

If you run a GTK-based desktop environment on your Raspberry Pi, getting remote desktop working with Vino is extremely easy.

Step 1: install the package:
sudo apt-get install vino

Step 2: Configure the server to not prompt to allow connections and use an empty password:
gsettings set org.gnome.Vino prompt-enabled false
gsettings set org.gnome.Vino vnc-password ''

Step 3: Start the server:
systemctl --user start vino-server

Now you can connect using any VNC capable client.

Debian on the Lenovo ThinkPad A485

Here are some notes about getting Debian up and running on the ThinkPad A485.

Install these missing firmware packages:

apt-get install firmware-amd-graphics firmware-realtek

..or download them onto removable media from another computer:
https://packages.debian.org/search?keywords=firmware-amd-graphics
https://packages.debian.org/search?keywords=firmware-realtek

With kernel 5.x the r8822be Wi-Fi driver kernel module is replaced by rtw_pci / rtw88 which needs missing firmware (Debian bug report):

wget -P /usr/lib/firmware/rtw88 https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/rtw88/rtw8822b_fw.bin
modprobe -r rtw_pci
modprobe -r rtw88
modprobe rtw_pci

Bluetooth will choke when using Laptop Mode Tools due to runtime PM. Blacklist the ID of the USB Bluetooth controller by adding this line to /etc/laptop-mode/conf.d/runtime-pm.conf:

AUTOSUSPEND_RUNTIME_DEVID_BLACKLIST="0bda:b023"

Blacklisting client mode BSSIDs in OpenWRT

I have an OpenWRT router that I use to privately share a connection to a public hotspot. In other words, I use one of the Wi-Fi interfaces to connect to the internet via a hotspot, and share it to my own devices via another Wi-Fi interface. This is pretty easy to accomplish with OpenWRT and simply requires switching the Wi-Fi interface to client mode and setting the network interface to something in the WAN firewall zone (typically wwan).

This post isn’t going to cover the basics of that configuration, but instead cover a problem I’ve had with hotspots that associate but then fail to respond to DHCP requests. That essentially kills my internet connection for a while until udhcpc times out (sometimes it doesn’t) and a new association attempt is made with a different access point. Each hotspot has its own BSSID, which is the MAC address of the access point. You can find this address either from the Wireless section of the web frontend, or from watching the association attempts from the system log (e.g. logread -f). There is no obvious way to blacklist a particular access point by MAC address in client mode from Luci (OpenWRT’s web frontend). It is pretty easy to accomplish from the command line. First, determine which radio you are using for the client mode connection, e.g. radio0, radio1, etc. and then find its configuration “section” name, e.g. “wifinet1”, “wifinet2”, etc.

wifi status

You can also get this information another way using the uci command:

uci show wireless

Once you have found the configuration section for the radio device you are using, it’s as simple as adding the blacklist value. Here we will assume the configuration section ‘wifinet1’ and set the blacklist to include the fake MAC address values ‘xx:xx:xx:xx:xx:xx’ and ‘nn:nn:nn:nn:nn:nn’:

uci set wireless.wifinet1.bssid_blacklist='xx:xx:xx:xx:xx:xx nn:nn:nn:nn:nn:nn'

As you can tell, the MAC addresses are separated by spaces.

Now write the changes to the system configuration:

uci commit

Finally, restart the wireless interface. We’ll assume radio0 as an example:

wifi up radio0

This will prevent the wireless client interface from connecting to the access points in the blacklist. This works because the bssid_blacklist value is passed through from uci to wpa_supplicant via hostapd.sh. Note that this value may get clobbered if you touch the wireless interface configuration from the Luci frontend since it is not included there.

btrfs inode errors with file extent discount / file extent holes

This was a new one for me. An external USB 3.0 btrfs RAID 0 volume had some random I/O errors of undetermined cause during heavy writes — no kernel oops or obvious bug, and no clear hardware failure either. It came after seeing a bunch of these in my kernel log:

xhci_hcd 0000:00:14.0: ERROR unknown event type 37

This apparently has something to do with filling a ring buffer according to this LKML post. I’m not sure if it’s related but it was coincident with the following errors.

I’ve been running btrfs on a number of volumes for years (with many previous catastrophes) and this is the first time I’ve seen this particular error:

btrfs check --repair /mountpoint
...
root 5 inode 7553112 errors 100, file extent discount
Found file extent holes:
start: 0, len: 16384
root 5 inode 7553113 errors 100, file extent discount
Found file extent holes:
start: 0, len: 12288
root 5 inode 7553115 errors 100, file extent discount
Found file extent holes:
start: 0, len: 28672
...
root 5 inode 7555752 errors 100, file extent discount
Found file extent holes:
start: 0, len: 45056
ERROR: errors found in fs roots
found 9165863124992 bytes used, error(s) found
total csum bytes: 8933283920
total tree bytes: 15941156864
total fs tree bytes: 5797117952
total extent tree bytes: 473710592
btree space waste bytes: 1645027279
file data blocks allocated: 9149921968128
referenced 9216958279680

The solution I came across is a bit time consuming. It relies on freeing the affected inodes, which in turn means removing the original files from the filesystem. You can copy them elsewhere or just delete them if you have a backup or decide they aren’t valuable. In my case I kept the files around long enough to see if they matched a backup — and they did, indicating that the files themselves weren’t affected by this problem.

First I took the output from btrfs check and picked out the inode numbers:

grep 'file extent discount' btrfs_check_output | cut -f4 -d' ' > bad_inodes

Explanation: I put the output from btrfs check into a file called btrfs_check_output. The grep command searches this file for the lines with inode numbers, and cut picks out just the inode numbers from the rest of the line: -f4 means take the fourth field -d' ' delimited by spaces. The output goes into a file called bad_inodes.

This ended up with a list of 705 bad inodes! Sheesh… now comes the long part. In order to find the files associated with these inodes, I put this Bash command line together:

while read inode; do find /mountpoint -xdev -inum $inode -print0 -quit; done < bad_inodes > bad_inode_files

Explanation: This reads the bad_inodes file as standard input and loops over each line as variable $inode and then executes a find. The output is sent to a file named bad_inode_files. The arguments to find are -inum which searches for a file by inode number, and -xdev which stops the file search from descending into other filesystems, since we don’t want to mistakenly find files with the same inode number on a different filesystem. The quit option stops the search after the first result, since we don’t need to keep searching the entire filesystem after we have located the file associated with a particular inode. -print0 is optional and is for handling filenames containing whitespace by delimiting each item of output with a null character instead of the default newline. You can substitute -print0 with plain old print if you aren’t going to process this output with another utility, or if you are sure there aren’t filenames with whitespace in your output.

This took a while to complete since it has to search for each inode starting at the root of the filesystem, and in this case it’s a 10TB array and 705 inodes. When it completed, it produced a list of affected files in a text file named bad_inode_files.

I could have just moved or deleted the files, but I wanted to inspect them first. The affected filesystem is a backup, so I compared the files to the originals. All of the files matched according to rsync which means that they’re probably not damaged. I then went ahead and deleted all of the affected files since I had them on a backup. If I didn’t have a backup I could have moved them to another location and then back.

Now after removing the files with the affected inodes, btrfs check returns no errors.