diff --git a/src/libos/src/config.rs b/src/libos/src/config.rs index d2f61e92..772da652 100644 --- a/src/libos/src/config.rs +++ b/src/libos/src/config.rs @@ -159,6 +159,7 @@ pub struct ConfigMountOptions { pub mac: Option, pub layers: Option>, pub temporary: bool, + pub cache_size: Option, } impl Config { @@ -266,10 +267,16 @@ impl ConfigMountOptions { } else { None }; + let cache_size = if input.cache_size.is_some() { + Some(parse_memory_size(input.cache_size.as_ref().unwrap())? as _) + } else { + None + }; Ok(ConfigMountOptions { mac, layers, temporary: input.temporary, + cache_size, }) } } @@ -406,4 +413,6 @@ struct InputConfigMountOptions { pub layers: Option>, #[serde(default)] pub temporary: bool, + #[serde(default)] + pub cache_size: Option, } diff --git a/src/libos/src/fs/rootfs.rs b/src/libos/src/fs/rootfs.rs index 9f4f7142..9a3c2506 100644 --- a/src/libos/src/fs/rootfs.rs +++ b/src/libos/src/fs/rootfs.rs @@ -212,29 +212,50 @@ fn open_or_create_sefs_according_to( } let source_path = mc.source.as_ref().unwrap(); let root_mac = mc.options.mac; + let cache_size = mc.options.cache_size; let sefs = if !mc.options.temporary { if root_mac.is_some() { SEFS::open( - Box::new(SgxStorage::new(source_path, user_key, &root_mac)), + Box::new(SgxStorage::new( + source_path, + user_key, + &root_mac, + cache_size, + )?), &time::OcclumTimeProvider, &SgxUuidProvider, )? } else if source_path.join("metadata").exists() { SEFS::open( - Box::new(SgxStorage::new(source_path, user_key, &root_mac)), + Box::new(SgxStorage::new( + source_path, + user_key, + &root_mac, + cache_size, + )?), &time::OcclumTimeProvider, &SgxUuidProvider, )? } else { SEFS::create( - Box::new(SgxStorage::new(source_path, user_key, &root_mac)), + Box::new(SgxStorage::new( + source_path, + user_key, + &root_mac, + cache_size, + )?), &time::OcclumTimeProvider, &SgxUuidProvider, )? } } else { SEFS::create( - Box::new(SgxStorage::new(source_path, user_key, &root_mac)), + Box::new(SgxStorage::new( + source_path, + user_key, + &root_mac, + cache_size, + )?), &time::OcclumTimeProvider, &SgxUuidProvider, )? diff --git a/src/libos/src/fs/sefs/mod.rs b/src/libos/src/fs/sefs/mod.rs index 67fd54f6..463278df 100644 --- a/src/libos/src/fs/sefs/mod.rs +++ b/src/libos/src/fs/sefs/mod.rs @@ -5,7 +5,3 @@ pub use self::sgx_uuid_provider::SgxUuidProvider; mod sgx_storage; mod sgx_uuid_provider; - -// Cache size of underlying SGX-PFS of SEFS -// Default cache size: 0x1000 * 48 -const SEFS_CACHE_SIZE: u64 = 0x1000 * 256; diff --git a/src/libos/src/fs/sefs/sgx_storage.rs b/src/libos/src/fs/sefs/sgx_storage.rs index cd63d54b..2e86d874 100644 --- a/src/libos/src/fs/sefs/sgx_storage.rs +++ b/src/libos/src/fs/sefs/sgx_storage.rs @@ -30,6 +30,7 @@ pub struct SgxStorage { path: PathBuf, encrypt_mode: EncryptMode, file_cache: Mutex>, + cache_size: Option, } impl SgxStorage { @@ -37,13 +38,16 @@ impl SgxStorage { path: impl AsRef, key: &Option, root_mac: &Option, - ) -> Self { + cache_size: Option, + ) -> Result { // assert!(path.as_ref().is_dir()); - SgxStorage { + Self::check_cache_size(&cache_size)?; + Ok(SgxStorage { path: path.as_ref().to_path_buf(), encrypt_mode: EncryptMode::new(key, root_mac), file_cache: Mutex::new(BTreeMap::new()), - } + cache_size, + }) } /// Get file by `file_id`. /// It lookups cache first, if miss, then call `open_fn` to open one, @@ -82,6 +86,21 @@ impl SgxStorage { ) -> Result { open_fn(self) } + + fn check_cache_size(cache_size: &Option) -> Result<()> { + const PAGE_SIZE: u64 = 0x1000; + const DEFAULT_CACHE_SIZE: u64 = 48 * PAGE_SIZE; + if let Some(size) = *cache_size { + if size < DEFAULT_CACHE_SIZE || size % PAGE_SIZE != 0 { + error!( + "invalid cache size: {}, must larger than default size: {} and aligned with page size: {}", + size, DEFAULT_CACHE_SIZE, PAGE_SIZE + ); + return_errno!(EINVAL, "invalid cache size"); + } + } + Ok(()) + } } impl Storage for SgxStorage { @@ -97,11 +116,9 @@ impl Storage for SgxStorage { let file = match self.encrypt_mode { EncryptMode::IntegrityOnly(_) => options.open_integrity_only(path)?, EncryptMode::EncryptWithIntegrity(key, _) | EncryptMode::Encrypt(key) => { - options.open_with(path, Some(&key), Some(SEFS_CACHE_SIZE))? - } - EncryptMode::EncryptAutoKey => { - options.open_with(path, None, Some(SEFS_CACHE_SIZE))? + options.open_with(path, Some(&key), self.cache_size)? } + EncryptMode::EncryptAutoKey => options.open_with(path, None, self.cache_size)?, }; // Check the MAC of the root file against the given root MAC of the storage @@ -134,11 +151,9 @@ impl Storage for SgxStorage { let file = match self.encrypt_mode { EncryptMode::IntegrityOnly(_) => options.open_integrity_only(path)?, EncryptMode::EncryptWithIntegrity(key, _) | EncryptMode::Encrypt(key) => { - options.open_with(path, Some(&key), Some(SEFS_CACHE_SIZE))? - } - EncryptMode::EncryptAutoKey => { - options.open_with(path, None, Some(SEFS_CACHE_SIZE))? + options.open_with(path, Some(&key), self.cache_size)? } + EncryptMode::EncryptAutoKey => options.open_with(path, None, self.cache_size)?, }; Ok(LockedFile(Arc::new(Mutex::new(file)))) })?; diff --git a/tools/gen_internal_conf/src/main.rs b/tools/gen_internal_conf/src/main.rs index a9163dd8..0695dfd4 100644 --- a/tools/gen_internal_conf/src/main.rs +++ b/tools/gen_internal_conf/src/main.rs @@ -199,7 +199,10 @@ fn main() { heap_max_size } else { // If the user doesn't provide a value, use the max value as heap_max_size. - std::cmp::max(heap_init_size, parse_memory_size(DEFAULT_CONFIG.kernel_heap_max_size)) + std::cmp::max( + heap_init_size, + parse_memory_size(DEFAULT_CONFIG.kernel_heap_max_size), + ) } }; @@ -540,6 +543,8 @@ struct OcclumMountOptions { pub layers: Option>, #[serde(default, skip_serializing_if = "is_false")] pub temporary: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cache_size: Option, } #[inline]