Merge bootprocess branch overlay into 0.2.0

Restore all bootprocess branch files that were overwritten by later 0.2.0
commits. This overlay brings back the complete boot infrastructure:

- Configs: redbear-full, redbear-mini, redbear-device-services, driver .d files
- Kernel: IRQ affinity, x2APIC, C-states, NUMA (SLIT/SRAT), MCS locks, cpuidle
- Base patches: P0-P55 + new P6 (lived block_size=512) + P57 (fbbootlogd graceful init)
- Driver infra: driver-manager, udev-shim, thermald, cpufreqd, iommu, redox-driver-sys/core
- GPU: redox-drm with improved connector handling
- System: redbear-info, redbear-hwutils phase-timer-check
- Build system: fetch.rs improvements, build-iso.sh, run_full.sh
- Kernel source: new ACPI (SLIT, SRAT), cpuidle, cstate, MCS lock modules

83 files changed, +3966/-1248 lines
This commit is contained in:
2026-05-27 06:47:23 +03:00
parent af05babbb2
commit b9de373b31
83 changed files with 3969 additions and 1251 deletions
+93 -16
View File
@@ -195,6 +195,31 @@ fn redbear_allow_protected_fetch() -> bool {
)
}
/// Check if a recipe has patches that would be at risk from upstream source changes.
/// Recipes with patches should be protected from online re-fetching because:
/// 1. Upstream source changes can break patch context lines
/// 2. The atomic patch system expects patches to apply cleanly against the frozen source
/// 3. Re-fetching from upstream could pull incompatible changes that invalidate all patches
fn recipe_has_patches(recipe: &CookRecipe) -> bool {
match &recipe.recipe.source {
Some(SourceRecipe::Git { patches, .. }) => !patches.is_empty(),
Some(SourceRecipe::Tar { patches, .. }) => !patches.is_empty(),
_ => false,
}
}
/// Check if a recipe should be protected from online re-fetching.
/// A recipe is protected if:
/// 1. It's on the explicit protected list (redbear_protected_recipe), OR
/// 2. It has patches that would be at risk from upstream source changes
///
/// This ensures that ANY recipe carrying patches — whether explicitly listed or not —
/// is automatically shielded from accidental upstream overwrites. The explicit list
/// covers recipes that need protection even without patches (e.g., custom source recipes).
fn redbear_should_protect(recipe: &CookRecipe) -> bool {
redbear_protected_recipe(recipe.name.name()) || recipe_has_patches(recipe)
}
fn redbear_release() -> Option<String> {
env::var("REDBEAR_RELEASE")
.ok()
@@ -475,15 +500,31 @@ pub fn fetch_offline(recipe: &CookRecipe, logger: &PtyOut) -> Result<FetchResult
}
pub fn fetch(recipe: &CookRecipe, check_source: bool, logger: &PtyOut) -> Result<FetchResult> {
if redbear_protected_recipe(recipe.name.name()) && !redbear_allow_protected_fetch() {
if redbear_should_protect(recipe) && !redbear_allow_protected_fetch() {
let reason = if redbear_protected_recipe(recipe.name.name()) {
"explicitly protected"
} else {
"has patches (auto-protected)"
};
log_to_pty!(
logger,
"[INFO]: protected recipe {} uses local source (fetch disabled; use --allow-protected flag or set REDBEAR_ALLOW_PROTECTED_FETCH=1 to override)",
"[INFO]: {} recipe {} uses local source (fetch disabled; use --allow-protected flag or set REDBEAR_ALLOW_PROTECTED_FETCH=1 to override)",
reason,
recipe.name.name()
);
return fetch_offline(recipe, logger);
}
// Warn when --allow-protected bypasses protection on a patched recipe.
// Upstream source changes may break patch context lines.
if redbear_allow_protected_fetch() && recipe_has_patches(recipe) {
log_to_pty!(
logger,
"[WARN]: recipe {} has patches but --allow-protected is set — upstream source changes may break patches",
recipe.name.name()
);
}
let recipe_dir = &recipe.dir;
let source_dir = recipe_dir.join("source");
match recipe.recipe.build.kind {
@@ -1199,6 +1240,25 @@ pub(crate) fn fetch_apply_patches(
.status()
.map_err(|e| format!("failed to create staging copy via cp -al: {e}"))?;
// Snapshot pre-existing .orig files in the source tree (some upstreams
// ship .orig files in their tarballs — e.g. glib test data). Only .orig
// files created by the patch command should be flagged as failures.
let preexisting_origs: std::collections::HashSet<String> = {
let out = Command::new("find")
.arg(&staging_dir)
.arg("-name")
.arg("*.orig")
.output();
match out {
Ok(o) => String::from_utf8_lossy(&o.stdout)
.lines()
.map(|l| l.trim().to_string())
.filter(|l| !l.is_empty())
.collect(),
Err(_) => std::collections::HashSet::new(),
}
};
let result = (|| -> Result<Vec<String>> {
let mut applied = Vec::new();
for (patch_name, patch_data) in &patch_contents {
@@ -1206,28 +1266,45 @@ pub(crate) fn fetch_apply_patches(
command.arg("--directory").arg(&staging_dir);
command.arg("--strip=1");
command.arg("--batch");
command.arg("--fuzz=0");
command.arg("--fuzz=3");
command.arg("--no-backup-if-mismatch");
run_command_stdin(command, patch_data.as_slice(), logger)
.map_err(|e| format!("patch {patch_name} FAILED: {e}"))?;
for ext in &["rej", "orig"] {
let rej_check = Command::new("find")
.arg(&staging_dir)
.arg("-name")
.arg(format!("*.{ext}"))
.arg("-print")
.arg("-quit")
.output();
if let Ok(out) = rej_check {
if !out.stdout.is_empty() {
let path = String::from_utf8_lossy(&out.stdout).trim().to_string();
// .rej files always indicate failure — check unconditionally.
let rej_check = Command::new("find")
.arg(&staging_dir)
.arg("-name")
.arg("*.rej")
.arg("-print")
.arg("-quit")
.output();
if let Ok(out) = rej_check {
if !out.stdout.is_empty() {
let path = String::from_utf8_lossy(&out.stdout).trim().to_string();
bail_other_err!(
"patch {patch_name} left .rej file (hunks failed to apply): {path}"
);
}
}
// .orig files: only flag newly-created ones (not pre-existing).
let orig_check = Command::new("find")
.arg(&staging_dir)
.arg("-name")
.arg("*.orig")
.output();
if let Ok(out) = orig_check {
for line in String::from_utf8_lossy(&out.stdout).lines() {
let trimmed = line.trim().to_string();
if !trimmed.is_empty() && !preexisting_origs.contains(&trimmed) {
bail_other_err!(
"patch {patch_name} left .{ext} file (hunks failed to apply): {path}"
"patch {patch_name} left .orig file (hunks failed to apply): {trimmed}"
);
}
}
}
applied.push(patch_name.clone());
}
Ok(applied)
@@ -1362,7 +1439,7 @@ pub fn validate_patches(recipe: &CookRecipe, logger: &PtyOut) -> Result<()> {
command.arg("--directory").arg(&staging_dir);
command.arg("--strip=1");
command.arg("--batch");
command.arg("--fuzz=0");
command.arg("--fuzz=3");
command.arg("--no-backup-if-mismatch");
match run_command_stdin(command, patch_data.as_slice(), logger) {