xtask: patch gen_init_cpio.c

Recent changes[0][1] have broken compatibility with macOS; add a patch
to conditionally compile these snippets.

Patch and compile the source unconditionally; caching only the network
portion is good enough and less error prone.

[0] ae18b94099
[1] 97169cd6d9
reviewable/pr1358/r4
Tamir Duberstein 2 weeks ago
parent 8e31f5fa43
commit bb45904b08
No known key found for this signature in database

@ -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);

@ -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.
@ -231,68 +233,83 @@ pub(crate) fn run(opts: Options) -> Result<()> {
// VM images and report to the user. The end.
create_dir_all(&cache_dir).context("failed to create cache dir")?;
let gen_init_cpio = cache_dir.join("gen_init_cpio");
let etag_path = cache_dir.join("gen_init_cpio.etag");
{
let gen_init_cpio_exists = gen_init_cpio.try_exists().with_context(|| {
format!("failed to check existence of {}", gen_init_cpio.display())
let dest_path = cache_dir.join("gen_init_cpio.c");
let etag_path = cache_dir.join("gen_init_cpio.etag");
let dest_path_exists = dest_path.try_exists().with_context(|| {
format!("failed to check existence of {}", dest_path.display())
})?;
let etag_path_exists = etag_path.try_exists().with_context(|| {
format!("failed to check existence of {}", etag_path.display())
})?;
if !gen_init_cpio_exists && etag_path_exists {
if !dest_path_exists && etag_path_exists {
println!(
"cargo:warning=({}).exists()={} != ({})={} (mismatch)",
gen_init_cpio.display(),
gen_init_cpio_exists,
dest_path.display(),
dest_path_exists,
etag_path.display(),
etag_path_exists,
)
}
}
let gen_init_cpio_source = {
drop(github_api_token); // Currently unused, but kept around in case we need it in the future.
// Currently unused. Can be used for authenticated requests if needed in the future.
drop(github_api_token);
let mut curl = Command::new("curl");
curl.args([
"-sfSL",
"https://raw.githubusercontent.com/torvalds/linux/master/usr/gen_init_cpio.c",
]);
"--output",
])
.arg(&dest_path);
for arg in ["--etag-compare", "--etag-save"] {
curl.arg(arg).arg(&etag_path);
}
let Output {
status,
stdout,
stderr,
} = curl
let output = curl
.output()
.with_context(|| format!("failed to run {curl:?}"))?;
let Output { status, .. } = &output;
if status.code() != Some(0) {
bail!("{curl:?} failed: stdout={stdout:?} stderr={stderr:?}")
bail!("{curl:?} failed: {output:?}")
}
stdout
};
if !gen_init_cpio_source.is_empty() {
let mut patch = Command::new("patch");
patch
.current_dir(&cache_dir)
.args(["--quiet", "--forward", "--output", "-"])
.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()

Loading…
Cancel
Save