Introduction

Google knows a lot about technology-related problems. Most of the time, I can just type my question in the One True Text Field and wait for the answer to magically appear in front of my eyes.

At times, however, the magical answering engine seems out of order. Some might say that it has to do with the alignment of the planets or a butterfly flapping its wings on the other side of the globe, but my guess is that somehow the information hasn't been posted online (or at least indexed properly).

This blog is my way of solving this problem and (hopefully!) making sure that people running into the same problems as me will not have to search for too long before finding the answers.

Background compilation using ionice as a normal user

Most people know that you can run commands "in the background" on UNIX by prefixing them with "nice":

nice run_long_script.sh

What that does of course is reduce the priority of the process so that the CPU scheduler only runs it when nothing else (of a higher priority) wants to run. What it doesn't do however is run the process without any impact whatsoever on your other tasks. The reason is that the background process can still ruin the performance of your computer by monopolizing the hard disk.

It turns out that Linux 2.6.13 or later (with the CFQ scheduler) support a tool called ionice which is a "nice" command for I/O operations (like disk accesses). It works like this:

ionice -c3 command

The only problem is that you can only reduce the IO priority of a process as root. The reason being that if you're not careful you could have a high priority (CPU priority that is) IO-blocked by a lower-priority process.

But if you run your compilation like this:

sudo ionice -c3 make

it will run the whole thing as root, which is probably not what you want. So you could do something like:

sudo ionice -c3 sudo -u myusername make

to run the compilation as yourself. Though one problem persists: sudo strips out your environment. So things like distcc and ccache may not work anymore.

Here's how I solved these problems in my background compilation script for custom kernel Debian packages:

#!/bin/bash
nice fakeroot make-kpkg --revision=custom.1.0 kernel_image &
BACKGROUND_BUILD=$!
sudo ionice -c3 -p $BACKGROUND_BUILD
wait $BACKGROUND_BUILD || exit 1  
Debugging concurrency problems: Forcing a process to run on a single CPU

Multi-threading can cause hard-to-diagnose problems and they are especially visible on multi-core CPUs (or multi-CPU systems) where threads actually run concurrently.

Here's a quick way to find out if the segfaults you are experiencing might be due to some concurrency/locking problem: force the application to run on a single CPU using schedtool (part of the schedtool package on Debian/Ubuntu).

schedtool -a 0 -e applicationname

This is just one example of what you can do with the CPU Affinity controls on Linux.

Command history in Oracle sqlplus: adding readline support at runtime

Readline-style editing (arrow keys, word deletion, command history, etc.) is a feature that most users expect out of a command-line application on Linux. And one that is painfully missing from Oracle sqlplus (the equivalent to psql).

Of course, Debian has a solution:

apt-get install rlwrap
rlwrap sqlplus

You may also find it useful if, for some reason, you need to use the dash shell interactively.

Encrypted swap partition on Debian/Ubuntu

The swap partition can hold a lot of unencrypted confidential information and the fact that it persists after shutting down the computer can be a problem.

Encrypting a swap partition however is slightly tricky if one wants to also support suspend-to-disk (also called hibernation). Here's a procedure that worked for me on both Debian Stretch and Ubuntu 18.04 (Bionic Beaver):

  1. Install the cryptsetup package:

    apt install cryptsetup
    
  2. Add this line to /etc/crypttab:

    sda2_crypt /dev/sda2 /dev/urandom cipher=aes-xts-plain64,size=256,swap,discard
    
  3. Set the swap partition to be this in /etc/fstab:

    /dev/mapper/sda2_crypt none swap sw 0 0
    

You will of course want to replace /dev/sda2 with the partition that currently holds your unencrypted swap.

This is loosely based on a similar procedure for Ubuntu 6.10, but I don't use suspend-to-disk and so I simplified the setup and use a random encryption key instead of a passphrase.