Stream: git-wasmtime

Topic: wasmtime / PR #14294 `wasmtime serve`: Allow inheriting s...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 20:56):

simolus3 opened PR #14294 from simolus3:serve-listenfds to bytecodealliance:main:

This adds the --listenfd option to wasmtime serve. When it's enabled and wasmtime is launched from a systemd socket unit, we use the socket created by systemd instead of creating a new one. The main benefit of this is efficiency: The wasmtime process is only started when the first client connects. Additionally, this allows sandboxing the process in a private network namespace (since the only socket it will use is inherited).

To test this, the systemfd utility may be convenient:

systemfd -s http::5000 -- cargo run -- serve file.wasm --listenfd

This also removes the old -S listenfd option: The only place using that option was a check that errors when it's set.

Closes https://github.com/bytecodealliance/wasmtime/issues/14289. As suggested in that thread, I've also linked the used systemd protocol for this in a comment.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 20:56):

simolus3 requested pchickey for a review on PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 20:56):

simolus3 requested wasmtime-core-reviewers for a review on PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 20:56):

simolus3 requested alexcrichton for a review on PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 20:56):

simolus3 requested wasmtime-default-reviewers for a review on PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 21:18):

:memo: bjorn3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 21:18):

:speech_balloon: bjorn3 created PR review comment:

Would it make sense to emit an explicit error outside Unix rather than treat it as non-existent flag?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 21:21):

:memo: bjorn3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 21:21):

:speech_balloon: bjorn3 created PR review comment:

This should probably be called at the start of main to ensure no other fd takes the place of a missing fd, violating I/O-safety.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2026 at 22:44):

github-actions[bot] added the label wasmtime:docs on PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 06:47):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 06:53):

:memo: simolus3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 06:53):

:speech_balloon: simolus3 created PR review comment:

I've changed that now to be called at the beginning of the command, but it's somewhat ugly.

What is this supposed to defend against, someone passing the LISTEN_FDS environment variable but no file descriptors? We only consider AF_INET sockets and this runs before the components so I don't see how we could confuse this with another fd.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:27):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:27):

:speech_balloon: alexcrichton created PR review comment:

The implementation in this crate looks pretty thin -- would it be possible to vendor the implementation here? Given that this is in theory a protocol set by someone else it seems like it shouldn't be changing all that much.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:27):

:speech_balloon: alexcrichton created PR review comment:

This looks like it's a man page for a function in a library somewhere, but do you know if there's documentation on what systemd does beyond this manpage? I'm not sure where this function lives, for example, and whether it's expected to link against this C library and this C library only to do things. Glancing at the listenfd crate it's not processing all the env vars that this function seems to document, so I'm not sure of the discrepancy there.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:27):

:speech_balloon: alexcrichton created PR review comment:

Should this perhaps be named something like systemd_listenfd? This seems specific to systemd itself and a bland name like --listenfd sounds like it's a more general option. Do you know if there happens to be a convention about how this is handled by other tools?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:49):

:memo: bjorn3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:49):

:speech_balloon: bjorn3 created PR review comment:

This function is in libsystemd. I seem to recall that at some point the systemd docs actually contained a standalone C implementation to copy into programs that otherwise don't depend on libsystemd, so it is definitively intended for this interface to be usable without libsystemd.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:50):

:memo: bjorn3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 14:50):

:speech_balloon: bjorn3 created PR review comment:

There is nothing intrinsically tying listenfd to systemd. The systemfd util implements the same interface and there is no reason other init systems can't implement it either.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:44):

:memo: simolus3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:44):

:speech_balloon: simolus3 created PR review comment:

Apologies, I was not familiar with the concept of IO safety. I'll find a way to call this first thing in main().

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:52):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:52):

:speech_balloon: alexcrichton created PR review comment:

Personally I wouldn't sweat this too much. I don't think it's worth contorting Wasmtime's CLI to make it apparent that this is happening right as fn main starts -- Wasmtime controls all the CLI entrypoints anyway. Where it currently is looks fine to me, and it's all during startup/CLI processing anyway so anywhere around there is fine.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:53):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 18:53):

:speech_balloon: alexcrichton created PR review comment:

This might then tie into my above question -- if the only documentation for this functionality is a man page for a function in libsystemd that doesn't sound like a generally reusable primitive, but if there's some documentation which is more general I think that would be good to have as a case for not naming this systemd-specific.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:18):

:memo: bjorn3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:18):

:speech_balloon: bjorn3 created PR review comment:

Before the portability page of systemd got changed to just list a general policy, it explicitly listed LISTEN_FDS as being a stable interface that is reimplementable independently of systemd: https://github.com/systemd/systemd/blob/0c40aef7ef1419233826b6fb7ccac12f7623033b/docs/PORTABILITY_AND_STABILITY.md

FWIW this is not the only generally reusable interface that is effectively only documented in the systemd man pages. Another example is /etc/os-release (replacement for /etc/lsb-release and distro specific files like /etc/debian_version), or /etc/machine-id (normally has the same value as /var/lib/dbus/machine-id). The "Boot Loader Specification" also originates from systemd, but nowadays Grub and Limine also supports it, not just sd-boot (this one has a specification at https://uapi-group.org/specifications/specs/boot_loader_specification/ though).

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:49):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:50):

:memo: simolus3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:50):

:speech_balloon: simolus3 created PR review comment:

I've vendored the implementation. I've also taken inspiration from command-fds and @bjorn3's suggestion to call this as early as possible.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:52):

:memo: simolus3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 19:52):

:speech_balloon: simolus3 created PR review comment:

The man page describes the protocol, in the "Notes" section:

Internally, sd_listen_fds() checks whether the $LISTEN_PID environment variable equals the daemon PID. If not, it returns immediately. [...] It parses the number passed in the $LISTEN_FDS environment variable, then sets the FD_CLOEXEC flag for the parsed number of file descriptors starting from SD_LISTEN_FDS_START. Finally, it returns the parsed number.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 08 2026 at 20:22):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:memo: alexcrichton submitted PR review:

Thanks! I've got some suggestions to use rustix instead of libc since that helps us with more typesafe/safe wrappers, and I've additionally put a comment about moving the handshake-style protocol to just one function called in serve.rs. Otherwise looks reasonable to me.

Also, sorry I forgot this earlier, but can you add a test for this as well? It's difficult to keep functionality like this working if it doesn't have any tests.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:speech_balloon: alexcrichton created PR review comment:

Could this use rustix::io::fcntl_setfd with error handling?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:speech_balloon: alexcrichton created PR review comment:

Could this use rustix::fs::fstat for safe bindings?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:speech_balloon: alexcrichton created PR review comment:

Could this use rustix::net::sockopt::socket_type for a safe alternative?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:speech_balloon: alexcrichton created PR review comment:

Could this use rustix::net::getsockname for a safe alternative?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 04:32):

:speech_balloon: alexcrichton created PR review comment:

Personally I would prefer to keep all the serve.rs-related code in serve.rs and avoid extra abstractions here (which have more #[cfg] which is more to validate, etc). I think it'd be fine to have init_inherited_fds marked unsafe, that returns the inherited sockets, and the // SAFETY ... comment on the call in serve.rs is high enough in the function that it's clear that nothing happens inbetween. That should keep everything contained without the need for more #[cfg] without compromising on safety.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 10 2026 at 21:24):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 10 2026 at 21:34):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 10 2026 at 22:32):

:memo: alexcrichton submitted PR review:

One question about returning an error if multiple sockets are inherited, but @simolus3 what do you think about calling this option --systemd-listenfd vs --listenfd?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 10 2026 at 22:32):

:speech_balloon: alexcrichton created PR review comment:

Could this use the send_request function? Otherwise this looks like a bit of duplication with what that's doing.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 10 2026 at 22:32):

:speech_balloon: alexcrichton created PR review comment:

Should this perhaps return an error if therea re multiple TCP sockets listed? Because otherwise using the first feels like it might lead to odd behavior if that happens to be the wrong one

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 10:17):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 10:19):

:memo: simolus3 submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 10:19):

:speech_balloon: simolus3 created PR review comment:

I've made that an error. I have also changed the function to error if no socket is passed at all, since it might be surprising to explicitly indicate that inherited sockets are requested with --systemd-listenfd only to then have wasmtime listen itself because of a mismatched environment variable that's ignored.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 10:21):

:speech_balloon: simolus3 edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 14:22):

:thumbs_up: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 14:22):

alexcrichton added PR #14294 wasmtime serve: Allow inheriting sockets from system manager to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 14:49):

github-merge-queue[bot] removed PR #14294 wasmtime serve: Allow inheriting sockets from system manager from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 14:53):

alexcrichton commented on PR #14294:

Ah the failure in CI is on a target where we're cross-compiling and running tests in QEMU. The best fix is to probably look at wasmtime_test_util::cargo_test_runner() and if that's Some then to just skip this test

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:14):

simolus3 updated PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:19):

simolus3 edited PR #14294:

This adds the --systemd-listenfd option to wasmtime serve. When it's enabled and wasmtime is launched from a systemd socket unit, we use the socket created by systemd instead of creating a new one. The main benefit of this is efficiency: The wasmtime process is only started when the first client connects. Additionally, this allows sandboxing the process in a private network namespace (since the only socket it will use is inherited).

To test this, the systemfd utility may be convenient:

systemfd -s http::5000 -- cargo run -- serve file.wasm --systemd-listenfd

This also removes the old -S listenfd option: The only place using that option was a check that errors when it's set.

Closes https://github.com/bytecodealliance/wasmtime/issues/14289. As suggested in that thread, I've also linked the used systemd protocol for this in a comment.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:25):

simolus3 commented on PR #14294:

Done!

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:28):

alexcrichton added PR #14294 wasmtime serve: Allow inheriting sockets from system manager to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:54):

:check: alexcrichton merged PR #14294.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 18:54):

alexcrichton removed PR #14294 wasmtime serve: Allow inheriting sockets from system manager from the merge queue.


Last updated: Sep 20 2026 at 18:08 UTC