patches and low-level development discussion
 help / color / mirror / code / Atom feed
From: Demi Marie Obenour <demiobenour@gmail.com>
To: Spectrum OS Development <devel@spectrum-os.org>
Cc: Demi Marie Obenour <demiobenour@gmail.com>, Alyssa Ross <hi@alyssa.is>
Subject: [PATCH 08/20] Standardize directories and symlinks in images
Date: Thu, 04 Sep 2025 17:26:30 -0400	[thread overview]
Message-ID: <20250904-systemd-v1-8-2a63b790a913@gmail.com> (raw)
In-Reply-To: <20250904-systemd-v1-0-2a63b790a913@gmail.com>

There are a few directories and symbolic links that a Linux system
should always have.  Even if Spectrum OS itself does not use them,
third-party dependencies and/or applications might rely on them.
Create these in scripts/make-erofs.sh rather than separately in
each VM's build scripts.  The creation of /run/lock assumes that
s6-linux-init is being used, but that assumption is easy to fix later.
This also enforces that the symlinks and directories were *not* created
in other places.  The app VM build violated this rule, so fix it.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
 host/rootfs/Makefile   |  15 ++------
 host/rootfs/bin        |   1 -
 host/rootfs/lib        |   1 -
 host/rootfs/sbin       |   1 -
 img/app/Makefile       |   8 ++--
 img/app/bin            |   1 -
 img/app/default.nix    | 101 +++++++++++++++++++++++++++++--------------------
 img/app/sbin           |   1 -
 scripts/make-erofs.sh  |  34 +++++++++++++++++
 vm/sys/net/Makefile    |   8 +---
 vm/sys/net/bin         |   1 -
 vm/sys/net/default.nix |   2 +
 vm/sys/net/lib         |   1 -
 vm/sys/net/sbin        |   1 -
 vm/sys/net/var/run     |   1 -
 15 files changed, 106 insertions(+), 71 deletions(-)

diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index dce78e60bc1a8c18f5f448aaa9aeed2c8a7da04e..6cdbac201257faedb70344bcfd5cf9d4fd25b507 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -54,7 +54,6 @@ FILES = \
 	etc/s6-linux-init/scripts/rc.init \
 	etc/xdg/weston/autolaunch \
 	etc/xdg/weston/weston.ini \
-	usr/share/dbus-1/services/org.freedesktop.portal.Documents.service \
 	usr/bin/assign-devices \
 	usr/bin/create-vm-dependencies \
 	usr/bin/run-appimage \
@@ -63,10 +62,10 @@ FILES = \
 	usr/bin/vm-import \
 	usr/bin/vm-start \
 	usr/bin/vm-stop \
-	usr/bin/xdg-open
+	usr/bin/xdg-open \
+	usr/share/dbus-1/services/org.freedesktop.portal.Documents.service
 
 DIRS = \
-	dev \
 	etc/s6-linux-init/env \
 	etc/s6-linux-init/run-image/configs \
 	etc/s6-linux-init/run-image/service/dbus/instance \
@@ -90,14 +89,11 @@ DIRS = \
 	etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/instances \
 	etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/data \
 	etc/s6-linux-init/run-image/service/xdg-desktop-portal-spectrum-host/template/env \
-	etc/s6-linux-init/run-image/user \
 	etc/s6-linux-init/run-image/vm/by-id \
 	etc/s6-linux-init/run-image/vm/by-name \
 	etc/s6-linux-init/run-image/wait \
 	ext \
-	run \
-	proc \
-	sys \
+	root \
 	var
 
 FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
@@ -105,11 +101,8 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
 # These are separate because they need to be included, but putting
 # them as make dependencies would confuse make.
 LINKS = \
-	bin \
 	etc/s6-linux-init/run-image/opengl-driver \
-	etc/s6-linux-init/run-image/service/vmm/template/run \
-	lib \
-	sbin
+	etc/s6-linux-init/run-image/service/vmm/template/run
 
 BUILD_FILES = build/etc/s6-rc
 
diff --git a/host/rootfs/bin b/host/rootfs/bin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/host/rootfs/bin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/host/rootfs/lib b/host/rootfs/lib
deleted file mode 120000
index 0d5487ba8608d4d1a7328cf8a4e0242d1988c491..0000000000000000000000000000000000000000
--- a/host/rootfs/lib
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib
\ No newline at end of file
diff --git a/host/rootfs/sbin b/host/rootfs/sbin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/host/rootfs/sbin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/img/app/Makefile b/img/app/Makefile
index c6b9a23ce8796582d6e2f5121c30c2269975aa2d..062082e35ba352a8f0520b28379690f5a2ba2ed3 100644
--- a/img/app/Makefile
+++ b/img/app/Makefile
@@ -57,15 +57,15 @@ VM_FILES = \
 	etc/wireplumber/wireplumber.conf.d/99_spectrum.conf \
 	etc/xdg/xdg-desktop-portal/portals.conf
 
-VM_DIRS = dev run proc sys tmp var \
+VM_DIRS = \
 	etc/s6-linux-init/run-image/service \
-	etc/s6-linux-init/run-image/user \
-	etc/s6-linux-init/run-image/wait
+	etc/s6-linux-init/run-image/wait \
+	var
 VM_FIFOS = etc/s6-linux-init/run-image/service/s6-linux-init-shutdownd/fifo
 
 # These are separate because they need to be included, but putting
 # them as make dependencies would confuse make.
-VM_LINKS = bin etc/ssl/certs/ca-certificates.crt sbin
+VM_LINKS = etc/ssl/certs/ca-certificates.crt
 
 VM_BUILD_FILES = build/etc/s6-rc
 
diff --git a/img/app/bin b/img/app/bin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/img/app/bin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/img/app/default.nix b/img/app/default.nix
index d3eed1f0accdc8968d1ba5bdec74ab597789082f..4daee260afd41de14de06a006b00c2c6db0f5e2a 100644
--- a/img/app/default.nix
+++ b/img/app/default.nix
@@ -12,6 +12,42 @@ pkgsStatic.callPackage (
 }:
 
 let
+  kernelTarget =
+    if stdenvNoCC.hostPlatform.isx86 then
+      # vmlinux.bin is the stripped version of vmlinux.
+      # Confusingly, compressed/vmlinux.bin is the stripped version of
+      # the top-level vmlinux target, while the top-level vmlinux.bin
+      # is the stripped version of compressed/vmlinux.  So we use
+      # compressed/vmlinux.bin, since we want a stripped version of
+      # the kernel that *hasn't* been built to be compressed.  Weird!
+      "compressed/vmlinux.bin"
+    else
+      stdenvNoCC.hostPlatform.linux-kernel.target;
+
+  kernel = (linux_latest.override {
+    structuredExtraConfig = with lib.kernel; {
+      DRM_FBDEV_EMULATION = lib.mkForce no;
+      EROFS_FS = yes;
+      FONTS = lib.mkForce unset;
+      FONT_8x8 = lib.mkForce unset;
+      FONT_TER16x32 = lib.mkForce unset;
+      FRAMEBUFFER_CONSOLE = lib.mkForce unset;
+      FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER = lib.mkForce unset;
+      FRAMEBUFFER_CONSOLE_DETECT_PRIMARY = lib.mkForce unset;
+      FRAMEBUFFER_CONSOLE_ROTATION = lib.mkForce unset;
+      RC_CORE = lib.mkForce unset;
+      VIRTIO = yes;
+      VIRTIO_BLK = yes;
+      VIRTIO_CONSOLE = yes;
+      VIRTIO_PCI = yes;
+      VT = no;
+    };
+  }).overrideAttrs ({ installFlags ? [], ... }: {
+    installFlags = installFlags ++ [
+      "KBUILD_IMAGE=$(boot)/${kernelTarget}"
+    ];
+  });
+
   appimageFhsenv = (buildFHSEnv (appimageTools.defaultFhsEnvArgs // {
     name = "vm-fhs-env";
     targetPkgs = pkgs: appimageTools.defaultFhsEnvArgs.targetPkgs pkgs ++ [
@@ -53,50 +89,33 @@ let
       pkgs.wireplumber
     ];
   })).fhsenv;
-in
 
-let
   packagesSysroot = runCommand "packages-sysroot" {} ''
-    mkdir -p $out/etc/ssl/certs
-    ln -s ${appimageFhsenv}/{lib64,usr} ${kernel}/lib $out
-    ln -s ${cacert}/etc/ssl/certs/* $out/etc/ssl/certs
+    set -eu
+    mkdir -p -- "$out/etc/ssl/certs" "$out/usr/bin"
+    # ../../scripts/make-erofs.sh will re-create these
+    rm -f -- "$out/usr/lib64" "$out/usr/lib"
+    source_dir=${lib.escapeShellArg appimageFhsenv}/usr
+    for i in "$source_dir"/*; do
+      subdir=''${i##*/}
+      case $subdir in
+      (bin|include|lib|lib64|libexec|sbin|share) :;;
+      (*) printf 'Bad subdirectory %s\n' "$subdir" >&2; exit 1;;
+      esac
+    done
+    if ! [ -h "$source_dir/lib" ]; then echo "FHSenv didn't make lib a symlink" >&2; exit 1; fi
+    ln -s -- "$source_dir/include" "$source_dir/libexec" "$source_dir/share" "$out/usr"
+    cp -RT -- "$source_dir/lib64" "$out/usr/lib"
+    # Do this first so that the subsequent call to cp (without -T)
+    # will create new entries in the existing bin directory.
+    cp -RT -- "$source_dir/sbin" "$out/usr/bin"
+    # with -T cp tries to delete the whole target directory first
+    cp -R -- "$source_dir/bin" "$out/usr"
+    # so that ln can make the symlink
+    chmod -- 0755 "$out/usr/lib"
+    ln -s -- ${lib.escapeShellArg kernel}/lib/modules "$out/usr/lib/"
+    ln -s -- ${lib.escapeShellArg cacert}/etc/ssl/certs/* "$out/etc/ssl/certs"
   '';
-
-  kernelTarget =
-    if stdenvNoCC.hostPlatform.isx86 then
-      # vmlinux.bin is the stripped version of vmlinux.
-      # Confusingly, compressed/vmlinux.bin is the stripped version of
-      # the top-level vmlinux target, while the top-level vmlinux.bin
-      # is the stripped version of compressed/vmlinux.  So we use
-      # compressed/vmlinux.bin, since we want a stripped version of
-      # the kernel that *hasn't* been built to be compressed.  Weird!
-      "compressed/vmlinux.bin"
-    else
-      stdenvNoCC.hostPlatform.linux-kernel.target;
-
-  kernel = (linux_latest.override {
-    structuredExtraConfig = with lib.kernel; {
-      DRM_FBDEV_EMULATION = lib.mkForce no;
-      EROFS_FS = yes;
-      FONTS = lib.mkForce unset;
-      FONT_8x8 = lib.mkForce unset;
-      FONT_TER16x32 = lib.mkForce unset;
-      FRAMEBUFFER_CONSOLE = lib.mkForce unset;
-      FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER = lib.mkForce unset;
-      FRAMEBUFFER_CONSOLE_DETECT_PRIMARY = lib.mkForce unset;
-      FRAMEBUFFER_CONSOLE_ROTATION = lib.mkForce unset;
-      RC_CORE = lib.mkForce unset;
-      VIRTIO = yes;
-      VIRTIO_BLK = yes;
-      VIRTIO_CONSOLE = yes;
-      VIRTIO_PCI = yes;
-      VT = no;
-    };
-  }).overrideAttrs ({ installFlags ? [], ... }: {
-    installFlags = installFlags ++ [
-      "KBUILD_IMAGE=$(boot)/${kernelTarget}"
-    ];
-  });
 in
 
 stdenvNoCC.mkDerivation {
diff --git a/img/app/sbin b/img/app/sbin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/img/app/sbin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/scripts/make-erofs.sh b/scripts/make-erofs.sh
index d566a4ac7b30f55338fe9b8b6a94702686f6ddd1..5196394d405310971659b0dbc0c91cfcaaaf9118 100755
--- a/scripts/make-erofs.sh
+++ b/scripts/make-erofs.sh
@@ -115,5 +115,39 @@ find "$root" \
 find "$root/etc" "$root/var" ! -type l -execdir chmod u+w,go-w,ugo+rX -- '{}' +
 chmod 0755 "$root"
 
+# Fix permissions on / so that the subsequent commands work
+chmod 0755 "$root"
+
+# Create the basic mount points for pseudo-filesystems and tmpfs filesystems.
+# These should always be mounted over, so use 0400 permissions for them.
+# 0000 would be better, but it breaks mkfs.erofs as it tries to open the
+# directories for reading.
+mkdir -m 0400 "$root/dev" "$root/proc" "$root/run" "$root/sys" "$root/tmp"
+
+# Cause s6-linux-init to create /run/lock and /run/user
+# with the correct mode (0755) and create /home,
+# /var/cache, /var/log, and /var/spool directly.
+mkdir -m 0755 \
+	"$root/etc/s6-linux-init/run-image/lock" \
+	"$root/etc/s6-linux-init/run-image/user" \
+	"$root/home" \
+	"$root/var/cache" \
+	"$root/var/log" \
+	"$root/var/spool"
+
+# Create symbolic links that are always expected to exist.
+chmod 0755 "$root/usr"
+ln -s ../proc/self/mounts "$root/etc/mtab"
+ln -s ../run "$root/var/run"
+ln -s ../run/lock "$root/var/lock"
+ln -s ../tmp "$root/var/tmp"
+ln -s bin "$root/usr/sbin"
+ln -s lib "$root/usr/lib64"
+ln -s usr/bin "$root/bin"
+ln -s usr/bin "$root/sbin"
+ln -s usr/lib "$root/lib"
+ln -s usr/lib "$root/lib64"
+chmod 0555 "$root/usr"
+
 # Make the erofs image.
 mkfs.erofs -x-1 -b4096 --all-root "$@" "$root"
diff --git a/vm/sys/net/Makefile b/vm/sys/net/Makefile
index e6819400b2079e3eaa9d24737b2fc4b816a592c8..a8ad03862165a69f3f7dd3e49f668cfa887d817f 100644
--- a/vm/sys/net/Makefile
+++ b/vm/sys/net/Makefile
@@ -39,11 +39,7 @@ VM_FILES = \
 	etc/s6-linux-init/run-image/service/getty-hvc0/run \
 	etc/s6-linux-init/scripts/rc.init \
 	etc/sysctl.conf
-VM_DIRS = dev etc/s6-linux-init/env run proc sys var/lib/connman
-
-# These are separate because they need to be included, but putting
-# them as make dependencies would confuse make.
-VM_LINKS = bin lib sbin var/run
+VM_DIRS = etc/s6-linux-init/env var/lib/connman
 
 VM_BUILD_FILES = build/etc/s6-rc
 
@@ -53,7 +49,7 @@ build/empty:
 build/rootfs.erofs: ../../../scripts/make-erofs.sh $(PACKAGES_FILE) $(VM_FILES) $(VM_BUILD_FILES) build/empty
 	( \
 	    cat $(PACKAGES_FILE) ;\
-	    for file in $(VM_FILES) $(VM_LINKS); do printf '%s\n%s\n' $$file $$file; done ;\
+	    for file in $(VM_FILES); do printf '%s\n%s\n' $$file $$file; done ;\
 	    for file in $(VM_BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
 	    printf 'build/empty\n%s\n' $(VM_DIRS) ;\
 	) | ../../../scripts/make-erofs.sh $@
diff --git a/vm/sys/net/bin b/vm/sys/net/bin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/vm/sys/net/bin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/vm/sys/net/default.nix b/vm/sys/net/default.nix
index b5873ebe1e80dd88c1ba997f7ebd3ee7369bb40f..a2c635e8ff09ab2b0ae4694344f3810c1b9739a5 100644
--- a/vm/sys/net/default.nix
+++ b/vm/sys/net/default.nix
@@ -51,6 +51,8 @@ let
     for pkg in ${lib.escapeShellArgs usrPackages}; do
         lndir -ignorelinks -silent "$pkg" "$out/usr"
     done
+    [ -h "$out/usr/sbin" ]
+    rm -f -- "$out/usr/sbin"
   '';
 
   nixosAllHardware = nixos ({ modulesPath, ... }: {
diff --git a/vm/sys/net/lib b/vm/sys/net/lib
deleted file mode 120000
index 0d5487ba8608d4d1a7328cf8a4e0242d1988c491..0000000000000000000000000000000000000000
--- a/vm/sys/net/lib
+++ /dev/null
@@ -1 +0,0 @@
-usr/lib
\ No newline at end of file
diff --git a/vm/sys/net/sbin b/vm/sys/net/sbin
deleted file mode 120000
index 1e881eda3a544eaa86b6019cbe7067ffc58bfafc..0000000000000000000000000000000000000000
--- a/vm/sys/net/sbin
+++ /dev/null
@@ -1 +0,0 @@
-usr/bin
\ No newline at end of file
diff --git a/vm/sys/net/var/run b/vm/sys/net/var/run
deleted file mode 120000
index 84ba55b912a470365255744b6bb42268254365e3..0000000000000000000000000000000000000000
--- a/vm/sys/net/var/run
+++ /dev/null
@@ -1 +0,0 @@
-../run
\ No newline at end of file

-- 
2.51.0


  parent reply	other threads:[~2025-09-04 23:48 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-04 21:26 [PATCH 00/20] Many image fixes and systemd integration Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 01/20] scripts/make-erofs.sh: Ensure that / is world-readable Demi Marie Obenour
2025-09-08  8:21   ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 02/20] scripts/make-erofs.sh: Do not read one byte at a time Demi Marie Obenour
2025-09-08  8:23   ` Alyssa Ross
2025-09-08 16:57     ` Demi Marie Obenour
2025-09-09 15:19       ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 03/20] scripts/make-erofs.sh: Avoid unneeded calls to awk and chmod Demi Marie Obenour
2025-09-08  8:28   ` Alyssa Ross
2025-09-08 17:14     ` Demi Marie Obenour
2025-09-10 18:45       ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 04/20] scripts/make-erofs.sh: Validate all paths Demi Marie Obenour
2025-09-08  8:36   ` Alyssa Ross
2025-09-08 18:21     ` Demi Marie Obenour
2025-09-10 18:54       ` Alyssa Ross
2025-09-21 12:09         ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 05/20] scripts/make-erofs.sh: Avoid unneeded calls to dirname Demi Marie Obenour
2025-09-10 20:04   ` Alyssa Ross
2025-09-10 20:06     ` Demi Marie Obenour
2025-09-19 16:47   ` Alyssa Ross
2025-09-19 19:04     ` Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 06/20] scripts/make-erofs.sh: Avoid unneeded calls to mkdir Demi Marie Obenour
2025-09-08  8:39   ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 07/20] scripts/make-erofs.sh: Standardize file modes in images Demi Marie Obenour
2025-09-08  8:46   ` Alyssa Ross
2025-09-08 17:16     ` Demi Marie Obenour
2025-09-19 17:50   ` Alyssa Ross
2025-09-19 19:18     ` Demi Marie Obenour
2025-09-21 12:23       ` Alyssa Ross
2025-09-04 21:26 ` Demi Marie Obenour [this message]
2025-09-08  8:59   ` [PATCH 08/20] Standardize directories and symlinks " Alyssa Ross
2025-09-08 18:05     ` Demi Marie Obenour
2025-09-19 17:53       ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 09/20] Add os-release file Demi Marie Obenour
2025-09-08  9:12   ` Alyssa Ross
2025-09-08 18:07     ` Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 10/20] host/rootfs: Set -eu in build Demi Marie Obenour
2025-09-08  9:13   ` Alyssa Ross
2025-09-08 18:08     ` Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 11/20] Add /dev/fd and /dev/std* Demi Marie Obenour
2025-09-08  9:18   ` Alyssa Ross
2025-09-08 18:12     ` Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 12/20] host/rootfs: Do not read from /dev/tty1 Demi Marie Obenour
2025-09-08  9:19   ` Alyssa Ross
2025-09-08 18:18     ` Demi Marie Obenour
2025-09-19 18:22       ` Alyssa Ross
2025-09-19 19:00         ` Demi Marie Obenour
2025-09-21  9:01           ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 13/20] host/rootfs: pass API socket as fd 3, not fd 0 Demi Marie Obenour
2025-09-08  9:44   ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 14/20] host/rootfs: Disable unneeded BusyBox tools Demi Marie Obenour
2025-09-08  9:24   ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 15/20] host/rootfs: Use real less, not BusyBox less Demi Marie Obenour
2025-09-08  9:25   ` Alyssa Ross
2025-09-08 18:16     ` Demi Marie Obenour
2025-09-19 18:45       ` Alyssa Ross
2025-09-19 19:01         ` Demi Marie Obenour
2025-09-21  9:02           ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 16/20] host/rootfs: explicitly set PATH in network add script Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 17/20] Use /etc/s6-rc/compiled for compiled s6-rc directory Demi Marie Obenour
2025-09-08  9:27   ` Alyssa Ross
2025-09-08 18:15     ` Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 18/20] host/rootfs: virtiofsd: Do not use FD 0 as the socket Demi Marie Obenour
2025-09-08  9:44   ` Alyssa Ross
2025-09-04 21:26 ` [PATCH 19/20] host/rootfs: Disable unneeded busybox stuff Demi Marie Obenour
2025-09-04 21:26 ` [PATCH 20/20] host/rootfs: Switch to systemd Demi Marie Obenour

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250904-systemd-v1-8-2a63b790a913@gmail.com \
    --to=demiobenour@gmail.com \
    --cc=devel@spectrum-os.org \
    --cc=hi@alyssa.is \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://spectrum-os.org/git/crosvm
	https://spectrum-os.org/git/doc
	https://spectrum-os.org/git/mktuntap
	https://spectrum-os.org/git/nixpkgs
	https://spectrum-os.org/git/spectrum
	https://spectrum-os.org/git/ucspi-vsock
	https://spectrum-os.org/git/www

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).