Skip to main content
  1. Posts/

l2k25 - OpenBSD Hackathon Leipzig 2025

·1096 words·6 mins· loading · loading ·
Rafael Sadowski
Author
Rafael Sadowski
Shut up and hack
Table of Contents

The l2k25 Leipzig Hackathon was only a short weekend trip for me. I could only attend for a long weekend, but that was enough to get a lot done and have a great time with my favorite project.

Since I had a quarterly Platform Engineering/AI core team meeting at my company in Düsseldorf beforehand, my journey to l2k25 started early Friday morning with the ICE train from Düsseldorf to Leipzig. I spent the morning on the train handling work tasks. Shortly before Leipzig, I closed my Computacenter MacBook and grabbed my OpenBSD ThinkPad. Hackathon time!

In the days before the hackathon, I was annoyed about our LXQt ports again. No one maintains them, but some people use them. Since LXQt fits into the Qt ecosystem and had some annoying old dependencies, I wanted to update it. I came across it when updating some ports from Qt5 to Qt6.

It would be helpful if maintainers could check whether there’s a button to enable Qt6. Often, this already exists. This would allow us to switch to Qt6, as my goal is to eventually get rid of Qt5. I know it will take a few more orbits around the sun.

At l2k25, I focused most of my energy on bug fixes and improvements to Qt6 and KDE in OpenBSD. Let me start with the biggest issue, as it fixes many problems.

QNetworkInformation
#

QNetworkInformation::instance provides a pointer, and if the ::loadBackendBy* call fails, it returns nullptr. According to the documentation, this behavior is expected. Unfortunately, there’s no working NetworkManager (QGNetworkManager plugin also not working properly), so ::instance provides a nullptr pointer on OpenBSD. More info: QNetworkInformation docs

Some programs don’t check for this case. Attentive readers might remember my last hackathon from Japan.

Unfortunately, several Akonadi modules continue to crash when loading models:

akonadi_followupreminder akonadi_ical_resource akonadi_maildispatcher_agent akonadi_mailmerge_agent akonadi_sendlater_agent

That’s exactly the problem. I was able to identify all these issues and fix them. I haven’t found time to push the fixes upstream yet, but the result is now a crash-free KDE PIM stack under OpenBSD!

The cool thing is that this also fixes the KDE Plasma WeatherEngine widget. This allows us to configure weather settings in KDE Plasma.

Qt6 ports infrastructure improvements
#

I was able to fix the tests in x11/qt6/qtbase, and they can be run if desired. The results look relatively good, considering that we’re not officially supported.

-Wl,-undefined,error and -Wl,--no-undefined are set by default in all Qt6 ports that use QtFlagHandlingHelpers.cmake. Based on a FreeBSD diff, I removed these flags.

I added LC_CTYPE=C.UTF-8 in qt6.port.mk. The reason is to eliminate the following warning during the build:

# Detected locale "C" with character encoding "US-ASCII", which is not UTF-8.
# Qt depends on a UTF-8 locale, and has switched to "C.UTF-8" instead.

This means that all Qt6 ports now have the following set at build time:

CONFIGURE_ENV += LC_CTYPE=C.UTF-8
MAKE_ENV +=      LC_CTYPE=C.UTF-8

While setting LC_CTYPE at build time seems straightforward, there are several concerns worth considering:

Build vs. Runtime Environment: The build environment typically doesn’t leak to end users, so setting locale variables during compilation is generally safe. However, it’s better to set only LC_CTYPE rather than LC_ALL, since other LC_* variables don’t function on OpenBSD anyway. Setting them provides no benefit but might mislead build systems into thinking we support features we don’t.

Runtime Implications: The more pressing question is what this means for actual Qt6 application usage. Locales are fundamentally user settings, not system configuration. If Qt6 requires UTF-8 locales to function properly, what happens when users run Qt6 applications with no LC_* variables set (default)? From what I understand, there’s a fallback to C.UTF-8.

Last but not least, I merged the latest published Qt6 CVE fixes (CVE-2025-5455, CVE-2025-6338, CVE-2025-5683), although these were fairly straightforward patches.

poll() busy-loop on socket close with POLLOUT
#

This short section describes a very interesting fix I found through FreeBSD.

Let’s look at the code part in sys/kern/sys_generic.c:

if (pl[i].events != 0 && pl[i].events != POLLOUT)
    DPRINTFN(0, "weird events %x\n", pl[i].events);

It seems like we have the same behavior as FreeBSD:

https://codereview.qt-project.org/c/qt/qtbase/+/651677

“On FreeBSD when asked for POLLOUT the poll() syscall returns only POLLHUP to signify the fact that the other side closed the connection. It never sends POLLERR for EOF cases, which results in a busy-loop inside the Glib dispatcher:

  • poll() returns immediately with POLLHUP for a closed socket
  • socketNotifierSourceCheck() does not detect it, because events = POLLOUT | POLLERR and we get .revents = POLLHUP. The (events & revents != 0) condition evaluates to false
  • the code decides there is nothing to do and a new iteration starts”

A similar issue in dbus code: GitLab freedesktop dbus.

The two fixes for dbus and qt6 are now loaded in OpenBSD.

Itinerary
#

What I find really cool is that thanks to the QNetworkInformation fix, Itinerary now works! We were able to import x11/kde-applications/itinerary. It’s a major KDE application that can be really helpful for travelers. Check it out.

General ports tree activities
#

During the hackathon, I had the idea to ask in chat if anyone needed something ported. That’s when databases/duckdb came up. I vaguely remembered there had been a suggestion on ports@. I picked it up, updated it to the latest version, and sent a new suggestion to ports@.

On my mission to get rid of Qt5 and py-qt5, I stumbled across textproc/calibre. I’m not quite done with it yet because the dependency chain is very long, but I’m confident I’ll get it done before 7.8.

compiler-rt, libunwind, libcxx, libcxxabi 19.1.7
#

My GitHub supporters who read the newsletter have known for some time that I’ve been working on this. At the hackathon, I had the opportunity to chat with several people, and we all agreed: the sooner we commit this before the release, the better. I didn’t have to work on it much during the hackathon since everything was already finished and the ports tree was in good shape. Thanks again to the whole team, especially tb@ and phessler@, who provided lots of support with ports bulk builds.

I’m really happy we managed to get this done before 7.8, and I’m a bit proud that I conquered this huge update. This was my first big update in src.

In the end, the compiler-rt, libunwind, libcxx, libcxxabi 19.1.7 update gives us a C++ implementation with new C++20, C++23 and C++26 features in the base system.

Thanks
#

A big thank you goes out to Jan Klemkow, Alexander Bluhm, all Genua OpenBSD hackers, and the OpenBSD Foundation for making this happen! Special thanks to our supporter Genua.