diff --git a/src/runtime-rs/crates/resource/src/coco_data/initdata_block.rs b/src/runtime-rs/crates/resource/src/coco_data/initdata_block.rs index 0cc27e4d4b..129e301c12 100644 --- a/src/runtime-rs/crates/resource/src/coco_data/initdata_block.rs +++ b/src/runtime-rs/crates/resource/src/coco_data/initdata_block.rs @@ -6,7 +6,7 @@ use flate2::{Compression, GzBuilder}; use std::{ fmt, fs, - io::{self, BufWriter, Seek, Write}, + io::{self, BufWriter, Write}, path::{Path, PathBuf}, }; use tempfile::NamedTempFile; @@ -159,7 +159,7 @@ fn create_compressed_block( writer.write_all(MAGIC_HEADER)?; info!(sl!(), "Magic header written: {:?}", MAGIC_HEADER); - // 7. Configure compression level and initialize GZ writer + // 7. First compress data to get the actual compressed size let compression = compression_level.map_or(Compression::best(), |lvl| Compression::new(lvl.min(9))); @@ -169,22 +169,24 @@ fn create_compressed_block( compression.level() ); - let mut gz = GzBuilder::new() - .filename("initdata.toml") // Embed original filename metadata - .comment("Generated by Confidential Containers") - .write(writer, compression); + // Compress data to a temporary buffer first to get the compressed size + let mut compressed_data = Vec::new(); + { + let mut gz = GzBuilder::new() + .filename("initdata.toml") // Embed original filename metadata + .comment("Generated by Confidential Containers") + .write(&mut compressed_data, compression); - // 8. Write data in chunks to avoid large memory allocation - let mut bytes_written = 0; - for chunk in initdata.as_bytes().chunks(buffer_size) { - bytes_written += gz.write(chunk)?; + // Write data in chunks to avoid large memory allocation + for chunk in initdata.as_bytes().chunks(buffer_size) { + gz.write_all(chunk)?; + } + + // Finalize compression + gz.finish()?; } - info!(sl!(), "written {} bytes", bytes_written); - - // 9. Finalize compression and retrieve writer - let mut writer = gz.finish()?; - let compressed_size = writer.stream_position()?; + let compressed_size = compressed_data.len() as u64; info!( sl!(), "Data compressed: {} -> {} bytes (ratio: {:.2}%)", @@ -193,8 +195,19 @@ fn create_compressed_block( (compressed_size as f64 / initdata_size as f64) * 100.0 ); + // 8. Write compressed data length (8 bytes, little-endian) + writer.write_all(&compressed_size.to_le_bytes())?; + info!( + sl!(), + "Compressed data length written: {} bytes", compressed_size + ); + + // 9. Write compressed data + writer.write_all(&compressed_data)?; + info!(sl!(), "Compressed data written"); + // 10. Calculate padding for sector alignment - let current_pos = compressed_size; + let current_pos = MAGIC_HEADER.len() as u64 + 8 + compressed_size; // magic + length + data let padding = (SECTOR_SIZE - (current_pos % SECTOR_SIZE)) % SECTOR_SIZE; // 11. Zero-byte padding using small blocks