deb: survive crashed sessions and config-blind resumes
Two failures from resumed kernel sessions: A resumed build re-runs debian/rules build, but the kernels keep their wrapper-step stamps in debian/stamps and the flavour config rule there exports .config from the annotations with no config prerequisite: the resumed build silently kept the previous attempt's configuration and a config edit never reached the .deb. Dropping the stamp cache unconditionally would impose the kernel packaging's shape on every package, so it is data-driven instead: packages declare the caches under a resume_clear quirk, and resumed builds remove those tree-relative paths before the build. The inner kbuild keeps its own incremental state, so only the cheap wrapper passes re-run and config-affected objects recompile. A SIGKILLed build (OOM) leaves its overlay mounts and /proc bind mount behind, and overlayfs creates root-owned work state inside the workdir: the next plain build (recording is always on, it replaces the session of its identity) failed to clear the leftovers with a permission error. Session clearing now unmounts everything under each entry at depth (re-reading /proc/mounts, tolerating mount stacks from consecutive crashes) and escalates through sudo; when the tree still cannot be cleared, the build reports it and continues without a session instead of layering over a half-cleared one.
This commit is contained in:
@@ -340,6 +340,31 @@ pub async fn build(
|
||||
);
|
||||
}
|
||||
|
||||
// A resumed build continues in the previous attempt's tree. Packages
|
||||
// whose debian/rules keeps an input-untracked stamp cache (quirk:
|
||||
// `resume_clear`, e.g. the kernels' `debian/stamps`, whose flavour
|
||||
// config rule exports .config with no config prerequisite) would build
|
||||
// from the previous attempt's configuration: drop the listed caches so
|
||||
// the wrapper steps re-run over the incremental inner builds.
|
||||
if resume {
|
||||
for rel in crate::quirks::get_resume_clear_paths(package, series) {
|
||||
let path = Path::new(package_dir_str).join(&rel);
|
||||
if !ctx.exists(&path).unwrap_or(false) {
|
||||
continue;
|
||||
}
|
||||
log::info!("Dropping the resumed build's cached '{rel}' (quirk)");
|
||||
let status = ctx
|
||||
.command("rm")
|
||||
.arg("-rf")
|
||||
.arg(&path)
|
||||
.status()
|
||||
.map_err(|e| format!("cannot drop '{rel}': {e}"))?;
|
||||
if !status.success() {
|
||||
return Err(format!("cannot drop '{rel}'").into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the build step
|
||||
log::debug!("Building (debian/rules build) package...");
|
||||
enter_phase(view, Phase::Building);
|
||||
|
||||
Reference in New Issue
Block a user