GNU Hurd development blog: 2026-q2
Hello and welcome to another Qoth! Here’s what’s been happening in Q2
of 2026!
Joshua Branson added a pretty cool svg logo for our ethernet
multiplexor. He built that image
with Inkscape whilst using a Hurd laptop (Thinkpad 420) running on
real iron! The Hurd wiki could certainly use more artwork. Perhaps
you have a favorite Hurd translator that you believes needs some
artwork!
Sergey Bugaev announced his WIP
9pfs
(source code),
and it has a wiki page! He writes:
Some years ago, I experimented with implementing a 9P translator for
the Hurd. Hopefully there is no need to tell this list what 9P is :)
Besides just browsing files on the few existing servers out there, a
potential use case is virtio-9p, to enable shared directory trees
between VMs and the host. But that would need someone to implement
virtio support in the Hurd.
I wanted to complete 9pfs before publishing, but that ultimately
didn't happen, so now it's time to turn it over to the community. I
now went and made the repository public on GitHub:
https://github.com/bugaevc/9pfs
What's implemented is basic browsing (readdir, stat), path resolution
(dir_lookup), and reading files (io_read). And below that, the whole
tracking for nodes, peropens, protids, fids, tags, and 9p RPCs.
Improvements are welcome, send patches to this list with [PATCH 9pfs]
in the subject. A good starting point would be to continue porting
things that I had implemented in the old netfs-based version (see
netfs.c) but didn't yet port to the new one.
He then got a little more motivated, and he added some write support!
Etienne Brateau added
validation
to msync, so
that the Hurd better follows POSIX.
Diego Nieto Cid worked on allowing privileged users to set their task
priority (nice value). His patches landed in
glibc
and GNU
Mach.
He also fixed a tiny
bug
in our test suite. He fixed an adjtime bug, which is helpful to the
OpenNTPD
port,
and he fixed
two more
bugs.
Paulo Duarte sent a RFC patch series trying to commit Sergey’s
previous AArch64 work. He writes:
This series adds the gnumach kernel-side implementation for the
aarch64 ABI Sergey landed in April 2024, plus the test-suite arms.
Patch 01 brings in the aarch64-only sources from bugaevc/wip-aarch64
verbatim, with Sergey as Author; the rest is mine.
The meaningful divergence from wip-aarch64 is what I left out:
roughly 150 files of cross-arch refactoring across kern/, ipc/, vm/,
device/intr.{c,h}, and the i386 tree. Each got replaced with a
smaller per-arch shim under aarch64/ so kern/bootstrap.c,
device/intr.{c,h}, kern/lock.h, and the i386 trees all stay
bit-identical to current master. The shared-file footprint outside
aarch64/ is four files: a new ELF constant, two missing decls plus
their include, and a linker-symbol filter extension...
Tested: 12/12 pass on x86_64, i686, and aarch64 under qemu. No
bare-metal validation yet. I plan to build bootable images and boot
the kernel on Apple M1 / Raspberry Pi (aarch64) and an x86_64 box
(x86_64 + i686). Help on any of these welcome.
He also fixed a tiny cross compilation issue.
gfleury fixed some tmpfs
typos.
He also fixed a kernel crash on a null pointer
deference.
Almudena Garcia is developing a WIP trivfs implementation in
rust. The work is
not complete yet, but it is possible to write Hurd translators in Rust!
Mikhail Karpov added some checks for mmap in several places.
He also worked on adding storeio to the bootstrap
chain.
This is actually quite interesting. Currently the Hurd sets device
entries in /dev/ statically. For example, I am writing this qoth on
a Hurd machine that is using two /dev/ entries for my filesystem:
/dev/wd0s1 for swap and /dev/wd0s5 for my root filesystem.
However, /dev/wd0s1 through /dev/wd0s16 exist on my computer!
Once Mikhail’s project is done, then the Hurd will dynamically
populate SATA devices at boot time! No more need for static
translators! He
writes:
I've expanded the functionality of the partfs translator to work
with multiple disks and their partitions. Thus, by running the
command:
settrans -c partfs /hurd/partfs /root/disk1.img /root/disk2.img /root/disk3.img
The translator directory will have the following directory tree:
partfs
├── 0
│ ├── 1
│ ├── 2
│ └── ...
├── 1
│ ├── 1
│ ├── 2
│ └── ...
├── 2
│ ├── 1
│ ├── 2
│ └── ...
Since the disks are directories, the cd and ls commands work in the translator node.
I also tested mounting, reading, and writing using the commands:
`settrans -c ext01 /hurd/ext2fs -w -T typed file:/root/partfs/0/1`
and
`settrans -c ext1_1 /hurd/ext2fs -w -T typed part:1:file:/root/partfs/1`
It actually is even cooler! Samuel (our fearless leader) is seeking
feedback
for how to name these newer /dev entries. Samuel writes:
One thing that would be really needed for efficiency is to implement
netfs_file_get_storage_info, so that libstore would be able to get the
underlying storage information, and directly get data from there rather
than partfs having to pass data with io_read/write.
I'm then wondering how this would fit in the "grand scheme". Our current
approach, /dev/hd0s* being always there, is indeed not really good
because it doesn't easily tell the user which partitions are actually
there. We used to have to have this because partitions used to be
handled by the kernel, and then we have moved to
storerio+parted-supported partitions, which brings much more
flexibility.
Perhaps we could use
settrans -c /dev/hd0s /hurd/partfs /dev/hd0
and then we'd have /dev/hd0s/1, which is almost like before, but allows
the entries to be dynamic. Actually, we could even have some
settrans -c /dev/hd /hurd/probedisk hd
and then we'd have /dev/hd/0, and we could have /dev/hd/0s being partfs,
so we'd eventually have
/dev/hd/0s/1
But I'm also thinking that perhaps it could be integrated more with
storeio, i.e. /dev/hd0 can as well also act as a directory with partfs
behavior, so you could have
/dev/hd0/1
and with the probedisk translator, you could have
/dev/hd/0/1
What do people think about it?
Mike Kelly has been hard at work porting OpenBSD’s
OpenNTPD,
which required some glibc work. The Hurd doesn’t currently have a
NTP daemon, so thanks Mike!
He also debugged a weird memory error with
rump,
and he provided a “brown-tape”
solution
for it. Hopefully, he (or you dear reader), can reach out to the
NetBSD people to fix this bug. This just goes to show that when two
projects use the same code, both projects benefit!
He also got a glibc patch
committed.
Essentially SIGSTOP/SIGCONT was duplicating portions of files,
which is now fixed. However, there are still some other
issues
with building some haskell packages.
Joan Lledó continued his work
on
porting
dhcpcd.
Also Roy Maples, the dhcpcd maintainer did a lot of helpful work to
help us out. Thanks Roy!
Bradley Morgan fixed a tiny implementation bug with
cat. He
also tweaked procfs to show hidden
files,
and he allowed passing “-s” to
init.
Previously, passing “-s” to init was silently ignored.
Johannes Schauer Marin Rodrigues has been working on getting s-build
to run on amd64
Hurd. It
is a rather long email thread, so grab some popcorn and dig in!
Milos Nikic ported
Neovim.
He also worked on
bug
fixes
to
libdiskfs,
and he fixed a deadlock bug in the “ext3/ext4” filesystem
journal.
In the last qoth we had talked about how the Milos was working on
adding an ext3/ext4 binary compatible journal. Samuel has committed
it! Samuel wrote:
There is a couple things that I fixed on the fly:
- We want to use pthread_cond_clockwait rather than
pthread_cond_timedwait, to be able to use CLOCK_MONOTONIC instead of
CLOCK_REALTIME, to avoid being hit by ntpdate and such.
- In diskfs_S_dir_rename, there was an addition of:
pthread_mutex_unlock (&fnp->lock);
which was clearly bogus: we were unlocking it again below.
There are a couple things that we'd want to fix now:
- when calling diskfs_file_update, don't we have to be inside a
transaction? Otherwise if we pass wait=1 and use a journal, we won't
be waiting AIUI? Notably, in diskfs_S_dir_rmdir we don't use a
transaction. And ideally we'd have an assertion that makes sure we
respect this.
- we should define some helper for this recurring pattern:
if ((docommit) && (diskfs_synchronous || diskfs_journal_needs_sync (txn)))
diskfs_journal_commit_transaction (txn);
else
diskfs_journal_stop_transaction (txn);
- journal_drain_deferred_blocks should document what it does, not just
its call conditions :), and more generally the functions that are
not already documented in a .h and not just a _locked variant of a
documented function.
Leonardo Lopes Pereira did some spring
cleaning
to remove some dead
code.
Samuel Thibault mentioned in an
email
that the Hurd can support nvmes with rump, but that the work was just
not done yet. Perhaps you, dear reader, would like to help us
accomplish this task?
The mysterious user yelini worked on porting the D language compiler.
Damien Zammit worked on tweaking the Hurd’s WIP
CI.
He also
fixed
several
bugs
to make it possible to run the Hurd’s test suite from GNU/Linux
running on an AArch64 computer. He also is working on integrating
qemu’s Hurd support into upstream qemu’s
CI,
so that the support does not bitrot.
Sophiel Zhou fixed a tiny pfinet permission checking
issue
and taught pfinet to not fail under memory pressure:
This series fixes two latent crash bugs in pfinet where mmap
return values go unchecked, may causing crash when memory is tight.
Both bugs follow the same pattern: mmap is called to grow a buffer,
but the returned pointer is dereferenced before (or without) checking
for MAP_FAILED. Under normal operation mmap rarely fails, so these
have gone unnoticed, but under address-space pressure pfinet would
crash.
Source: Planet GNU