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

Libc: More libc functions for Redis(Part 3) #108

Merged
merged 1 commit into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions crates/axfs_vfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ pub trait VfsNodeOps: Send + Sync {
ax_err!(Unsupported)
}

/// Renames or moves existing file or directory.
fn rename(&self, _src_path: &str, _dst_path: &str) -> VfsResult {
ax_err!(Unsupported)
}

/// Convert `&self` to [`&dyn Any`][1] that can use
/// [`Any::downcast_ref`][2].
///
Expand Down
4 changes: 3 additions & 1 deletion modules/axfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ documentation = "https://rcore-os.github.io/arceos/axfs/index.html"
[features]
devfs = ["dep:axfs_devfs"]
ramfs = ["dep:axfs_ramfs"]
procfs = ["dep:axfs_ramfs"]
sysfs = ["dep:axfs_ramfs"]
fatfs = ["dep:fatfs"]
myfs = ["dep:crate_interface"]
use-ramdisk = []

default = ["devfs", "ramfs", "fatfs"]
default = ["devfs", "ramfs", "fatfs", "procfs", "sysfs"]

[dependencies]
log = "0.4"
Expand Down
8 changes: 8 additions & 0 deletions modules/axfs/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,11 @@ pub fn remove_dir(path: &str) -> io::Result<()> {
pub fn remove_file(path: &str) -> io::Result<()> {
crate::root::remove_file(None, path)
}

/// Rename a file or directory to a new name.
/// Delete the original file if `old` already exists.
///
/// This only works then the new path is in the same mounted fs.
pub fn rename(old: &str, new: &str) -> io::Result<()> {
crate::root::rename(old, new)
}
8 changes: 8 additions & 0 deletions modules/axfs/src/fops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ impl Directory {
self.entry_idx += n;
Ok(n)
}

/// Rename a file or directory to a new name.
/// Delete the original file if `old` already exists.
///
/// This only works then the new path is in the same mounted fs.
pub fn rename(&self, old: &str, new: &str) -> AxResult {
coolyjg marked this conversation as resolved.
Show resolved Hide resolved
crate::root::rename(old, new)
}
}

impl Drop for File {
Expand Down
12 changes: 12 additions & 0 deletions modules/axfs/src/fs/fatfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,18 @@ impl VfsNodeOps for DirWrapper<'static> {
}
Ok(dirents.len())
}

fn rename(&self, src_path: &str, dst_path: &str) -> VfsResult {
// `src_path` and `dst_path` should in the same mounted fs
debug!(
"rename at fatfs, src_path: {}, dst_path: {}",
src_path, dst_path
);

coolyjg marked this conversation as resolved.
Show resolved Hide resolved
self.0
.rename(src_path, &self.0, dst_path)
.map_err(as_vfs_err)
}
}

impl VfsOps for FatFileSystem {
Expand Down
1 change: 1 addition & 0 deletions modules/axfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ extern crate alloc;

mod dev;
mod fs;
mod mounts;
mod root;

pub mod api;
Expand Down
80 changes: 80 additions & 0 deletions modules/axfs/src/mounts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use alloc::sync::Arc;
use axfs_vfs::{VfsNodeType, VfsOps, VfsResult};

use crate::fs;

#[cfg(feature = "devfs")]
pub(crate) fn devfs() -> Arc<fs::devfs::DeviceFileSystem> {
let null = fs::devfs::NullDev;
let zero = fs::devfs::ZeroDev;
let bar = fs::devfs::ZeroDev;
let devfs = fs::devfs::DeviceFileSystem::new();
let foo_dir = devfs.mkdir("foo");
devfs.add("null", Arc::new(null));
devfs.add("zero", Arc::new(zero));
foo_dir.add("bar", Arc::new(bar));
Arc::new(devfs)
}

#[cfg(feature = "ramfs")]
pub(crate) fn ramfs() -> Arc<fs::ramfs::RamFileSystem> {
Arc::new(fs::ramfs::RamFileSystem::new())
}

#[cfg(feature = "procfs")]
pub(crate) fn procfs() -> VfsResult<Arc<fs::ramfs::RamFileSystem>> {
let procfs = fs::ramfs::RamFileSystem::new();
let proc_root = procfs.root_dir();

// Create /proc/sys/net/core/somaxconn
proc_root.create("sys", VfsNodeType::Dir)?;
proc_root.create("sys/net", VfsNodeType::Dir)?;
proc_root.create("sys/net/core", VfsNodeType::Dir)?;
proc_root.create("sys/net/core/somaxconn", VfsNodeType::File)?;
let file_somaxconn = proc_root.clone().lookup("./sys/net/core/somaxconn")?;
file_somaxconn.write_at(0, b"4096\n")?;

// Create /proc/sys/vm/overcommit_memory
proc_root.create("sys/vm", VfsNodeType::Dir)?;
proc_root.create("sys/vm/overcommit_memory", VfsNodeType::File)?;
let file_over = proc_root.clone().lookup("./sys/vm/overcommit_memory")?;
file_over.write_at(0, b"0\n")?;

// Create /proc/self/stat
proc_root.create("self", VfsNodeType::Dir)?;
proc_root.create("self/stat", VfsNodeType::File)?;

Ok(Arc::new(procfs))
}

#[cfg(feature = "sysfs")]
pub(crate) fn sysfs() -> VfsResult<Arc<fs::ramfs::RamFileSystem>> {
let sysfs = fs::ramfs::RamFileSystem::new();
let sys_root = sysfs.root_dir();

// Create /sys/kernel/mm/transparent_hugepage/enabled
sys_root.create("kernel", VfsNodeType::Dir)?;
sys_root.create("kernel/mm", VfsNodeType::Dir)?;
sys_root.create("kernel/mm/transparent_hugepage", VfsNodeType::Dir)?;
sys_root.create("kernel/mm/transparent_hugepage/enabled", VfsNodeType::File)?;
let file_hp = sys_root
.clone()
.lookup("./kernel/mm/transparent_hugepage/enabled")?;
file_hp.write_at(0, b"always [madvise] never\n")?;

// Create /sys/devices/system/clocksource/clocksource0/current_clocksource
sys_root.create("devices", VfsNodeType::Dir)?;
sys_root.create("devices/system", VfsNodeType::Dir)?;
sys_root.create("devices/system/clocksource", VfsNodeType::Dir)?;
sys_root.create("devices/system/clocksource/clocksource0", VfsNodeType::Dir)?;
sys_root.create(
"devices/system/clocksource/clocksource0/current_clocksource",
VfsNodeType::File,
)?;
let file_cc = sys_root
.clone()
.lookup("devices/system/clocksource/clocksource0/current_clocksource")?;
file_cc.write_at(0, b"tsc\n")?;

Ok(Arc::new(sysfs))
}
58 changes: 37 additions & 21 deletions modules/axfs/src/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use axfs_vfs::{VfsNodeAttr, VfsNodeOps, VfsNodeRef, VfsNodeType, VfsOps, VfsResu
use axsync::Mutex;
use lazy_init::LazyInit;

use crate::{api::FileType, fs};
use crate::{api::FileType, fs, mounts};

static CURRENT_DIR_PATH: Mutex<String> = Mutex::new(String::new());
static CURRENT_DIR: LazyInit<Mutex<VfsNodeRef>> = LazyInit::new();
Expand Down Expand Up @@ -131,6 +131,16 @@ impl VfsNodeOps for RootDirectory {
}
})
}

fn rename(&self, src_path: &str, dst_path: &str) -> VfsResult {
self.lookup_mounted_fs(src_path, |fs, rest_path| {
if rest_path.is_empty() {
ax_err!(PermissionDenied) // cannot rename mount points
} else {
fs.root_dir().rename(rest_path, dst_path)
}
})
}
}

pub(crate) fn init_rootfs(disk: crate::dev::Disk) {
Expand All @@ -148,28 +158,26 @@ pub(crate) fn init_rootfs(disk: crate::dev::Disk) {
let mut root_dir = RootDirectory::new(main_fs);

#[cfg(feature = "devfs")]
{
let null = fs::devfs::NullDev;
let zero = fs::devfs::ZeroDev;
let bar = fs::devfs::ZeroDev;
let devfs = fs::devfs::DeviceFileSystem::new();
let foo_dir = devfs.mkdir("foo");
devfs.add("null", Arc::new(null));
devfs.add("zero", Arc::new(zero));
foo_dir.add("bar", Arc::new(bar));

root_dir
.mount("/dev", Arc::new(devfs))
.expect("failed to mount devfs at /dev");
}
root_dir
.mount("/dev", mounts::devfs())
.expect("failed to mount devfs at /dev");

#[cfg(feature = "ramfs")]
{
let ramfs = fs::ramfs::RamFileSystem::new();
root_dir
.mount("/tmp", Arc::new(ramfs))
.expect("failed to mount ramfs at /tmp");
}
root_dir
.mount("/tmp", mounts::ramfs())
.expect("failed to mount ramfs at /tmp");

// Mount another ramfs as procfs
coolyjg marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(feature = "procfs")]
root_dir // should not fail
.mount("/proc", mounts::procfs().unwrap())
.expect("fail to mount procfs at /proc");

// Mount another ramfs as sysfs
#[cfg(feature = "sysfs")]
root_dir // should not fail
coolyjg marked this conversation as resolved.
Show resolved Hide resolved
.mount("/sys", mounts::sysfs().unwrap())
.expect("fail to mount sysfs at /sys");

ROOT_DIR.init_by(Arc::new(root_dir));
CURRENT_DIR.init_by(Mutex::new(ROOT_DIR.clone()));
Expand Down Expand Up @@ -292,3 +300,11 @@ pub(crate) fn set_current_dir(path: &str) -> AxResult {
Ok(())
}
}

pub(crate) fn rename(old: &str, new: &str) -> AxResult {
if parent_node_of(None, new).lookup(new).is_ok() {
warn!("dst file already exist, now remove it");
remove_file(None, new)?;
}
parent_node_of(None, old).rename(old, new)
}
1 change: 1 addition & 0 deletions ulib/axlibc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct {{
"pthread_.*",
"epoll_event",
"iovec",
"tm",
];
let allow_vars = [
"O_.*",
Expand Down
16 changes: 16 additions & 0 deletions ulib/axlibc/c/env.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

Expand All @@ -12,3 +14,17 @@ char *getenv(const char *name)
return *e + l + 1;
return 0;
}

// TODO
int setenv(const char *__name, const char *__value, int __replace)
{
unimplemented();
return 0;
}

// TODO
int unsetenv(const char *__name)
{
unimplemented();
return 0;
}
9 changes: 9 additions & 0 deletions ulib/axlibc/c/flock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>
#include <sys/file.h>

// TODO
int flock(int __fd, int __operation)
{
unimplemented();
return 0;
}
Loading
Loading