The hunt for a kernel bug, part 3: compiling a kernel

Compiling a Linux kernel sounds scary and complicated, but I found out it actually isn’t.

The first thing to do, is to install some prerequisites:

$ sudo apt install --yes asciidoc binutils-dev bison build-essential ccache \
    crash dwarves fakeroot flex git git-core git-doc git-email kernel-package \
    kernel-wedge kexec-tools libelf-dev libncurses5 libncurses5-dev libssl-dev \
    makedumpfile zstd
$ sudo apt-get --yes build-dep linux

Next I cloned the Ubuntu Impish repository. This takes a while…

$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-impish.git
$ cd ubuntu-impish

Now let’s see which versions are in the repository:

$ git tag --list
Ubuntu-5.11.0-16.17
Ubuntu-5.11.0-18.19+21.10.1
Ubuntu-5.11.0-20.21+21.10.1
Ubuntu-5.13.0-11.11
Ubuntu-5.13.0-12.12
Ubuntu-5.13.0-13.13
Ubuntu-5.13.0-14.14
Ubuntu-5.13.0-15.15
Ubuntu-5.13.0-16.16
Ubuntu-5.13.0-17.17
Ubuntu-5.13.0-18.18
Ubuntu-5.13.0-19.19
Ubuntu-5.13.0-20.20
Ubuntu-5.13.0-21.21
Ubuntu-5.13.0-22.22
Ubuntu-5.13.0-23.23
Ubuntu-5.13.0-24.24
Ubuntu-5.13.0-25.26
Ubuntu-5.13.0-26.27
Ubuntu-5.13.0-27.29
Ubuntu-5.13.0-28.31
Ubuntu-5.13.0-29.32
Ubuntu-5.13.0-30.33
Ubuntu-5.13.0-31.34
Ubuntu-5.13.0-32.35
freeze-20211018
freeze-20211108
freeze-20220131
freeze-20220221
v5.11
v5.13

The two tags that interest me, are Ubuntu-5.13.0-22.22 and Ubuntu-5.13.0-23.23. I’m starting with the former.

git checkout Ubuntu-5.13.0-22.22

First I copy the configuration of the current running kernel to the working directory:

$ cp /boot/config-$(uname --kernel-release) .config

I don’t want or need full debugging. That makes an enormous kernel and it takes twice as long to compile, so I turn debugging off:

$ scripts/config --disable DEBUG_INFO

I need to disable certificate stuff:

$ scripts/config --disable SYSTEM_TRUSTED_KEYS
$ scripts/config --disable SYSTEM_REVOCATION_KEYS

Next: update the kernel config and set all new symbols to their default value.

$ make olddefconfig

Then the most exciting thing can start: actually compiling the kernel!

$ make clean
$ time make --jobs=$(getconf _NPROCESSORS_ONLN) bindeb-pkg \
    LOCALVERSION=-$(git describe --long | tr '[:upper:]' '[:lower:]')
  • time is to see how long the compilation took.
  • getconf _NPROCESSORS_ONLN queries the number of processors on the computer. make will then try to run that many jobs in parallel.
  • bindeb-pkg will create .deb packages in the directory above.
  • LOCALVERSION appends a string to the kernel name.
  • git describe --long shows how far after a tag a certain commit is. In this case: Ubuntu-5.13.0-22.22-0-g3ab15e228151
    • Ubuntu-5.13.0-22.22 is the tag.
    • 0 is how many commits after the tag. In this case it’s the tag itself.
    • 3ab15e228151 is the abbreviated hash of the current commit.
  • tr '[:upper:]' '[:lower:]' is needed because .deb packages can’t contain upper case letters (I found out the hard way).

Now go grab a coffee, tea or chai latte. Compilation took 22 minutes on my computer.

Chai latte

When the compilation is done, there are 3 .deb packages in the directory above:

$ ls -1 ../*.deb
../linux-headers-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151_5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151-21_amd64.deb
../linux-image-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151_5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151-21_amd64.deb
../linux-libc-dev_5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151-21_amd64.deb

Install the linux-headers and the linux-image packages, you don’t need the libc-dev package.

$ sudo dpkg --install \
    ../linux-{headers,image}-*$(git describe --long | tr '[:upper:]' '[:lower:]')*.deb

The kernel is now installed in the /boot directory, and it’s available in the Grub menu after reboot.

$ ls -1 /boot/*$(git describe --long | tr '[:upper:]' '[:lower:]')*
/boot/config-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151
/boot/initrd.img-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151
/boot/System.map-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151
/boot/vmlinuz-5.13.19-ubuntu-5.13.0-22.22-0-g3ab15e228151

Kernel ubuntu-5.13.0-22.22-0-g3ab15e228151 is, for all intents and purposes, the same as kernel 5.13.0-22-generic, so I expected it to be a “good” kernel, and it was.

For kernel Ubuntu-5.13.0-23.23 I did the same thing: starting from the git checkout. I skipped copying and editing the config file, because between minor releases I don’t expect there to be much change. I did run make olddefconfig for good measure, though. As expected, the keyboard and mouse didn’t work with the compiled ...-23 kernel.

Next up: using git bisect to find the exact commit where it went wrong. It’s got to be somewhere between ...-22 and ...-23!

The hunt for a kernel bug, part 2: an easy way to install mainline kernels

As I wrote previously, I’m suspecting a Linux kernel bug somewhere between versions 5.13.0-22 and 5.13.0-23, in the Ubuntu kernels. I wanted to know if the issue only surfaced in Ubuntu-flavored kernels, or also in the upstream (mainline) kernels from kernel.org.

There is an Ubuntu Mainline PPA with all the upstream kernels, but I found it a bit too opaque to use. Fortunately I found the Ubuntu Mainline Kernel Installer (UMKI), a tool for installing the latest Linux kernels on Ubuntu-based distributions.

Ubuntu Mainline Kernel Installer (UMKI)

The UMKI is pretty straightforward. It fetches a list of kernels from the Ubuntu Mainline PPA and a GUI displays available and installed kernels, regardless of how they were installed. It installs the kernel, headers and modules. There is also a CLI client.

To install the UMKI:

sudo add-apt-repository ppa:cappelikan/ppa
sudo apt update
sudo apt install mainline

With that out of the way, there’s the matter of deciding which kernels to try. The “interesting” Ubuntu kernels are 5.13.0-22 and 5.13.0-23, so the mainline kernels I definitely want to test, are around those versions. That means 5.13.0 and 5.13.1. I also want to try the latest 5.13.x kernel, so that’s 5.13.19, and the most recent stable kernel, 5.16.11 (as of 2022-03-01).

To summarize, I have tested these mainline kernels:

  • 5.13.0
  • 5.13.1
  • 5.13.19
  • 5.16.11

The result (after several reboots)? With all of them, my keyboard and mouse worked without a hitch. That means the issue most likely doesn’t occur in (stable) mainline kernels, only in kernels with additional patches from Ubuntu.

Up next: compiling kernels from source.

Lasciate ogne speranza, voi ch’intrate.

Dante Alighieri

The hunt for a kernel bug, part 1

The operating system on my computer is Ubuntu Linux, version 21.10 (Impish Indri). Recently I had an issue that, after a kernel update (and reboot), my USB keyboard and mouse didn’t work any more in the login screen. Huh, that’s unexpected.
The issue was:

  • At the Grub boot menu, the keyboard works: I can use the keys, the numlock led lights up, the LCD of the Logitech G19 displays a logo.
  • At the Ubuntu login screen, the keyboard (and the mouse) went dark: no backlight of the keys, no numlock led, no logo on the display. And the mouse cursor didn’t move on screen.

Must be a problem at my end, I initially thought, because surely, something so essential as input devices wouldn’t break by a simple kernel update? So I did some basic troubleshooting:

  • Have you tried to turn it off and on again?
Have you tried to turn it off and on again?
Have you tried to turn it off and on again?
  • Plug the keyboard in another USB port.
  • Try a different keyboard.
  • Start with the older kernel, which was still in the Grub menu. And indeed, this gave me back control over my input devices!

So if the only thing I changed was the kernel, then maybe it’s a kernel bug after all?

I know that Ubuntu 21.10 uses kernel 5.something, and I know that I use the generic kernels. So which kernels are we talking about, actually?

$ apt-cache show linux-image-5*-generic | grep Package: | sed 's/Package: //g'
linux-image-5.13.0-19-generic
linux-image-5.13.0-20-generic
linux-image-5.13.0-21-generic
linux-image-5.13.0-22-generic
linux-image-5.13.0-23-generic
linux-image-5.13.0-25-generic
linux-image-5.13.0-27-generic
linux-image-5.13.0-28-generic
linux-image-5.13.0-30-generic

9 kernels, that’s not too bad. All of them 5.13.0-XX-generic. So I just installed all the kernels:

$ sudo apt install --yes \
    linux-{image,headers,modules,modules-extra,tools}-5.13.0-*-generic
One Eternity Later

My /boot directory is quite busy now:

$  ls -hl /boot
total 1,2G
drwxr-xr-x  4 root root  12K mrt  1 18:11 .
drwxr-xr-x 20 root root 4,0K mrt  1 18:11 ..
-rw-r--r--  1 root root 252K okt  7 11:09 config-5.13.0-19-generic
-rw-r--r--  1 root root 252K okt 15 15:53 config-5.13.0-20-generic
-rw-r--r--  1 root root 252K okt 19 10:41 config-5.13.0-21-generic
-rw-r--r--  1 root root 252K nov  5 10:21 config-5.13.0-22-generic
-rw-r--r--  1 root root 252K nov 26 12:14 config-5.13.0-23-generic
-rw-r--r--  1 root root 252K jan  7 16:16 config-5.13.0-25-generic
-rw-r--r--  1 root root 252K jan 12 15:43 config-5.13.0-27-generic
-rw-r--r--  1 root root 252K jan 13 18:13 config-5.13.0-28-generic
-rw-r--r--  1 root root 252K feb  4 17:40 config-5.13.0-30-generic
drwx------  4 root root 4,0K jan  1  1970 efi
drwxr-xr-x  5 root root 4,0K mrt  1 18:11 grub
lrwxrwxrwx  1 root root   28 feb 28 04:26 initrd.img -> initrd.img-5.13.0-22-generic
-rw-r--r--  1 root root  40M mrt  1 16:02 initrd.img-5.13.0-19-generic
-rw-r--r--  1 root root  40M mrt  1 17:39 initrd.img-5.13.0-20-generic
-rw-r--r--  1 root root  40M mrt  1 17:38 initrd.img-5.13.0-21-generic
-rw-r--r--  1 root root  40M feb 26 13:55 initrd.img-5.13.0-22-generic
-rw-r--r--  1 root root  40M mrt  1 17:40 initrd.img-5.13.0-23-generic
-rw-r--r--  1 root root  40M mrt  1 17:40 initrd.img-5.13.0-25-generic
-rw-r--r--  1 root root  40M mrt  1 17:41 initrd.img-5.13.0-27-generic
-rw-r--r--  1 root root  40M mrt  1 17:41 initrd.img-5.13.0-28-generic
-rw-r--r--  1 root root  40M mrt  1 17:38 initrd.img-5.13.0-30-generic
-rw-------  1 root root 5,7M okt  7 11:09 System.map-5.13.0-19-generic
-rw-------  1 root root 5,7M okt 15 15:53 System.map-5.13.0-20-generic
-rw-------  1 root root 5,7M okt 19 10:41 System.map-5.13.0-21-generic
-rw-------  1 root root 5,7M nov  5 10:21 System.map-5.13.0-22-generic
-rw-------  1 root root 5,7M nov 26 12:14 System.map-5.13.0-23-generic
-rw-------  1 root root 5,7M jan  7 16:16 System.map-5.13.0-25-generic
-rw-------  1 root root 5,7M jan 12 15:43 System.map-5.13.0-27-generic
-rw-------  1 root root 5,7M jan 13 18:13 System.map-5.13.0-28-generic
-rw-------  1 root root 5,7M feb  4 17:40 System.map-5.13.0-30-generic
lrwxrwxrwx  1 root root   25 feb 28 04:27 vmlinuz -> vmlinuz-5.13.0-22-generic
-rw-------  1 root root 9,8M okt  7 19:37 vmlinuz-5.13.0-19-generic
-rw-------  1 root root 9,8M okt 15 15:56 vmlinuz-5.13.0-20-generic
-rw-------  1 root root 9,8M okt 19 10:43 vmlinuz-5.13.0-21-generic
-rw-------  1 root root 9,8M nov  5 13:51 vmlinuz-5.13.0-22-generic
-rw-------  1 root root 9,8M nov 26 11:52 vmlinuz-5.13.0-23-generic
-rw-------  1 root root 9,8M jan  7 16:19 vmlinuz-5.13.0-25-generic
-rw-------  1 root root 9,8M jan 12 16:19 vmlinuz-5.13.0-27-generic
-rw-------  1 root root 9,8M jan 13 18:10 vmlinuz-5.13.0-28-generic
-rw-------  1 root root 9,8M feb  4 17:46 vmlinuz-5.13.0-30-generic

I tried all these kernels. The last kernel where my input devices still worked, was 5.13.0-22-generic, and the first where they stopped working, was 5.13.0-23-generic. Which leads me to assume that some unintended change was introduced between those two versions, and it hasn’t been fixed since.

For now, I’m telling Ubuntu to keep kernel 5.13.0-22-generic and not upgrade to a more recent version.

$ sudo apt-mark hold linux-image-5.13.0-22-generic
linux-image-5.13.0-22-generic set on hold.

I also want Grub to show me the known working kernel as the default change. To do that, I’ve put this in /etc/default/grub:

GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.13.0-22-generic"

followed by sudo update-grub.

I’ll do the following things next, to get to the bottom of this:

How I organize my message flow

Email

I use 2 email clients at the same time: Thunderbird and Gmail.

  • Thunderbird: runs on my local system, it’s very fast, it shows me all the metadata of an email in the way I want, the email list is not paged, I can use it for high volume actions on email. These happen on my local system, and then the IMAP protocol gradually syncs it to Gmail. I also find that Thunderbird’s email notifications integrate nicer in Ubuntu.
  • Gmail: can’t be beaten for search. It also groups mail conversations. And then there are labels!
How to turn on Conversation View in Gmail

Gmail has several tabs: Primary, Social, Promotions, Updates and Forums. Gmail is usually smart enough that it can classify most emails in the correct tab. If it doesn’t: drag the email to the correct tab, and Gmail will ask you if all future emails of that sender should go to the same tab. This system works well enough for me. My email routine is to first check the tabs Social, Promotions and Forums, and delete or unsubscribe from most emails that end up there. All emails about the #jobhunt go to Updates. I clean up the other emails in that tab (delete, unsubscribe, filter, archive) so that only the #jobhunt emails remain. Those I give a label – more about that later. Then I go to the Inbox. Any emails there (shouldn’t be many) are also taken care of: delete, unsubscribe, filter, archive or reply.

Enable Gmail tabs
Gmail tabs

Google has 3 Send options: regular Send, Schedule send (which I don’t use) and Send + Archive. The last one is probably my favorite button. When I reply to an email, it is in most cases a final action on that item, so after the email is sent, it’s dealt with, and I don’t need to see it in my Inbox any more. And if there is a reply on the email, then the entire conversation will just go to the Inbox again (unarchived).

Send + Archive

I love labels! At the level of an individual email, you can add several labels. The tabs are also labels, so if you add the label Inbox to an archived email, then it will be shown in the Inbox again. At the level of the entire mailbox, labels behave a bit like mail folders. You can even have labels within labels, in a directory structure. Contrary to traditional mail clients, where an email could only be in one mail folder, you can add as many labels as you want.
The labels are also shown as folders in an IMAP mail client like Thunderbird. If you move an email from one folder to another, then the corresponding label gets updated in Gmail.
The filters that I use in my #jobhunt are work/jobhunt, work/jobhunt/call_back, work/jobhunt/not_interesting, work/jobhunt/not_interesting/freelance, work/jobhunt/not_interesting/abroad, work/jobsites and work/coaching. The emails that end up with the abroad label, are source material for my blog post Working Abroad?

The label list on the left looks like a directory structure. It’s actually a mix of labels and traditional folders like Sent, Drafts, Spam, Trash,… Those are always visible at the top. Then there is a neat little trick for labels. If you have a lot of labels, like me, then Gmail will hide some of them behind a “More” button. You can influence which labels are always visible by selecting Show if unread on that label. This only applies to top-level labels. When there are no unread emails with that label or any of it’s sublabels, then the label will be hidden below the More button. As soon as there are unread mails with that label or any of it’s sublabels, then the label will be visible. Mark all mails as read, and the label is out of view. Again, less clutter, you only see it when you need it.

Show if unread

Filters, filters, filters. I think I have a gazillion filters. (208, actually – I exported them to XML so I could count them) Each time I have more than two emails that have something meaningful in common, I make a filter. Most of my filters have the setting ‘Skip Inbox’. They will remain unread in the label where I put them, and I’ll read them when it’s convenient for me. For example, emails that are automatically labelled takeaway aren’t important and don’t need to be in the Inbox, but when I want to order takeaway, I take a look in that folder to see if there are any promo codes.

Email templates. Write a draft email, click on the 3 dots bottom right, save draft as template. Now I can reuse the same text so that I don’t have to write for the umpteenth time that I don’t do freelance. I could send an autoreply with templates, but for now I’ll still do it manually.

LinkedIn

I can be short about that: it’s a mess. You can only access LinkedIn messages from the website, and if you have a lot of messages, then it behaves like a garbage pile. Some people also have an expectation that it’s some sort of instant messaging. For me it definitely isn’t. And just like with email: I archive LinkedIn chats as soon as I have replied.

I used to have an autoreply that told people to email me, and gave a link to my CV and my blog. What do you think, should I enable that again?

A small rant about dependencies (and a promise)

Every now and then I run into some awesome open source project on GitHub, that is written in some cool programming language, and it assumes that the development tools for that language are already installed. My assumption is that they have a specific target audience in mind: an already existing developer community around that specific language. People who already have those tools installed.

The annoying thing is when someone like me, who doesn’t really need to know if a thing is written in Python or Ruby or JavaScript or whatever, tries to follow instructions like these:

$ pip install foo
Command 'pip' not found
$ gem install bar
Command 'gem' not found
$ yarn install baz
Command 'yarn' not found
$ ./configure && make && sudo make install
Command 'make' not found

By now, I already know that I first need to do sudo apt install python3-pip (or the equivalent installation commands for RubyGems, Yarn, build-essential,…). I also understand that, within the context of a specific developer community, this is so obvious that it is often assumed. That being said, I am making a promise:

For every open source project that I will henceforth publish online (on Github or any other code sharing platforms), I promise to do the following things:
(1) Test the installation on at least one clean installed operating system – which will be documented.
(2) Include full installation steps in the documentation, including all frameworks, development tools, etc. that would otherwise be assumed.
(3) Where possible and useful, provide an installation script.

The operating system I’m currently targeting, is Ubuntu, which means I’ll include apt commands. I’m counting on Continuous Integration to help me test on other operating systems that I don’t personally use.

What are my preferred roles?

Definitely a halfling barbarian. Alignment: chaotic neutral.

Oh, you didn’t mean tabletop role playing but job roles? Riiiight…

I don’t think that this blog post will ever be complete, and it will always be evolving. But at this point, some of the things that I see myself doing:


Anything related to Continuous Delivery in software. From my perspective, that may include:

  • Test Automation – I’ve done this a lot, I liked it and wouldn’t mind doing more of it.
  • DevOps – I’m still not sure if DevOps must be a separate role, or if other roles can work better if they apply DevOps principles. That being said, I have done some devops-ish things, I liked it, and I would sure like to do more of it.
  • Software Development – There, I’ve put it in writing. I haven’t done this yet in a work context, but I like doing it and learning about it. And really – isn’t test automation also writing software?

Maybe you noticed that in none of these things I mention a specific technology. There may be tech&tools that I already have experience with, and you can read about that in my CV or on LinkedIn, but that is not what this blog post is about. I believe that technologies can (and should) always be learned, and it’s more of an attitude to work quality-driven.


Technical Storytelling or Technical Community Management
Storytelling can help simplify the complexities of new technologies. It’s a combination of technical skills, communication skills and empathy. It’s about supporting a community by creating helpful content, from sample code to tutorials, blog posts(*) and videos; speaking at conferences; and helping improve a product or technology by collecting feedback from the community. I recently read a blog post on this, and I can totally recognize myself there.

(*) Yes, the blog posts that I’m writing now, are also written with that kind of role in mind.


Also have a look at the roles that I am not interested in (but do get a lot of emails about).

What is my preferred region?

When recruiters contact me, I invariably get asked in what region I am willing to work. Well. It depends.
(scroll down for a map if you don’t want to read).

The thing is, I actually enjoy going from point A to point B. At the same time, if it is in much less than ideal situations (lots of traffic, or crowded public transportation), then I may get overstimulated, which leads to fatigue and lack of concentration. The least enjoyable commute was only 20km, by car, but it typically took me more than one hour. This was when a new bridge was constructed over the Scheldt in Temse.

The most pleasant work experiences I had, involved these commute patterns:

  • A 3km bicycle ride (about 10 minutes).
  • 30 km by car, with the first 15 minutes on almost empty rural roads, and then 25 minutes on a highway in the direction that had the least amount of traffic.
  • 5km, which I did on foot in 50 minutes (I was training for the Dodentocht at the time).
  • 40km, which I did with 5 minutes bicycle, 35 minutes train, 5 minutes walking. Ideal for listening to one or two episodes of a podcast. Doing the same distance by car would taken me about the same amount of time, in ideal conditions. And I can’t focus on traffic and listen to a podcast at the same time.
  • 6km, which was 20 minutes on a bicycle or 12 minutes by car. I preferred cycling, because I had separate bike lanes for about 80% of the way. 20 minutes was also an ideal amount of time to listen to one epidode of a podcast.

That looks like a lot of cycling, even though I don’t really consider myself to be an athletic type. It’s also eco-friendly, even though I don’t really consider myself to be an eco-warrior.

I’m not a petrol head, I don’t know anything about cars. 4 wheels and steering wheel, that’s about the limit of my knowledge. Currently I don’t even have a car, I make use of car sharing services like Cambio on the rare occasions that I actually need a car. At the same time, I do enjoy the experience of driving, especially long, smooth stretches. For example each year I go to a music course somewhere in the middle of Germany. That’s a 5 hour drive, not including stops. I absolutely love the change of scenery along the way. But but me in city traffic for an hour and I get too much input.

I have found a website where you can draw a map of the places you can reach within a certain time: TravelTime (the also have an API! ❤️).

This is a map I made with the following data:

  • Yellow: reachable by cycling in 30 minutes or less. That’s about all of the city center of Ghent.
  • Red: reachable by public transport in 1 hour or less. That doesn’t get me to Antwerp, Mechelen or Kortrijk, but Brussels and Bruges are just about reachable.
  • Blue: reachable by car in 45 minutes or less. That barely touches Antwerp. Brussels: the north, west and south edges. Kortrijk and Bruges are also within reach. Why the cutoff at 45 minutes? Well, I would need really, really good other motivations to consider Brussels. Some time ago I thought that 30 minutes would be my maximum, but it isn’t. I’d rather call it an optimum than a maximum.
TravelTime

Even with this map, I still have a personal bias. Most of my social life occurs somewhere in the triangle Ghent-Antwerp-Brussels. It becomes harder to do something after work when working in West-Flanders. It’s not a hard pass, just a preference.

I have more to tell on this topic, so I might update this blog post later.

Installing Ubuntu 20.04 LTS on 2011 MacBook Air

My laptop is a 2011 MacBook Air. I’m not a huge Apple fan, it’s just that at the time it had the most interesting hardware features compared to similar laptops. And it’s quite sturdy, so that’s nice.

Over the years I have experimented with installing Linux in parallel to the OS X operating system, but in the end I settled on installing my favorite Linux tools inside OS X using Homebrew, because having two different operating systems on one laptop was Too Much Effort. In recent times Apple has decided, in it’s infinite wisdom (no sarcasm at all *cough*), that it will no longer provide operating system upgrades for older hardware. Okay, then. Lately the laptop had become slow as molasses anyway, so I decided to replace OS X entirely with Ubuntu. No more half measures! I chose 20.04 LTS for the laptop because reasons. 🙂

The laptop was really slow…

According to the Ubuntu Community Help Wiki, all hardware should be supported, except Thunderbolt. I don’t use anything Thunderbolt, so that’s OK for me. The installation was pretty straightforward: I just created a bootable USB stick and powered on the Mac with the Option/Alt (⌥) key pressed. Choose EFI Boot in the Startup Manager, and from there on it’s all a typical Ubuntu installation.

screenshot
Startup Manager

I did not bother with any of the customizations described on the Ubuntu Wiki, because everything worked straight out of the box, and besides, the wiki is terribly outdated anyway.

The end result? I now have a laptop that feels snappy again, and that still gets updates for the operating system and the installed applications. And it’s my familiar Linux. What’s next? I’m thinking about using Ansible to configure the laptop.

To finish, I want to show you my sticker collection on the laptop. There’s still room for a lot more!

sticker collection on my laptop. Photo copyright: me.

Working abroad?

Occasionally (about 4% of people contacting me) I get a job offer for somewhere in another country.

This is a list of places outside of Belgium where people are apparently interested in having me. 😀

  • India (Hyderabad)
  • Germany (Berlin, Munich, Stuttgart, Wiesbaden)
  • United Kindom (London)
  • France (Paris)
  • Italy (Turin)
  • Spain (Madrid)
  • Poland
  • Netherlands (Amsterdam, Rotterdam, The Hague, Utrecht, Eindhoven, Groningen, Almere, Arnhem, Maastricht, Leiden, Deventer, Delft, Heerenveen)
  • Sweden (Stockholm)
  • Austria (Graz)
  • Switzerland (Zurich)
  • Norway (Stavanger)
  • Luxembourg (Luxembourg City, Pétange)

I have never considered moving permanently to another country for work, and I wouldn’t feel comfortable to move to a country where I don’t speak the language. Even if the company language is English, I would still need to communicate with people in everyday life, for example going to the shop. So from the list above, only France and the Netherlands would remain.

Besides the language, there is still the matter of being cut off from the people who matter to me. Yes there is the internet, and during the pandemic there was virtually no other way to stay in touch, but still… it’s not the same. I already have some friends in the Netherlands, so (hypothetically) I would feel less alone there. But there are still plenty of interesting local companies to work for, so no thanks for now.

Have you ever been invited to work abroad? If yes, what was your motivation for doing so? What were your experiences? Feel free to share in the comments!

Thanks, but no thanks

After reading a few hundred emails from recruiters, I see a couple of trends popping up. I’m being contacted for job offers that really aren’t relevant or interesting for me. Some of them may be attributed to automatic keyword scanning. But still. If possible, I would kindly ask everyone not to contact me for any of the following:

  • Freelance: I have never done freelance before. Working freelance means that I would first have to start all the paperwork to become self-employed, and at this moment I’m not interested in doing all that. Maybe that could change in the faraway future, but at this point in my life I prefer permanent positions.
  • C/C++ embedded development: At one of my previous jobs, I did testing on the embedded software of a smart printer. Testing. Not development. I have never written a single line of C or C++ in my life. I would probably be able to read and understand other people’s code, but I’m sure that there are plenty of people who are really fluent in C/C++.
  • Drupal development: A long, long time ago, I made and maintained a few small Drupal sites. I have also been to one or two Drupal Dev Days in the early 2000s. I think I still have a T-shirt somewhere. But in all that time, I only did Drupal admin, I never went into the itty-gritty PHP to write custom Drupal code. And I’m pretty sure that my Drupal skills are quite rusty now.
  • Node.js development: Oh dear. I did a few tiny Node.js projects: some “glue code”, some rapid prototyping. Nothing fancy, nothing production quality, never more than 100 lines of code. Let’s not do that.
    EDIT 2021-10-25: I may have changed my opinion on this one! More about this in an upcoming blogpost.
    EDIT 2021-10-29: it’s online: What are my preferred roles.
  • SharePoint development: With the eternal words of William Shakespeare:

Fie on’t! ah fie! ’tis an unweeded garden,
That grows to seed; things rank and gross in nature
Possess it merely. That it should come to this!

Hamlet, Act I, Scene ii

  • Quality Control Operator: This is typically a case of blindly searching for keywords and not verifying the results. I have worked as a Software Quality Engineer, so if you search only for “quality”, you’ll end up with jobs where you do actual physical inspection of physical products. Rule of thumb: if I can’t test it with an Assert-statement in some kind of programming language, then it’s probably not the kind of “quality” that I’m looking for.
  • Production / “blue collar jobs”: Yeah well let’s not do that at all, shall we? With all due respect for the people who do this type of work, and some of it is really essential work, but I don’t think that this would ever make me happy.
  • First line tech support: Been there, done that, got the battle scars. Never again, thank you very much.

Benefits for not contacting me for any of these: you don’t waste time chasing a dead-end lead, and I can spend more time on reading and reacting to job offers that actually are relevant, interesting and even exciting. Everybody happy! 🙂