runtime-rs: Fix initdata length field missing when create block

The init data could not be read properly within kata-agent because the
data length field was omitted, a consequence of a mismatch in the data
write format.

Fixes #11556

Signed-off-by: alex.lyn <alex.lyn@antgroup.com>
This commit is contained in:
alex.lyn 2025-07-11 20:16:32 +08:00 committed by Fupan Li
parent b76efa2a25
commit 56c0c172fa

View File

@ -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