Enable TRIM on external LUKS encrypted drive

If you use an encrypted external SSD, you should periodically trim it. The first step would be to make sure the external drive itself supports trimming. The next step would be to make sure the LUKS partition on the device supports trimming as well. By default, encrypted filesystems do not support passing discard requests due to some security concerns. For example, crypttab man page states:

WARNING: Assess the specific security risks carefully before enabling this option. For example, allowing discards on encrypted devices may lead to the leak of information about the ciphertext device (filesystem type, used space etc.) if the discarded blocks can be located easily on the device later.

For most users, the benefit of TRIM outweigh those security concerns. The easiest way to enable TRIM is to pass the dicard option in /etc/crypttab. For example:

cdisk0 UUID=12345678-9abc-def012345-6789abcdef01 none luks,discard

The problem with the /etc/crypttab approach is that it requires you to pre-configure your external drives. A better approach would be to enable discards at the LUKS configuration, which would apply automatically whenever the drive is used. This can be done in LUKS version 2 headers.

# cryptsetup --allow-discards --persistent refresh luks-643dc0f7-c876-4e37-9207-5c053a75fc70

Where luks-643dc0f7-c876-4e37-9207-5c053a75fc70 is the name of the mapping for the encrypted drive. You can verify that allow_discards is now part of the flag by dumping the LUKS header.

# cryptsetup luksDump /dev/sda4 | grep Flags
Flags:       	allow-discard

Now, you should be able to use fstrim to trim your external SSD with LUKS encryption drive.

Enable TRIM/discard on external SSD

First, find out whether your device already supports TRIM commands.

$ lsblk --discard

Non-zero values in the DISC-GRAN and DISC-MAX indicate support. If it looks like your external SSD doesn’t support trimming, then maybe it supports UNMAP which is equivalent (UNMAP is just in the SCSI command set vs TRIM which is in the ATA command set). Assuming your external drive is /dev/sda

# apt install sg3-utils
# sg_vpd -a /dev/sda | grep -i unmap

If the last command has Unmap command supported (LBPU): 1 it means the drive supports the UNMAP command. If it’s supported, and discard wasn’t supported, it’s likely the kernel didn’t detect the UNMAP support. You can verify it by reading /sys/block/sda/device/scsi_disk/0\:0\:0\:0/provisioning_mode

$ cat /sys/block/sda/device/scsi_disk/0\:0\:0\:0/provisioning_mode 
full

full means no support. As we know our device supports unmap we can manually instruct the kernel about it.

# echo "unmap" >/sys/block/sda/device/scsi_disk/0\:0\:0\:0/provisioning_mode 

Now, lsblk --discard should report that the drive supports trimming, and you can use fstrim to trim it.

Making the change permanent

The changes above are ephemeral and will be reverted once you disconnect the drive. If you want to automatically apply those changes whenever your external drive is connected, we need to use udev rules.

Add the following rule to udev under /etc/udev/rules.d/90-usb-discard.rules

ACTION=="add|change", ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="1932", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"

Replace idVendor and idProduct above with the corresponding values for your device, as can be found in the output of lsusb.

Reload the udev rules using

# udevadm control --reload

Use Alt-Shift for keyboard layout switching in GNOME 40

Since GNOME 40 the keyboard layout indicator doesn’t work if the keyboard is switched using a key combination defined in GNOME Tweaks. The indicator does work for key combinations defined through GNOME Setting’s Keyboard Shortcut settings. However, GNOME Settings doesn’t allow one to set Alt+Shift as the key combination layout switching, as it seems to require at least one non-modifier key in every shortcut. This limitation only exists in GNOME Settings GUI and you can work around it by defining the shortcut using gsettings:

$ gsettings set org.gnome.desktop.wm.keybindings switch-input-source "['<Shift>Alt_L']"
$ gsettings set org.gnome.desktop.wm.keybindings switch-input-source-backward "['<Alt>Shift_L']"

Downgrade PipeWire 0.3.39 to 0.3.38

PipeWire 0.3.39 on Debian deprecates pipewire-media-session in favor of WirePlumber. The main issue I found with the new version is that it doesn’t support Bluetooth profile autoswitching, as it is unimplemented in WirePlumber. The best solution until this is resolved is simply holding back upgrading to 0.3.39. If you already upgraded, downgrading is a bit of hassle.

The first step is to retrieve all the necessary packages in the last working version, which is 0.3.38-2.

$ cd `mktemp -d`
$ debsnap -a amd64 --binary -d . gstreamer1.0-pipewire 0.3.38-2
$ debsnap -a amd64 --binary -d . libpipewire-0.3-0 0.3.38-2
$ debsnap -a all --binary -d . libpipewire-0.3-common 0.3.38-2
$ debsnap -a amd64 --binary -d . libpipewire-0.3-modules 0.3.38-2
$ debsnap -a amd64 --binary -d . pipewire-audio-client-libraries 0.3.38-2
$ debsnap -a amd64 --binary -d . pipewire-bin 0.3.38-2
$ debsnap -a amd64 --binary -d . pipewire-pulse 0.3.38-2
$ debsnap -a amd64 --binary -d . pipewire 0.3.38-2
$ debsnap -a amd64 --binary -d . pipewire-media-session 0.3.38-2
$ debsnap -a amd64 --binary -d . libspa-0.2-modules 0.3.38-2
$ debsnap -a amd64 --binary -d . libspa-0.2-bluetooth 0.3.38-2

Install all the retrieved packages and mark some of the packages back as automatically installed.

$ sudo apt install ./*.deb
$ sudo apt-mark auto gstreamer1.0-pipewire libpipewire-0.3-0 libpipewire-0.3-common libpipewire-0.3-modules pipewire-bin pipewire libspa-0.2-modules

Mark pipewire-media-session as held so it won’t get accidentally removed again.

$ sudo apt-mark hold pipewire-media-session

Finally, restart PipeWire.

$ systemctl --user daemon-reload
$ systemctl --user restart pipewire pipewire-pulse

Removing PulseAudio after migrating to PipeWire

After migrating to PipeWire you would want to fully remove PulseAudio. The problem is that certain packages, for example libcanberra-pulse, depend on pulseaudio even though they would work just as well if pipewire-pulse is installed. There are several relevant bugs to solve this issue, but meanwhile we could use equivs to generate a fake package that provides pulseaudio.

Copy the following file locally as pulseaudio-fake:

Section: misc
Priority: optional
Standards-Version: 3.9.2

Package: pulseaudio-fake
Provides: pulseaudio
Description: Fake pulseaudio package to satisfy depdendencies.
 This solves depdendencies for packages like libcanberra-pulse when actually using PipeWire instead of PulseAudio.

Build a package from it using equivs and install it:

$ equivs-build ./pulseaudio-fake
$ sudo apt install ./pulseaudio-fake_1.0_all.deb

Now you can safely remove pulseaudio.

GNOME 40 on Debian Unstable

These are the steps I took to install (most of) GNOME 40 Debian Unstable:

$ sudo apt install -t experimental gnome-shell gjs mutter gnome-control-center gnome-desktop3-data
$ sudo apt-mark auto gjs mutter

Failing to install gjs 1.68 from experimental will result in white or blue desktop backgrounds regardless of the wallpaper you choose. This bug was reported in Arch.

Most of GNOME 40 functionality should now work, including the updated activities overview.

What doesn’t work? Settings->About still display GNOME’s version as 3.38. I suspect it’s because gnome-session is still at 3.38.

Update 2021-08-24: I upgraded to gnome-session 40.1.1 and it didn’t solve the version string issue.

Update 2021-08-31: Following a comment by Jeremy, I installed gnome-desktop3-data from experimental and it fixed the version string issue.

[coc.nvim]: UnhandledRejection: Launching server “jedi” using command jedi-language-server failed.

Recently I switched over to coc.nvim, and when trying to edit a Python file, I encountered the following error:

[coc.nvim]: UnhandledRejection: Launching server "jedi" using command jedi-language-server failed.

The first problem turned out to be that while I had jedi installed, I didn’t install jedi-language-server. This can be done using:

pip install -u jedi-language-server

Next, coc.nvim couldn’t find the jedi-language-server executable, despite it being on my $PATH. The solution was to specifically define it in ~/.vim/coc-settings.json:

{
  "jedi.executable.command": "/home/guyru/.local/bin/jedi-language-server",
}

tmux <-> Wayland Clipboard integration

tmux 3.2 and above provides the copy-command option to set a command to pipe text to copy. You will also need wl-copy command from the wl-clipboard package. Add the following line to your ~/.tmux.conf:

set -s copy-command 'wl-copy'

As of writing this post, tmux-3.2 is only available in experimental, so you’ll need to install it from there:

$ sudo apt install -t experimental tmux