From 3f0544513daa192545b511b19447ac9402ff56c4 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 2 Oct 2025 11:22:22 -0400 Subject: [PATCH] xtask: patch gen_init_cpio.c Recent changes[0][1] have broken compatibility with macOS; add a patch to conditionally compile these snippets. [0] https://github.com/torvalds/linux/commit/ae18b94099b04264b32e33b057114024bc72c993 [1] https://github.com/torvalds/linux/commit/97169cd6d95b338f2dbf5d3154b7d2233fce7d8a --- xtask/patches/gen_init_cpio.c.macos.diff | 32 +++++++++++++++++ xtask/src/run.rs | 45 ++++++++++++++++++------ 2 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 xtask/patches/gen_init_cpio.c.macos.diff diff --git a/xtask/patches/gen_init_cpio.c.macos.diff b/xtask/patches/gen_init_cpio.c.macos.diff new file mode 100644 index 00000000..f15c322e --- /dev/null +++ b/xtask/patches/gen_init_cpio.c.macos.diff @@ -0,0 +1,32 @@ +diff --git a/gen_init_cpio.c b/gen_init_cpio.c +index 75e9561b..406c4d0a 100644 +--- a/gen_init_cpio.c ++++ b/gen_init_cpio.c +@@ -453,6 +453,7 @@ static int cpio_mkfile(const char *name, const char *location, + push_pad(namepadlen ? namepadlen : padlen(offset, 4)) < 0) + goto error; + ++#ifdef __linux__ + if (size) { + this_read = copy_file_range(file, NULL, outfd, NULL, size, 0); + if (this_read > 0) { +@@ -463,6 +464,7 @@ static int cpio_mkfile(const char *name, const char *location, + } + /* short or failed copy falls back to read/write... */ + } ++#endif + + while (size) { + unsigned char filebuf[65536]; +@@ -671,7 +673,10 @@ int main (int argc, char *argv[]) + break; + case 'o': + outfd = open(optarg, +- O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC, ++#ifdef O_LARGEFILE ++ O_LARGEFILE | ++#endif ++ O_WRONLY | O_CREAT | O_TRUNC, + 0600); + if (outfd < 0) { + fprintf(stderr, "failed to open %s\n", optarg); diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 53a79f56..863086b7 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -1,7 +1,7 @@ use std::{ ffi::OsString, fmt::Write as _, - fs::{OpenOptions, copy, create_dir_all}, + fs::{OpenOptions, copy, create_dir_all, write}, io::{BufRead as _, BufReader, Write as _}, ops::Deref as _, path::{Path, PathBuf}, @@ -16,6 +16,8 @@ use clap::Parser; use walkdir::WalkDir; use xtask::{AYA_BUILD_INTEGRATION_BPF, Errors}; +const GEN_INIT_CPIO_PATCH: &str = include_str!("../patches/gen_init_cpio.c.macos.diff"); + #[derive(Parser)] enum Environment { /// Runs the integration tests locally. @@ -277,22 +279,45 @@ pub(crate) fn run(opts: Options) -> Result<()> { }; if !gen_init_cpio_source.is_empty() { + let tmp_dir = tempfile::tempdir().context("tempdir failed")?; + let source_path = tmp_dir.path().join("gen_init_cpio.c"); + write(&source_path, &gen_init_cpio_source) + .with_context(|| format!("failed to write {}", source_path.display()))?; + + let mut patch = Command::new("patch"); + patch + .current_dir(tmp_dir.path()) + .args(["-p1", "-s", "-o", "-"]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()); + let mut patch_child = patch + .spawn() + .with_context(|| format!("failed to spawn {patch:?}"))?; + + let Child { stdin, stdout, .. } = &mut patch_child; + let mut stdin = stdin.take().unwrap(); + stdin + .write_all(GEN_INIT_CPIO_PATCH.as_bytes()) + .with_context(|| format!("failed to write to {patch:?} stdin"))?; + drop(stdin); // Must explicitly close to signal EOF. + let stdout = stdout.take().unwrap(); + let mut clang = Command::new("clang"); clang .args(["-g", "-O2", "-x", "c", "-", "-o"]) .arg(&gen_init_cpio) - .stdin(Stdio::piped()); - let mut clang_child = clang + .stdin(stdout); + let clang_child = clang .spawn() .with_context(|| format!("failed to spawn {clang:?}"))?; - let Child { stdin, .. } = &mut clang_child; - - let mut stdin = stdin.take().unwrap(); - stdin - .write_all(&gen_init_cpio_source) - .with_context(|| format!("failed to write to {clang:?} stdin"))?; - drop(stdin); // Must explicitly close to signal EOF. + let output = patch_child + .wait_with_output() + .with_context(|| format!("failed to wait for {patch:?}"))?; + let Output { status, .. } = &output; + if status.code() != Some(0) { + bail!("{patch:?} failed: {output:?}") + } let output = clang_child .wait_with_output()