Skip to content

Keep unique linux assets based on content hash - #66

Merged
ermo merged 1 commit into
fix/cmdline-orderingfrom
fix/unique-kernel-detection
Aug 10, 2026
Merged

Keep unique linux assets based on content hash#66
ermo merged 1 commit into
fix/cmdline-orderingfrom
fix/unique-kernel-detection

Conversation

@tarkah

@tarkah tarkah commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Resolves #64

This computes blake3 over all installable kernel files & ensures that "conflicts" (same file name / different hash) across entries get written out & linked so that we don't clobber a previous entry's assets w/ assets that have fundamentally changed within the same kernel version.

To ensure all conflicts get written out, we append a conflict id suffix to each file ONLY if conflicts exist. If no conflicts exist, the file has no suffix / looks as it did before.

The suffix is just a deterministic conflict id based on the stable sort of each conflicting assets blake3 hash -> its index into that conflict array. So rerunning will always produce the same suffix & linkage from the entry without leaking any implementation detail.

Test

I've clobbered my current state initrd with echo "1" >> /usr/lib/kernel/7.1.5-46.stable/50-default.initrd. I have two states sharing this kernel version, so this should now produce 2 distinct assets & each entry should link to the correct one:

image

Looks good!

@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch 2 times, most recently from 1ec95b9 to a64e3cf Compare August 6, 2026 02:37
@tarkah
tarkah marked this pull request as draft August 6, 2026 22:01
@tarkah

tarkah commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Converting to draft as we finalize the exact convention for shipping conflicts as separate files.

@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from a64e3cf to a62c550 Compare August 7, 2026 16:47
@tarkah
tarkah changed the base branch from main to fix/cmdline-ordering August 7, 2026 16:47
@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from a62c550 to ce44791 Compare August 7, 2026 19:22
@tarkah
tarkah marked this pull request as ready for review August 7, 2026 19:33
@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from ce44791 to 85cb794 Compare August 7, 2026 19:37

@ermo ermo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loving the snafu contexts.

Have a few questions related to the method that appears to be the load-bearing functionality, though. =)

.insert(asset);
}

fn get_with_context<'b>(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn get_with_context<'b>(
/// (explain why this is a clever way of doing things)
fn get_with_context<'b>(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do 👍

num_conflicts: 0,
conflict_index: 0,
}),
len => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My brain is too stupid to understand what this does. Help?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a catch-all pattern match which binds the value to that var. So anything not 0 or 1 will get caught by this as len var.

@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch 4 times, most recently from ae8d145 to 69ccfc2 Compare August 8, 2026 19:03
@bhh32

bhh32 commented Aug 9, 2026

Copy link
Copy Markdown

@tarkah, this looks good to me except for one thing. Looking at what changed_files() does, it looks like it might be introduction a bit of a performance hit through rehashing on the copy detection pass that already existed.

Since you're hashing them all up front now, when the copy detection pass runs through changed_files() via install()

// build up the total changeset
let mut changeset = vec![(sysroot.join(&entry.kernel.image), vmlinuz.clone())];
changeset.extend(initrds);
// Determine which need copying now.
let needs_writing = changed_files(changeset.as_slice());
log::trace!("requires update: {needs_writing:?}");
it matches on files_identical():

pub fn changed_files(files: &[(PathBuf, PathBuf)]) -> Vec<(&PathBuf, &PathBuf)> {
let mut hasher = blake3::Hasher::new();
files
.iter()
.filter_map(|(source, dest)| match files_identical(&mut hasher, source, dest) {

files_identical() then rehashes the source file that was already hashed up front by the PR code:

/// Compare two files with blake3 to see if they differ
fn files_identical(hasher: &mut blake3::Hasher, a: &Path, b: &Path) -> io::Result<bool> {
let fi_a = File::open(a)?;
let fi_b = File::open(b)?;
let fi_a_m = fi_a.metadata()?;
let fi_b_m = fi_b.metadata()?;
if fi_a_m.size() != fi_b_m.size() || fi_a_m.file_type() != fi_b_m.file_type() {
Ok(false)
} else {
hasher.update_mmap_rayon(a)?;
let result_a = hasher.finalize();
hasher.reset();
hasher.update_mmap_rayon(b)?;
let result_b = hasher.finalize();
hasher.reset();
Ok(result_a == result_b)
}
}

I'm not sure if we're super worried about this, but that doubles the source I/O per boot sync, which depending on the system and how many states there are (the system I'm writing this on has 204 states), it could be negligible to several seconds anytime a successful moss sync -u or moss it <pkg-name> command is ran.

@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from 69ccfc2 to 63d0d72 Compare August 10, 2026 15:47
@tarkah

tarkah commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@tarkah, this looks good to me except for one thing. Looking at what changed_files() does, it looks like it might be introduction a bit of a performance hit through rehashing on the copy detection pass that already existed.

Yup, I am aware of this but I've purposely tried to minimize any alterations to the existing flows & logic. I think we can clean this up in a future wider refactor.

The good news is we only ever pass in up to 5 states from moss and blake3 be pretty quick so I don't see this as much of a blocker currently.

@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from 63d0d72 to 44114c7 Compare August 10, 2026 15:53
@tarkah
tarkah force-pushed the fix/unique-kernel-detection branch from 44114c7 to a2844d3 Compare August 10, 2026 16:17
@ermo
ermo merged commit bd22eea into main Aug 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Re-installed kernel detection

3 participants