Skip to content

Commit

Permalink
Builder: introduce artifact storage
Browse files Browse the repository at this point in the history
Add new ArtifactBufferWriter struct, it provides a writer to allow
writing bootstrap or blob data to a single file or in a directory.

It's useful in diff build scenario, we need to dump bootstrap for
every layer concurrently, with the aid of BootstrapManager, we can
create multiple BootstrapContexts to write bootstrap to a directory.

Signed-off-by: Yan Song <imeoer@linux.alibaba.com>
  • Loading branch information
imeoer authored and chuanlang.gcw committed Dec 3, 2021
1 parent 9b73bcb commit 3cbceb6
Show file tree
Hide file tree
Showing 15 changed files with 231 additions and 191 deletions.
2 changes: 1 addition & 1 deletion rafs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl RafsIoRead for File {}
pub type RafsIoWriter = Box<dyn RafsIoWrite>;

/// A helper trait for RafsIoWriter.
pub trait RafsIoWrite: Write + Seek {
pub trait RafsIoWrite: Write + Seek + 'static {
fn as_any(&self) -> &dyn Any;

fn validate_alignment(&mut self, size: usize, alignment: usize) -> Result<usize> {
Expand Down
8 changes: 4 additions & 4 deletions rafs/src/metadata/cached_v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ mod cached_tests {
};
use crate::metadata::layout::{RafsXAttrs, RAFS_ROOT_INODE};
use crate::metadata::{RafsInode, RafsStore, RafsSuperMeta};
use crate::{RafsIoReader, RafsIoWriter};
use crate::{BufWriter, RafsIoReader};

#[test]
fn test_load_inode() {
Expand All @@ -744,7 +744,7 @@ mod cached_tests {
.read(true)
.open("/tmp/buf_1")
.unwrap();
let mut writer = Box::new(f.try_clone().unwrap()) as RafsIoWriter;
let mut writer = BufWriter::new(f.try_clone().unwrap());
let mut reader = Box::new(f.try_clone().unwrap()) as RafsIoReader;

let mut ondisk_inode = RafsV5Inode::new();
Expand Down Expand Up @@ -815,7 +815,7 @@ mod cached_tests {
.read(true)
.open("/tmp/buf_2")
.unwrap();
let mut writer = Box::new(f.try_clone().unwrap()) as RafsIoWriter;
let mut writer = BufWriter::new(f.try_clone().unwrap());
let mut reader = Box::new(f.try_clone().unwrap()) as RafsIoReader;
let file_name = OsString::from("c_inode_2");
let symlink_name = OsString::from("c_inode_1");
Expand Down Expand Up @@ -856,7 +856,7 @@ mod cached_tests {
.read(true)
.open("/tmp/buf_3")
.unwrap();
let mut writer = Box::new(f.try_clone().unwrap()) as RafsIoWriter;
let mut writer = BufWriter::new(f.try_clone().unwrap());
let mut reader = Box::new(f.try_clone().unwrap()) as RafsIoReader;
let file_name = OsString::from("c_inode_3");
let mut ondisk_inode = RafsV5Inode::new();
Expand Down
28 changes: 14 additions & 14 deletions rafs/src/metadata/layout/v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ use crate::metadata::layout::{bytes_to_os_str, MetaRange, RafsXAttrs, RAFS_SUPER
use crate::metadata::{
Inode, RafsInode, RafsStore, RafsSuperFlags, RAFS_DEFAULT_CHUNK_SIZE, RAFS_MAX_CHUNK_SIZE,
};
use crate::{impl_bootstrap_converter, impl_pub_getter_setter, RafsIoReader, RafsIoWriter};
use crate::{impl_bootstrap_converter, impl_pub_getter_setter, RafsIoReader, RafsIoWrite};

// With Rafs v5, the storage manager needs to access file system metadata to decompress the
// compressed blob file. To avoid circular dependency, the following Rafs v5 metadata structures
Expand Down Expand Up @@ -354,7 +354,7 @@ impl RafsV5SuperBlock {
}

impl RafsStore for RafsV5SuperBlock {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.write_all(self.as_ref())?;
w.validate_alignment(self.as_ref().len(), RAFSV5_ALIGNMENT)
}
Expand Down Expand Up @@ -464,7 +464,7 @@ impl RafsV5InodeTable {
}

impl RafsStore for RafsV5InodeTable {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let (_, data, _) = unsafe { self.data.align_to::<u8>() };

w.write_all(data)?;
Expand Down Expand Up @@ -516,7 +516,7 @@ impl RafsV5PrefetchTable {
}

/// Store the inode prefetch table to a writer.
pub fn store(&mut self, w: &mut RafsIoWriter) -> Result<usize> {
pub fn store(&mut self, w: &mut dyn RafsIoWrite) -> Result<usize> {
// Sort prefetch table by inode index, hopefully, it can save time when mounting rafs
// Because file data is dumped in the order of inode index.
self.inodes.sort_unstable();
Expand Down Expand Up @@ -710,13 +710,13 @@ impl RafsV5BlobTable {
}

/// Store the extended blob information array.
pub fn store_extended(&self, w: &mut RafsIoWriter) -> Result<usize> {
pub fn store_extended(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
self.extended.store(w)
}
}

impl RafsStore for RafsV5BlobTable {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let mut size = 0;
self.entries
.iter()
Expand Down Expand Up @@ -858,7 +858,7 @@ impl RafsV5ExtBlobTable {
}

impl RafsStore for RafsV5ExtBlobTable {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let mut size = 0;

// Store the list of entries
Expand Down Expand Up @@ -1043,7 +1043,7 @@ pub struct RafsV5InodeWrapper<'a> {
}

impl<'a> RafsStore for RafsV5InodeWrapper<'a> {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let mut size: usize = 0;

let inode_data = self.inode.as_ref();
Expand Down Expand Up @@ -1109,7 +1109,7 @@ impl RafsV5ChunkInfo {
}

impl RafsStore for RafsV5ChunkInfo {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.write_all(self.as_ref())?;
w.validate_alignment(self.as_ref().len(), RAFSV5_ALIGNMENT)
}
Expand Down Expand Up @@ -1175,7 +1175,7 @@ impl RafsXAttrs {
rafsv5_align(self.size())
}

pub fn store_v5(&self, w: &mut RafsIoWriter) -> Result<usize> {
pub fn store_v5(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let mut size = 0;

if !self.pairs.is_empty() {
Expand Down Expand Up @@ -1417,7 +1417,7 @@ pub mod tests {

use super::*;
use crate::metadata::RafsStore;
use crate::{RafsIoRead, RafsIoReader, RafsIoWrite};
use crate::{RafsIoRead, RafsIoReader};
use std::any::Any;
use std::str::FromStr;

Expand Down Expand Up @@ -1535,7 +1535,7 @@ pub mod tests {
.write(true)
.open(tmp_file.as_path())
.unwrap();
let mut writer = Box::new(BufWriter::new(file)) as Box<dyn RafsIoWrite>;
let mut writer = BufWriter::new(file);
table.store(&mut writer).unwrap();

// Load extended blob table
Expand Down Expand Up @@ -1817,7 +1817,7 @@ pub mod tests {
.write(true)
.open(tmp_file.as_path())
.unwrap();
let mut writer = Box::new(BufWriter::new(file)) as Box<dyn RafsIoWrite>;
let mut writer = BufWriter::new(file);
writer.write_all(&[0u8; 8]).unwrap();
assert_eq!(table.store(&mut writer).unwrap(), 8);
writer.flush().unwrap();
Expand Down Expand Up @@ -1880,7 +1880,7 @@ pub mod tests {
.write(true)
.open(tmp_file.as_path())
.unwrap();
let mut writer = Box::new(BufWriter::new(file)) as Box<dyn RafsIoWrite>;
let mut writer = BufWriter::new(file);
assert_eq!(inode_wrapper.store(&mut writer).unwrap(), 144);
writer.flush().unwrap();

Expand Down
32 changes: 16 additions & 16 deletions rafs/src/metadata/layout/v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use lazy_static::lazy_static;
use std::convert::{TryFrom, TryInto};
use std::ffi::OsStr;
use std::fmt::Debug;
use std::io::{Read, Result, Write};
use std::io::{Read, Result};
use std::mem::size_of;
use std::os::unix::ffi::OsStrExt;
use std::sync::Arc;
Expand All @@ -18,7 +18,7 @@ use storage::meta::BlobMetaHeaderOndisk;
use storage::{compress, RAFS_MAX_CHUNK_SIZE};

use crate::metadata::{layout::RafsXAttrs, RafsStore, RafsSuperFlags};
use crate::{impl_bootstrap_converter, impl_pub_getter_setter, RafsIoReader, RafsIoWriter};
use crate::{impl_bootstrap_converter, impl_pub_getter_setter, RafsIoReader, RafsIoWrite};

/// EROFS metadata slot size.
pub const EROFS_INODE_SLOT_SIZE: usize = 1 << EROFS_INODE_SLOT_BITS;
Expand Down Expand Up @@ -211,7 +211,7 @@ impl RafsV6SuperBlock {
impl RafsStore for RafsV6SuperBlock {
// This method must be called before RafsV6SuperBlockExt::store(), otherwise data written by
// RafsV6SuperBlockExt::store() will be overwritten.
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
debug_assert!(((EROFS_SUPER_OFFSET + EROFS_SUPER_BLOCK_SIZE) as u64) < EROFS_BLOCK_SIZE);
w.write_all(&[0u8; EROFS_SUPER_OFFSET as usize])?;
w.write_all(self.as_ref())?;
Expand Down Expand Up @@ -349,7 +349,7 @@ impl RafsV6SuperBlockExt {
}

impl RafsStore for RafsV6SuperBlockExt {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.seek_to_offset((EROFS_SUPER_OFFSET + EROFS_SUPER_BLOCK_SIZE) as u64)?;
w.write_all(self.as_ref())?;
w.seek_to_offset(EROFS_BLOCK_SIZE as u64)?;
Expand Down Expand Up @@ -520,7 +520,7 @@ impl RafsV6InodeExtended {
impl_bootstrap_converter!(RafsV6InodeExtended);

impl RafsStore for RafsV6InodeExtended {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
// TODO: need to write xattr as well.
w.write_all(self.as_ref())?;
Ok(self.as_ref().len())
Expand Down Expand Up @@ -583,7 +583,7 @@ impl RafsV6Dirent {
}

impl RafsStore for RafsV6Dirent {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.write_all(self.as_ref())?;

Ok(self.as_ref().len())
Expand Down Expand Up @@ -700,7 +700,7 @@ impl RafsV6InodeChunkAddr {
impl_bootstrap_converter!(RafsV6InodeChunkAddr);

impl RafsStore for RafsV6InodeChunkAddr {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.write_all(self.as_ref())?;

Ok(self.as_ref().len())
Expand Down Expand Up @@ -776,7 +776,7 @@ impl RafsV6Device {
impl_bootstrap_converter!(RafsV6Device);

impl RafsStore for RafsV6Device {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
w.write_all(self.as_ref())?;

Ok(self.as_ref().len())
Expand Down Expand Up @@ -1094,7 +1094,7 @@ impl RafsV6BlobTable {
}

impl RafsStore for RafsV6BlobTable {
fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
for blob_info in self.entries.iter() {
let blob: RafsV6Blob = RafsV6Blob::from_blob_info(blob_info)?;
trace!(
Expand Down Expand Up @@ -1279,7 +1279,7 @@ impl RafsXAttrs {
}

/// Write Xattr to rafsv6 ondisk inode.
pub fn store_v6(&self, w: &mut RafsIoWriter) -> Result<usize> {
pub fn store_v6(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
// TODO: check count of shared.
let header = RafsV6XattrIbodyHeader::new();
w.write_all(header.as_ref())?;
Expand Down Expand Up @@ -1329,7 +1329,7 @@ impl RafsXAttrs {
#[cfg(test)]
mod tests {
use super::*;
use crate::{RafsIoRead, RafsIoWrite};
use crate::{BufWriter, RafsIoRead};
use std::ffi::OsString;
use std::fs::OpenOptions;
use vmm_sys_util::tempfile::TempFile;
Expand All @@ -1348,7 +1348,7 @@ mod tests {
.write(false)
.open(temp.as_path())
.unwrap();
let mut writer: Box<dyn RafsIoWrite> = Box::new(w);
let mut writer = BufWriter::new(w);
let mut reader: Box<dyn RafsIoRead> = Box::new(r);

sb.s_blocks = 0x1000;
Expand Down Expand Up @@ -1382,7 +1382,7 @@ mod tests {
.write(false)
.open(temp.as_path())
.unwrap();
let mut writer: Box<dyn RafsIoWrite> = Box::new(w);
let mut writer = BufWriter::new(w);
let mut reader: Box<dyn RafsIoRead> = Box::new(r);

let mut inode = RafsV6InodeExtended::new();
Expand Down Expand Up @@ -1447,7 +1447,7 @@ mod tests {
.write(false)
.open(temp.as_path())
.unwrap();
let mut writer: Box<dyn RafsIoWrite> = Box::new(w);
let mut writer = BufWriter::new(w);
let mut reader: Box<dyn RafsIoRead> = Box::new(r);

let mut chunk = RafsV6InodeChunkAddr::new();
Expand Down Expand Up @@ -1476,7 +1476,7 @@ mod tests {
.write(false)
.open(temp.as_path())
.unwrap();
let mut writer: Box<dyn RafsIoWrite> = Box::new(w);
let mut writer = BufWriter::new(w);
let mut reader: Box<dyn RafsIoRead> = Box::new(r);

let id = [0xa5u8; 32];
Expand Down Expand Up @@ -1535,7 +1535,7 @@ mod tests {
.write(false)
.open(temp.as_path())
.unwrap();
let mut writer: Box<dyn RafsIoWrite> = Box::new(w);
let mut writer = BufWriter::new(w);
let mut reader: Box<dyn RafsIoRead> = Box::new(r);

let mut xattrs = RafsXAttrs::new();
Expand Down
2 changes: 1 addition & 1 deletion rafs/src/metadata/md_v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl RafsSuper {
Ok(true)
}

pub(crate) fn store_v5(&self, w: &mut RafsIoWriter) -> Result<usize> {
pub(crate) fn store_v5(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
let mut sb = RafsV5SuperBlock::new();

sb.set_magic(self.meta.magic);
Expand Down
4 changes: 2 additions & 2 deletions rafs/src/metadata/md_v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl RafsSuper {
mod tests {
use super::*;
use crate::metadata::RafsStore;
use crate::RafsIoWriter;
use crate::BufWriter;
use std::fs::OpenOptions;
use std::io::Write;
use vmm_sys_util::tempfile::TempFile;
Expand Down Expand Up @@ -107,7 +107,7 @@ mod tests {
.open(t_file.as_path())
.unwrap();
let sb = RafsV6SuperBlock::new();
let mut writer = Box::new(file) as RafsIoWriter;
let mut writer = BufWriter::new(file);
sb.store(&mut writer).unwrap();

let file = OpenOptions::new()
Expand Down
6 changes: 3 additions & 3 deletions rafs/src/metadata/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use storage::device::{BlobChunkInfo, BlobInfo, BlobIoVec};
use self::layout::{XattrName, XattrValue, RAFS_SUPER_VERSION_V5, RAFS_SUPER_VERSION_V6};
use self::noop::NoopSuperBlock;
use crate::fs::{RafsConfig, RAFS_DEFAULT_ATTR_TIMEOUT, RAFS_DEFAULT_ENTRY_TIMEOUT};
use crate::{RafsError, RafsIoReader, RafsIoWriter, RafsResult};
use crate::{RafsError, RafsIoReader, RafsIoWrite, RafsResult};

pub mod cached_v5;
pub mod direct_v5;
Expand Down Expand Up @@ -203,7 +203,7 @@ pub trait RafsInode: Any {
/// Trait to store Rafs meta block and validate alignment.
pub trait RafsStore {
/// Write the Rafs filesystem metadata to a writer.
fn store(&self, w: &mut RafsIoWriter) -> Result<usize>;
fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize>;
}

bitflags! {
Expand Down Expand Up @@ -470,7 +470,7 @@ impl RafsSuper {
}

/// Store RAFS metadata to backend storage.
pub fn store(&self, w: &mut RafsIoWriter) -> Result<usize> {
pub fn store(&self, w: &mut dyn RafsIoWrite) -> Result<usize> {
if self.meta.is_v5() {
return self.store_v5(w);
}
Expand Down
Loading

0 comments on commit 3cbceb6

Please sign in to comment.