diff options
author | Alyssa Ross <hi@alyssa.is> | 2023-03-21 15:11:07 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2023-03-21 15:43:58 +0000 |
commit | 2a338f7e1abe182d1c0ec496540349d2084e9b4b (patch) | |
tree | b8f1bb936fc1dbab7733487b96dbbaea5174b5fb | |
parent | 048fadd0a4bf8b29227dc67f39363305b84ff29a (diff) | |
download | spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar.gz spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar.bz2 spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar.lz spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar.xz spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.tar.zst spectrum-2a338f7e1abe182d1c0ec496540349d2084e9b4b.zip |
scripts/make-gpt.sh: use copy_file_range(2)
Before this change, a clean release/live "make -j4" had a median runtime of 85 seconds. Now, it's 37 seconds. That much of a reduction in iteration time is worth the extra complexity. Signed-off-by: Alyssa Ross <hi@alyssa.is>
-rw-r--r-- | host/initramfs/default.nix | 7 | ||||
-rw-r--r-- | host/rootfs/default.nix | 15 | ||||
-rw-r--r-- | img/app/default.nix | 12 | ||||
-rw-r--r-- | release/live/default.nix | 15 | ||||
-rwxr-xr-x | scripts/make-gpt.sh | 10 | ||||
-rw-r--r-- | tools/lseek/Makefile | 23 | ||||
-rw-r--r-- | tools/lseek/default.nix | 26 | ||||
-rw-r--r-- | tools/lseek/lseek.c | 59 | ||||
-rw-r--r-- | vm/sys/net/default.nix | 12 |
9 files changed, 160 insertions, 19 deletions
diff --git a/host/initramfs/default.nix b/host/initramfs/default.nix index b9b22ae..22dcbed 100644 --- a/host/initramfs/default.nix +++ b/host/initramfs/default.nix @@ -1,11 +1,14 @@ -# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is> +# SPDX-FileCopyrightText: 2021-2023 Alyssa Ross <hi@alyssa.is> # SPDX-License-Identifier: MIT import ../../lib/eval-config.nix ( + { config, src +, lseek ? import ../../tools/lseek { inherit config; } , rootfs ? import ../rootfs { inherit config; } , ... }: + config.pkgs.callPackage ( { lib, stdenvNoCC, makeModulesClosure, runCommand, writeReferencesToFile @@ -89,7 +92,7 @@ stdenvNoCC.mkDerivation { MICROCODE = microcode; PACKAGES_CPIO = packagesCpio; - nativeBuildInputs = [ cpio ]; + nativeBuildInputs = [ cpio lseek ]; makeFlags = [ "dest=$(out)" ]; diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix index 23e4b38..637c607 100644 --- a/host/rootfs/default.nix +++ b/host/rootfs/default.nix @@ -1,9 +1,18 @@ # SPDX-License-Identifier: MIT -# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is> +# SPDX-FileCopyrightText: 2021-2023 Alyssa Ross <hi@alyssa.is> # SPDX-FileCopyrightText: 2022 Unikie import ../../lib/eval-config.nix ( -{ config, src, ... }: let inherit (config) pkgs; in + +{ config, src +, lseek ? import ../../tools/lseek { inherit config; } +, ... +}: + +let + inherit (config) pkgs; +in + pkgs.pkgsStatic.callPackage ( { lib, stdenvNoCC, nixos, runCommand, writeReferencesToFile, s6-rc, tar2ext4 @@ -124,7 +133,7 @@ stdenvNoCC.mkDerivation { inherit src; sourceRoot = "source/host/rootfs"; - nativeBuildInputs = [ s6-rc tar2ext4 ]; + nativeBuildInputs = [ lseek s6-rc tar2ext4 ]; MODULES_ALIAS = "${kernel}/lib/modules/${kernel.modDirVersion}/modules.alias"; MODULES_ORDER = "${kernel}/lib/modules/${kernel.modDirVersion}/modules.order"; diff --git a/img/app/default.nix b/img/app/default.nix index 70e6e33..538dfe2 100644 --- a/img/app/default.nix +++ b/img/app/default.nix @@ -1,8 +1,14 @@ # SPDX-License-Identifier: MIT -# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is> +# SPDX-FileCopyrightText: 2021-2023 Alyssa Ross <hi@alyssa.is> import ../../lib/eval-config.nix ( -{ config, src, terminfo ? config.pkgs.foot.terminfo, ... }: + +{ config, src +, lseek ? import ../../tools/lseek { inherit config; } +, terminfo ? config.pkgs.foot.terminfo +, ... +}: + config.pkgs.pkgsStatic.callPackage ( { lib, stdenvNoCC, runCommand, writeReferencesToFile, buildPackages @@ -65,7 +71,7 @@ stdenvNoCC.mkDerivation { inherit src; sourceRoot = "source/img/app"; - nativeBuildInputs = [ jq s6-rc tar2ext4 util-linux ]; + nativeBuildInputs = [ jq lseek s6-rc tar2ext4 util-linux ]; PACKAGES_TAR = packagesTar; VMLINUX = "${kernel.dev}/vmlinux"; diff --git a/release/live/default.nix b/release/live/default.nix index 7ab7a22..b7ee036 100644 --- a/release/live/default.nix +++ b/release/live/default.nix @@ -1,12 +1,19 @@ # SPDX-License-Identifier: MIT -# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is> +# SPDX-FileCopyrightText: 2021-2023 Alyssa Ross <hi@alyssa.is> # SPDX-FileCopyrightText: 2022 Unikie -import ../../lib/eval-config.nix ({ config, src, ... }: +import ../../lib/eval-config.nix ( + +{ config, src +, lseek ? import ../../tools/lseek { inherit config; } +, ... +}: + config.pkgs.callPackage ( { stdenvNoCC, cryptsetup, dosfstools, jq, mtools, util-linux, stdenv -, systemd }: +, systemd +}: let inherit (config) pkgs; @@ -26,7 +33,7 @@ stdenvNoCC.mkDerivation { inherit src; sourceRoot = "source/release/live"; - nativeBuildInputs = [ cryptsetup dosfstools jq mtools util-linux ]; + nativeBuildInputs = [ cryptsetup dosfstools jq lseek mtools util-linux ]; EXT_FS = extfs; INITRAMFS = initramfs; diff --git a/scripts/make-gpt.sh b/scripts/make-gpt.sh index 6931879..2d4cd59 100755 --- a/scripts/make-gpt.sh +++ b/scripts/make-gpt.sh @@ -20,10 +20,12 @@ sizeMiB() { # Copies from path $3 into partition number $2 in partition table $1. fillPartition() { - sfdisk -J "$1" | jq -r --argjson index "$2" \ - '.partitiontable.partitions[$index] | "\(.start) \(.size)"' | - (read -r start size; - dd if="$3" of="$1" seek="$start" count="$size" conv=notrunc) + start="$(sfdisk -J "$1" | jq -r --argjson index "$2" \ + '.partitiontable.partitions[$index].start * 512')" + + # GNU cat will use copy_file_range(2) if possible, whereas dd + # will always do a userspace copy, which is significantly slower. + lseek -S 1 "$start" cat "$3" 1<>"$1" } # Prints the partition path from a PATH:PARTTYPE[:PARTUUID[:PARTLABEL]] string. diff --git a/tools/lseek/Makefile b/tools/lseek/Makefile new file mode 100644 index 0000000..f62419b --- /dev/null +++ b/tools/lseek/Makefile @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2023 Alyssa Ross <hi@alyssa.is> +# SPDX-License-Identifier: EUPL-1.2+ + +.POSIX: + +CFLAGS = -Wall -Wextra -Wpedantic -O -g +INSTALL = install +INSTALL_PROGRAM = $(INSTALL) + +prefix = /usr/local +bindir = $(prefix)/bin + +all: lseek +.PHONY: all + +install: lseek + mkdir -p $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) lseek $(DESTDIR)$(bindir) +.PHONY: install + +clean: + rm -f lseek *.o +.PHONY: clean diff --git a/tools/lseek/default.nix b/tools/lseek/default.nix new file mode 100644 index 0000000..3d303cf --- /dev/null +++ b/tools/lseek/default.nix @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2023 Alyssa Ross <hi@alyssa.is> +# SPDX-License-Identifier: MIT + +import ../../lib/eval-config.nix ({ config, src, ... }: config.pkgs.pkgsStatic.callPackage ( + +{ lib, stdenv }: + +stdenv.mkDerivation { + name = "lseek"; + + inherit src; + sourceRoot = "source/tools/lseek"; + + makeFlags = [ "prefix=$(out)" ]; + + enableParallelBuilding = true; + + meta = with lib; { + description = "Seek an open file descriptor, then exec."; + license = licenses.eupl12; + maintainers = with maintainers; [ qyliss ]; + platforms = platforms.unix; + }; +} + +) { }) diff --git a/tools/lseek/lseek.c b/tools/lseek/lseek.c new file mode 100644 index 0000000..64dd561 --- /dev/null +++ b/tools/lseek/lseek.c @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2023 Alyssa Ross <hi@alyssa.is> +// SPDX-License-Identifier: EUPL-1.2+ + +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdnoreturn.h> +#include <string.h> +#include <unistd.h> + +noreturn static void ex_usage(void) +{ + fprintf(stderr, "Usage: lseek [ -C | -E | -S ] fd offset prog...\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) +{ + int opt, whence = SEEK_CUR; + long fd, offset; + + while ((opt = getopt(argc, argv, "+CES")) != -1) { + switch (opt) { + case 'C': + whence = SEEK_CUR; + break; + case 'E': + whence = SEEK_END; + break; + case 'S': + whence = SEEK_SET; + break; + default: + ex_usage(); + } + } + + if (optind > argc - 2) + ex_usage(); + + fd = strtol(argv[optind++], NULL, 10); + if (fd < 0 || fd > INT_MAX) + errx(EXIT_FAILURE, "%s", strerror(EBADF)); + + errno = 0; + offset = strtol(argv[optind++], NULL, 10); + if (errno) + err(EXIT_FAILURE, "bad offset: %s", argv[optind - 1]); + if (offset != (off_t)offset) + errx(EXIT_FAILURE, "%s", strerror(EINVAL)); + + if (lseek(fd, offset, whence) == -1) + err(EXIT_FAILURE, NULL); + + execvp(argv[optind], argv + optind); + err(EXIT_FAILURE, "exec"); +} diff --git a/vm/sys/net/default.nix b/vm/sys/net/default.nix index 2af46b2..19f749a 100644 --- a/vm/sys/net/default.nix +++ b/vm/sys/net/default.nix @@ -1,8 +1,14 @@ # SPDX-License-Identifier: MIT -# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is> +# SPDX-FileCopyrightText: 2021-2023 Alyssa Ross <hi@alyssa.is> import ../../../lib/eval-config.nix ( -{ config, src, terminfo ? config.pkgs.foot.terminfo, ... }: + +{ config, src +, lseek ? import ../../../tools/lseek { inherit config; } +, terminfo ? config.pkgs.foot.terminfo +, ... +}: + config.pkgs.pkgsStatic.callPackage ( { lib, stdenvNoCC, runCommand, writeReferencesToFile, buildPackages @@ -74,7 +80,7 @@ stdenvNoCC.mkDerivation { inherit src; sourceRoot = "source/vm/sys/net"; - nativeBuildInputs = [ jq s6-rc tar2ext4 util-linux ]; + nativeBuildInputs = [ jq lseek s6-rc tar2ext4 util-linux ]; PACKAGES_TAR = packagesTar; VMLINUX = "${kernel.dev}/vmlinux"; |