From 906ea0b68f8735d241427d6dd305574faa1a1b0e Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Thu, 2 Mar 2023 15:05:29 +0800 Subject: [PATCH] rafs: do not include chunk info array in the metadata blob Now we can reconstruct chunk info from RAFS v6 data blob with embedded chunk digest, so no need to embed the chunk info array in the metadata blob anymore, which helps to dramatically reduce size of metadata blob for big images. Signed-off-by: Jiang Liu --- src/bin/nydus-image/core/bootstrap.rs | 51 +++++++++++++++------------ src/bin/nydus-image/core/node.rs | 14 ++++---- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/bin/nydus-image/core/bootstrap.rs b/src/bin/nydus-image/core/bootstrap.rs index 031e9f53869..3def2171ee2 100644 --- a/src/bin/nydus-image/core/bootstrap.rs +++ b/src/bin/nydus-image/core/bootstrap.rs @@ -24,6 +24,7 @@ use nydus_utils::digest::{self, DigestHasher, RafsDigest}; use super::context::{ ArtifactStorage, BlobManager, BootstrapContext, BootstrapManager, BuildContext, ConversionType, }; +use super::feature::Feature; use super::node::{Node, WhiteoutType, OVERLAYFS_WHITEOUT_OPAQUE}; use super::tree::Tree; @@ -599,13 +600,16 @@ impl Bootstrap { ext_sb.set_blob_table_offset(blob_table_offset); ext_sb.set_blob_table_size(blob_table_size as u32); - // collect all chunks in this bootstrap. + // Collect all chunks in this bootstrap. // HashChunkDict cannot be used here, because there will be duplicate chunks between layers, // but there is no deduplication during the actual construction. // Each layer uses the corresponding chunk in the blob of its own layer. - // If HashChunkDict is used here, it will cause duplication. The chunks are removed, - // resulting in incomplete chunk info. - let mut chunk_cache = BTreeMap::new(); + // For RAFSv6 with chunk digest array, there's no need to save the chunk info array anymore. + let mut chunk_cache = if ctx.features.is_enabled(Feature::BlobToc) { + None + } else { + Some(BTreeMap::new()) + }; // Dump bootstrap timing_tracer!( @@ -616,7 +620,7 @@ impl Bootstrap { bootstrap_ctx.writer.as_mut(), orig_meta_addr, meta_addr, - &mut chunk_cache, + chunk_cache.as_mut(), ) .context("failed to dump bootstrap")?; } @@ -644,25 +648,26 @@ impl Bootstrap { pt.store(bootstrap_ctx.writer.as_mut()).unwrap(); } - // TODO: get rid of the chunk info array. - // Dump chunk info array. - let chunk_table_offset = bootstrap_ctx - .writer - .seek_to_end() - .context("failed to seek to bootstrap's end for chunk table")?; - let mut chunk_table_size: u64 = 0; - for (_, chunk) in chunk_cache.iter() { - let chunk_size = chunk - .store(bootstrap_ctx.writer.as_mut()) - .context("failed to dump chunk table")?; - chunk_table_size += chunk_size as u64; + if let Some(chunk_cache) = chunk_cache.as_ref() { + // Dump chunk info array if needed. + let chunk_table_offset = bootstrap_ctx + .writer + .seek_to_end() + .context("failed to seek to bootstrap's end for chunk table")?; + let mut chunk_table_size: u64 = 0; + for (_, chunk) in chunk_cache.iter() { + let chunk_size = chunk + .store(bootstrap_ctx.writer.as_mut()) + .context("failed to dump chunk table")?; + chunk_table_size += chunk_size as u64; + } + ext_sb.set_chunk_table(chunk_table_offset, chunk_table_size); + debug!( + "chunk_table offset {} size {}", + chunk_table_offset, chunk_table_size + ); + Self::rafsv6_align_to_block(bootstrap_ctx)?; } - ext_sb.set_chunk_table(chunk_table_offset, chunk_table_size); - debug!( - "chunk_table offset {} size {}", - chunk_table_offset, chunk_table_size - ); - Self::rafsv6_align_to_block(bootstrap_ctx)?; // Prepare device slots. let pos = bootstrap_ctx diff --git a/src/bin/nydus-image/core/node.rs b/src/bin/nydus-image/core/node.rs index 4587024e40d..c03ff1cf609 100644 --- a/src/bin/nydus-image/core/node.rs +++ b/src/bin/nydus-image/core/node.rs @@ -899,7 +899,7 @@ impl Node { f_bootstrap: &mut dyn RafsIoWrite, orig_meta_addr: u64, meta_addr: u64, - chunk_cache: &mut BTreeMap, + chunk_cache: Option<&mut BTreeMap>, ) -> Result<()> { let xattr_inline_count = self.xattrs.count_v6(); ensure!( @@ -1273,7 +1273,7 @@ impl Node { &mut self, ctx: &mut BuildContext, f_bootstrap: &mut dyn RafsIoWrite, - chunk_cache: &mut BTreeMap, + mut chunk_cache: Option<&mut BTreeMap>, inode: &mut Box, ) -> Result<()> { let mut is_continuous = true; @@ -1289,10 +1289,12 @@ impl Node { v6_chunk.set_blob_ci_index(chunk.inner.index()); v6_chunk.set_block_addr((uncompressed_offset / EROFS_BLOCK_SIZE) as u32); chunks.extend(v6_chunk.as_ref()); - chunk_cache.insert( - DigestWithBlobIndex(*chunk.inner.id(), chunk.inner.blob_index() + 1), - chunk.inner.clone(), - ); + if let Some(v) = chunk_cache.as_mut() { + v.insert( + DigestWithBlobIndex(*chunk.inner.id(), chunk.inner.blob_index() + 1), + chunk.inner.clone(), + ); + } if let Some((prev_idx, prev_pos)) = prev { if prev_pos + ctx.chunk_size as u64 != uncompressed_offset || prev_idx != blob_idx {