Modify the statfs on SEFS or UnionFS with ocall
This commit is contained in:
parent
16e8b12e4d
commit
85d6977118
@ -153,6 +153,8 @@ enclave {
|
|||||||
|
|
||||||
void occlum_ocall_sync(void);
|
void occlum_ocall_sync(void);
|
||||||
|
|
||||||
|
int occlum_ocall_statfs([in, string] const char* path, [out] struct statfs* buf) propagate_errno;
|
||||||
|
|
||||||
void* occlum_ocall_posix_memalign(size_t alignment, size_t size);
|
void* occlum_ocall_posix_memalign(size_t alignment, size_t size);
|
||||||
void occlum_ocall_free([user_check] void* ptr);
|
void occlum_ocall_free([user_check] void* ptr);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ struct occlum_stdio_fds {
|
|||||||
int stderr_fd;
|
int stderr_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _timespec{
|
struct _timespec{
|
||||||
time_t tv_sec;
|
time_t tv_sec;
|
||||||
syscall_slong_t tv_nsec;
|
syscall_slong_t tv_nsec;
|
||||||
};
|
};
|
||||||
@ -34,4 +34,19 @@ typedef struct {
|
|||||||
unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
|
unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
|
||||||
} fd_set;
|
} fd_set;
|
||||||
|
|
||||||
|
struct statfs {
|
||||||
|
unsigned long f_type;
|
||||||
|
unsigned long f_bsize;
|
||||||
|
unsigned long f_blocks;
|
||||||
|
unsigned long f_bfree;
|
||||||
|
unsigned long f_bavail;
|
||||||
|
unsigned long f_files;
|
||||||
|
unsigned long f_ffree;
|
||||||
|
int f_fsid[2];
|
||||||
|
unsigned long f_namelen;
|
||||||
|
unsigned long f_frsize;
|
||||||
|
unsigned long f_flags;
|
||||||
|
unsigned long f_spare[4];
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __OCCLUM_EDL_TYPES_H__ */
|
#endif /* __OCCLUM_EDL_TYPES_H__ */
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use rcore_fs::vfs::FsInfo;
|
use rcore_fs::vfs::FsInfo;
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
pub fn do_fstatfs(fd: FileDesc) -> Result<Statfs> {
|
pub fn do_fstatfs(fd: FileDesc) -> Result<Statfs> {
|
||||||
debug!("fstatfs: fd: {}", fd);
|
debug!("fstatfs: fd: {}", fd);
|
||||||
|
|
||||||
let file_ref = current!().file(fd)?;
|
let file_ref = current!().file(fd)?;
|
||||||
let statfs = Statfs::from(file_ref.fs()?.info());
|
let statfs = {
|
||||||
|
let fs_info = file_ref.fs()?.info();
|
||||||
|
do_statfs_inner(fs_info)?
|
||||||
|
};
|
||||||
trace!("fstatfs result: {:?}", statfs);
|
trace!("fstatfs result: {:?}", statfs);
|
||||||
Ok(statfs)
|
Ok(statfs)
|
||||||
}
|
}
|
||||||
@ -18,12 +22,28 @@ pub fn do_statfs(path: &str) -> Result<Statfs> {
|
|||||||
let fs = current.fs().read().unwrap();
|
let fs = current.fs().read().unwrap();
|
||||||
fs.lookup_inode(path)?
|
fs.lookup_inode(path)?
|
||||||
};
|
};
|
||||||
let statfs = Statfs::from(inode.fs().info());
|
let statfs = {
|
||||||
|
let fs_info = inode.fs().info();
|
||||||
|
do_statfs_inner(fs_info)?
|
||||||
|
};
|
||||||
trace!("statfs result: {:?}", statfs);
|
trace!("statfs result: {:?}", statfs);
|
||||||
Ok(statfs)
|
Ok(statfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
fn do_statfs_inner(fs_info: FsInfo) -> Result<Statfs> {
|
||||||
|
let statfs = if fs_info.magic == rcore_fs_unionfs::UNIONFS_MAGIC
|
||||||
|
|| fs_info.magic == rcore_fs_sefs::SEFS_MAGIC as usize
|
||||||
|
{
|
||||||
|
let mut host_statfs = host_statfs()?;
|
||||||
|
host_statfs.f_type = fs_info.magic;
|
||||||
|
host_statfs
|
||||||
|
} else {
|
||||||
|
Statfs::from(fs_info)
|
||||||
|
};
|
||||||
|
Ok(statfs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Statfs {
|
pub struct Statfs {
|
||||||
/// Type of filesystem
|
/// Type of filesystem
|
||||||
@ -52,6 +72,21 @@ pub struct Statfs {
|
|||||||
f_spare: [usize; 4],
|
f_spare: [usize; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Statfs {
|
||||||
|
fn validate(&self) -> Result<()> {
|
||||||
|
if self.f_blocks < self.f_bfree || self.f_blocks < self.f_bavail {
|
||||||
|
return_errno!(EINVAL, "invalid blocks");
|
||||||
|
}
|
||||||
|
if self.f_files < self.f_ffree {
|
||||||
|
return_errno!(EINVAL, "invalid inodes");
|
||||||
|
}
|
||||||
|
if self.f_bsize == 0 || self.f_namelen == 0 || self.f_frsize == 0 {
|
||||||
|
return_errno!(EINVAL, "invalid non-zero fields");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<FsInfo> for Statfs {
|
impl From<FsInfo> for Statfs {
|
||||||
fn from(info: FsInfo) -> Self {
|
fn from(info: FsInfo) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -78,3 +113,23 @@ impl From<FsInfo> for Statfs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn host_statfs() -> Result<Statfs> {
|
||||||
|
extern "C" {
|
||||||
|
fn occlum_ocall_statfs(ret: *mut i32, path: *const i8, buf: *mut Statfs) -> sgx_status_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ret: i32 = 0;
|
||||||
|
let mut statfs: Statfs = Default::default();
|
||||||
|
let host_dir = unsafe { CString::new(INSTANCE_DIR.as_bytes()).unwrap() };
|
||||||
|
let sgx_status = unsafe { occlum_ocall_statfs(&mut ret, host_dir.as_ptr(), &mut statfs) };
|
||||||
|
assert!(sgx_status == sgx_status_t::SGX_SUCCESS);
|
||||||
|
assert!(ret == 0 || libc::errno() == Errno::EINTR as i32);
|
||||||
|
if ret != 0 {
|
||||||
|
return_errno!(EINTR, "failed to get host statfs");
|
||||||
|
}
|
||||||
|
|
||||||
|
// do sanity check
|
||||||
|
statfs.validate().expect("invalid statfs");
|
||||||
|
Ok(statfs)
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <sys/select.h> // import fd_set
|
#include <sys/select.h> // import fd_set
|
||||||
#include <sys/time.h> // import struct timeval
|
#include <sys/time.h> // import struct timeval
|
||||||
#include <sys/uio.h> // import struct iovec
|
#include <sys/uio.h> // import struct iovec
|
||||||
|
#include <sys/vfs.h> // import struct statfs
|
||||||
#include <occlum_pal_api.h> // import occlum_stdio_fds
|
#include <occlum_pal_api.h> // import occlum_stdio_fds
|
||||||
|
|
||||||
#endif /* __OCCLUM_EDL_TYPES__ */
|
#endif /* __OCCLUM_EDL_TYPES__ */
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
|
||||||
void occlum_ocall_sync(void) {
|
void occlum_ocall_sync(void) {
|
||||||
sync();
|
sync();
|
||||||
@ -41,3 +42,7 @@ int occlum_ocall_ioctl(int fd, int request, void *arg, size_t len) {
|
|||||||
|
|
||||||
return ioctl(fd, request, arg);
|
return ioctl(fd, request, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int occlum_ocall_statfs(const char *path, struct statfs *buf) {
|
||||||
|
return statfs(path, buf);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user