From 15883f96ca882fac4b66a028b0309edbd323a0a8 Mon Sep 17 00:00:00 2001 From: Tomas Valenta Date: Thu, 9 Apr 2026 20:57:11 -0700 Subject: [PATCH 1/2] fix: normalize kernel output dirs from x86_64 to amd64 The infra orchestrator's TargetArch() uses Go's runtime.GOARCH convention (amd64) but kernels were stored under x86_64/, causing gcsfuse stat misses and a ~15-40ms penalty per sandbox create on GCE nodes. Map x86_64 -> amd64 in build output so GCS paths match what the orchestrator looks up. Include a migration script for existing buckets. --- README.md | 6 ++- build.sh | 22 ++++++++--- migrate-gcs-arch.sh | 94 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 6 deletions(-) create mode 100755 migrate-gcs-arch.sh diff --git a/README.md b/README.md index dc4eb4e..b1e1579 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,15 @@ This project automates the building of custom Linux kernels for Firecracker micr # or directly ./build.sh ``` - The built kernels will be placed in `builds/vmlinux-/vmlinux.bin`. + The built kernels will be placed in `builds/vmlinux-//vmlinux.bin` where `` is `amd64` or `arm64` (Go/OCI convention). For x86_64 backward compatibility, a legacy copy is also placed at `builds/vmlinux-/vmlinux.bin`. ## Development Workflow - On every push, GitHub Actions will automatically build the kernels and save it as an artifact. +## Architecture naming + +Output directories use Go's `runtime.GOARCH` convention (`amd64`, `arm64`) so they match the infra orchestrator's `TargetArch()` path resolution. The build-time variable `TARGET_ARCH` (`x86_64`, `arm64`) is only used internally for config paths and cross-compilation flags. + ## New Kernel in E2B's infra _Note: these steps should give you new kernel on your self-hosted E2B using https://github.com/e2b-dev/infra_ diff --git a/build.sh b/build.sh index 56df2cc..209ee22 100755 --- a/build.sh +++ b/build.sh @@ -7,6 +7,18 @@ set -euo pipefail TARGET_ARCH="${TARGET_ARCH:-x86_64}" HOST_ARCH="$(uname -m)" +# Go/OCI-normalized arch name for output directory structure. +# The infra orchestrator uses Go's runtime.GOARCH convention (amd64/arm64) +# for path resolution, so output directories must match. +normalize_arch() { + case "$1" in + x86_64) echo "amd64" ;; + aarch64) echo "arm64" ;; + *) echo "$1" ;; + esac +} +OUTPUT_ARCH="$(normalize_arch "$TARGET_ARCH")" + function install_dependencies { local packages=( bc bison busybox-static cpio curl flex gcc libelf-dev libssl-dev make patch squashfs-tools tree @@ -59,14 +71,14 @@ function build_version { fi echo "Copying finished build to builds directory" - # Always output to {arch}/ subdirectory - mkdir -p "../builds/vmlinux-${version}/${TARGET_ARCH}" + # Output to normalized arch dir (amd64/arm64) matching Go's runtime.GOARCH + mkdir -p "../builds/vmlinux-${version}/${OUTPUT_ARCH}" if [[ "$TARGET_ARCH" == "arm64" ]]; then - cp arch/arm64/boot/Image "../builds/vmlinux-${version}/${TARGET_ARCH}/vmlinux.bin" + cp arch/arm64/boot/Image "../builds/vmlinux-${version}/${OUTPUT_ARCH}/vmlinux.bin" else - cp vmlinux "../builds/vmlinux-${version}/${TARGET_ARCH}/vmlinux.bin" + cp vmlinux "../builds/vmlinux-${version}/${OUTPUT_ARCH}/vmlinux.bin" fi - + # x86_64: also copy to legacy path (no arch subdir) for backwards compat if [[ "$TARGET_ARCH" == "x86_64" ]]; then cp vmlinux "../builds/vmlinux-${version}/vmlinux.bin" diff --git a/migrate-gcs-arch.sh b/migrate-gcs-arch.sh new file mode 100755 index 0000000..d8b8fa2 --- /dev/null +++ b/migrate-gcs-arch.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Copies kernel files from x86_64/ to amd64/ subdirectories in GCS buckets. +# +# The infra orchestrator's TargetArch() normalizes x86_64 -> amd64 (Go convention), +# so kernels stored under x86_64/ are never found by the arch-aware path resolution, +# causing a gcsfuse stat penalty on every sandbox create. +# +# Usage: +# ./migrate-gcs-arch.sh # dry-run: show what would be copied +# ./migrate-gcs-arch.sh --apply # copy x86_64/ -> amd64/ +# ./migrate-gcs-arch.sh --delete-old # dry-run: show what old x86_64/ files would be deleted +# ./migrate-gcs-arch.sh --delete-old --apply # actually delete old x86_64/ files +# +# Recommended workflow: +# 1. ./migrate-gcs-arch.sh gs://my-bucket # review what will be copied +# 2. ./migrate-gcs-arch.sh gs://my-bucket --apply # copy to amd64/ +# 3. ... verify everything works ... +# 4. ./migrate-gcs-arch.sh gs://my-bucket --delete-old # review what will be deleted +# 5. ./migrate-gcs-arch.sh gs://my-bucket --delete-old --apply # clean up old x86_64/ + +set -euo pipefail + +BUCKET="${1:?Usage: $0 [--apply] [--delete-old]}" +shift + +APPLY=false +DELETE_OLD=false +for arg in "$@"; do + case "$arg" in + --apply) APPLY=true ;; + --delete-old) DELETE_OLD=true ;; + *) echo "Unknown flag: $arg"; exit 1 ;; + esac +done + +# Normalize bucket name — strip gs:// prefix if provided, we add it back +BUCKET="${BUCKET#gs://}" + +echo "Scanning gs://${BUCKET} for x86_64/ paths..." +echo "" + +objects=$(gsutil ls -r "gs://${BUCKET}/**/x86_64/**" 2>/dev/null || true) + +if [[ -z "$objects" ]]; then + echo "No x86_64/ paths found in gs://${BUCKET}" + exit 0 +fi + +count=0 +if [[ "$DELETE_OLD" == true ]]; then + while IFS= read -r src; do + [[ -z "$src" ]] && continue + [[ "$src" == */ ]] && continue + + if [[ "$APPLY" == true ]]; then + echo " DELETE $src" + gsutil rm "$src" + else + echo " [dry-run] would delete $src" + fi + ((count++)) || true + done <<< "$objects" + + echo "" + echo "Total: $count objects" + if [[ "$APPLY" != true ]]; then + echo "" + echo "This was a dry run. Add --apply to actually delete." + fi +else + while IFS= read -r src; do + [[ -z "$src" ]] && continue + [[ "$src" == */ ]] && continue + + dst="${src/\/x86_64\//\/amd64\/}" + + if [[ "$APPLY" == true ]]; then + echo " COPY $src" + echo " -> $dst" + gsutil cp "$src" "$dst" + else + echo " [dry-run] $src" + echo " -> $dst" + fi + ((count++)) || true + done <<< "$objects" + + echo "" + echo "Total: $count objects" + if [[ "$APPLY" != true ]]; then + echo "" + echo "This was a dry run. Add --apply to actually copy." + fi +fi From 63b1dd0d81bbba4e39d1f91b4b9ccc3a6b344a77 Mon Sep 17 00:00:00 2001 From: Tomas Valenta Date: Thu, 9 Apr 2026 21:06:32 -0700 Subject: [PATCH 2/2] Fix escaping --- migrate-gcs-arch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrate-gcs-arch.sh b/migrate-gcs-arch.sh index d8b8fa2..3dd5267 100755 --- a/migrate-gcs-arch.sh +++ b/migrate-gcs-arch.sh @@ -72,7 +72,7 @@ else [[ -z "$src" ]] && continue [[ "$src" == */ ]] && continue - dst="${src/\/x86_64\//\/amd64\/}" + dst="${src/\/x86_64\///amd64/}" if [[ "$APPLY" == true ]]; then echo " COPY $src"