Skip to content

Commit

Permalink
nydusd: support remove specified blobs
Browse files Browse the repository at this point in the history
The currently API only supports removing all blobs associated with a
domain, so enhance the API to support removing specific blob too.
Also rename BlobObjectParam to BlobCacheObjectId.

Signed-off-by: Jiang Liu <gerry@linux.alibaba.com>
  • Loading branch information
jiangliu committed Jun 4, 2022
1 parent 10bb584 commit c74a772
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 27 deletions.
13 changes: 10 additions & 3 deletions api/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,16 @@ pub struct BlobCacheList {
pub blobs: Vec<BlobCacheEntry>,
}

/// Identifier for cached blob objects.
///
/// Domains are used to control the blob sharing scope. All blobs associated with the same domain
/// will be shared/reused, but blobs associated with different domains are isolated.
#[derive(Clone, Deserialize, Debug)]
pub struct BlobObjectParam {
pub struct BlobCacheObjectId {
/// Domain identifier for the object.
pub domain_id: String,
/// Blob identifier for the object.
pub blob_id: String,
}

#[derive(Debug)]
Expand Down Expand Up @@ -140,8 +147,8 @@ pub enum ApiRequest {
// Nydus API v2
DaemonInfoV2,
CreateBlobObject(BlobCacheEntry),
GetBlobObject(BlobObjectParam),
DeleteBlobObject(BlobObjectParam),
GetBlobObject(BlobCacheObjectId),
DeleteBlobObject(BlobCacheObjectId),
ListBlobObject,
}

Expand Down
8 changes: 5 additions & 3 deletions api/src/http_endpoint_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use dbs_uhttp::{Method, Request, Response};

use crate::http::{
error_response, extract_query_part, parse_body, success_response, translate_status_code,
ApiError, ApiRequest, ApiResponse, ApiResponsePayload, BlobObjectParam, EndpointHandler,
ApiError, ApiRequest, ApiResponse, ApiResponsePayload, BlobCacheObjectId, EndpointHandler,
HttpError, HttpResult,
};

Expand Down Expand Up @@ -57,7 +57,8 @@ impl EndpointHandler for BlobObjectListHandlerV2 {
match (req.method(), req.body.as_ref()) {
(Method::Get, None) => {
if let Some(domain_id) = extract_query_part(req, "domain_id") {
let param = BlobObjectParam { domain_id };
let blob_id = extract_query_part(req, "blob_id").unwrap_or_default();
let param = BlobCacheObjectId { domain_id, blob_id };
let r = kicker(ApiRequest::GetBlobObject(param));
return Ok(convert_to_response(r, HttpError::GetBlobObjects));
}
Expand All @@ -70,7 +71,8 @@ impl EndpointHandler for BlobObjectListHandlerV2 {
}
(Method::Delete, None) => {
if let Some(domain_id) = extract_query_part(req, "domain_id") {
let param = BlobObjectParam { domain_id };
let blob_id = extract_query_part(req, "blob_id").unwrap_or_default();
let param = BlobCacheObjectId { domain_id, blob_id };
let r = kicker(ApiRequest::DeleteBlobObject(param));
return Ok(convert_to_response(r, HttpError::DeleteBlobObject));
}
Expand Down
4 changes: 2 additions & 2 deletions src/bin/nydusd/api_server_glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use nix::unistd::Pid;
use nydus::{FsBackendType, NydusError};
use nydus_api::http::{
start_http_thread, ApiError, ApiMountCmd, ApiRequest, ApiResponse, ApiResponsePayload,
ApiResult, BlobCacheEntry, BlobObjectParam, DaemonConf, DaemonErrorKind, MetricsErrorKind,
ApiResult, BlobCacheEntry, BlobCacheObjectId, DaemonConf, DaemonErrorKind, MetricsErrorKind,
};
use nydus_utils::metrics;

Expand Down Expand Up @@ -311,7 +311,7 @@ impl ApiServer {
}
}

fn remove_blob_cache_entry(&self, param: &BlobObjectParam) -> ApiResponse {
fn remove_blob_cache_entry(&self, param: &BlobCacheObjectId) -> ApiResponse {
match DAEMON_CONTROLLER.get_blob_cache_mgr() {
None => Err(ApiError::DaemonAbnormal(DaemonErrorKind::Unsupported)),
Some(mgr) => {
Expand Down
44 changes: 30 additions & 14 deletions src/bin/nydusd/blob_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ use std::io::{Error, ErrorKind, Result};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, MutexGuard};

use nydus_api::http::{BlobCacheEntry, BlobCacheList, BlobObjectParam, BLOB_CACHE_TYPE_BOOTSTRAP};
use nydus_api::http::{
BlobCacheEntry, BlobCacheList, BlobCacheObjectId, BLOB_CACHE_TYPE_BOOTSTRAP,
};
use rafs::metadata::{RafsMode, RafsSuper};
use storage::cache::FsCacheConfig;
use storage::device::BlobInfo;
use storage::factory::{BackendConfig, CacheConfig, FactoryConfig};

const ID_SPLITTER: &str = "/";

fn generate_blob_key(domain_id: &str, blob_id: &str) -> String {
/// Generate blob key from domain and blob ids.
pub fn generate_blob_key(domain_id: &str, blob_id: &str) -> String {
if domain_id.is_empty() {
blob_id.to_string()
} else {
Expand Down Expand Up @@ -132,16 +135,29 @@ impl BlobCacheState {
Ok(())
}

fn remove(&mut self, domain_id: &str) {
let scoped_blob_prefix = format!("{}{}", domain_id, ID_SPLITTER);
self.id_to_config_map.retain(|_k, v| match v {
BlobCacheObjectConfig::Bootstrap(o) => {
!o.scoped_blob_id.starts_with(&scoped_blob_prefix)
}
BlobCacheObjectConfig::DataBlob(o) => {
!o.scoped_blob_id.starts_with(&scoped_blob_prefix)
}
})
fn remove(&mut self, param: &BlobCacheObjectId) {
if param.blob_id.is_empty() && !param.domain_id.is_empty() {
// Remove all blobs associated with the domain.
let scoped_blob_prefix = format!("{}{}", param.domain_id, ID_SPLITTER);
self.id_to_config_map.retain(|_k, v| match v {
BlobCacheObjectConfig::Bootstrap(o) => {
!o.scoped_blob_id.starts_with(&scoped_blob_prefix)
}
BlobCacheObjectConfig::DataBlob(o) => {
!o.scoped_blob_id.starts_with(&scoped_blob_prefix)
}
});
} else {
let scoped_blob_prefix = if param.domain_id.is_empty() {
format!("{}", param.blob_id)
} else {
format!("{}{}{}", param.domain_id, ID_SPLITTER, param.blob_id)
};
self.id_to_config_map.retain(|_k, v| match v {
BlobCacheObjectConfig::Bootstrap(o) => !o.scoped_blob_id.eq(&scoped_blob_prefix),
BlobCacheObjectConfig::DataBlob(o) => !o.scoped_blob_id.eq(&scoped_blob_prefix),
});
}
}

fn get(&self, key: &str) -> Option<BlobCacheObjectConfig> {
Expand Down Expand Up @@ -199,9 +215,9 @@ impl BlobCacheMgr {
}

/// Remove a blob object from the cache manager.
pub fn remove_blob_entry(&self, param: &BlobObjectParam) -> Result<()> {
pub fn remove_blob_entry(&self, param: &BlobCacheObjectId) -> Result<()> {
let mut state = self.get_state();
state.remove(&param.domain_id);
state.remove(param);
Ok(())
}

Expand Down
9 changes: 4 additions & 5 deletions src/bin/nydusd/fs_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ use storage::device::BlobPrefetchRequest;
use storage::factory::BLOB_FACTORY;

use crate::blob_cache::{
BlobCacheConfigBootstrap, BlobCacheConfigDataBlob, BlobCacheMgr, BlobCacheObjectConfig,
generate_blob_key, BlobCacheConfigBootstrap, BlobCacheConfigDataBlob, BlobCacheMgr,
BlobCacheObjectConfig,
};

ioctl_write_int!(fscache_cread, 0x98, 1);
Expand Down Expand Up @@ -381,12 +382,10 @@ impl FsCacheHandler {
None => msg.volume_key.clone(),
Some(str) => str.to_string(),
};
let key = domain_id + "-" + &msg.cookie_key;
let key = generate_blob_key(&domain_id, &msg.cookie_key);
let msg = match self.get_config(&key) {
None => {
unsafe {
libc::close(msg.fd as i32);
}
unsafe { libc::close(msg.fd as i32) };
format!("copen {},{}", hdr.msg_id, -libc::ENOENT)
}
Some(cfg) => match cfg {
Expand Down

0 comments on commit c74a772

Please sign in to comment.