Skip to content

Commit

Permalink
image-rs: use a sha256 hash to mark different Overlayfs mounts
Browse files Browse the repository at this point in the history
Before this commit, different Overlayfs mounts of a same ImageClient
would mark its mounts as 1, 2, 3... Thus there will be 0,1,2... under
$work_dir/overlayfs.

If a ImageClient with same work dir launches, new mounts will fail as
the original index cannot be correctly read from the meta store json
file.

To make it easy, we changed the way to distinguish different mounts, by
calculating a hash from (overlay layer paths, mount paths, time). As the
three variables should not be the same, thus we could avoid collisions
of overlayfs working dir.

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
  • Loading branch information
Xynnn007 committed Aug 18, 2024
1 parent 97133a3 commit 316ac26
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
2 changes: 1 addition & 1 deletion image-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ oci-client-native = ["oci-client/native-tls"]
signature-simple-xrss = ["signature-simple", "dep:reqwest"]
signature-simple = ["signature", "sequoia-openpgp", "serde_yaml"]

snapshot-overlayfs = ["nix"]
snapshot-overlayfs = ["hex", "nix"]
snapshot-unionfs = ["nix", "dircpy", "fs_extra"]

getresource = ["lazy_static", "cfg-if"]
Expand Down
15 changes: 4 additions & 11 deletions image-rs/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0

use anyhow::{anyhow, bail, Result};
use anyhow::{anyhow, bail, Context, Result};
use oci_client::manifest::{OciDescriptor, OciImageManifest};
use oci_client::secrets::RegistryAuth;
use oci_client::Reference;
Expand Down Expand Up @@ -113,29 +113,22 @@ impl ImageClient {
///Initialize metadata database and supported snapshots.
pub fn init_snapshots(
config: &ImageConfig,
meta_store: &MetaStore,
_meta_store: &MetaStore,
) -> HashMap<SnapshotType, Box<dyn Snapshotter>> {
let mut snapshots = HashMap::new();

#[cfg(feature = "snapshot-overlayfs")]
{
let overlay_index = meta_store
.snapshot_db
.get(&SnapshotType::Overlay.to_string())
.unwrap_or(&0);
let data_dir = config.work_dir.join(SnapshotType::Overlay.to_string());
let overlayfs = OverlayFs::new(
data_dir,
std::sync::atomic::AtomicUsize::new(*overlay_index),
);
let overlayfs = OverlayFs::new(data_dir);
snapshots.insert(
SnapshotType::Overlay,
Box::new(overlayfs) as Box<dyn Snapshotter>,
);
}
#[cfg(feature = "snapshot-unionfs")]
{
let occlum_unionfs_index = meta_store
let occlum_unionfs_index = _meta_store
.snapshot_db
.get(&SnapshotType::OcclumUnionfs.to_string())
.unwrap_or(&0);
Expand Down
33 changes: 27 additions & 6 deletions image-rs/src/snapshots/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,52 @@

use anyhow::{anyhow, Result};
use nix::mount::MsFlags;
use sha2::{Digest, Sha256};
use std::fs;
use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::SystemTime;

use crate::snapshots::{MountPoint, SnapshotType, Snapshotter};

#[derive(Debug)]
pub struct OverlayFs {
data_dir: PathBuf,
index: AtomicUsize,
}

impl OverlayFs {
/// Create a new instance of [OverlayFs].
pub fn new(data_dir: PathBuf, index: AtomicUsize) -> Self {
OverlayFs { data_dir, index }
pub fn new(data_dir: PathBuf) -> Self {
OverlayFs { data_dir }
}
}

impl Snapshotter for OverlayFs {
fn mount(&mut self, layer_path: &[&str], mount_path: &Path) -> Result<MountPoint> {
let fs_type = SnapshotType::Overlay.to_string();
let overlay_lowerdir = layer_path.join(":");
let index = self.index.fetch_add(1, Ordering::SeqCst).to_string();
let work_dir = self.data_dir.join(index);

// derive an index path from the mount materials and current time
let mount_index = {
let mut hasher = Sha256::new();
hasher.update(layer_path.concat());
hasher.update(mount_path.as_os_str().as_bytes());

let now = SystemTime::now();
let since_unix_epoch = now
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards");

let secs = since_unix_epoch.as_secs();
let nanos = since_unix_epoch.subsec_nanos();

let mut time_seed = Vec::new();
time_seed.extend(&secs.to_le_bytes());
time_seed.extend(&nanos.to_le_bytes());
hasher.update(time_seed);
hex::encode(hasher.finalize())
};
let work_dir = self.data_dir.join(mount_index);
let overlay_upperdir = work_dir.join("upperdir");
let overlay_workdir = work_dir.join("workdir");

Expand Down

0 comments on commit 316ac26

Please sign in to comment.