Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wasi-fyi tests #4708

Merged
merged 28 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c031632
make rename file test repeatable
maminrayej May 16, 2024
1246108
make rename dir test repeatable
maminrayej May 16, 2024
1f44a86
make path_create_directory return error if no dir was created
maminrayej May 16, 2024
b1b885c
make create dir test repeatable
maminrayej May 16, 2024
7db2a81
enable create dir test
maminrayej May 16, 2024
2d03eca
add wasi-fyi test for create dir all for existing dirs
maminrayej May 16, 2024
2f2fe7e
add wasi-fyi test for create dir all for new dirs
maminrayej May 16, 2024
7798f93
add basic support for symlinks to the API
maminrayej May 16, 2024
28f64bd
arc_fs: add symlink support
maminrayej May 16, 2024
0097fcf
empty_fs: add symlink support
maminrayej May 16, 2024
a6d383f
host_fs: add symlink support
maminrayej May 16, 2024
12a5818
overlayfs: add symlink support
maminrayej May 16, 2024
3e3d30d
passthru_fs: add symlink support
maminrayej May 16, 2024
224157c
scoped_directory: add symlink support
maminrayej May 16, 2024
c41589c
static_fs: add symlink support
maminrayej May 16, 2024
79f9181
tmp_fs: add symlink support
maminrayej May 16, 2024
5a341f8
trace_fs: add symlink support
maminrayej May 16, 2024
2f1d474
union_fs: add symlink support
maminrayej May 16, 2024
fa99b3d
webc_fs: add symlink support
maminrayej May 16, 2024
a1c999c
webc_volume_fs: add symlink support
maminrayej May 16, 2024
c423918
mem_fs: add symlink support
maminrayej May 16, 2024
05adc18
wasifs: add symlink support
maminrayej May 16, 2024
f761294
relative_or_common_fs: add symlink support
maminrayej May 16, 2024
003d3f2
mapped_path_fs: add symlink support
maminrayej May 16, 2024
c78eadf
remove unncessary print from ported_readlink test
maminrayej May 16, 2024
bbc3f0f
add output of ported_readlink test
maminrayej May 16, 2024
307fe98
enable ported_readlink test
maminrayej May 16, 2024
6dbd4c2
Merge branch 'main' into fix-wasi-fyi-tests
maminrayej May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/arc_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ impl ArcFileSystem {
}

impl FileSystem for ArcFileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
self.fs.readlink(path)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
self.fs.read_dir(path)
}
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/empty_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ pub struct EmptyFileSystem {}

#[allow(unused_variables)]
impl FileSystem for EmptyFileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
Err(FsError::EntryNotFound)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
// Special-case the root path by returning an empty iterator.
// An empty file system should still be readable, just not contain
Expand Down
10 changes: 10 additions & 0 deletions lib/virtual-fs/src/host_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ impl FileSystem {
}

impl crate::FileSystem for FileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
fs::read_link(path).map_err(Into::into)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
let read_dir = fs::read_dir(path)?;
let mut data = read_dir
Expand Down Expand Up @@ -153,6 +157,12 @@ impl crate::FileSystem for FileSystem {
.and_then(TryInto::try_into)
.map_err(Into::into)
}

fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
fs::symlink_metadata(path)
.and_then(TryInto::try_into)
.map_err(Into::into)
}
}

impl TryInto<Metadata> for std::fs::Metadata {
Expand Down
13 changes: 10 additions & 3 deletions lib/virtual-fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub trait ClonableVirtualFile: VirtualFile + Clone {}
pub use ops::{copy_reference, copy_reference_ext};

pub trait FileSystem: fmt::Debug + Send + Sync + 'static + Upcastable {
fn readlink(&self, path: &Path) -> Result<PathBuf>;
fn read_dir(&self, path: &Path) -> Result<ReadDir>;
fn create_dir(&self, path: &Path) -> Result<()>;
fn remove_dir(&self, path: &Path) -> Result<()>;
Expand All @@ -99,9 +100,7 @@ pub trait FileSystem: fmt::Debug + Send + Sync + 'static + Upcastable {
/// This method gets metadata without following symlinks in the path.
/// Currently identical to `metadata` because symlinks aren't implemented
/// yet.
fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
self.metadata(path)
}
fn symlink_metadata(&self, path: &Path) -> Result<Metadata>;
fn remove_file(&self, path: &Path) -> Result<()>;

fn new_open_options(&self) -> OpenOptions;
Expand All @@ -128,6 +127,10 @@ where
(**self).read_dir(path)
}

fn readlink(&self, path: &Path) -> Result<PathBuf> {
(**self).readlink(path)
}

fn create_dir(&self, path: &Path) -> Result<()> {
(**self).create_dir(path)
}
Expand All @@ -144,6 +147,10 @@ where
(**self).metadata(path)
}

fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
(**self).symlink_metadata(path)
}

fn remove_file(&self, path: &Path) -> Result<()> {
(**self).remove_file(path)
}
Expand Down
29 changes: 29 additions & 0 deletions lib/virtual-fs/src/mem_fs/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,18 @@ impl FileSystem {
}

impl crate::FileSystem for FileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
// Read lock.
let guard = self.inner.read().map_err(|_| FsError::Lock)?;

// Canonicalize the path.
let (_, inode_of_directory) = guard.canonicalize(path)?;
match inode_of_directory {
InodeResolution::Found(_) => Err(FsError::InvalidInput),
InodeResolution::Redirect(fs, path) => fs.readlink(path.as_path()),
}
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
// Read lock.
let guard = self.inner.read().map_err(|_| FsError::Lock)?;
Expand Down Expand Up @@ -591,6 +603,23 @@ impl crate::FileSystem for FileSystem {
}
}

fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
// Read lock.
let guard = self.inner.read().map_err(|_| FsError::Lock)?;
match guard.inode_of(path)? {
InodeResolution::Found(inode) => Ok(guard
.storage
.get(inode)
.ok_or(FsError::UnknownError)?
.metadata()
.clone()),
InodeResolution::Redirect(fs, path) => {
drop(guard);
fs.symlink_metadata(path.as_path())
}
}
}

fn remove_file(&self, path: &Path) -> Result<()> {
let (inode_of_parent, position, inode_of_file) = {
// Read lock.
Expand Down
58 changes: 58 additions & 0 deletions lib/virtual-fs/src/overlay_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,35 @@ where
S: for<'a> FileSystems<'a> + Send + Sync + 'static,
for<'a> <<S as FileSystems<'a>>::Iter as IntoIterator>::IntoIter: Send,
{
fn readlink(&self, path: &Path) -> crate::Result<PathBuf> {
// Whiteout files can not be read, they are just markers
if ops::is_white_out(path).is_some() {
return Err(FsError::EntryNotFound);
}

// Check if the file is in the primary
match self.primary.readlink(path) {
Ok(meta) => return Ok(meta),
Err(e) if should_continue(e) => {}
Err(e) => return Err(e),
}

// There might be a whiteout, search for this
if ops::has_white_out(&self.primary, path) {
return Err(FsError::EntryNotFound);
}

// Otherwise scan the secondaries
for fs in self.secondaries.filesystems() {
match fs.readlink(path) {
Err(e) if should_continue(e) => continue,
other => return other,
}
}

Err(FsError::EntryNotFound)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir, FsError> {
let mut entries = Vec::new();
let mut had_at_least_one_success = false;
Expand Down Expand Up @@ -328,6 +357,35 @@ where
Err(FsError::EntryNotFound)
}

fn symlink_metadata(&self, path: &Path) -> crate::Result<Metadata> {
// Whiteout files can not be read, they are just markers
if ops::is_white_out(path).is_some() {
return Err(FsError::EntryNotFound);
}

// Check if the file is in the primary
match self.primary.symlink_metadata(path) {
Ok(meta) => return Ok(meta),
Err(e) if should_continue(e) => {}
Err(e) => return Err(e),
}

// There might be a whiteout, search for this
if ops::has_white_out(&self.primary, path) {
return Err(FsError::EntryNotFound);
}

// Otherwise scan the secondaries
for fs in self.secondaries.filesystems() {
match fs.symlink_metadata(path) {
Err(e) if should_continue(e) => continue,
other => return other,
}
}

Err(FsError::EntryNotFound)
}

fn remove_file(&self, path: &Path) -> Result<(), FsError> {
// It is not possible to delete whiteout files directly, instead
// one must delete the original file
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/passthru_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ impl PassthruFileSystem {
}

impl FileSystem for PassthruFileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
self.fs.readlink(path)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
self.fs.read_dir(path)
}
Expand Down
10 changes: 10 additions & 0 deletions lib/virtual-fs/src/scoped_directory_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ impl ScopedDirectoryFileSystem {
}

impl FileSystem for ScopedDirectoryFileSystem {
fn readlink(&self, path: &Path) -> crate::Result<PathBuf> {
let path = self.prepare_path(path);
self.inner.readlink(&path)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir, FsError> {
let path = self.prepare_path(path);

Expand Down Expand Up @@ -94,6 +99,11 @@ impl FileSystem for ScopedDirectoryFileSystem {
self.inner.metadata(&path)
}

fn symlink_metadata(&self, path: &Path) -> crate::Result<Metadata> {
let path = self.prepare_path(path);
self.inner.symlink_metadata(&path)
}

fn remove_file(&self, path: &Path) -> Result<(), FsError> {
let path = self.prepare_path(path);
self.inner.remove_file(&path)
Expand Down
14 changes: 14 additions & 0 deletions lib/virtual-fs/src/static_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ fn transform_into_read_dir(path: &Path, fs_entries: &[FsEntry<'_>]) -> crate::Re
}

impl FileSystem for StaticFileSystem {
fn readlink(&self, path: &Path) -> crate::Result<PathBuf> {
let path = normalizes_path(path);
if self
.volumes
.values()
.find_map(|v| v.get_file_entry(&path).ok())
.is_some()
{
Err(FsError::InvalidInput)
} else {
self.memory.readlink(Path::new(&path))
}
}

fn read_dir(&self, path: &Path) -> Result<ReadDir, FsError> {
let path = normalizes_path(path);
for volume in self.volumes.values() {
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/tmp_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ impl TmpFileSystem {
}

impl FileSystem for TmpFileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
self.fs.readlink(path)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
self.fs.read_dir(path)
}
Expand Down
10 changes: 10 additions & 0 deletions lib/virtual-fs/src/trace_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ impl<F> FileSystem for TraceFileSystem<F>
where
F: FileSystem,
{
#[tracing::instrument(level = "trace", skip(self), err)]
fn readlink(&self, path: &std::path::Path) -> crate::Result<PathBuf> {
self.0.readlink(path)
}

#[tracing::instrument(level = "trace", skip(self), err)]
fn read_dir(&self, path: &std::path::Path) -> crate::Result<crate::ReadDir> {
self.0.read_dir(path)
Expand Down Expand Up @@ -68,6 +73,11 @@ where
self.0.metadata(path)
}

#[tracing::instrument(level = "trace", skip(self), err)]
fn symlink_metadata(&self, path: &std::path::Path) -> crate::Result<crate::Metadata> {
self.0.symlink_metadata(path)
}

#[tracing::instrument(level = "trace", skip(self), err)]
fn remove_file(&self, path: &std::path::Path) -> crate::Result<()> {
self.0.remove_file(path)
Expand Down
26 changes: 26 additions & 0 deletions lib/virtual-fs/src/union_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,32 @@ impl UnionFileSystem {
}

impl FileSystem for UnionFileSystem {
fn readlink(&self, path: &Path) -> Result<PathBuf> {
debug!("readlink: path={}", path.display());
let mut ret_error = FsError::EntryNotFound;
let path = path.to_string_lossy();
for (path_inner, mount) in filter_mounts(&self.mounts, path.as_ref()) {
match mount.fs.readlink(Path::new(path_inner.as_str())) {
Ok(ret) => {
return Ok(ret);
}
Err(err) => {
// This fixes a bug when attempting to create the directory /usr when it does not exist
// on the x86 version of memfs
// TODO: patch virtual-fs and remove
if let FsError::NotAFile = &err {
ret_error = FsError::EntryNotFound;
} else {
debug!("readlink failed: (path={}) - {}", path, err);
ret_error = err;
}
}
}
}
debug!("readlink: failed={}", ret_error);
Err(ret_error)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir> {
debug!("read_dir: path={}", path.display());
self.read_dir_internal(path)
Expand Down
4 changes: 4 additions & 0 deletions lib/virtual-fs/src/webc_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ where
T: std::fmt::Debug + Send + Sync + 'static,
T: Deref<Target = WebC<'static>>,
{
fn readlink(&self, _path: &Path) -> crate::Result<PathBuf> {
Err(FsError::InvalidInput)
}

fn read_dir(&self, path: &Path) -> Result<ReadDir, FsError> {
let path = normalizes_path(path);
let read_dir_result = self
Expand Down
8 changes: 8 additions & 0 deletions lib/virtual-fs/src/webc_volume_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ impl WebcVolumeFileSystem {
}

impl FileSystem for WebcVolumeFileSystem {
fn readlink(&self, _path: &Path) -> crate::Result<PathBuf> {
Err(FsError::InvalidInput)
}

fn read_dir(&self, path: &Path) -> Result<crate::ReadDir, FsError> {
let meta = self.metadata(path)?;

Expand Down Expand Up @@ -134,6 +138,10 @@ impl FileSystem for WebcVolumeFileSystem {
.ok_or(FsError::EntryNotFound)
}

fn symlink_metadata(&self, path: &Path) -> crate::Result<Metadata> {
self.metadata(path)
}

fn remove_file(&self, path: &Path) -> Result<(), FsError> {
let meta = self.metadata(path)?;

Expand Down
13 changes: 12 additions & 1 deletion lib/wasix/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@ impl WasiFsRoot {
}

impl FileSystem for WasiFsRoot {
fn readlink(&self, path: &Path) -> virtual_fs::Result<PathBuf> {
match self {
WasiFsRoot::Sandbox(fs) => fs.readlink(path),
WasiFsRoot::Backing(fs) => fs.readlink(path),
}
}

fn read_dir(&self, path: &Path) -> virtual_fs::Result<virtual_fs::ReadDir> {
match self {
WasiFsRoot::Sandbox(fs) => fs.read_dir(path),
Expand Down Expand Up @@ -992,7 +999,8 @@ impl WasiFs {
}
} else if file_type.is_symlink() {
should_insert = false;
let link_value = file.read_link().map_err(map_io_err)?;
let link_value =
self.root_fs.readlink(&file).ok().ok_or(Errno::Noent)?;
debug!("attempting to decompose path {:?}", link_value);

let (pre_open_dir_fd, relative_path) = if link_value.is_relative() {
Expand Down Expand Up @@ -2026,6 +2034,9 @@ impl FallbackFileSystem {
}

impl FileSystem for FallbackFileSystem {
fn readlink(&self, _path: &Path) -> virtual_fs::Result<PathBuf> {
Self::fail()
}
fn read_dir(&self, _path: &Path) -> Result<virtual_fs::ReadDir, FsError> {
Self::fail();
}
Expand Down
Loading
Loading