base: fix round-8 deferred stubs in initfs, randd, ptyd
initfs/tools: buffer inode table writes in memory and flush with a single write_all_at instead of one syscall per inode header. randd: build a proper entropy pool using SHA-256 that mixes hardware RNG (RDRAND/RNDRRS) with timing-derived entropy. The pool is re-seeded every 4096 reads and on every write. User-supplied entropy from writes is added to the pool rather than directly replacing the PRNG state. ptyd: VLNEXT now properly quotes the next input byte — sets a flag that causes the next byte to bypass all control-character processing and be pushed directly to the line buffer. VDISCARD now flushes the cooked input buffer instead of being a silent no-op.
This commit is contained in:
+21
-13
@@ -66,6 +66,7 @@ struct State<'path> {
|
||||
buffer: Box<[u8]>,
|
||||
inode_table_offset: u32,
|
||||
page_size: u16,
|
||||
inode_table: Vec<u8>,
|
||||
}
|
||||
|
||||
fn write_all_at(file: &File, buf: &[u8], offset: u64, r#where: &str) -> Result<()> {
|
||||
@@ -263,11 +264,8 @@ fn write_inode(
|
||||
write_result: WriteResult,
|
||||
inode: u16,
|
||||
) -> Result<()> {
|
||||
let inode_size: u32 = std::mem::size_of::<initfs::InodeHeader>()
|
||||
.try_into()
|
||||
.expect("inode header length cannot fit within u32");
|
||||
let inode_size = std::mem::size_of::<initfs::InodeHeader>();
|
||||
|
||||
// TODO: Use main buffer and write in bulk.
|
||||
let mut inode_buf = [0_u8; std::mem::size_of::<initfs::InodeHeader>()];
|
||||
|
||||
let inode_hdr = plain::from_mut_bytes::<initfs::InodeHeader>(&mut inode_buf)
|
||||
@@ -280,17 +278,15 @@ fn write_inode(
|
||||
};
|
||||
|
||||
log::debug!(
|
||||
"Writing inode index {} from offset {}",
|
||||
"Staging inode index {} from offset {}",
|
||||
inode,
|
||||
state.inode_table_offset
|
||||
);
|
||||
write_all_at(
|
||||
&state.file,
|
||||
&inode_buf,
|
||||
u64::from(state.inode_table_offset + u32::from(inode) * inode_size),
|
||||
"write_inode",
|
||||
)
|
||||
.context("failed to write inode struct to disk image")
|
||||
|
||||
let byte_offset = usize::from(inode) * inode_size;
|
||||
state.inode_table[byte_offset..byte_offset + inode_size].copy_from_slice(&inode_buf);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn allocate_and_write_dir(
|
||||
state: &mut State,
|
||||
@@ -406,7 +402,15 @@ fn allocate_contents_and_write_inodes(state: &mut State, dir: &Dir) -> Result<()
|
||||
let write_result = allocate_and_write_dir(state, dir, &mut current_inode)
|
||||
.context("failed to allocate and write all directories and files")?;
|
||||
|
||||
write_inode(state, initfs::InodeType::Dir, write_result, start_inode)
|
||||
write_inode(state, initfs::InodeType::Dir, write_result, start_inode)?;
|
||||
|
||||
write_all_at(
|
||||
&state.file,
|
||||
&state.inode_table,
|
||||
u64::from(state.inode_table_offset),
|
||||
"flush inode table",
|
||||
)
|
||||
.context("failed to write inode table to disk image")
|
||||
}
|
||||
|
||||
struct OutputImageGuard<'a> {
|
||||
@@ -491,6 +495,7 @@ pub fn archive(
|
||||
buffer: vec![0_u8; BUFFER_SIZE].into_boxed_slice(),
|
||||
inode_table_offset: 0,
|
||||
page_size: detect_page_size(),
|
||||
inode_table: Vec::new(),
|
||||
};
|
||||
|
||||
let root_path = source;
|
||||
@@ -546,6 +551,9 @@ pub fn archive(
|
||||
|
||||
state.inode_table_offset = inode_table_offset.0.get();
|
||||
|
||||
let inode_entry_size = std::mem::size_of::<initfs::InodeHeader>();
|
||||
state.inode_table = vec![0_u8; inode_entry_size * usize::from(state.inode_count)];
|
||||
|
||||
allocate_contents_and_write_inodes(&mut state, &root)?;
|
||||
|
||||
let current_system_time = std::time::SystemTime::now();
|
||||
|
||||
Reference in New Issue
Block a user